9 Commits

Author SHA1 Message Date
John Alanbrook
024d796ca4 add asan error vm stacktrace 2026-02-06 21:49:53 -06:00
John Alanbrook
ea185dbffd rm typeof 2026-02-06 21:26:45 -06:00
John Alanbrook
6571262af0 mach disrupt support 2026-02-06 21:09:18 -06:00
John Alanbrook
77ae133747 Merge branch 'mcode2' into mach 2026-02-06 20:45:57 -06:00
John Alanbrook
142a2d518b Merge branch 'stacktrace' into mach 2026-02-06 20:44:43 -06:00
John Alanbrook
5b65c64fe5 stack traces 2026-02-06 20:44:38 -06:00
John Alanbrook
e985fa5fe1 disrupt/disruption; remove try/catch 2026-02-06 18:40:56 -06:00
John Alanbrook
160ade2410 smarter gc malloc for large allocations 2026-02-06 18:38:23 -06:00
John Alanbrook
e2bc5948c1 fix functions and closures in mach 2026-02-06 18:30:26 -06:00
9 changed files with 670 additions and 453 deletions

View File

@@ -574,7 +574,21 @@ int cell_init(int argc, char **argv)
if (JS_IsException(result)) { if (JS_IsException(result)) {
JSValue exc = JS_GetException(ctx); JSValue exc = JS_GetException(ctx);
const char *str = JS_ToCString(ctx, exc); const char *str = JS_ToCString(ctx, exc);
if (str) { printf("Exception: %s\n", str); JS_FreeCString(ctx, str); } if (str) { printf("Error: %s\n", str); JS_FreeCString(ctx, str); }
cJSON *stack = JS_GetStack(ctx);
if (stack) {
int n = cJSON_GetArraySize(stack);
for (int i = 0; i < n; i++) {
cJSON *fr = cJSON_GetArrayItem(stack, i);
const char *fn = cJSON_GetStringValue(cJSON_GetObjectItem(fr, "function"));
const char *file = cJSON_GetStringValue(cJSON_GetObjectItem(fr, "file"));
int line = (int)cJSON_GetNumberValue(cJSON_GetObjectItem(fr, "line"));
int col = (int)cJSON_GetNumberValue(cJSON_GetObjectItem(fr, "column"));
printf(" at %s (%s:%d:%d)\n", fn ? fn : "<anonymous>", file ? file : "<unknown>", line, col);
}
cJSON_Delete(stack);
}
JS_FreeValue(ctx, exc);
} else if (!JS_IsNull(result)) { } else if (!JS_IsNull(result)) {
const char *str = JS_ToCString(ctx, result); const char *str = JS_ToCString(ctx, result);
if (str) { printf("%s\n", str); JS_FreeCString(ctx, str); } if (str) { printf("%s\n", str); JS_FreeCString(ctx, str); }
@@ -716,6 +730,20 @@ int cell_init(int argc, char **argv)
printf("Error: %s\n", err_str); printf("Error: %s\n", err_str);
JS_FreeCString(ctx, err_str); JS_FreeCString(ctx, err_str);
} }
cJSON *stack = JS_GetStack(ctx);
if (stack) {
int n = cJSON_GetArraySize(stack);
for (int i = 0; i < n; i++) {
cJSON *fr = cJSON_GetArrayItem(stack, i);
const char *fn = cJSON_GetStringValue(cJSON_GetObjectItem(fr, "function"));
const char *file = cJSON_GetStringValue(cJSON_GetObjectItem(fr, "file"));
int line = (int)cJSON_GetNumberValue(cJSON_GetObjectItem(fr, "line"));
int col = (int)cJSON_GetNumberValue(cJSON_GetObjectItem(fr, "column"));
printf(" at %s (%s:%d:%d)\n", fn ? fn : "<anonymous>", file ? file : "<unknown>", line, col);
}
cJSON_Delete(stack);
}
JS_FreeValue(ctx, exc);
exit_code = 1; exit_code = 1;
} else if (!JS_IsNull(result)) { } else if (!JS_IsNull(result)) {
const char *str = JS_ToCString(ctx, result); const char *str = JS_ToCString(ctx, result);

File diff suppressed because it is too large Load Diff

View File

@@ -1260,6 +1260,11 @@ char *JS_Mcode (const char *ast_json);
Returns result of execution, or JS_EXCEPTION on error. */ Returns result of execution, or JS_EXCEPTION on error. */
JSValue JS_CallMcode (JSContext *ctx, const char *mcode_json); JSValue JS_CallMcode (JSContext *ctx, const char *mcode_json);
/* Get stack trace as cJSON array of frame objects.
Returns NULL if no register VM frame is active.
Caller must call cJSON_Delete() on the result. */
struct cJSON *JS_GetStack (JSContext *ctx);
/* Integrate a CellModule with an environment and execute. /* Integrate a CellModule with an environment and execute.
Returns callable function value, or JS_EXCEPTION on error. */ Returns callable function value, or JS_EXCEPTION on error. */
JSValue cell_module_integrate (JSContext *ctx, CellModule *mod, JSValue env); JSValue cell_module_integrate (JSContext *ctx, CellModule *mod, JSValue env);

39
tests/demo.ce Normal file
View File

@@ -0,0 +1,39 @@
function safe_add(a, b) {
return a + b
} disruption {
print("disruption caught in safe_add")
}
function inner() {
disrupt
}
function outer() {
inner()
} disruption {
print("disruption caught in outer — from inner()")
}
// Test 1: explicit disrupt with handler
function test_explicit() {
disrupt
} disruption {
print("test 1: explicit disrupt handled")
}
test_explicit()
// Test 2: type error disrupt (number + function)
safe_add(1, print)
// Test 3: unwinding — inner disrupts, outer catches
outer()
// Test 4: disrupt from inside disruption clause
function test_nested() {
disrupt
} disruption {
print("test 4: first disruption")
}
test_nested()
print("done")

View File

@@ -252,29 +252,21 @@ loop: for (var m = 0; m < 3; m++) {
} }
} }
// --- try/catch/finally --- // --- disrupt and disruption ---
var tc function disrupt_test() {
try { disrupt
throw "error"
} catch (e) {
tc = e
} }
var tcf = 0 function disruption_test() {
try { var x = 1
throw "err" } disruption {
} catch (e) { var y = 2
tcf = 1
} finally {
tcf += 10
} }
// --- try/finally (no catch) --- function disrupt_with_disruption() {
var tf = 0 disrupt
try { } disruption {
tf = 1 var handled = true
} finally {
tf += 1
} }
// --- delete operator --- // --- delete operator ---

View File

@@ -1 +0,0 @@
try { 1 } catch(e) { 2 }

View File

@@ -1 +0,0 @@
var x = 1; try { throw 0 } catch(e) { x = 2 } finally { x = x + 1 }; x

View File

@@ -1 +0,0 @@
var x = 1; try { x = 2 } finally { x = 3 }; x

View File

@@ -1 +0,0 @@
try { throw "err" } catch(e) { e }