mirror of
				https://github.com/janet-lang/janet
				synced 2025-10-31 07:33:01 +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_length = 0; | ||||
|  | ||||
|     x = janet_get1(s, janet_ckeywordv("symbolslots")); | ||||
|     x = janet_get1(s, janet_ckeywordv("symbolmap")); | ||||
|     if (janet_indexed_view(x, &arr, &count)) { | ||||
|         def->symbolmap_length = 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])) { | ||||
|                 janet_asm_error(&a, "expected integer"); | ||||
|             } | ||||
|             if (!janet_checktype(tup[3], JANET_STRING)) { | ||||
|                 janet_asm_error(&a, "expected string"); | ||||
|             if (!janet_checktype(tup[3], JANET_SYMBOL)) { | ||||
|                 janet_asm_error(&a, "expected symbol"); | ||||
|             } | ||||
|             ss.birth_pc = janet_unwrap_integer(tup[0]); | ||||
|             ss.death_pc = janet_unwrap_integer(tup[1]); | ||||
|             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; | ||||
|         } | ||||
|     } | ||||
|     if (def->symbolmap_length) def->flags |= JANET_FUNCDEF_FLAG_HASSYMBOLMAP; | ||||
|  | ||||
|     /* Set 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[1] = janet_wrap_integer(ss.death_pc); | ||||
|         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->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("name"), janet_disasm_name(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("sourcemap"), janet_disasm_sourcemap(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" | ||||
|               "* :name - name of 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" | ||||
|               "* :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" | ||||
|   | ||||
| @@ -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). */ | ||||
| void janetc_nameslot(JanetCompiler *c, const uint8_t *sym, JanetSlot s) { | ||||
|     SymPair sp; | ||||
|     int32_t cnt = janet_v_count(c->buffer); | ||||
|     sp.sym = sym; | ||||
|     sp.sym2 = sym; | ||||
|     sp.slot = s; | ||||
|     sp.keep = 0; | ||||
|     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; | ||||
|     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 = janet_v_flatten(locals); | ||||
|     if (def->symbolmap_length) def->flags |= JANET_FUNCDEF_FLAG_HASSYMBOLMAP; | ||||
|  | ||||
|     /* Pop the scope */ | ||||
|     janetc_popscope(c); | ||||
|   | ||||
| @@ -334,7 +334,7 @@ static Janet doframe(JanetStackFrame *frame) { | ||||
|             JanetTable *local_bindings = janet_table(0); | ||||
|             for (int32_t i = def->symbolmap_length - 1; i >= 0; 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) { | ||||
|                     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); | ||||
|     if (def->flags & JANET_FUNCDEF_FLAG_HASDEFS) | ||||
|         pushint(st, def->defs_length); | ||||
|     if (def->flags & JANET_FUNCDEF_FLAG_HASSYMBOLMAP) | ||||
|         pushint(st, def->symbolmap_length); | ||||
|     if (def->flags & JANET_FUNCDEF_FLAG_HASNAME) | ||||
|         marshal_one(st, janet_wrap_string(def->name), flags); | ||||
|     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++) | ||||
|         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 */ | ||||
|     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 */ | ||||
|     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 */ | ||||
|     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 environments_length = 0; | ||||
|         int32_t defs_length = 0; | ||||
|         int32_t symbolmap_length = 0; | ||||
|  | ||||
|         /* Read flags and other fixed values */ | ||||
|         def->flags = readint(st, &data); | ||||
| @@ -848,6 +859,8 @@ static const uint8_t *unmarshal_one_def( | ||||
|             environments_length = readnat(st, &data); | ||||
|         if (def->flags & JANET_FUNCDEF_FLAG_HASDEFS) | ||||
|             defs_length = readnat(st, &data); | ||||
|         if (def->flags & JANET_FUNCDEF_FLAG_HASSYMBOLMAP) | ||||
|             symbolmap_length = readnat(st, &data); | ||||
|  | ||||
|         /* Check name and source (optional) */ | ||||
|         if (def->flags & JANET_FUNCDEF_FLAG_HASNAME) { | ||||
| @@ -876,6 +889,26 @@ static const uint8_t *unmarshal_one_def( | ||||
|         } | ||||
|         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 */ | ||||
|         def->bytecode = janet_malloc(sizeof(uint32_t) * bytecode_length); | ||||
|         if (!def->bytecode) { | ||||
|   | ||||
| @@ -1004,6 +1004,7 @@ struct JanetAbstractHead { | ||||
| /* Some function definition flags */ | ||||
| #define JANET_FUNCDEF_FLAG_VARARG 0x10000 | ||||
| #define JANET_FUNCDEF_FLAG_NEEDSENV 0x20000 | ||||
| #define JANET_FUNCDEF_FLAG_HASSYMBOLMAP 0x40000 | ||||
| #define JANET_FUNCDEF_FLAG_HASNAME 0x80000 | ||||
| #define JANET_FUNCDEF_FLAG_HASSOURCE 0x100000 | ||||
| #define JANET_FUNCDEF_FLAG_HASDEFS 0x200000 | ||||
|   | ||||
| @@ -3,53 +3,42 @@ | ||||
| (import ./helper :prefix "" :exit true) | ||||
| (start-suite 15) | ||||
|  | ||||
| (assert (deep= (in (disasm (defn a [] (def x 10) x)) :symbolslots) nil) | ||||
|   "no symbolslots when *debug* is false") | ||||
| (assert (deep= (in (disasm (defn a [] (def x 10) x)) :symbolmap) | ||||
|                @[[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] | ||||
|     (def x 10) | ||||
|     (do | ||||
|       (def y 20) | ||||
|       (def z 30) | ||||
|       (+ x y z))) | ||||
|   (def x 10) | ||||
|   (do | ||||
|     (def y 20) | ||||
|     (def z 30) | ||||
|     (+ x y z))) | ||||
| (def symbolslots (in (disasm a) :symbolslots)) | ||||
| (def f (asm (disasm a))) | ||||
| (assert (deep= (in (disasm f) :symbolslots) | ||||
|                 symbolslots) | ||||
|   "symbolslots survive disasm/asm") | ||||
| (setdyn *debug* false) | ||||
|                symbolslots) | ||||
|         "symbolslots survive disasm/asm") | ||||
|  | ||||
| # need to fix upvalues | ||||
| (comment | ||||
|   (setdyn *debug* true) | ||||
|   (setdyn :pretty-format "%.40M") | ||||
|     (def f (fn [x] (fn [y] (+ x y)))) | ||||
|     (assert (deep= (map last (in (disasm (f 10)) :symbolslots)) | ||||
|                   @["x" "y"]) | ||||
|             "symbolslots upvalues") | ||||
|   (setdyn *debug* false) | ||||
|   ) | ||||
|   (def f (fn [x] (fn [y] (+ x y)))) | ||||
|   (assert (deep= (map last (in (disasm (f 10)) :symbolmap)) | ||||
|                  @['x 'y]) | ||||
|           "symbolslots upvalues")) | ||||
|  | ||||
| (setdyn *debug* true) | ||||
| (assert (deep= (in (disasm (defn a [arg] | ||||
|                             (def x 10) | ||||
|                             (do | ||||
|                               (def y 20) | ||||
|                               (def z 30) | ||||
|                               (+ x y z)))) :symbolslots) | ||||
|                @[[-1 2147483647 0 "arg"] | ||||
|                  [0 2147483647 1 "a"] | ||||
|                  [1 2147483647 2 "x"] | ||||
|                  [2 7 3 "y"] | ||||
|                  [3 7 4 "z"]]) | ||||
|   "arg & inner symbolslots") | ||||
| (setdyn *debug* false) | ||||
|                              (def x 10) | ||||
|                              (do | ||||
|                                (def y 20) | ||||
|                                (def z 30) | ||||
|                                (+ x y z)))) :symbolmap) | ||||
|                @[[0 7 0 'arg] | ||||
|                  [0 7 1 'a] | ||||
|                  [1 7 2 'x] | ||||
|                  [2 7 3 'y] | ||||
|                  [3 7 4 'z]]) | ||||
|         "arg & inner symbolslots") | ||||
|  | ||||
| (end-suite) | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Calvin Rose
					Calvin Rose