Progress.

This commit is contained in:
Calvin Rose 2023-02-02 21:08:48 -06:00
parent fa277c3797
commit f4bc89d1c0
10 changed files with 80 additions and 90 deletions

View File

@ -2769,13 +2769,9 @@
# define variables available at breakpoint
(def frame ((debug/stack fiber) 0))
(def symbolslots ((disasm (frame :function)) :symbolslots))
(def pc (frame :pc))
(loop [[birth death slot sym] :in symbolslots]
(when (and (<= birth pc)
(< pc death))
(put nextenv (symbol sym) @{:value (get-in frame [:slots slot])})))
(eachp [local value] (get frame :locals)
(put nextenv local @{:value value}))
(merge-into nextenv debugger-env)
(defn debugger-chunks [buf p]

View File

@ -722,20 +722,20 @@ static JanetAssembleResult janet_asm1(JanetAssembler *parent, Janet source, int
}
/* Set symbolslots */
def->symbolslots = NULL;
def->symbolslots_length = 0;
def->symbolmap = NULL;
def->symbolmap_length = 0;
x = janet_get1(s, janet_ckeywordv("symbolslots"));
if (janet_indexed_view(x, &arr, &count)) {
def->symbolslots_length = count;
def->symbolslots = janet_malloc(sizeof(JanetSymbolSlot) * (size_t) count);
if (NULL == def->symbolslots) {
def->symbolmap_length = count;
def->symbolmap = janet_malloc(sizeof(JanetSymbolMap) * (size_t)count);
if (NULL == def->symbolmap) {
JANET_OUT_OF_MEMORY;
}
for (i = 0; i < count; i++) {
const Janet *tup;
Janet entry = arr[i];
JanetSymbolSlot ss;
JanetSymbolMap ss;
if (!janet_checktype(entry, JANET_TUPLE)) {
janet_asm_error(&a, "expected tuple");
}
@ -756,8 +756,7 @@ static JanetAssembleResult janet_asm1(JanetAssembler *parent, Janet source, int
ss.death_pc = janet_unwrap_integer(tup[1]);
ss.slot_index = janet_unwrap_integer(tup[2]);
ss.symbol = janet_unwrap_string(tup[3]);
def->symbolslots[i] = ss;
def->symbolmap[i] = ss;
}
}
@ -923,11 +922,12 @@ static Janet janet_disasm_slotcount(JanetFuncDef *def) {
}
static Janet janet_disasm_symbolslots(JanetFuncDef *def) {
// *debug* was probably not true when compiling the function
if (def->symbolslots == NULL) { return janet_wrap_nil(); }
JanetArray *symbolslots = janet_array(def->symbolslots_length);
for (int32_t i = 0; i < def->symbolslots_length; i++) {
JanetSymbolSlot ss = def->symbolslots[i];
if (def->symbolmap == NULL) {
return janet_wrap_nil();
}
JanetArray *symbolslots = janet_array(def->symbolmap_length);
for (int32_t i = 0; i < def->symbolmap_length; i++) {
JanetSymbolMap ss = def->symbolmap[i];
Janet *t = janet_tuple_begin(4);
t[0] = janet_wrap_integer(ss.birth_pc);
t[1] = janet_wrap_integer(ss.death_pc);
@ -935,7 +935,7 @@ static Janet janet_disasm_symbolslots(JanetFuncDef *def) {
t[3] = janet_cstringv((const char *) ss.symbol);
symbolslots->data[i] = janet_wrap_tuple(janet_tuple_end(t));
}
symbolslots->count = def->symbolslots_length;
symbolslots->count = def->symbolmap_length;
return janet_wrap_array(symbolslots);
}

View File

@ -218,7 +218,7 @@ JanetFuncDef *janet_funcdef_alloc(void) {
def->closure_bitset = NULL;
def->flags = 0;
def->slotcount = 0;
def->symbolslots = NULL;
def->symbolmap = NULL;
def->arity = 0;
def->min_arity = 0;
def->max_arity = INT32_MAX;
@ -230,7 +230,7 @@ JanetFuncDef *janet_funcdef_alloc(void) {
def->constants_length = 0;
def->bytecode_length = 0;
def->environments_length = 0;
def->symbolslots_length = 0;
def->symbolmap_length = 0;
return def;
}

View File

@ -94,11 +94,12 @@ void janetc_freeslot(JanetCompiler *c, JanetSlot s) {
void janetc_nameslot(JanetCompiler *c, const uint8_t *sym, JanetSlot s) {
SymPair sp;
sp.sym = sym;
sp.sym2 = sym;
sp.slot = s;
sp.keep = 0;
sp.slot.flags |= JANET_SLOT_NAMED;
// -1 because c->buffer has already passed the `def`/`var`
sp.bytecode_pos = janet_v_count(c->buffer) - 1;
sp.birth_pc = janet_v_count(c->buffer);
sp.death_pc = UINT32_MAX;
janet_v_push(c->scope->syms, sp);
}
@ -161,42 +162,24 @@ void janetc_popscope(JanetCompiler *c) {
if (oldscope->flags & JANET_SCOPE_CLOSURE) {
newscope->flags |= JANET_SCOPE_CLOSURE;
}
if (newscope->ra.max < oldscope->ra.max)
if (newscope->ra.max < oldscope->ra.max) {
newscope->ra.max = oldscope->ra.max;
}
/* Keep upvalue slots */
/* Keep upvalue slots and symbols for debugging. */
for (int32_t i = 0; i < janet_v_count(oldscope->syms); i++) {
SymPair pair = oldscope->syms[i];
/* The variable should not be lexically accessible */
pair.sym = NULL;
if (pair.death_pc == UINT32_MAX) {
pair.death_pc = (uint32_t) janet_v_count(c->buffer);
}
if (pair.keep) {
/* The variable should not be lexically accessible */
pair.sym = NULL;
janet_v_push(newscope->syms, pair);
/* The variable should also not be included in the locals */
pair.sym2 = NULL;
janetc_regalloc_touch(&newscope->ra, pair.slot.index);
}
}
}
if (janet_truthy(janet_dyn("debug"))) {
bool top_level = (oldscope->flags & (JANET_SCOPE_FUNCTION | JANET_SCOPE_UNUSED));
/* push symbol slots */
JanetSymbolSlot ss;
int32_t scope_end = top_level ? INT32_MAX : janet_v_count(c->buffer);
janet_assert(janet_v_count(c->local_symbols) > 0, "c->local_symbols should not be empty");
// due to scopes being added "in reverse" (filo), we will reverse all symbols later. therefore we must first reverse the order of symbols inside each scope as well.
for (int32_t i = janet_v_count(oldscope->syms) - 1; i >= 0; i--) {
SymPair pair = oldscope->syms[i];
if (pair.sym != NULL) {
ss.birth_pc = pair.bytecode_pos;
ss.death_pc = scope_end;
ss.slot_index = pair.slot.index;
ss.symbol = pair.sym;
janet_v_push(janet_v_last(c->local_symbols), ss);
}
janet_v_push(newscope->syms, pair);
}
}
@ -949,26 +932,27 @@ JanetFuncDef *janetc_pop_funcdef(JanetCompiler *c) {
def->closure_bitset = chunks;
}
/* Pop the scope */
janetc_popscope(c);
if (janet_truthy(janet_dyn("debug"))) {
JanetSymbolSlot *last_symbols = janet_v_last(c->local_symbols);
def->symbolslots_length = janet_v_count(last_symbols);
def->symbolslots = janet_malloc(sizeof(JanetSymbolSlot) * def->symbolslots_length);
if (NULL == def->bytecode) {
JANET_OUT_OF_MEMORY;
}
// add in reverse, because scopes have been added filo
for (int i = 0; i < janet_v_count(last_symbols); i++) {
def->symbolslots[def->symbolslots_length - i - 1] = last_symbols[i];
/* Capture symbol to local mapping */
JanetSymbolMap *locals = NULL;
for (int32_t i = 0; i < janet_v_count(scope->syms); i++) {
SymPair pair = scope->syms[i];
if (pair.sym2) {
if (pair.death_pc == UINT32_MAX) {
pair.death_pc = def->bytecode_length;
}
JanetSymbolMap jsm;
jsm.birth_pc = pair.birth_pc;
jsm.death_pc = pair.death_pc;
jsm.slot_index = pair.slot.index;
jsm.symbol = pair.sym2;
janet_v_push(locals, jsm);
}
}
def->symbolmap_length = janet_v_count(locals);
def->symbolmap = janet_v_flatten(locals);
janet_v_pop(c->local_symbols);
/* Pop the scope */
janetc_popscope(c);
return def;
}
@ -980,7 +964,6 @@ static void janetc_init(JanetCompiler *c, JanetTable *env, const uint8_t *where,
c->mapbuffer = NULL;
c->recursion_guard = JANET_RECURSION_GUARD;
c->env = env;
c->local_symbols = NULL;
c->source = where;
c->current_mapping.line = -1;
c->current_mapping.column = -1;
@ -998,7 +981,6 @@ static void janetc_init(JanetCompiler *c, JanetTable *env, const uint8_t *where,
static void janetc_deinit(JanetCompiler *c) {
janet_v_free(c->buffer);
janet_v_free(c->mapbuffer);
janet_v_free(c->local_symbols);
c->env = NULL;
}
@ -1012,7 +994,6 @@ JanetCompileResult janet_compile_lint(Janet source,
janetc_init(&c, env, where, lints);
/* Push a function scope */
janet_v_push(c.local_symbols, NULL);
janetc_scope(&rootscope, &c, JANET_SCOPE_FUNCTION | JANET_SCOPE_TOP, "root");
/* Set initial form options */
@ -1031,9 +1012,6 @@ JanetCompileResult janet_compile_lint(Janet source,
} else {
c.result.error_mapping = c.current_mapping;
janetc_popscope(&c);
if (janet_truthy(janet_dyn("debug"))) {
janet_v_pop(c.local_symbols);
}
}
janetc_deinit(&c);

View File

@ -111,14 +111,16 @@ struct JanetSlot {
typedef struct SymPair {
JanetSlot slot;
const uint8_t *sym;
const uint8_t *sym2;
int keep;
int32_t bytecode_pos;
uint32_t birth_pc;
uint32_t death_pc;
} SymPair;
/* A lexical scope during compilation */
struct JanetScope {
/* For debugging */
/* For debugging the compiler */
const char *name;
/* Scopes are doubly linked list */
@ -161,8 +163,6 @@ struct JanetCompiler {
/* Hold the environment */
JanetTable *env;
JanetSymbolSlot **local_symbols;
/* Name of source to attach to generated functions */
const uint8_t *source;

View File

@ -329,6 +329,18 @@ static Janet doframe(JanetStackFrame *frame) {
safe_memcpy(slots->data, stack, sizeof(Janet) * def->slotcount);
slots->count = def->slotcount;
janet_table_put(t, janet_ckeywordv("slots"), janet_wrap_array(slots));
/* Add local bindings */
if (def->symbolmap) {
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);
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(t, janet_ckeywordv("locals"), janet_wrap_table(local_bindings));
}
}
return janet_wrap_table(t);
}

View File

@ -209,6 +209,12 @@ static void janet_mark_funcdef(JanetFuncDef *def) {
janet_mark_string(def->source);
if (def->name)
janet_mark_string(def->name);
if (def->symbolmap) {
for (int i = 0; i < def->symbolmap_length; i++) {
janet_mark_string(def->symbolmap[i].symbol);
}
}
}
static void janet_mark_function(JanetFunction *func) {
@ -314,7 +320,7 @@ static void janet_deinit_block(JanetGCObject *mem) {
janet_free(def->bytecode);
janet_free(def->sourcemap);
janet_free(def->closure_bitset);
janet_free(def->symbolslots);
janet_free(def->symbolmap);
}
break;
}

View File

@ -824,8 +824,8 @@ static const uint8_t *unmarshal_one_def(
def->constants = NULL;
def->bytecode = NULL;
def->sourcemap = NULL;
def->symbolslots = NULL;
def->symbolslots_length = 0;
def->symbolmap = NULL;
def->symbolmap_length = 0;
janet_v_push(st->lookup_defs, def);
/* Set default lengths to zero */

View File

@ -753,7 +753,6 @@ static JanetSlot janetc_while(JanetFopts opts, int32_t argn, const Janet *argv)
if (c->buffer) janet_v__cnt(c->buffer) = labelwt;
if (c->mapbuffer) janet_v__cnt(c->mapbuffer) = labelwt;
janet_v_push(c->local_symbols, NULL);
janetc_scope(&tempscope, c, JANET_SCOPE_FUNCTION, "while-iife");
/* Recompile in the function scope */
@ -830,7 +829,6 @@ static JanetSlot janetc_fn(JanetFopts opts, int32_t argn, const Janet *argv) {
/* Begin function */
c->scope->flags |= JANET_SCOPE_CLOSURE;
janet_v_push(c->local_symbols, NULL);
janetc_scope(&fnscope, c, JANET_SCOPE_FUNCTION, "function");
if (argn == 0) {

View File

@ -356,7 +356,7 @@ typedef struct JanetOSRWLock JanetOSRWLock;
/* What to do when out of memory */
#ifndef JANET_OUT_OF_MEMORY
#define JANET_OUT_OF_MEMORY do { fprintf(stderr, "janet out of memory\n"); exit(1); } while (0)
#define JANET_OUT_OF_MEMORY do { fprintf(stderr, "%s:%d - janet out of memory\n", __FILE__, __LINE__); exit(1); } while (0)
#endif
#ifdef JANET_BSD
@ -448,7 +448,7 @@ typedef struct JanetReg JanetReg;
typedef struct JanetRegExt JanetRegExt;
typedef struct JanetMethod JanetMethod;
typedef struct JanetSourceMapping JanetSourceMapping;
typedef struct JanetSymbolSlot JanetSymbolSlot;
typedef struct JanetSymbolMap JanetSymbolMap;
typedef struct JanetView JanetView;
typedef struct JanetByteView JanetByteView;
typedef struct JanetDictView JanetDictView;
@ -1020,7 +1020,7 @@ struct JanetSourceMapping {
};
/* Symbol to slot mapping & lifetime structure. */
struct JanetSymbolSlot {
struct JanetSymbolMap {
uint32_t birth_pc;
uint32_t death_pc;
uint32_t slot_index;
@ -1040,7 +1040,7 @@ struct JanetFuncDef {
JanetSourceMapping *sourcemap;
JanetString source;
JanetString name;
JanetSymbolSlot *symbolslots;
JanetSymbolMap *symbolmap;
int32_t flags;
int32_t slotcount; /* The amount of stack space required for the function */
@ -1051,7 +1051,7 @@ struct JanetFuncDef {
int32_t bytecode_length;
int32_t environments_length;
int32_t defs_length;
int32_t symbolslots_length;
int32_t symbolmap_length;
};
/* A function environment */