diff --git a/src/core/specials.c b/src/core/specials.c index ccc36536..4a553412 100644 --- a/src/core/specials.c +++ b/src/core/specials.c @@ -116,7 +116,7 @@ static JanetSlot janetc_unquote(JanetFopts opts, int32_t argn, const Janet *argv return janetc_cslot(janet_wrap_nil()); } -/* Preform destructuring. Be careful to +/* Perform destructuring. Be careful to * keep the order registers are freed. * Returns if the slot 'right' can be freed. */ static int destructure(JanetCompiler *c, @@ -282,12 +282,13 @@ static int varleaf( if (c->scope->flags & JANET_SCOPE_TOP) { /* Global var, generate var */ JanetSlot refslot; + JanetTable *entry = janet_table_clone(reftab); JanetArray *ref = janet_array(1); janet_array_push(ref, janet_wrap_nil()); - janet_table_put(reftab, janet_ckeywordv("ref"), janet_wrap_array(ref)); - janet_table_put(reftab, janet_ckeywordv("source-map"), + janet_table_put(entry, janet_ckeywordv("ref"), janet_wrap_array(ref)); + janet_table_put(entry, janet_ckeywordv("source-map"), janet_wrap_tuple(janetc_make_sourcemap(c))); - janet_table_put(c->env, janet_wrap_symbol(sym), janet_wrap_table(reftab)); + janet_table_put(c->env, janet_wrap_symbol(sym), janet_wrap_table(entry)); refslot = janetc_cslot(janet_wrap_array(ref)); janetc_emit_ssu(c, JOP_PUT_INDEX, refslot, s, 0, 0); return 1; @@ -312,13 +313,14 @@ static int defleaf( JanetSlot s, JanetTable *tab) { if (c->scope->flags & JANET_SCOPE_TOP) { - janet_table_put(tab, janet_ckeywordv("source-map"), + JanetTable *entry = janet_table_clone(tab); + janet_table_put(entry, janet_ckeywordv("source-map"), janet_wrap_tuple(janetc_make_sourcemap(c))); JanetSlot valsym = janetc_cslot(janet_ckeywordv("value")); - JanetSlot tabslot = janetc_cslot(janet_wrap_table(tab)); + JanetSlot tabslot = janetc_cslot(janet_wrap_table(entry)); /* Add env entry to env */ - janet_table_put(c->env, janet_wrap_symbol(sym), janet_wrap_table(tab)); + janet_table_put(c->env, janet_wrap_symbol(sym), janet_wrap_table(entry)); /* Put value in table when evaulated */ janetc_emit_sss(c, JOP_PUT, tabslot, valsym, s, 0); diff --git a/src/core/table.c b/src/core/table.c index 6b107efa..f37eee0e 100644 --- a/src/core/table.c +++ b/src/core/table.c @@ -208,6 +208,18 @@ const JanetKV *janet_table_to_struct(JanetTable *t) { return janet_struct_end(st); } +/* Clone a table. */ +JanetTable *janet_table_clone(JanetTable *table) { + JanetTable *newTable = janet_gcalloc(JANET_MEMORY_TABLE, sizeof(JanetTable)); + memcpy(newTable, table, sizeof(JanetTable)); + newTable->data = malloc(newTable->capacity * sizeof(JanetKV)); + if (NULL == newTable->data) { + JANET_OUT_OF_MEMORY; + } + memcpy(newTable->data, table->data, table->capacity * sizeof(JanetKV)); + return newTable; +} + /* Merge a table or struct into a table */ static void janet_table_mergekv(JanetTable *table, const JanetKV *kvs, int32_t cap) { int32_t i; diff --git a/src/include/janet.h b/src/include/janet.h index 0f8c323a..8ce39b4b 100644 --- a/src/include/janet.h +++ b/src/include/janet.h @@ -1202,6 +1202,7 @@ JANET_API const JanetKV *janet_table_to_struct(JanetTable *t); JANET_API void janet_table_merge_table(JanetTable *table, JanetTable *other); JANET_API void janet_table_merge_struct(JanetTable *table, const JanetKV *other); JANET_API JanetKV *janet_table_find(JanetTable *t, Janet key); +JANET_API JanetTable *janet_table_clone(JanetTable *table); /* Fiber */ JANET_API JanetFiber *janet_fiber(JanetFunction *callee, int32_t capacity, int32_t argc, const Janet *argv); diff --git a/test/suite0.janet b/test/suite0.janet index ae6bda0b..eca5733e 100644 --- a/test/suite0.janet +++ b/test/suite0.janet @@ -303,5 +303,16 @@ # Regression Test (assert (= 1 (((compile '(fn [] 1) @{})))) "regression test") +# Regression Test #137 +(def [a b c] (range 10)) +(assert (= a 0) "regression #137 (1)") +(assert (= b 1) "regression #137 (2)") +(assert (= c 2) "regression #137 (3)") + +(var [x y z] (range 10)) +(assert (= a 0) "regression #137 (4)") +(assert (= b 1) "regression #137 (5)") +(assert (= c 2) "regression #137 (6)") + (end-suite)