From 05b57550dad6f7f4bb37ddbdca30e4fb94bc8006 Mon Sep 17 00:00:00 2001 From: John Alanbrook Date: Mon, 29 Dec 2025 13:01:05 -0600 Subject: [PATCH] vm trampoline setup --- source/quickjs.c | 59 +++++++++++++++++++++++++++++++++++++++++++++--- tests/suite.cm | 2 +- 2 files changed, 57 insertions(+), 4 deletions(-) diff --git a/source/quickjs.c b/source/quickjs.c index 86840cac..2a9d20c7 100644 --- a/source/quickjs.c +++ b/source/quickjs.c @@ -337,6 +337,28 @@ struct VMFrame { int stack_size_allocated; /* total size allocated for this frame */ }; +/* Execution state returned by vm_execute_frame */ +typedef enum { + VM_EXEC_NORMAL, /* Continue executing current frame */ + VM_EXEC_RETURN, /* Frame returned, pop and resume caller */ + VM_EXEC_CALL, /* Need to push new frame for call */ + VM_EXEC_EXCEPTION, /* Exception thrown, unwind frames */ +} VMExecState; + +/* Call info for frame push */ +typedef struct { + JSValue func_obj; + JSValue this_obj; + JSValue new_target; + int argc; + JSValue *argv; + const uint8_t *ret_pc; + int ret_sp_offset; + int call_argc; + int call_has_this; + int is_tail_call; +} VMCallInfo; + typedef enum { JS_GC_OBJ_TYPE_JS_OBJECT, JS_GC_OBJ_TYPE_FUNCTION_BYTECODE, @@ -902,6 +924,9 @@ static JSValue js_call_bound_function(JSContext *ctx, JSValueConst func_obj, static JSValue JS_CallInternal(JSContext *ctx, JSValueConst func_obj, JSValueConst this_obj, JSValueConst new_target, int argc, JSValue *argv, int flags); +static JSValue JS_CallInternal_OLD(JSContext *ctx, JSValueConst func_obj, + JSValueConst this_obj, JSValueConst new_target, + int argc, JSValue *argv, int flags); static JSValue JS_CallConstructorInternal(JSContext *ctx, JSValueConst func_obj, JSValueConst new_target, @@ -12968,9 +12993,35 @@ static JSValue JS_CallTrampoline(JSContext *caller_ctx, JSValueConst func_obj, return ret_val; } +/* Execute a single frame (delegates to OLD implementation for now) */ +static VMExecState vm_execute_frame(JSContext *ctx, struct VMFrame *frame, + JSValue *ret_val, VMCallInfo *call_info) +{ + /* TODO: Replace with proper bytecode loop extraction */ + /* For now, delegate to the old recursive implementation */ + *ret_val = JS_CallInternal_OLD(ctx, frame->cur_func, frame->this_obj, + frame->new_target, frame->arg_count, + vm_frame_get_arg_buf(ctx, frame), 0); + if (JS_IsException(*ret_val)) + return VM_EXEC_EXCEPTION; + return VM_EXEC_RETURN; +} + +/* Trampoline-based JS_CallInternal - eliminates C stack recursion */ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj, JSValueConst this_obj, JSValueConst new_target, int argc, JSValue *argv, int flags) +{ + /* TODO: Implement full trampoline */ + /* For now, just delegate to OLD implementation */ + return JS_CallInternal_OLD(caller_ctx, func_obj, this_obj, new_target, + argc, argv, flags); +} + +/* OLD recursive implementation - to be removed after trampoline is complete */ +static JSValue JS_CallInternal_OLD(JSContext *caller_ctx, JSValueConst func_obj, + JSValueConst this_obj, JSValueConst new_target, + int argc, JSValue *argv, int flags) { JSRuntime *rt = caller_ctx->rt; JSContext *ctx; @@ -13370,7 +13421,8 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj, /* Record call site */ profile_record_call_site(rt, b, (uint32_t)(pc - b->byte_code_buf)); #endif - ret_val = JS_CallInternal(ctx, call_argv[-1], JS_NULL, + /* TODO: Use trampoline - for now keep recursive */ + ret_val = JS_CallInternal_OLD(ctx, call_argv[-1], JS_NULL, JS_NULL, call_argc, call_argv, 0); if (unlikely(JS_IsException(ret_val))) goto exception; @@ -13414,7 +13466,7 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj, /* Record call site */ profile_record_call_site(rt, b, (uint32_t)(pc - b->byte_code_buf)); #endif - ret_val = JS_CallInternal(ctx, call_argv[-1], call_argv[-2], + ret_val = JS_CallInternal_OLD(ctx, call_argv[-1], call_argv[-2], JS_NULL, call_argc, call_argv, 0); if (unlikely(JS_IsException(ret_val))) goto exception; @@ -13522,7 +13574,7 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj, ret_val = JS_EvalObject(ctx, JS_NULL, obj, JS_EVAL_TYPE_DIRECT, scope_idx); } else { - ret_val = JS_CallInternal(ctx, call_argv[-1], JS_NULL, + ret_val = JS_CallInternal_OLD(ctx, call_argv[-1], JS_NULL, JS_NULL, call_argc, call_argv, 0); } if (unlikely(JS_IsException(ret_val))) @@ -15653,6 +15705,7 @@ enum { /* FutureReservedWords when parsing strict mode code */ TOK_IMPLEMENTS, TOK_INTERFACE, + TOK_LET, TOK_PRIVATE, TOK_PROTECTED, TOK_PUBLIC, diff --git a/tests/suite.cm b/tests/suite.cm index 7cb91e49..a4b2e6d3 100644 --- a/tests/suite.cm +++ b/tests/suite.cm @@ -1,7 +1,7 @@ // Comprehensive test suite for cell runtime stability // Tests all core features before implementing performance optimizations // (bytecode passes, ICs, quickening, tail call optimization) - +// return { // ============================================================================ // ARITHMETIC OPERATORS - Numbers