Merge branch 'pitweb' into mach

This commit is contained in:
2026-02-09 12:57:01 -06:00
10 changed files with 248 additions and 13999 deletions

View File

@@ -288,113 +288,11 @@ static int run_test_suite(size_t heap_size)
}
/* Run an immediate script string */
static int run_eval(const char *script_or_file, int print_bytecode, int use_bootstrap_env)
{
if (!find_cell_shop()) return 1;
/* Check if argument is a file path */
struct stat st;
char *script = NULL;
char *allocated_script = NULL;
const char *filename = "<eval>";
if (stat(script_or_file, &st) == 0 && S_ISREG(st.st_mode)) {
/* It's a file, read its contents */
FILE *f = fopen(script_or_file, "r");
if (!f) {
printf("Failed to open file: %s\n", script_or_file);
return 1;
}
allocated_script = malloc(st.st_size + 1);
if (!allocated_script) {
fclose(f);
printf("Failed to allocate memory for script\n");
return 1;
}
size_t read_size = fread(allocated_script, 1, st.st_size, f);
fclose(f);
allocated_script[read_size] = '\0';
script = allocated_script;
filename = script_or_file;
} else {
/* Treat as inline script */
script = (char *)script_or_file;
}
JSRuntime *rt = JS_NewRuntime();
if (!rt) {
printf("Failed to create JS runtime\n");
free(allocated_script);
return 1;
}
JSContext *ctx = JS_NewContext(rt);
if (!ctx) {
printf("Failed to create JS context\n");
JS_FreeRuntime(rt);
free(allocated_script);
return 1;
}
int result = 0;
JSGCRef bytecode_ref;
JS_PushGCRef(ctx, &bytecode_ref);
bytecode_ref.val = JS_Compile(ctx, script, strlen(script), filename);
if (JS_IsException(bytecode_ref.val)) {
uncaught_exception(ctx, bytecode_ref.val);
JS_PopGCRef(ctx, &bytecode_ref);
result = 1;
} else {
if (print_bytecode) {
printf("=== Compiled Bytecode ===\n");
JS_DumpFunctionBytecode(ctx, bytecode_ref.val);
}
JSValue env = JS_NULL;
if (use_bootstrap_env) {
JSGCRef env_ref, json_ref, nota_ref, wota_ref;
JS_PushGCRef(ctx, &env_ref);
JS_PushGCRef(ctx, &json_ref);
JS_PushGCRef(ctx, &nota_ref);
JS_PushGCRef(ctx, &wota_ref);
env_ref.val = JS_NewObject(ctx);
/* Create modules with GC rooting, then stone them */
json_ref.val = js_json_use(ctx);
nota_ref.val = js_nota_use(ctx);
wota_ref.val = js_wota_use(ctx);
JS_SetPropertyStr(ctx, env_ref.val, "json", JS_Stone(ctx, json_ref.val));
JS_SetPropertyStr(ctx, env_ref.val, "nota", JS_Stone(ctx, nota_ref.val));
JS_SetPropertyStr(ctx, env_ref.val, "wota", JS_Stone(ctx, wota_ref.val));
env = JS_Stone(ctx, env_ref.val);
JS_PopGCRef(ctx, &wota_ref);
JS_PopGCRef(ctx, &nota_ref);
JS_PopGCRef(ctx, &json_ref);
JS_PopGCRef(ctx, &env_ref);
}
JSValue v = JS_Integrate(ctx, bytecode_ref.val, env);
JS_PopGCRef(ctx, &bytecode_ref);
if (JS_IsException(v)) {
uncaught_exception(ctx, v);
result = 1;
} else {
JS_FreeValue(ctx, v);
}
}
JS_FreeContext(ctx);
JS_FreeRuntime(rt);
free(allocated_script);
return result;
}
static void print_usage(const char *prog)
{
printf("Usage: %s [options] <script> [args...]\n\n", prog);
printf("Run a cell script (.ce actor or .cm module).\n\n");
printf("Options:\n");
printf(" -e, --eval <code|file> Evaluate code or run a file directly\n");
printf(" -p, --print-bytecode <code|file> Compile and print bytecode\n");
printf(" -s, --serializers <code|file> Run with json/nota/wota in env\n");
printf(" --ast <code|file> Output AST as JSON\n");
printf(" --tokenize <code|file> Output token array as JSON\n");
printf(" --mcode <code|file> Output MCODE IR as JSON\n");
@@ -633,29 +531,11 @@ int cell_init(int argc, char **argv)
JSValue result = JS_CallMcodeTreeEnv(ctx, mcode, hidden_env);
int exit_code = 0;
if (JS_IsException(result)) {
JSValue exc = JS_GetException(ctx);
const char *str = NULL;
if (JS_IsObject(exc)) {
JSValue msg = JS_GetPropertyStr(ctx, exc, "message");
str = JS_ToCString(ctx, msg);
}
if (!str) str = JS_ToCString(ctx, exc);
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);
/* Error already printed to stderr by JS_Throw* */
JS_GetException(ctx);
exit_code = 1;
} else if (!JS_IsNull(result)) {
const char *str = JS_ToCString(ctx, result);
if (str) { printf("%s\n", str); JS_FreeCString(ctx, str); }
@@ -663,7 +543,7 @@ int cell_init(int argc, char **argv)
JS_FreeContext(ctx);
JS_FreeRuntime(rt);
return JS_IsException(result) ? 1 : 0;
return exit_code;
}
/* Check for --mach flag to dump MACH bytecode */
@@ -779,6 +659,7 @@ int cell_init(int argc, char **argv)
int exit_code = 0;
if (JS_IsException(result)) {
<<<<<<< HEAD
JSValue exc = JS_GetException(ctx);
const char *err_str = NULL;
if (JS_IsObject(exc)) {
@@ -804,6 +685,10 @@ int cell_init(int argc, char **argv)
cJSON_Delete(stack);
}
JS_FreeValue(ctx, exc);
=======
/* Error already printed to stderr by JS_Throw* */
JS_GetException(ctx);
>>>>>>> pitweb
exit_code = 1;
} else if (!JS_IsNull(result)) {
const char *str = JS_ToCString(ctx, result);
@@ -818,19 +703,6 @@ int cell_init(int argc, char **argv)
return exit_code;
}
/* Check for -e or --eval flag to run immediate script */
/* Also check for -p flag to print bytecode */
/* -s / --serializers flag provides json, nota, wota in env */
if (argc >= 3 && (strcmp(argv[1], "-e") == 0 || strcmp(argv[1], "--eval") == 0)) {
return run_eval(argv[2], 0, 0);
}
if (argc >= 3 && (strcmp(argv[1], "-p") == 0 || strcmp(argv[1], "--print-bytecode") == 0)) {
return run_eval(argv[2], 1, 0);
}
if (argc >= 3 && (strcmp(argv[1], "-s") == 0 || strcmp(argv[1], "--serializers") == 0)) {
return run_eval(argv[2], 0, 1);
}
int script_start = 1;
/* Find the cell shop at ~/.cell */
@@ -904,31 +776,11 @@ void cell_trace_sethook(cell_hook)
int uncaught_exception(JSContext *js, JSValue v)
{
cell_rt *rt = JS_GetContextOpaque(js);
if (!JS_HasException(js)) {
JS_FreeValue(js,v);
(void)v;
if (!JS_HasException(js))
return 1;
}
JSValue exp = JS_GetException(js);
JSValue message = JS_GetPropertyStr(js, exp, "message");
const char *msg_str = JS_ToCString(js, message);
if (msg_str) {
printf("Exception: %s\n", msg_str);
JS_FreeCString(js, msg_str);
}
JS_FreeValue(js, message);
JSValue stack = JS_GetPropertyStr(js, exp, "stack");
const char *stack_str = JS_ToCString(js, stack);
if (stack_str) {
printf("Stack:\n%s\n", stack_str);
JS_FreeCString(js, stack_str);
}
JS_FreeValue(js, stack);
JS_FreeValue(js, exp);
JS_FreeValue(js, v);
/* Error message and backtrace were already printed to stderr
by JS_ThrowError2 / print_backtrace. Just clear the flag. */
JS_GetException(js);
return 0;
}
}