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: Mon, 31 Oct 2022 10:51:29 +0100

PS The use of assert in assert(mprotect(...)) will be fixed to work in
NDEBUG builds.

Am So., 30. Okt. 2022 um 14:38 Uhr schrieb Marc Nieper-Wißkirchen
<marc.nieper+gnu@gmail.com>:
>
> 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]