mirror of
				https://github.com/janet-lang/janet
				synced 2025-10-30 23:23:07 +00:00 
			
		
		
		
	Update symbolmapping code with marshal/unmarshal.
This commit is contained in:
		| @@ -721,11 +721,10 @@ static JanetAssembleResult janet_asm1(JanetAssembler *parent, Janet source, int | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /* Set symbolslots */ |     /* Set symbolmap */ | ||||||
|     def->symbolmap = NULL; |     def->symbolmap = NULL; | ||||||
|     def->symbolmap_length = 0; |     def->symbolmap_length = 0; | ||||||
|  |     x = janet_get1(s, janet_ckeywordv("symbolmap")); | ||||||
|     x = janet_get1(s, janet_ckeywordv("symbolslots")); |  | ||||||
|     if (janet_indexed_view(x, &arr, &count)) { |     if (janet_indexed_view(x, &arr, &count)) { | ||||||
|         def->symbolmap_length = count; |         def->symbolmap_length = count; | ||||||
|         def->symbolmap = janet_malloc(sizeof(JanetSymbolMap) * (size_t)count); |         def->symbolmap = janet_malloc(sizeof(JanetSymbolMap) * (size_t)count); | ||||||
| @@ -749,16 +748,17 @@ static JanetAssembleResult janet_asm1(JanetAssembler *parent, Janet source, int | |||||||
|             if (!janet_checkint(tup[2])) { |             if (!janet_checkint(tup[2])) { | ||||||
|                 janet_asm_error(&a, "expected integer"); |                 janet_asm_error(&a, "expected integer"); | ||||||
|             } |             } | ||||||
|             if (!janet_checktype(tup[3], JANET_STRING)) { |             if (!janet_checktype(tup[3], JANET_SYMBOL)) { | ||||||
|                 janet_asm_error(&a, "expected string"); |                 janet_asm_error(&a, "expected symbol"); | ||||||
|             } |             } | ||||||
|             ss.birth_pc = janet_unwrap_integer(tup[0]); |             ss.birth_pc = janet_unwrap_integer(tup[0]); | ||||||
|             ss.death_pc = janet_unwrap_integer(tup[1]); |             ss.death_pc = janet_unwrap_integer(tup[1]); | ||||||
|             ss.slot_index = janet_unwrap_integer(tup[2]); |             ss.slot_index = janet_unwrap_integer(tup[2]); | ||||||
|             ss.symbol = janet_unwrap_string(tup[3]); |             ss.symbol = janet_unwrap_symbol(tup[3]); | ||||||
|             def->symbolmap[i] = ss; |             def->symbolmap[i] = ss; | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |     if (def->symbolmap_length) def->flags |= JANET_FUNCDEF_FLAG_HASSYMBOLMAP; | ||||||
|  |  | ||||||
|     /* Set environments */ |     /* Set environments */ | ||||||
|     x = janet_get1(s, janet_ckeywordv("environments")); |     x = janet_get1(s, janet_ckeywordv("environments")); | ||||||
| @@ -934,7 +934,7 @@ static Janet janet_disasm_symbolslots(JanetFuncDef *def) { | |||||||
|         t[0] = janet_wrap_integer(ss.birth_pc); |         t[0] = janet_wrap_integer(ss.birth_pc); | ||||||
|         t[1] = janet_wrap_integer(ss.death_pc); |         t[1] = janet_wrap_integer(ss.death_pc); | ||||||
|         t[2] = janet_wrap_integer(ss.slot_index); |         t[2] = janet_wrap_integer(ss.slot_index); | ||||||
|         t[3] = janet_cstringv((const char *) ss.symbol); |         t[3] = janet_wrap_symbol(ss.symbol); | ||||||
|         symbolslots->data[i] = janet_wrap_tuple(janet_tuple_end(t)); |         symbolslots->data[i] = janet_wrap_tuple(janet_tuple_end(t)); | ||||||
|     } |     } | ||||||
|     symbolslots->count = def->symbolmap_length; |     symbolslots->count = def->symbolmap_length; | ||||||
| @@ -1021,7 +1021,7 @@ Janet janet_disasm(JanetFuncDef *def) { | |||||||
|     janet_table_put(ret, janet_ckeywordv("structarg"), janet_disasm_structarg(def)); |     janet_table_put(ret, janet_ckeywordv("structarg"), janet_disasm_structarg(def)); | ||||||
|     janet_table_put(ret, janet_ckeywordv("name"), janet_disasm_name(def)); |     janet_table_put(ret, janet_ckeywordv("name"), janet_disasm_name(def)); | ||||||
|     janet_table_put(ret, janet_ckeywordv("slotcount"), janet_disasm_slotcount(def)); |     janet_table_put(ret, janet_ckeywordv("slotcount"), janet_disasm_slotcount(def)); | ||||||
|     janet_table_put(ret, janet_ckeywordv("symbolslots"), janet_disasm_symbolslots(def)); |     janet_table_put(ret, janet_ckeywordv("symbolmap"), janet_disasm_symbolslots(def)); | ||||||
|     janet_table_put(ret, janet_ckeywordv("constants"), janet_disasm_constants(def)); |     janet_table_put(ret, janet_ckeywordv("constants"), janet_disasm_constants(def)); | ||||||
|     janet_table_put(ret, janet_ckeywordv("sourcemap"), janet_disasm_sourcemap(def)); |     janet_table_put(ret, janet_ckeywordv("sourcemap"), janet_disasm_sourcemap(def)); | ||||||
|     janet_table_put(ret, janet_ckeywordv("environments"), janet_disasm_environments(def)); |     janet_table_put(ret, janet_ckeywordv("environments"), janet_disasm_environments(def)); | ||||||
| @@ -1058,7 +1058,7 @@ JANET_CORE_FN(cfun_disasm, | |||||||
|               "* :source - name of source file that this function was compiled from.\n" |               "* :source - name of source file that this function was compiled from.\n" | ||||||
|               "* :name - name of function.\n" |               "* :name - name of function.\n" | ||||||
|               "* :slotcount - how many virtual registers, or slots, this function uses. Corresponds to stack space used by function.\n" |               "* :slotcount - how many virtual registers, or slots, this function uses. Corresponds to stack space used by function.\n" | ||||||
|               "* :symbolslots - all symbols and their slots.\n" |               "* :symbolmap - all symbols and their slots.\n" | ||||||
|               "* :constants - an array of constants referenced by this function.\n" |               "* :constants - an array of constants referenced by this function.\n" | ||||||
|               "* :sourcemap - a mapping of each bytecode instruction to a line and column in the source file.\n" |               "* :sourcemap - a mapping of each bytecode instruction to a line and column in the source file.\n" | ||||||
|               "* :environments - an internal mapping of which enclosing functions are referenced for bindings.\n" |               "* :environments - an internal mapping of which enclosing functions are referenced for bindings.\n" | ||||||
|   | |||||||
| @@ -93,12 +93,13 @@ void janetc_freeslot(JanetCompiler *c, JanetSlot s) { | |||||||
| /* Add a slot to a scope with a symbol associated with it (def or var). */ | /* Add a slot to a scope with a symbol associated with it (def or var). */ | ||||||
| void janetc_nameslot(JanetCompiler *c, const uint8_t *sym, JanetSlot s) { | void janetc_nameslot(JanetCompiler *c, const uint8_t *sym, JanetSlot s) { | ||||||
|     SymPair sp; |     SymPair sp; | ||||||
|  |     int32_t cnt = janet_v_count(c->buffer); | ||||||
|     sp.sym = sym; |     sp.sym = sym; | ||||||
|     sp.sym2 = sym; |     sp.sym2 = sym; | ||||||
|     sp.slot = s; |     sp.slot = s; | ||||||
|     sp.keep = 0; |     sp.keep = 0; | ||||||
|     sp.slot.flags |= JANET_SLOT_NAMED; |     sp.slot.flags |= JANET_SLOT_NAMED; | ||||||
|     sp.birth_pc = janet_v_count(c->buffer); |     sp.birth_pc = cnt ? cnt - 1 : 0; | ||||||
|     sp.death_pc = UINT32_MAX; |     sp.death_pc = UINT32_MAX; | ||||||
|     janet_v_push(c->scope->syms, sp); |     janet_v_push(c->scope->syms, sp); | ||||||
| } | } | ||||||
| @@ -950,6 +951,7 @@ JanetFuncDef *janetc_pop_funcdef(JanetCompiler *c) { | |||||||
|     } |     } | ||||||
|     def->symbolmap_length = janet_v_count(locals); |     def->symbolmap_length = janet_v_count(locals); | ||||||
|     def->symbolmap = janet_v_flatten(locals); |     def->symbolmap = janet_v_flatten(locals); | ||||||
|  |     if (def->symbolmap_length) def->flags |= JANET_FUNCDEF_FLAG_HASSYMBOLMAP; | ||||||
|  |  | ||||||
|     /* Pop the scope */ |     /* Pop the scope */ | ||||||
|     janetc_popscope(c); |     janetc_popscope(c); | ||||||
|   | |||||||
| @@ -334,7 +334,7 @@ static Janet doframe(JanetStackFrame *frame) { | |||||||
|             JanetTable *local_bindings = janet_table(0); |             JanetTable *local_bindings = janet_table(0); | ||||||
|             for (int32_t i = def->symbolmap_length - 1; i >= 0; i--) { |             for (int32_t i = def->symbolmap_length - 1; i >= 0; i--) { | ||||||
|                 JanetSymbolMap jsm = def->symbolmap[i]; |                 JanetSymbolMap jsm = def->symbolmap[i]; | ||||||
|                 uint32_t pc = (uint32_t) (frame->pc - def->bytecode); |                 uint32_t pc = (uint32_t)(frame->pc - def->bytecode); | ||||||
|                 if (pc >= jsm.birth_pc && pc < jsm.death_pc) { |                 if (pc >= jsm.birth_pc && pc < jsm.death_pc) { | ||||||
|                     janet_table_put(local_bindings, janet_wrap_symbol(jsm.symbol), stack[jsm.slot_index]); |                     janet_table_put(local_bindings, janet_wrap_symbol(jsm.symbol), stack[jsm.slot_index]); | ||||||
|                 } |                 } | ||||||
|   | |||||||
| @@ -252,6 +252,8 @@ static void marshal_one_def(MarshalState *st, JanetFuncDef *def, int flags) { | |||||||
|         pushint(st, def->environments_length); |         pushint(st, def->environments_length); | ||||||
|     if (def->flags & JANET_FUNCDEF_FLAG_HASDEFS) |     if (def->flags & JANET_FUNCDEF_FLAG_HASDEFS) | ||||||
|         pushint(st, def->defs_length); |         pushint(st, def->defs_length); | ||||||
|  |     if (def->flags & JANET_FUNCDEF_FLAG_HASSYMBOLMAP) | ||||||
|  |         pushint(st, def->symbolmap_length); | ||||||
|     if (def->flags & JANET_FUNCDEF_FLAG_HASNAME) |     if (def->flags & JANET_FUNCDEF_FLAG_HASNAME) | ||||||
|         marshal_one(st, janet_wrap_string(def->name), flags); |         marshal_one(st, janet_wrap_string(def->name), flags); | ||||||
|     if (def->flags & JANET_FUNCDEF_FLAG_HASSOURCE) |     if (def->flags & JANET_FUNCDEF_FLAG_HASSOURCE) | ||||||
| @@ -261,6 +263,14 @@ static void marshal_one_def(MarshalState *st, JanetFuncDef *def, int flags) { | |||||||
|     for (int32_t i = 0; i < def->constants_length; i++) |     for (int32_t i = 0; i < def->constants_length; i++) | ||||||
|         marshal_one(st, def->constants[i], flags); |         marshal_one(st, def->constants[i], flags); | ||||||
|  |  | ||||||
|  |     /* Marshal symbol map, if needed */ | ||||||
|  |     for (int32_t i = 0; i < def->symbolmap_length; i++) { | ||||||
|  |         pushint(st, (int32_t) def->symbolmap[i].birth_pc); | ||||||
|  |         pushint(st, (int32_t) def->symbolmap[i].death_pc); | ||||||
|  |         pushint(st, (int32_t) def->symbolmap[i].slot_index); | ||||||
|  |         marshal_one(st, janet_wrap_symbol(def->symbolmap[i].symbol), flags); | ||||||
|  |     } | ||||||
|  |  | ||||||
|     /* marshal the bytecode */ |     /* marshal the bytecode */ | ||||||
|     janet_marshal_u32s(st, def->bytecode, def->bytecode_length); |     janet_marshal_u32s(st, def->bytecode, def->bytecode_length); | ||||||
|  |  | ||||||
| @@ -270,7 +280,7 @@ static void marshal_one_def(MarshalState *st, JanetFuncDef *def, int flags) { | |||||||
|  |  | ||||||
|     /* marshal the sub funcdefs if needed */ |     /* marshal the sub funcdefs if needed */ | ||||||
|     for (int32_t i = 0; i < def->defs_length; i++) |     for (int32_t i = 0; i < def->defs_length; i++) | ||||||
|         marshal_one_def(st, def->defs[i], flags); |         marshal_one_def(st, def->defs[i], flags + 1); | ||||||
|  |  | ||||||
|     /* marshal source maps if needed */ |     /* marshal source maps if needed */ | ||||||
|     if (def->flags & JANET_FUNCDEF_FLAG_HASSOURCEMAP) { |     if (def->flags & JANET_FUNCDEF_FLAG_HASSOURCEMAP) { | ||||||
| @@ -833,6 +843,7 @@ static const uint8_t *unmarshal_one_def( | |||||||
|         int32_t constants_length = 0; |         int32_t constants_length = 0; | ||||||
|         int32_t environments_length = 0; |         int32_t environments_length = 0; | ||||||
|         int32_t defs_length = 0; |         int32_t defs_length = 0; | ||||||
|  |         int32_t symbolmap_length = 0; | ||||||
|  |  | ||||||
|         /* Read flags and other fixed values */ |         /* Read flags and other fixed values */ | ||||||
|         def->flags = readint(st, &data); |         def->flags = readint(st, &data); | ||||||
| @@ -848,6 +859,8 @@ static const uint8_t *unmarshal_one_def( | |||||||
|             environments_length = readnat(st, &data); |             environments_length = readnat(st, &data); | ||||||
|         if (def->flags & JANET_FUNCDEF_FLAG_HASDEFS) |         if (def->flags & JANET_FUNCDEF_FLAG_HASDEFS) | ||||||
|             defs_length = readnat(st, &data); |             defs_length = readnat(st, &data); | ||||||
|  |         if (def->flags & JANET_FUNCDEF_FLAG_HASSYMBOLMAP) | ||||||
|  |             symbolmap_length = readnat(st, &data); | ||||||
|  |  | ||||||
|         /* Check name and source (optional) */ |         /* Check name and source (optional) */ | ||||||
|         if (def->flags & JANET_FUNCDEF_FLAG_HASNAME) { |         if (def->flags & JANET_FUNCDEF_FLAG_HASNAME) { | ||||||
| @@ -876,6 +889,26 @@ static const uint8_t *unmarshal_one_def( | |||||||
|         } |         } | ||||||
|         def->constants_length = constants_length; |         def->constants_length = constants_length; | ||||||
|  |  | ||||||
|  |         /* Unmarshal symbol map, if needed */ | ||||||
|  |         if (def->flags & JANET_FUNCDEF_FLAG_HASSYMBOLMAP) { | ||||||
|  |             size_t size = sizeof(JanetSymbolMap) * symbolmap_length; | ||||||
|  |             def->symbolmap = janet_malloc(size); | ||||||
|  |             if (def->symbolmap == NULL) { | ||||||
|  |                 JANET_OUT_OF_MEMORY; | ||||||
|  |             } | ||||||
|  |             for (int32_t i = 0; i < symbolmap_length; i++) { | ||||||
|  |                 def->symbolmap[i].birth_pc = (uint32_t) readint(st, &data); | ||||||
|  |                 def->symbolmap[i].death_pc = (uint32_t) readint(st, &data); | ||||||
|  |                 def->symbolmap[i].slot_index = (uint32_t) readint(st, &data); | ||||||
|  |                 Janet value; | ||||||
|  |                 data = unmarshal_one(st, data, &value, flags + 1); | ||||||
|  |                 if (!janet_checktype(value, JANET_SYMBOL)) | ||||||
|  |                     janet_panic("expected symbol in symbol map"); | ||||||
|  |                 def->symbolmap[i].symbol = janet_unwrap_symbol(value); | ||||||
|  |             } | ||||||
|  |             def->symbolmap_length = (uint32_t) symbolmap_length; | ||||||
|  |         } | ||||||
|  |  | ||||||
|         /* Unmarshal bytecode */ |         /* Unmarshal bytecode */ | ||||||
|         def->bytecode = janet_malloc(sizeof(uint32_t) * bytecode_length); |         def->bytecode = janet_malloc(sizeof(uint32_t) * bytecode_length); | ||||||
|         if (!def->bytecode) { |         if (!def->bytecode) { | ||||||
|   | |||||||
| @@ -1004,6 +1004,7 @@ struct JanetAbstractHead { | |||||||
| /* Some function definition flags */ | /* Some function definition flags */ | ||||||
| #define JANET_FUNCDEF_FLAG_VARARG 0x10000 | #define JANET_FUNCDEF_FLAG_VARARG 0x10000 | ||||||
| #define JANET_FUNCDEF_FLAG_NEEDSENV 0x20000 | #define JANET_FUNCDEF_FLAG_NEEDSENV 0x20000 | ||||||
|  | #define JANET_FUNCDEF_FLAG_HASSYMBOLMAP 0x40000 | ||||||
| #define JANET_FUNCDEF_FLAG_HASNAME 0x80000 | #define JANET_FUNCDEF_FLAG_HASNAME 0x80000 | ||||||
| #define JANET_FUNCDEF_FLAG_HASSOURCE 0x100000 | #define JANET_FUNCDEF_FLAG_HASSOURCE 0x100000 | ||||||
| #define JANET_FUNCDEF_FLAG_HASDEFS 0x200000 | #define JANET_FUNCDEF_FLAG_HASDEFS 0x200000 | ||||||
|   | |||||||
| @@ -3,53 +3,42 @@ | |||||||
| (import ./helper :prefix "" :exit true) | (import ./helper :prefix "" :exit true) | ||||||
| (start-suite 15) | (start-suite 15) | ||||||
|  |  | ||||||
| (assert (deep= (in (disasm (defn a [] (def x 10) x)) :symbolslots) nil) | (assert (deep= (in (disasm (defn a [] (def x 10) x)) :symbolmap) | ||||||
|   "no symbolslots when *debug* is false") |                @[[0 3 0 'a] [1 3 1 'x]]) | ||||||
|  |         "symbolslots when *debug* is true") | ||||||
|  |  | ||||||
| (setdyn *debug* true) |  | ||||||
| (assert (deep= (in (disasm (defn a [] (def x 10) x)) :symbolslots) |  | ||||||
|                @[[0 2147483647 0 "a"] [1 2147483647 1 "x"]]) |  | ||||||
|   "symbolslots when *debug* is true") |  | ||||||
| (setdyn *debug* false) |  | ||||||
|  |  | ||||||
| (setdyn *debug* true) |  | ||||||
| (defn a [arg] | (defn a [arg] | ||||||
|     (def x 10) |   (def x 10) | ||||||
|     (do |   (do | ||||||
|       (def y 20) |     (def y 20) | ||||||
|       (def z 30) |     (def z 30) | ||||||
|       (+ x y z))) |     (+ x y z))) | ||||||
| (def symbolslots (in (disasm a) :symbolslots)) | (def symbolslots (in (disasm a) :symbolslots)) | ||||||
| (def f (asm (disasm a))) | (def f (asm (disasm a))) | ||||||
| (assert (deep= (in (disasm f) :symbolslots) | (assert (deep= (in (disasm f) :symbolslots) | ||||||
|                 symbolslots) |                symbolslots) | ||||||
|   "symbolslots survive disasm/asm") |         "symbolslots survive disasm/asm") | ||||||
| (setdyn *debug* false) |  | ||||||
|  |  | ||||||
| # need to fix upvalues | # need to fix upvalues | ||||||
| (comment | (comment | ||||||
|   (setdyn *debug* true) |   (setdyn *debug* true) | ||||||
|   (setdyn :pretty-format "%.40M") |   (setdyn :pretty-format "%.40M") | ||||||
|     (def f (fn [x] (fn [y] (+ x y)))) |   (def f (fn [x] (fn [y] (+ x y)))) | ||||||
|     (assert (deep= (map last (in (disasm (f 10)) :symbolslots)) |   (assert (deep= (map last (in (disasm (f 10)) :symbolmap)) | ||||||
|                   @["x" "y"]) |                  @['x 'y]) | ||||||
|             "symbolslots upvalues") |           "symbolslots upvalues")) | ||||||
|   (setdyn *debug* false) |  | ||||||
|   ) |  | ||||||
|  |  | ||||||
| (setdyn *debug* true) |  | ||||||
| (assert (deep= (in (disasm (defn a [arg] | (assert (deep= (in (disasm (defn a [arg] | ||||||
|                             (def x 10) |                              (def x 10) | ||||||
|                             (do |                              (do | ||||||
|                               (def y 20) |                                (def y 20) | ||||||
|                               (def z 30) |                                (def z 30) | ||||||
|                               (+ x y z)))) :symbolslots) |                                (+ x y z)))) :symbolmap) | ||||||
|                @[[-1 2147483647 0 "arg"] |                @[[0 7 0 'arg] | ||||||
|                  [0 2147483647 1 "a"] |                  [0 7 1 'a] | ||||||
|                  [1 2147483647 2 "x"] |                  [1 7 2 'x] | ||||||
|                  [2 7 3 "y"] |                  [2 7 3 'y] | ||||||
|                  [3 7 4 "z"]]) |                  [3 7 4 'z]]) | ||||||
|   "arg & inner symbolslots") |         "arg & inner symbolslots") | ||||||
| (setdyn *debug* false) |  | ||||||
|  |  | ||||||
| (end-suite) | (end-suite) | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Calvin Rose
					Calvin Rose