lightning
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: A first attempt to implement jit_embed


From: Marc Nieper-Wißkirchen
Subject: Re: A first attempt to implement jit_embed
Date: Sun, 30 Oct 2022 14:38:53 +0100

Here is a patch that implements, documents, and tests jit_protect and
jit_unprotect:

>From 80e6db240196e7cea0d69897a04aeb18007495cd Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marc=20Nieper-Wi=C3=9Fkirchen?= <marc@nieper-wisskirchen.de>
Date: Sun, 30 Oct 2022 14:34:08 +0100
Subject: [PATCH] Add user-visible functions jit_protect and jit_unprotect.

* check/Makefile.am: Add test for jit_protect and jit_unprotect.
* check/protect.c: New test.
* doc/body.texi: Add documentation for jit_protect and
jit_unprotect.
* include/lightning.h.in: Add prototypes for jit_protect and
jit_unprotect.
* include/lightning/jit_private.h: Add a field to store the size
of the protected memory.
* lib/lightning.c: Remember the size of the protected memory and
implement the two new functions.
---
 ChangeLog                       | 14 ++++++++
 check/Makefile.am               |  8 +++--
 check/protect.c                 | 59 +++++++++++++++++++++++++++++++++
 doc/body.texi                   | 22 ++++++++++++
 include/lightning.h.in          |  4 +++
 include/lightning/jit_private.h |  2 ++
 lib/lightning.c                 | 26 +++++++++++++--
 7 files changed, 130 insertions(+), 5 deletions(-)
 create mode 100644 check/protect.c

diff --git a/ChangeLog b/ChangeLog
index 40ade7a..0848e6c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,17 @@
+2022-10-30  Marc Nieper-Wißkirchen  <marc@nieper-wisskirchen.de>
+
+    Add user-visible functions jit_protect and jit_unprotect.
+    * check/Makefile.am: Add test for jit_protect and jit_unprotect.
+    * check/protect.c: New test.
+    * doc/body.texi: Add documentation for jit_protect and
+    jit_unprotect.
+    * include/lightning.h.in: Add prototypes for jit_protect and
+    jit_unprotect.
+    * include/lightning/jit_private.h: Add a field to store the size
+    of the protected memory.
+    * lib/lightning.c: Remember the size of the protected memory and
+    implement the two new functions.
+
 2022-10-12 Paulo Andrade <pcpa@gnu.org>

     * include/lightning/jit_loongarch.h, lib/jit_loongarch-cpu.c,
diff --git a/check/Makefile.am b/check/Makefile.am
index f58dc8b..f1839ef 100644
--- a/check/Makefile.am
+++ b/check/Makefile.am
@@ -17,7 +17,7 @@
 AM_CFLAGS = -I$(top_builddir)/include -I$(top_srcdir)/include -D_GNU_SOURCE

 check_PROGRAMS = lightning ccall self setcode nodata ctramp carg cva_list \
-    catomic
+    catomic protect

 lightning_LDADD = $(top_builddir)/lib/liblightning.la -lm $(SHLIB)
 lightning_SOURCES = lightning.c
@@ -46,6 +46,9 @@ cva_list_SOURCES = cva_list.c
 catomic_LDADD = $(top_builddir)/lib/liblightning.la -lm -lpthread $(SHLIB)
 catomic_SOURCES = catomic.c

+protect_LDADD = $(top_builddir)/lib/liblightning.la -lm $(SHLIB)
+protect_SOURCES = protect.c
+
 $(top_builddir)/lib/liblightning.la:
     cd $(top_builddir)/lib; $(MAKE) $(AM_MAKEFLAGS) liblightning.la

@@ -324,7 +327,8 @@ $(nodata_TESTS):    check.nodata.sh
 TESTS += $(nodata_TESTS)
 endif

-TESTS += ccall self setcode nodata ctramp carg cva_list catomic
+TESTS += ccall self setcode nodata ctramp carg cva_list catomic \
+         protect
 CLEANFILES = $(TESTS)

 #TESTS_ENVIRONMENT=$(srcdir)/run-test;
