1
0
mirror of https://github.com/janet-lang/janet synced 2025-06-07 00:54:12 +00:00

Allow round-tripping more functions with disasm and asm.

Nested functions that captured with environments didn't
work well with asm.
This commit is contained in:
Calvin Rose 2023-01-30 09:03:39 -06:00
parent 244833cfa1
commit dacbe29771
5 changed files with 28 additions and 8 deletions

View File

@ -187,7 +187,11 @@ static void janet_asm_longjmp(JanetAssembler *a) {
/* Throw some kind of assembly error */ /* Throw some kind of assembly error */
static void janet_asm_error(JanetAssembler *a, const char *message) { static void janet_asm_error(JanetAssembler *a, const char *message) {
if (a->errindex < 0) {
a->errmessage = janet_formatc("%s", message);
} else {
a->errmessage = janet_formatc("%s, instruction %d", message, a->errindex); a->errmessage = janet_formatc("%s, instruction %d", message, a->errindex);
}
janet_asm_longjmp(a); janet_asm_longjmp(a);
} }
#define janet_asm_assert(a, c, m) do { if (!(c)) janet_asm_error((a), (m)); } while (0) #define janet_asm_assert(a, c, m) do { if (!(c)) janet_asm_error((a), (m)); } while (0)
@ -516,6 +520,7 @@ static JanetAssembleResult janet_asm1(JanetAssembler *parent, Janet source, int
#endif #endif
if (NULL != a.parent) { if (NULL != a.parent) {
janet_asm_deinit(&a); janet_asm_deinit(&a);
a.parent->errmessage = a.errmessage;
janet_asm_longjmp(a.parent); janet_asm_longjmp(a.parent);
} }
result.funcdef = NULL; result.funcdef = NULL;
@ -601,6 +606,9 @@ static JanetAssembleResult janet_asm1(JanetAssembler *parent, Janet source, int
/* Parse sub funcdefs */ /* Parse sub funcdefs */
x = janet_get1(s, janet_ckeywordv("closures")); x = janet_get1(s, janet_ckeywordv("closures"));
if (janet_checktype(x, JANET_NIL)) {
x = janet_get1(s, janet_ckeywordv("defs"));
}
if (janet_indexed_view(x, &arr, &count)) { if (janet_indexed_view(x, &arr, &count)) {
int32_t i; int32_t i;
for (i = 0; i < count; i++) { for (i = 0; i < count; i++) {
@ -714,8 +722,17 @@ static JanetAssembleResult janet_asm1(JanetAssembler *parent, Janet source, int
} }
/* Set environments */ /* Set environments */
def->environments = def->environments = janet_realloc(def->environments, def->environments_length * sizeof(int32_t));
janet_realloc(def->environments, def->environments_length * sizeof(int32_t)); x = janet_get1(s, janet_ckeywordv("environments"));
if (janet_indexed_view(x, &arr, &count)) {
def->environments_length = count;
for (int32_t i = 0; i < count; i++) {
if (!janet_checkint(arr[i])) {
janet_asm_error(&a, "expected integer");
}
def->environments[i] = janet_unwrap_integer(arr[i]);
}
}
if (NULL == def->environments) { if (NULL == def->environments) {
JANET_OUT_OF_MEMORY; JANET_OUT_OF_MEMORY;
} }
@ -961,7 +978,7 @@ JANET_CORE_FN(cfun_asm,
JanetAssembleResult res; JanetAssembleResult res;
res = janet_asm(argv[0], 0); res = janet_asm(argv[0], 0);
if (res.status != JANET_ASSEMBLE_OK) { if (res.status != JANET_ASSEMBLE_OK) {
janet_panics(res.error); janet_panics(res.error ? res.error : janet_cstring("invalid assembly"));
} }
return janet_wrap_function(janet_thunk(res.funcdef)); return janet_wrap_function(janet_thunk(res.funcdef));
} }

View File

@ -131,9 +131,9 @@ void janet_stacktrace_ext(JanetFiber *fiber, Janet err, const char *prefix) {
if (!wrote_error) { if (!wrote_error) {
JanetFiberStatus status = janet_fiber_status(fiber); JanetFiberStatus status = janet_fiber_status(fiber);
janet_eprintf("%s%s: %s\n", janet_eprintf("%s%s: %s\n",
prefix, prefix ? prefix : "",
janet_status_names[status], janet_status_names[status],
errstr); errstr ? errstr : janet_status_names[status]);
wrote_error = 1; wrote_error = 1;
} }

View File

@ -109,7 +109,7 @@ static void string_description_b(JanetBuffer *buffer, const char *title, void *p
pbuf.p = pointer; pbuf.p = pointer;
*c++ = '<'; *c++ = '<';
/* Maximum of 32 bytes for abstract type name */ /* Maximum of 32 bytes for abstract type name */
for (i = 0; title[i] && i < 32; ++i) for (i = 0; i < 32 && title[i]; ++i)
*c++ = ((uint8_t *)title) [i]; *c++ = ((uint8_t *)title) [i];
*c++ = ' '; *c++ = ' ';
*c++ = '0'; *c++ = '0';

View File

@ -918,7 +918,7 @@ static JanetSignal run_vm(JanetFiber *fiber, Janet in) {
int32_t i; int32_t i;
for (i = 0; i < elen; ++i) { for (i = 0; i < elen; ++i) {
int32_t inherit = fd->environments[i]; int32_t inherit = fd->environments[i];
if (inherit == -1) { if (inherit == -1 || inherit >= func->def->environments_length) {
JanetStackFrame *frame = janet_stack_frame(stack); JanetStackFrame *frame = janet_stack_frame(stack);
if (!frame->env) { if (!frame->env) {
/* Lazy capture of current stack frame */ /* Lazy capture of current stack frame */

View File

@ -102,5 +102,8 @@
(assert (= 6 (with-dyns [*err* errout] (dummy 1 2 3))) "trace to custom err function") (assert (= 6 (with-dyns [*err* errout] (dummy 1 2 3))) "trace to custom err function")
(assert (deep= @"trace (dummy 1 2 3)\n" b) "trace buffer correct")) (assert (deep= @"trace (dummy 1 2 3)\n" b) "trace buffer correct"))
(def f (asm (disasm (fn [x] (fn [y] (+ x y))))))
(assert (= ((f 10) 37) 47) "asm environment tables")
(end-suite) (end-suite)