From 1adb61f0060f57a855f36ba054730d811ec24ede Mon Sep 17 00:00:00 2001 From: HarlonWang <81813780@qq.com> Date: Wed, 7 Sep 2022 10:15:38 +0800 Subject: [PATCH 1/2] fix: missing formal parameter is not an actual error. --- quickjs.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/quickjs.c b/quickjs.c index 791601391..9f26de79f 100644 --- a/quickjs.c +++ b/quickjs.c @@ -33202,7 +33202,15 @@ static __exception int js_parse_function_decl2(JSParseState *s, } } } else { - js_parse_error(s, "missing formal parameter"); + // Make a judgment here. + // There may be parsing errors in js_parse_skip_parens_token, + // to avoid the exceptions here covering the actual errors. + JSValue error = JS_GetException(ctx); + if (!JS_IsNull(error) && JS_IsError(ctx, error)) { + JS_Throw(ctx, error); + } else { + js_parse_error(s, "missing formal parameter"); + } goto fail; } if (rest && s->token.val != ')') { From e2e83c14532f85d233c51f4bfd1f64f76b396c89 Mon Sep 17 00:00:00 2001 From: HarlonWang <81813780@qq.com> Date: Fri, 30 Sep 2022 10:41:33 +0800 Subject: [PATCH 2/2] optimize: type error not a function and its name, refer to this: https://github.com/bellard/quickjs/pull/117 --- quickjs.c | 88 +++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 85 insertions(+), 3 deletions(-) diff --git a/quickjs.c b/quickjs.c index 9f26de79f..05843042e 100644 --- a/quickjs.c +++ b/quickjs.c @@ -6732,6 +6732,13 @@ static JSValue JS_ThrowTypeErrorNotASymbol(JSContext *ctx) return JS_ThrowTypeError(ctx, "not a symbol"); } +static JSValue JS_ThrowTypeErrorNotAFunction(JSContext *ctx, JSAtom name) +{ + char buf[ATOM_GET_STR_BUF_SIZE]; + return JS_ThrowTypeError(ctx, "'%s' is not a function", + JS_AtomGetStr(ctx, buf, sizeof(buf), name)); +} + static JSValue JS_ThrowReferenceErrorNotDefined(JSContext *ctx, JSAtom name) { char buf[ATOM_GET_STR_BUF_SIZE]; @@ -16639,7 +16646,64 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj, has_call_argc: call_argv = sp - call_argc; sf->cur_pc = pc; - ret_val = JS_CallInternal(ctx, call_argv[-1], JS_UNDEFINED, + JSValue func = call_argv[-1]; + // When the call is not a function, an exception is thrown and its name. + if (!JS_IsFunction(ctx, func)) { + // Currently, only call0 is handled. + if(opcode == OP_call0) { + if(pc[-2] == OP_set_loc0) { + JS_ThrowTypeErrorNotAFunction(ctx, b->vardefs[b->arg_count].var_name); + goto exception; + } else if(pc[-2] == OP_set_loc1) { + JS_ThrowTypeErrorNotAFunction(ctx, b->vardefs[b->arg_count + 1].var_name); + goto exception; + } else if(pc[-2] == OP_set_loc2) { + JS_ThrowTypeErrorNotAFunction(ctx, b->vardefs[b->arg_count + 2].var_name); + goto exception; + } else if(pc[-2] == OP_set_loc3) { + JS_ThrowTypeErrorNotAFunction(ctx, b->vardefs[b->arg_count + 3].var_name); + goto exception; + } else if(pc[-3] == OP_set_loc8) { + JS_ThrowTypeErrorNotAFunction(ctx, b->vardefs[pc[-2]].var_name); + goto exception; + } else if(pc[-4] == OP_get_arg) { + JS_ThrowTypeErrorNotAFunction(ctx, b->vardefs[pc[-3]].var_name); + goto exception; + } else if(pc[-2] == OP_get_arg0) { + JS_ThrowTypeErrorNotAFunction(ctx, b->vardefs[0].var_name); + goto exception; + } else if(pc[-2] == OP_get_arg1) { + JS_ThrowTypeErrorNotAFunction(ctx, b->vardefs[1].var_name); + goto exception; + } else if(pc[-2] == OP_get_arg2) { + JS_ThrowTypeErrorNotAFunction(ctx, b->vardefs[2].var_name); + goto exception; + } else if(pc[-2] == OP_get_arg3) { + JS_ThrowTypeErrorNotAFunction(ctx, b->vardefs[3].var_name); + goto exception; + } else if(pc[-6] == OP_get_var){ + pc -= 5; + JS_ThrowTypeErrorNotAFunction(ctx, get_u32(pc)); + goto exception; + } else if(pc[-4] == OP_get_var_ref) { + JS_ThrowTypeErrorNotAFunction(ctx, b->closure_var[pc[-3]].var_name); + goto exception; + } else if(pc[-2] == OP_get_var_ref0) { + JS_ThrowTypeErrorNotAFunction(ctx, b->closure_var[0].var_name); + goto exception; + } else if(pc[-2] == OP_get_var_ref1) { + JS_ThrowTypeErrorNotAFunction(ctx, b->closure_var[1].var_name); + goto exception; + } else if(pc[-2] == OP_get_var_ref2) { + JS_ThrowTypeErrorNotAFunction(ctx, b->closure_var[2].var_name); + goto exception; + } else if(pc[-2] == OP_get_var_ref3) { + JS_ThrowTypeErrorNotAFunction(ctx, b->closure_var[3].var_name); + goto exception; + } + } + } + ret_val = JS_CallInternal(ctx, func, JS_UNDEFINED, JS_UNDEFINED, call_argc, call_argv, 0); if (unlikely(JS_IsException(ret_val))) goto exception; @@ -16675,7 +16739,19 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj, pc += 2; call_argv = sp - call_argc; sf->cur_pc = pc; - ret_val = JS_CallInternal(ctx, call_argv[-1], call_argv[-2], + JSValue func = call_argv[-1]; + // When the call is not a function, an exception is thrown and its name. + if(!JS_IsFunction(ctx, func)) { + // Currently, only call_method is handled. + if(opcode == OP_call_method) { + if(pc[-5] == OP_push_const8 && pc[-10] == OP_get_field2) { + pc -= 9; + JS_ThrowTypeErrorNotAFunction(ctx, get_u32(pc)); + goto exception; + } + } + } + ret_val = JS_CallInternal(ctx, func, call_argv[-2], JS_UNDEFINED, call_argc, call_argv, 0); if (unlikely(JS_IsException(ret_val))) goto exception; @@ -35959,7 +36035,13 @@ static int check_function(JSContext *ctx, JSValueConst obj) { if (likely(JS_IsFunction(ctx, obj))) return 0; - JS_ThrowTypeError(ctx, "not a function"); + JSAtom atom = JS_ValueToAtom(ctx, obj); + if (atom == JS_ATOM_NULL) { + JS_ThrowTypeError(ctx, "not a function"); + } else { + JS_ThrowTypeErrorNotAFunction(ctx, atom); + } + JS_FreeAtom(ctx, atom); return -1; }