diff --git a/check/protect.c b/check/protect.c
new file mode 100644
index 0000000..256242b
--- /dev/null
+++ b/check/protect.c
@@ -0,0 +1,59 @@
+/*
+ * Simple test of (un)protecting a code buffer.
+ */
+
+#include <lightning.h>
+#include <stdio.h>
+#include <assert.h>
+
+#define MARKER 10
+
+int
+main(int argc, char *argv[])
+{
+    jit_state_t         *_jit;
+    jit_node_t           *load, *label, *ok;
+    unsigned char        *ptr;
+    void        (*function)(void);
+    int              mmap_prot, mmap_flags;
+
+    init_jit(argv[0]);
+    _jit = jit_new_state();
+
+    jit_prolog();
+
+    load = jit_movi(JIT_R0, 0);
+    jit_ldr_c(JIT_R0, JIT_R0);
+    ok = jit_forward();
+    jit_patch_at(jit_beqi(JIT_R0, MARKER), ok);
+    jit_prepare();
+    jit_pushargi(1);
+    jit_finishi(exit);
+    jit_link(ok);
+    jit_prepare();
+    jit_pushargi((jit_word_t)"%s\n");
+    jit_ellipsis();
+    jit_pushargi((jit_word_t)"ok");
+    jit_finishi(printf);
+
+    jit_epilog();
+    label = jit_indirect();
+    jit_prolog();               /* Reserves enough space for a byte.  */
+    jit_patch_at(load, label);
+
+    function = jit_emit();
+    if (function == NULL)
+    abort();
+
+    jit_unprotect ();
+    ptr = jit_address (label);
+    *ptr = MARKER;
+    jit_protect ();
+
+    jit_clear_state();
+
+    (*function)();
+
+    jit_destroy_state();
+    finish_jit();
+}
diff --git a/doc/body.texi b/doc/body.texi
index 1d8d277..58f84ee 100644
--- a/doc/body.texi
+++ b/doc/body.texi
@@ -1680,6 +1680,28 @@ Get the current memory allocation function.
Also, unlike the GNU GMP
 counterpart, it is an error to pass @code{NULL} pointers as arguments.
 @end deftypefun

+@section Protection
+Unless an alternate code buffer is used (see below), @code{jit_emit}
+set the access protections that the code buffer's memory can be read and
+executed, but not modified.  One can use the following functions after
+@code{jit_emit} but before @code{jit_clear} to temporarily lift the
+protection:
+
+@deftypefun void jit_unprotect ()
+Changes the access protection that the code buffer's memory can be read and
+modified.  Before the emitted code can be invoked, @code{jit_protect}
+has to be called to reset the change.
+
+This procedure has no effect when an alternate code buffer (see below) is used.
+@end deftypefun
+
+@deftypefun void jit_protect ()
+Changes the access protection that the code buffer's memory can be read and
+executed.
+
+This procedure has no effect when an alternate code buffer (see below) is used.
+@end deftypefun
+
 @section Alternate code buffer
 To instruct @lightning{} to use an alternate code buffer it is required
 to call @code{jit_realize} before @code{jit_emit}, and then query states
diff --git a/include/lightning.h.in b/include/lightning.h.in
index 67c6af1..2ed593b 100644
--- a/include/lightning.h.in
+++ b/include/lightning.h.in
@@ -1016,6 +1016,10 @@ extern void _jit_frame(jit_state_t*, jit_int32_t);
 extern void _jit_tramp(jit_state_t*, jit_int32_t);
 #define jit_emit()        _jit_emit(_jit)
 extern jit_pointer_t _jit_emit(jit_state_t*);
+#define jit_unprotect()         _jit_unprotect(_jit)
+extern void _jit_unprotect(jit_state_t*);
+#define jit_protect()           _jit_protect(_jit)
+extern void _jit_protect(jit_state_t*);

 #define jit_print()        _jit_print(_jit)
 extern void _jit_print(jit_state_t*);
