streamlined cell running
This commit is contained in:
@@ -650,6 +650,7 @@ int cell_init(int argc, char **argv)
|
||||
|
||||
JSValue hidden_env = JS_NewObject(ctx);
|
||||
JS_SetPropertyStr(ctx, hidden_env, "os", js_os_use(ctx));
|
||||
JS_SetPropertyStr(ctx, hidden_env, "core_path", JS_NewString(ctx, core_path));
|
||||
JSValue args_arr = JS_NewArray(ctx);
|
||||
for (int i = 2; i < argc; i++) {
|
||||
JSValue str = JS_NewString(ctx, argv[i]);
|
||||
@@ -679,41 +680,72 @@ int cell_init(int argc, char **argv)
|
||||
return exit_code;
|
||||
}
|
||||
|
||||
int script_start = 1;
|
||||
/* Default: run script through mach-run bootstrap pipeline */
|
||||
if (!find_cell_shop()) return 1;
|
||||
|
||||
/* Find the cell shop at ~/.cell */
|
||||
int found = find_cell_shop();
|
||||
if (!found) {
|
||||
size_t boot_size;
|
||||
char *boot_data = load_core_file("internal/bootstrap.cm", &boot_size);
|
||||
if (!boot_data) {
|
||||
printf("ERROR: Could not load internal/bootstrap.cm from %s\n", core_path);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Create the initial actor from the command line */
|
||||
int actor_argc = argc - script_start;
|
||||
char **actor_argv = argv + script_start;
|
||||
cJSON *boot_ast = JS_ASTTree(boot_data, boot_size, "internal/bootstrap.cm");
|
||||
free(boot_data);
|
||||
if (!boot_ast) {
|
||||
printf("Failed to parse internal/bootstrap.cm\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
WotaBuffer startwota;
|
||||
wota_buffer_init(&startwota, 5);
|
||||
wota_write_record(&startwota, 2);
|
||||
wota_write_text(&startwota, "program");
|
||||
wota_write_text(&startwota, actor_argv[0]);
|
||||
wota_write_text(&startwota, "arg");
|
||||
wota_write_array(&startwota, actor_argc - 1);
|
||||
for (int i = 1; i < actor_argc; i++)
|
||||
wota_write_text(&startwota, actor_argv[i]);
|
||||
|
||||
/* Initialize synchronization primitives */
|
||||
actor_initialize();
|
||||
|
||||
root_cell = create_actor(startwota.data);
|
||||
#ifndef TARGET_PLAYDATE
|
||||
signal(SIGINT, signal_handler);
|
||||
signal(SIGTERM, signal_handler);
|
||||
signal(SIGSEGV, signal_handler);
|
||||
signal(SIGABRT, signal_handler);
|
||||
#endif
|
||||
actor_loop();
|
||||
if (print_tree_errors(boot_ast)) {
|
||||
cJSON_Delete(boot_ast);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
JSRuntime *rt = JS_NewRuntime();
|
||||
if (!rt) {
|
||||
printf("Failed to create JS runtime\n");
|
||||
cJSON_Delete(boot_ast);
|
||||
return 1;
|
||||
}
|
||||
JSContext *ctx = JS_NewContextWithHeapSize(rt, 16 * 1024 * 1024);
|
||||
if (!ctx) {
|
||||
printf("Failed to create JS context\n");
|
||||
cJSON_Delete(boot_ast); JS_FreeRuntime(rt);
|
||||
return 1;
|
||||
}
|
||||
|
||||
JS_FreeValue(ctx, js_blob_use(ctx));
|
||||
|
||||
JSValue hidden_env = JS_NewObject(ctx);
|
||||
JS_SetPropertyStr(ctx, hidden_env, "os", js_os_use(ctx));
|
||||
JS_SetPropertyStr(ctx, hidden_env, "core_path", JS_NewString(ctx, core_path));
|
||||
JSValue args_arr = JS_NewArray(ctx);
|
||||
for (int i = 1; i < argc; i++) {
|
||||
JSValue str = JS_NewString(ctx, argv[i]);
|
||||
JS_ArrayPush(ctx, &args_arr, str);
|
||||
}
|
||||
JS_SetPropertyStr(ctx, hidden_env, "args", args_arr);
|
||||
hidden_env = JS_Stone(ctx, hidden_env);
|
||||
|
||||
JSValue result = JS_RunMachTree(ctx, boot_ast, hidden_env);
|
||||
cJSON_Delete(boot_ast);
|
||||
|
||||
int exit_code = 0;
|
||||
if (JS_IsException(result)) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
JS_FreeContext(ctx);
|
||||
JS_FreeRuntime(rt);
|
||||
return exit_code;
|
||||
}
|
||||
|
||||
int JS_ArrayLength(JSContext *js, JSValue a)
|
||||
|
||||
@@ -10434,6 +10434,39 @@ static JSValue js_mach_eval (JSContext *ctx, JSValue this_val, int argc, JSValue
|
||||
return result;
|
||||
}
|
||||
|
||||
/* mach_eval_ast(name, ast_json, env?) - compile pre-parsed AST and run */
|
||||
static JSValue js_mach_eval_ast (JSContext *ctx, JSValue this_val, int argc, JSValue *argv) {
|
||||
if (argc < 2 || !JS_IsText (argv[0]) || !JS_IsText (argv[1]))
|
||||
return JS_ThrowTypeError (ctx, "mach_eval_ast requires (name, ast_json) text arguments");
|
||||
|
||||
const char *name = JS_ToCString (ctx, argv[0]);
|
||||
if (!name) return JS_EXCEPTION;
|
||||
|
||||
const char *json_str = JS_ToCString (ctx, argv[1]);
|
||||
if (!json_str) {
|
||||
JS_FreeCString (ctx, name);
|
||||
return JS_EXCEPTION;
|
||||
}
|
||||
|
||||
cJSON *ast = cJSON_Parse (json_str);
|
||||
JS_FreeCString (ctx, json_str);
|
||||
|
||||
if (!ast) {
|
||||
JS_FreeCString (ctx, name);
|
||||
return JS_ThrowSyntaxError (ctx, "mach_eval_ast: failed to parse AST JSON");
|
||||
}
|
||||
|
||||
/* Set the filename on the AST root */
|
||||
cJSON_DeleteItemFromObjectCaseSensitive (ast, "filename");
|
||||
cJSON_AddStringToObject (ast, "filename", name);
|
||||
|
||||
JSValue env = (argc >= 3 && JS_IsObject (argv[2])) ? argv[2] : JS_NULL;
|
||||
JSValue result = JS_RunMachTree (ctx, ast, env);
|
||||
cJSON_Delete (ast);
|
||||
JS_FreeCString (ctx, name);
|
||||
return result;
|
||||
}
|
||||
|
||||
/* ============================================================================
|
||||
* stone() function - deep freeze with blob support
|
||||
* ============================================================================
|
||||
@@ -11527,6 +11560,7 @@ static void JS_AddIntrinsicBaseObjects (JSContext *ctx) {
|
||||
/* Core functions - using GC-safe helper */
|
||||
js_set_global_cfunc(ctx, "eval", js_cell_eval, 2);
|
||||
js_set_global_cfunc(ctx, "mach_eval", js_mach_eval, 3);
|
||||
js_set_global_cfunc(ctx, "mach_eval_ast", js_mach_eval_ast, 3);
|
||||
js_set_global_cfunc(ctx, "stone", js_cell_stone, 1);
|
||||
js_set_global_cfunc(ctx, "length", js_cell_length, 1);
|
||||
js_set_global_cfunc(ctx, "call", js_cell_call, 3);
|
||||
|
||||
Reference in New Issue
Block a user