rm quickjs vm
This commit is contained in:
190
source/cell.c
190
source/cell.c
@@ -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, ¬a_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, ¬a_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,24 +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 = 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); }
|
||||
@@ -658,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 */
|
||||
@@ -774,26 +659,8 @@ int cell_init(int argc, char **argv)
|
||||
|
||||
int exit_code = 0;
|
||||
if (JS_IsException(result)) {
|
||||
JSValue exc = JS_GetException(ctx);
|
||||
const char *err_str = JS_ToCString(ctx, exc);
|
||||
if (err_str) {
|
||||
printf("Error: %s\n", 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);
|
||||
/* 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);
|
||||
@@ -808,19 +675,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 */
|
||||
@@ -894,31 +748,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;
|
||||
}
|
||||
Reference in New Issue
Block a user