diff --git a/include/lightning/jit_private.h b/include/lightning/jit_private.h
index 6d93ad8..a0c59af 100644
--- a/include/lightning/jit_private.h
+++ b/include/lightning/jit_private.h
@@ -658,6 +658,8 @@ struct jit_state {
     struct {
     jit_uint8_t    *ptr;
     jit_word_t     length;
+        /* PROTECTED bytes starting at PTR are mprotect'd. */
+        jit_word_t       protected;
     } code;
     struct {
     jit_uint8_t    *ptr;
diff --git a/lib/lightning.c b/lib/lightning.c
index 00f2a07..8bb1fcf 100644
--- a/lib/lightning.c
+++ b/lib/lightning.c
@@ -2398,12 +2398,12 @@ _jit_emit(jit_state_t *_jit)
     assert(result == 0);
     }
     if (!_jit->user_code) {
-    length = _jit->pc.uc - _jit->code.ptr;
+    _jit->code.protected = _jit->pc.uc - _jit->code.ptr;
 #  if __riscv && __WORDSIZE == 64
     /* FIXME should start adding consts at a page boundary */
-    length -= _jitc->consts.hash.count * sizeof(jit_word_t);
+    _jit->code.protected -= _jitc->consts.hash.count * sizeof(jit_word_t);
 #  endif
-    result = mprotect(_jit->code.ptr, length, PROT_READ | PROT_EXEC);
+    result = mprotect(_jit->code.ptr, _jit->code.protected, PROT_READ
| PROT_EXEC);
     assert(result == 0);
     }
 #endif /* HAVE_MMAP */
@@ -2413,6 +2413,26 @@ fail:
     return (NULL);
 }

