mcode->mach
This commit is contained in:
189
source/runtime.c
189
source/runtime.c
@@ -1139,10 +1139,6 @@ void gc_scan_object (JSContext *ctx, void *ptr, uint8_t *from_base, uint8_t *fro
|
||||
nested->name = gc_copy_value (ctx, nested->name, from_base, from_end, to_base, to_free, to_end);
|
||||
}
|
||||
}
|
||||
} else if (fn->kind == JS_FUNC_KIND_MCODE) {
|
||||
/* MCODE function - scan outer_frame and env_record */
|
||||
fn->u.mcode.outer_frame = gc_copy_value (ctx, fn->u.mcode.outer_frame, from_base, from_end, to_base, to_free, to_end);
|
||||
fn->u.mcode.env_record = gc_copy_value (ctx, fn->u.mcode.env_record, from_base, from_end, to_base, to_free, to_end);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -4630,8 +4626,6 @@ JSValue JS_CallInternal (JSContext *ctx, JSValue func_obj, JSValue this_obj,
|
||||
case JS_FUNC_KIND_REGISTER:
|
||||
return JS_CallRegisterVM (ctx, f->u.reg.code, this_obj, argc, argv,
|
||||
f->u.reg.env_record, f->u.reg.outer_frame);
|
||||
case JS_FUNC_KIND_MCODE:
|
||||
return mcode_exec (ctx, f->u.mcode.code, this_obj, argc, argv, f->u.mcode.outer_frame);
|
||||
default:
|
||||
return JS_ThrowTypeError (ctx, "not a function");
|
||||
}
|
||||
@@ -4653,8 +4647,6 @@ JSValue JS_Call (JSContext *ctx, JSValue func_obj, JSValue this_obj, int argc, J
|
||||
case JS_FUNC_KIND_REGISTER:
|
||||
return JS_CallRegisterVM (ctx, f->u.reg.code, this_obj, argc, argv,
|
||||
f->u.reg.env_record, f->u.reg.outer_frame);
|
||||
case JS_FUNC_KIND_MCODE:
|
||||
return mcode_exec (ctx, f->u.mcode.code, this_obj, argc, argv, f->u.mcode.outer_frame);
|
||||
default:
|
||||
return JS_ThrowTypeError (ctx, "not a function");
|
||||
}
|
||||
@@ -10117,83 +10109,6 @@ int js_is_blob (JSContext *js, JSValue v) {
|
||||
* ============================================================================
|
||||
*/
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
/* mach_compile_ast(name, ast_json) - compile pre-parsed AST to binary blob */
|
||||
static JSValue js_mach_compile_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_compile_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_compile_ast: failed to parse AST JSON");
|
||||
}
|
||||
|
||||
cJSON_DeleteItemFromObjectCaseSensitive (ast, "filename");
|
||||
cJSON_AddStringToObject (ast, "filename", name);
|
||||
|
||||
MachCode *mc = JS_CompileMachTree (ast);
|
||||
cJSON_Delete (ast);
|
||||
JS_FreeCString (ctx, name);
|
||||
|
||||
if (!mc)
|
||||
return JS_ThrowSyntaxError (ctx, "mach_compile_ast: failed to compile AST");
|
||||
|
||||
size_t blob_size;
|
||||
uint8_t *buf = JS_SerializeMachCode (mc, &blob_size);
|
||||
JS_FreeMachCode (mc);
|
||||
|
||||
if (!buf)
|
||||
return JS_ThrowInternalError (ctx, "mach_compile_ast: serialization failed");
|
||||
|
||||
JSValue result = js_new_blob_stoned_copy (ctx, buf, blob_size);
|
||||
sys_free (buf);
|
||||
return result;
|
||||
}
|
||||
|
||||
/* mach_load(blob, env?) - deserialize and execute binary blob */
|
||||
static JSValue js_mach_load (JSContext *ctx, JSValue this_val, int argc, JSValue *argv) {
|
||||
if (argc < 1)
|
||||
@@ -10207,6 +10122,11 @@ static JSValue js_mach_load (JSContext *ctx, JSValue this_val, int argc, JSValue
|
||||
if (!mc)
|
||||
return JS_ThrowSyntaxError (ctx, "mach_load: failed to deserialize bytecode");
|
||||
|
||||
{
|
||||
extern void verify_getup(MachCode *mc, const char *path);
|
||||
verify_getup(mc, "MACH_LOAD");
|
||||
}
|
||||
|
||||
JSValue env = (argc >= 2 && JS_IsObject (argv[1])) ? argv[1] : JS_NULL;
|
||||
|
||||
JSGCRef env_ref;
|
||||
@@ -10220,35 +10140,6 @@ static JSValue js_mach_load (JSContext *ctx, JSValue this_val, int argc, JSValue
|
||||
return result;
|
||||
}
|
||||
|
||||
/* mcode_run(name, mcode_json, env?) - run pre-compiled mcode JSON */
|
||||
static JSValue js_mcode_run (JSContext *ctx, JSValue this_val, int argc, JSValue *argv) {
|
||||
if (argc < 2 || !JS_IsText (argv[0]) || !JS_IsText (argv[1]))
|
||||
return JS_ThrowTypeError (ctx, "mcode_run requires (name, mcode_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 *mcode = cJSON_Parse (json_str);
|
||||
JS_FreeCString (ctx, json_str);
|
||||
|
||||
if (!mcode) {
|
||||
JS_FreeCString (ctx, name);
|
||||
return JS_ThrowSyntaxError (ctx, "mcode_run: failed to parse mcode JSON");
|
||||
}
|
||||
|
||||
JSValue env = (argc >= 3 && JS_IsObject (argv[2])) ? argv[2] : JS_NULL;
|
||||
JSValue result = JS_CallMcodeTreeEnv (ctx, mcode, env);
|
||||
/* mcode tree ownership transferred to JS_CallMcodeTreeEnv — do not free */
|
||||
JS_FreeCString (ctx, name);
|
||||
return result;
|
||||
}
|
||||
|
||||
/* mach_eval_mcode(name, mcode_json, env?) - compile mcode IR and run via register VM */
|
||||
static JSValue js_mach_eval_mcode (JSContext *ctx, JSValue this_val, int argc, JSValue *argv) {
|
||||
if (argc < 2 || !JS_IsText (argv[0]) || !JS_IsText (argv[1]))
|
||||
@@ -10298,6 +10189,61 @@ static JSValue js_mach_eval_mcode (JSContext *ctx, JSValue this_val, int argc, J
|
||||
return result;
|
||||
}
|
||||
|
||||
/* mach_compile_mcode_bin(name, mcode_json) - compile mcode IR to serialized binary blob */
|
||||
static JSValue js_mach_compile_mcode_bin (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_compile_mcode_bin requires (name, mcode_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 *mcode = cJSON_Parse (json_str);
|
||||
JS_FreeCString (ctx, json_str);
|
||||
|
||||
if (!mcode) {
|
||||
JS_FreeCString (ctx, name);
|
||||
return JS_ThrowSyntaxError (ctx, "mach_compile_mcode_bin: failed to parse mcode JSON");
|
||||
}
|
||||
|
||||
if (!cJSON_GetObjectItemCaseSensitive (mcode, "filename"))
|
||||
cJSON_AddStringToObject (mcode, "filename", name);
|
||||
|
||||
MachCode *mc = mach_compile_mcode (mcode);
|
||||
cJSON_Delete (mcode);
|
||||
JS_FreeCString (ctx, name);
|
||||
|
||||
if (!mc)
|
||||
return JS_ThrowInternalError (ctx, "mach_compile_mcode_bin: compilation failed");
|
||||
|
||||
size_t size = 0;
|
||||
uint8_t *data = JS_SerializeMachCode (mc, &size);
|
||||
|
||||
/* DEBUG: verify round-trip */
|
||||
{
|
||||
MachCode *mc2 = JS_DeserializeMachCode (data, size);
|
||||
if (mc2) {
|
||||
extern void verify_getup(MachCode *mc, const char *path);
|
||||
verify_getup(mc2, "ROUNDTRIP");
|
||||
JS_FreeMachCode (mc2);
|
||||
}
|
||||
}
|
||||
|
||||
JS_FreeMachCode (mc);
|
||||
|
||||
if (!data)
|
||||
return JS_ThrowInternalError (ctx, "mach_compile_mcode_bin: serialization failed");
|
||||
|
||||
JSValue blob = js_new_blob_stoned_copy (ctx, data, size);
|
||||
sys_free (data);
|
||||
return blob;
|
||||
}
|
||||
|
||||
/* ============================================================================
|
||||
* stone() function - deep freeze with blob support
|
||||
* ============================================================================
|
||||
@@ -11398,11 +11344,9 @@ static void JS_AddIntrinsicBaseObjects (JSContext *ctx) {
|
||||
}
|
||||
|
||||
/* Core functions - using GC-safe helper */
|
||||
js_set_global_cfunc(ctx, "mach_eval_ast", js_mach_eval_ast, 3);
|
||||
js_set_global_cfunc(ctx, "mcode_run", js_mcode_run, 3);
|
||||
js_set_global_cfunc(ctx, "mach_compile_ast", js_mach_compile_ast, 2);
|
||||
js_set_global_cfunc(ctx, "mach_load", js_mach_load, 2);
|
||||
js_set_global_cfunc(ctx, "mach_eval_mcode", js_mach_eval_mcode, 3);
|
||||
js_set_global_cfunc(ctx, "mach_compile_mcode_bin", js_mach_compile_mcode_bin, 2);
|
||||
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);
|
||||
@@ -13150,17 +13094,6 @@ cJSON *JS_GetStack(JSContext *ctx) {
|
||||
line = code->line_table[pc].line;
|
||||
col = code->line_table[pc].col;
|
||||
}
|
||||
} else if (fn->kind == JS_FUNC_KIND_MCODE && fn->u.mcode.code) {
|
||||
JSMCode *code = fn->u.mcode.code;
|
||||
file = code->filename;
|
||||
func_name = code->name;
|
||||
if (!is_first) {
|
||||
pc = (uint32_t)(JS_VALUE_GET_INT(frame->address) >> 16);
|
||||
}
|
||||
if (code->line_table && pc < code->instr_count) {
|
||||
line = code->line_table[pc].line;
|
||||
col = code->line_table[pc].col;
|
||||
}
|
||||
}
|
||||
|
||||
cJSON *entry = cJSON_CreateObject();
|
||||
|
||||
Reference in New Issue
Block a user