Simplify exiting interpreter with exception

- Avoid keeping the exception object around
- Avoid passing the responsibility of freeing the exeption object to the
  caller
This commit is contained in:
Saúl Ibarra Corretgé 2025-01-06 11:17:22 +01:00
parent 6d64933328
commit 97ea19dc81
9 changed files with 21 additions and 39 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

12
qjs.c
View file

@ -399,6 +399,7 @@ int main(int argc, char **argv)
JSContext *ctx;
JSValue ret = JS_UNDEFINED;
struct trace_malloc_data trace_data = { NULL };
int r = 0;
int optind = 1;
char *compile_file = NULL;
char *exe = NULL;
@ -683,17 +684,16 @@ start:
}
if (standalone || compile_file) {
if (JS_IsException(ret)) {
ret = JS_GetException(ctx);
r = 1;
} else {
JS_FreeValue(ctx, ret);
ret = js_std_loop(ctx);
r = js_std_loop(ctx);
}
} else {
ret = js_std_loop(ctx);
r = js_std_loop(ctx);
}
if (!JS_IsUndefined(ret)) {
js_std_dump_error1(ctx, ret);
JS_FreeValue(ctx, ret);
if (r) {
js_std_dump_error(ctx);
goto fail;
}
}

11
qjsc.c
View file

@ -315,7 +315,6 @@ static const char main_c_template1[] =
"int main(int argc, char **argv)\n"
"{\n"
" int r;\n"
" JSValue ret;\n"
" JSRuntime *rt;\n"
" JSContext *ctx;\n"
" r = 0;\n"
@ -325,14 +324,12 @@ static const char main_c_template1[] =
;
static const char main_c_template2[] =
" ret = js_std_loop(ctx);\n"
" if (JS_IsException(ret)) {\n"
" js_std_dump_error1(ctx, ret);\n"
" r = 1;\n"
" r = js_std_loop(ctx);\n"
" if (r) {\n"
" js_std_dump_error(ctx);\n"
" }\n"
" JS_FreeValue(ctx, ret);\n"
" JS_FreeContext(ctx);\n"
" js_std_free_handlers(rt);\n"
" JS_FreeContext(ctx);\n"
" JS_FreeRuntime(rt);\n"
" return r;\n"
"}\n";

View file

@ -161,7 +161,6 @@ typedef struct JSThreadState {
struct list_head port_list; /* list of JSWorkerMessageHandler.link */
int eval_script_recurse; /* only used in the main thread */
int64_t next_timer_id; /* for setTimeout / setInterval */
JSValue exc; /* current exception from one of our handlers */
BOOL can_js_os_poll;
/* not used in the main thread */
JSWorkerMessagePipe *recv_pipe, *send_pipe;
@ -2274,12 +2273,8 @@ static int call_handler(JSContext *ctx, JSValue func)
ret = JS_Call(ctx, func1, JS_UNDEFINED, 0, NULL);
JS_FreeValue(ctx, func1);
r = 0;
if (JS_IsException(ret)) {
JSRuntime *rt = JS_GetRuntime(ctx);
JSThreadState *ts = js_get_thread_state(rt);
ts->exc = JS_GetException(ctx);
if (JS_IsException(ret))
r = -1;
}
JS_FreeValue(ctx, ret);
return r;
}
@ -3543,10 +3538,10 @@ static void *worker_func(void *opaque)
js_std_dump_error(ctx);
JS_FreeValue(ctx, val);
JS_FreeValue(ctx, js_std_loop(ctx));
js_std_loop(ctx);
JS_FreeContext(ctx);
js_std_free_handlers(rt);
JS_FreeContext(ctx);
JS_FreeRuntime(rt);
return NULL;
}
@ -4082,7 +4077,6 @@ void js_std_init_handlers(JSRuntime *rt)
init_list_head(&ts->port_list);
ts->next_timer_id = 1;
ts->exc = JS_UNDEFINED;
js_set_thread_state(rt, ts);
JS_AddRuntimeFinalizer(rt, js_std_finalize, ts);
@ -4140,7 +4134,7 @@ static void js_dump_obj(JSContext *ctx, FILE *f, JSValue val)
}
}
void js_std_dump_error1(JSContext *ctx, JSValue exception_val)
static void js_std_dump_error1(JSContext *ctx, JSValue exception_val)
{
JSValue val;
BOOL is_error;
@ -4178,12 +4172,11 @@ void js_std_promise_rejection_tracker(JSContext *ctx, JSValue promise,
}
/* main loop which calls the user JS callbacks */
JSValue js_std_loop(JSContext *ctx)
int js_std_loop(JSContext *ctx)
{
JSRuntime *rt = JS_GetRuntime(ctx);
JSThreadState *ts = js_get_thread_state(rt);
JSContext *ctx1;
JSValue ret;
int err;
for(;;) {
@ -4191,10 +4184,8 @@ JSValue js_std_loop(JSContext *ctx)
for(;;) {
err = JS_ExecutePendingJob(JS_GetRuntime(ctx), &ctx1);
if (err <= 0) {
if (err < 0) {
ts->exc = JS_GetException(ctx1);
if (err < 0)
goto done;
}
break;
}
}
@ -4203,9 +4194,7 @@ JSValue js_std_loop(JSContext *ctx)
break;
}
done:
ret = ts->exc;
ts->exc = JS_UNDEFINED;
return ret;
return JS_HasException(ctx);
}
/* Wait for a promise and execute pending jobs while waiting for

View file

@ -37,12 +37,11 @@ JSModuleDef *js_init_module_std(JSContext *ctx, const char *module_name);
JSModuleDef *js_init_module_os(JSContext *ctx, const char *module_name);
JSModuleDef *js_init_module_bjson(JSContext *ctx, const char *module_name);
void js_std_add_helpers(JSContext *ctx, int argc, char **argv);
JSValue js_std_loop(JSContext *ctx);
int js_std_loop(JSContext *ctx);
JSValue js_std_await(JSContext *ctx, JSValue obj);
void js_std_init_handlers(JSRuntime *rt);
void js_std_free_handlers(JSRuntime *rt);
void js_std_dump_error(JSContext *ctx);
void js_std_dump_error1(JSContext *ctx, JSValue exception_val);
uint8_t *js_load_file(JSContext *ctx, size_t *pbuf_len, const char *filename);
int js_module_set_import_meta(JSContext *ctx, JSValue func_val,
JS_BOOL use_realpath, JS_BOOL is_main);

View file

@ -1555,12 +1555,9 @@ static int eval_buf(JSContext *ctx, const char *buf, size_t buf_len,
}
if (local) {
JSValue val = js_std_loop(ctx);
if (JS_IsException(val)) {
js_std_dump_error1(ctx, val);
ret = -1;
}
JS_FreeValue(ctx, val);
ret = js_std_loop(ctx);
if (ret)
js_std_dump_error(ctx);
}
JS_FreeCString(ctx, error_name);