+void
+_jit_protect(jit_state_t *_jit)
+{
+#if !HAVE_MMAP
+  assert (_jit->user_code);
+#endif
+  if (_jit->user_code) return;
+  assert (mprotect (_jit->code.ptr, _jit->code.protected, PROT_READ |
PROT_EXEC) == 0);
+}
+
+void
+_jit_unprotect(jit_state_t *_jit)
+{
+#if !HAVE_MMAP
+  assert (_jit->user_code);
+#endif
+  if (_jit->user_code) return;
+  assert (mprotect (_jit->code.ptr, _jit->code.protected, PROT_READ |
PROT_WRITE) == 0);
+}
+
 void
 _jit_frame(jit_state_t *_jit, jit_int32_t frame)
 {
-- 
2.34.1

Am Sa., 29. Okt. 2022 um 23:18 Uhr schrieb Marc Nieper-Wißkirchen
<marc.nieper+gnu@gmail.com>:
>
> Am Di., 16. Aug. 2022 um 20:35 Uhr schrieb Paulo César Pereira de
> Andrade <paulo.cesar.pereira.de.andrade@gmail.com>:
> >
> > Em dom., 14 de ago. de 2022 às 17:35, Marc Nieper-Wißkirchen
> > <marc.nieper+gnu@gmail.com> escreveu:
> >
> >   Hi,
> >
> > > With the patch below, I implemented
> > >
> > > jit_embed(jit_pointer_t data, jit_uint32_t length)
> > >
> > > At the moment, the implementation is for x86, but porting to other CPUs 
> > > is simple.
> > >
> > > Criticism is welcome.
> >
> >   It appears you forgot to add the embed.tst file to the patch.
> >   It could be useful to add multiple data types, so one could even add
> > assembly code in some different way, like encoded bytes.
>
> What do you mean by this? The DATA can point to arbitrary data,
> including machine code.
>
> jit_embed, however, has one limitation: the data has to be known
> during jitting.  For example, this precludes an address only known
> after code generation is embedded.
>
> This, let me suggest an instruction jit_skip instead that works like
> jit_align and emits nops (as many as jit_skip's argument says).  The
> corresponding memory area can be patched later after the code is
> emitted.
>
> So that this works for non-alternative code buffers, two procedures
> jit_unprotect and jit_protect have to be offered as well. They can be
> called after jit_emit and before jit_clear.  Jit_unprotect makes the
> code memory area writable (and possibly non-executable), jit_protect
> reverses this.
>
> What do you think? It looks a lot more flexible to me.
>
> Thank you,
>
> Marc
>
>
>
> >
> >   It should also be possible to add embed data larger than jit_instr_max.
> >   Could change lib/jit_size.c:_jit_get_size() to check for jit_embed and
> > update the guessed size as appropriate. BTW, jit_get_size() likely
> > overestimates the size. It just plays safe, to not risk writing out of 
> > bounds.
> >   jit_code_embed should be handled in a special way, so that the jit_*sz.c
> > files would not add the largest found value when computing the size.
> >   The patch also did not update the jit_x86-sz.c file, nor any other files,
> > so, it will compute the guessed buffer size incorrectly.
> >   Probably  no need to have jit_cc_a1_len, otherwise, could have a
> > generic way to print integers. Currently it only prints hexadecimal values
> > for any immediate value. Having it print signed integers for offsets would
> > be useful.
> >   Could also use the word (w) field, no need for an extra uint32 field.
> >   I suggested a prototype with a int32 field because I do not expect one
> > to embed more than 2G of data in a code buffer :)
> >
> > > Thanks,
> > >
> > > Marc
> > >
> > > diff --git a/bootstrap.conf b/bootstrap.conf
> > > index 423491b..c257814 100644
> > > --- a/bootstrap.conf
> > > +++ b/bootstrap.conf
> > > @@ -18,6 +18,7 @@
> > >
> > >  # gnulib modules used by this package.
> > >  gnulib_modules="
> > > +  obstack
> > >  "
> > >
> > >  # gnulib library name.
> > > diff --git a/check/Makefile.am b/check/Makefile.am
> > > index fc9f232..48b6f41 100644
> > > --- a/check/Makefile.am
> > > +++ b/check/Makefile.am
> > > @@ -49,6 +49,7 @@ EXTRA_DIST = \
> > >   3to2.tst 3to2.ok \
> > >   add.tst add.ok \
> > >   align.tst align.ok \
> > > + embed.tst embed.ok \
> > >   allocai.tst allocai.ok \
> > >   allocar.tst allocar.ok \
> > >   bp.tst bp.ok \
> > > @@ -113,7 +114,7 @@ EXTRA_DIST = \
> > >   run-test all.tst
> > >
> > >  base_TESTS = \
> > > - 3to2 add align allocai \
> > > + 3to2 add align embed allocai \
> > >   allocar bp divi fib rpn \
> > >   ldstr ldsti \
> > >   ldstxr ldstxi \
> > > @@ -192,7 +193,8 @@ endif
> > >  if test_arm_arm
> > >  #arm_TESTS = $(addsuffix .arm, $(base_TESTS))
> > >  arm_TESTS = \
> > > - 3to2.arm add.arm align.arm allocai.arm \
> > > + 3to2.arm add.arm align.arm embed.arm \
> > > + allocai.arm \
> > >   allocar.arm bp.arm divi.arm fib.arm \
> > >   rpn.arm ldstr.arm ldsti.arm \
> > >   ldstxr.arm ldstxi.arm \
> > > diff --git a/check/lightning.c b/check/lightning.c
> > > index 3cf3e70..0a4b5ca 100644
> > > --- a/check/lightning.c
> > > +++ b/check/lightning.c
> > > @@ -26,6 +26,7 @@
> > >  #else
> > >  #  include <unistd.h>
> > >  #endif
> > > +#include <obstack.h>
> > >  #include <stdio.h>
> > >  #include <stdarg.h>
> > >  #include <lightning.h>
> > > @@ -529,6 +530,7 @@ static label_t *get_label(skip_t skip);
> > >  static token_t regname(void);
> > >  static token_t identifier(int ch);
> > >  static void get_data(type_t type);
> > > +static void get_embedded_data(type_t type);
> > >  static void dot(void);
> > >  static token_t number(int ch);
> > >  static int escape(int ch);
> > > @@ -585,6 +587,7 @@ static int  symbol_offset;
> > >  static hash_t *instrs;
> > >  static char *data;
> > >  static size_t  data_offset, data_length;
> > > +static struct obstack     obstack[1];
> > >  static instr_t  instr_vector[] = {
> > >  #define entry(value) { NULL, #value, value }
> > >  #define entry2(name, function) { NULL, name, function }
> > > @@ -833,6 +836,12 @@ static instr_t  instr_vector[] = {
> > >  #undef entry
> > >  };
> > >
> > > +/*
> > > + * Obstack allocation
> > > + */
> > > +#define obstack_chunk_alloc xmalloc
> > > +#define obstack_chunk_free free
> > > +
> > >  /*
> > >   * Implementation
> > >   */
> > > @@ -2176,6 +2185,9 @@ get_data(type_t type)
> > >      token_t token;
> > >      char *test = data;
> > >
> > > +    if (parser.parsing == PARSING_CODE)
> > > +      return get_embedded_data(type);
> > > +
> > >      for (;;) {
> > >   switch (type) {
> > >      case type_c:
> > > @@ -2239,6 +2251,32 @@ get_data(type_t type)
> > >      }
> > >  }
> > >
> > > +static void
> > > +get_embedded_data(type_t type)
> > > +{
> > > +    void *data;
> > > +    int ch;
> > > +    jit_uint32_t len;
> > > +
> > > +    for (;;) {
> > > + switch (type) {
> > > + case type_i:
> > > +    len = sizeof(signed int);
> > > +    data = obstack_alloc(obstack, len);
> > > +    *(signed int *)data = get_int(skip_ws);
> > > +    jit_embed(data, len);
> > > +    break;
> > > + /* FIXME **more types** */
> > > + default:
> > > +    abort();
> > > + }
> > > + ch = skipws();
> > > + if (ch == '\n' || ch == ';' || ch == EOF)
> > > +    break;
> > > + ungetch(ch);
> > > +    }
> > > +}
> > > +
> > >  static void
> > >  dot(void)
> > >  {
> > > @@ -4086,6 +4124,8 @@ main(int argc, char *argv[])
> > >      optind = 1;
> > >  #endif
> > >
> > > +    obstack_init (obstack);
> > > +
> > >      progname = argv[0];
> > >
> > >      init_jit(progname);
> > > @@ -4344,5 +4384,7 @@ main(int argc, char *argv[])
> > >
> > >      finish_jit();
> > >
> > > +    obstack_free (obstack, NULL);
> > > +
> > >      return (0);
> > >  }
> > > diff --git a/gnulib-lib/.gitignore b/gnulib-lib/.gitignore
> > > index d9f5394..9d61cde 100644
> > > --- a/gnulib-lib/.gitignore
> > > +++ b/gnulib-lib/.gitignore
> > > @@ -1,2 +1,18 @@
> > >  /Makefile.am
> > > -/dummy.c
> > > +/_Noreturn.h
> > > +/alignof.h
> > > +/arg-nonnull.h
> > > +/c++defs.h
> > > +/exitfail.c
> > > +/exitfail.h
> > > +/gettext.h
> > > +/limits.in.h
> > > +/obstack.c
> > > +/obstack.h
> > > +/stddef.in.h
> > > +/stdint.in.h
> > > +/stdlib.in.h
> > > +/sys_types.in.h
> > > +/unistd.c
> > > +/unistd.in.h
> > > +/warn-on-use.h
> > > diff --git a/include/lightning.h.in b/include/lightning.h.in
> > > index 887a951..a7186a7 100644
> > > --- a/include/lightning.h.in
> > > +++ b/include/lightning.h.in
> > > @@ -187,6 +187,8 @@ typedef enum {
> > >  #define jit_align(u) jit_new_node_w(jit_code_align, u)
> > >      jit_code_live, jit_code_align,
> > >      jit_code_save, jit_code_load,
> > > +#define jit_embed(u,v)          jit_new_node_pl(jit_code_embed,u,v)
> > > +    jit_code_embed,
> > >  #define jit_name(u) _jit_name(_jit,u)
> > >      jit_code_name,
> > >  #define jit_note(u, v) _jit_note(_jit, u, v)
> > > @@ -1096,6 +1098,9 @@ extern jit_node_t *_jit_new_node_pwf(jit_state_t*, 
> > > jit_code_t,
> > >  #define jit_new_node_pwd(c,u,v,w) _jit_new_node_pwd(_jit,c,u,v,w)
> > >  extern jit_node_t *_jit_new_node_pwd(jit_state_t*, jit_code_t,
> > >       jit_pointer_t, jit_word_t, jit_float64_t);
> > > +#define jit_new_node_pl(c,u,v)    _jit_new_node_pl(_jit,c,u,v)
> > > +extern jit_node_t *_jit_new_node_pl(jit_state_t*, jit_code_t,
> > > +    jit_pointer_t, jit_uint32_t);
> > >
> > >  #define jit_arg_register_p(u) _jit_arg_register_p(_jit,u)
> > >  extern jit_bool_t _jit_arg_register_p(jit_state_t*, jit_node_t*);
> > > diff --git a/include/lightning/jit_private.h 
> > > b/include/lightning/jit_private.h
> > > index 0af24cb..97822e2 100644
> > > --- a/include/lightning/jit_private.h
> > > +++ b/include/lightning/jit_private.h
> > > @@ -276,6 +276,7 @@ extern jit_node_t *_jit_data(jit_state_t*, const 
> > > void*,
> > >  #define jit_cc_a2_int 0x00100000 /* arg2 is immediate word */
> > >  #define jit_cc_a2_flt 0x00200000 /* arg2 is immediate float */
> > >  #define jit_cc_a2_dbl 0x00400000 /* arg2 is immediate double */
> > > +#define jit_cc_a1_len           0x00800000 /* arg1 is an immediate uint 
> > > length */
> > >
> > >  #if __ia64__ || (__sparc__ && __WORDSIZE == 64)
> > >  extern void
> > > @@ -381,6 +382,7 @@ union jit_data {
> > >      jit_float64_t d;
> > >      jit_pointer_t p;
> > >      jit_node_t *n;
> > > +    jit_uint32_t         l;
> > >  };
> > >
> > >  struct jit_note {
> > > diff --git a/lib/jit_names.c b/lib/jit_names.c
> > > index ebd3d56..69ae274 100644
> > > --- a/lib/jit_names.c
> > > +++ b/lib/jit_names.c
> > > @@ -21,6 +21,7 @@ static char *code_name[] = {
> > >      "data",
> > >      "live", "align",
> > >      "save", "load",
> > > +    "embed",
> > >      "#name", "#note",
> > >      "label",
> > >      "prolog",
> > > diff --git a/lib/jit_print.c b/lib/jit_print.c
> > > index 61d9650..b9b3ece 100644
> > > --- a/lib/jit_print.c
> > > +++ b/lib/jit_print.c
> > > @@ -107,7 +107,7 @@ _jit_print_node(jit_state_t *_jit, jit_node_t *node)
> > >   (jit_cc_a0_int|jit_cc_a0_flt|jit_cc_a0_dbl|jit_cc_a0_jmp|
> > >   jit_cc_a0_reg|jit_cc_a0_rlh|jit_cc_a0_arg|
> > >   jit_cc_a1_reg|jit_cc_a1_int|jit_cc_a1_flt|jit_cc_a1_dbl|jit_cc_a1_arg|
> > > - jit_cc_a2_reg|jit_cc_a2_int|jit_cc_a2_flt|jit_cc_a2_dbl);
> > > + jit_cc_a2_reg|jit_cc_a2_int|jit_cc_a2_flt|jit_cc_a2_dbl|jit_cc_a1_len);
> > >      if (!(node->flag & jit_flag_synth) && ((value & jit_cc_a0_jmp) ||
> > >     node->code == jit_code_finishr ||
> > >     node->code == jit_code_finishi))
> > > @@ -289,6 +289,10 @@ _jit_print_node(jit_state_t *_jit, jit_node_t *node)
> > >      else
> > >   print_flt(node->w.d);
> > >      return;
> > > +        l:
> > > +    print_chr(' '); print_ptr(node->u.p);
> > > +    print_chr(' '); print_dec(node->v.l);
> > > +    return;
> > >   case jit_code_name:
> > >      print_chr(' ');
> > >      if (node->v.p && _jitc->emit)
> > > @@ -371,7 +375,9 @@ _jit_print_node(jit_state_t *_jit, jit_node_t *node)
> > >      goto n_r_f;
> > >   case jit_cc_a0_jmp|jit_cc_a1_reg|jit_cc_a2_dbl:
> > >      goto n_r_d;
> > > - default:
> > > +        case jit_cc_a1_len:
> > > +    goto l;
> > > +        default:
> > >      abort();
> > >      }
> > >      break;
> > > diff --git a/lib/jit_x86.c b/lib/jit_x86.c
> > > index e3e1383..b650f7f 100644
> > > --- a/lib/jit_x86.c
> > > +++ b/lib/jit_x86.c
> > > @@ -1598,6 +1598,11 @@ _emit_code(jit_state_t *_jit)
> > >   if ((word = _jit->pc.w & (node->u.w - 1)))
> > >      nop(node->u.w - word);
> > >   break;
> > > +    case jit_code_embed:
> > > + assert(node->v.l <= jit_get_max_instr());
> > > + jit_memcpy(_jit->pc.uc, node->u.p, node->v.l);
> > > + _jit->pc.uc += node->v.l;
> > > + break;
> > >      case jit_code_note: case jit_code_name:
> > >   node->u.w = _jit->pc.w;
> > >   break;
> > > diff --git a/lib/lightning.c b/lib/lightning.c
> > > index b78bd07..374aa32 100644
> > > --- a/lib/lightning.c
> > > +++ b/lib/lightning.c
> > > @@ -1198,6 +1198,17 @@ _jit_new_node_pwd(jit_state_t *_jit, jit_code_t 
> > > code,
> > >      return (link_node(node));
> > >  }
> > >
> > > +jit_node_t *
> > > +_jit_new_node_pl(jit_state_t *_jit, jit_code_t code,
> > > + jit_pointer_t u, jit_uint32_t v)
> > > +{
> > > +    jit_node_t *node = new_node(code);
> > > +    assert(!_jitc->realize);
> > > +    node->u.p = u;
> > > +    node->v.l = v;
> > > +    return (link_node(node));
> > > +}
> > > +
> > >  jit_node_t *
> > >  _jit_label(jit_state_t *_jit)
> > >  {
> > > @@ -1316,6 +1327,9 @@ _jit_classify(jit_state_t *_jit, jit_code_t code)
> > >   case jit_code_finishi: /* synthesized will set jit_cc_a0_jmp */
> > >      mask = jit_cc_a0_int;
> > >      break;
> > > +        case jit_code_embed:
> > > +    mask = jit_cc_a1_len;
> > > +    break;
> > >   case jit_code_reti_f: case jit_code_pushargi_f:
> > >      mask = jit_cc_a0_flt;
> > >      break;
> > > diff --git a/m4/.gitignore b/m4/.gitignore
> > > index 24e2f3f..870b024 100644
> > > --- a/m4/.gitignore
> > > +++ b/m4/.gitignore
> > > @@ -8,3 +8,21 @@
> > >  /gnulib-comp.m4
> > >  /gnulib-tool.m4
> > >  /zzgnulib.m4
> > > +/absolute-header.m4
> > > +/extensions.m4
> > > +/extern-inline.m4
> > > +/include_next.m4
> > > +/limits-h.m4
> > > +/multiarch.m4
> > > +/obstack.m4
> > > +/off_t.m4
> > > +/pid_t.m4
> > > +/ssize_t.m4
> > > +/stddef_h.m4
> > > +/stdint.m4
> > > +/stdlib_h.m4
> > > +/sys_types_h.m4
> > > +/unistd_h.m4
> > > +/warn-on-use.m4
> > > +/wchar_t.m4
> > > +/wint_t.m4
> > > diff --git a/m4/gnulib-cache.m4 b/m4/gnulib-cache.m4
> > > index 45be7ba..2a2d48b 100644
> > > --- a/m4/gnulib-cache.m4
> > > +++ b/m4/gnulib-cache.m4
> > > @@ -36,12 +36,13 @@
> > >  #  --aux-dir=build-aux \
> > >  #  --no-conditional-dependencies \
> > >  #  --libtool \
> > > -#  --macro-prefix=gl
> > > +#  --macro-prefix=gl \
> > > +#  obstack
> > >
> > >  # Specification in the form of a few gnulib-tool.m4 macro invocations:
> > >  gl_LOCAL_DIR([gl])
> > >  gl_MODULES([
> > > -
> > > +  obstack
> > >  ])
> > >  gl_AVOID([])
> > >  gl_SOURCE_BASE([gnulib-lib])



reply via email to

[Prev in Thread] Current Thread [Next in Thread]