From: Dmitry Volyntsev Date: Wed, 4 Mar 2026 07:22:54 +0000 (-0800) Subject: Fixed call argument evaluation. X-Git-Tag: 0.9.7~16 X-Git-Url: http://www.kaiwu.me/postgresql/commit/?a=commitdiff_plain;h=fd5e523fc01036638c6ec0aa75519e2f42a0bfab;p=njs.git Fixed call argument evaluation. Previously, call lowering created FUNCTION_FRAME and METHOD_FRAME before argument evaluation. This made call ordering observably wrong: for non-callable callees, the error was thrown before arguments with side effects were evaluated, violating the ECMAScript specification. It also prevented await expressions in call arguments, which were rejected at parse time because suspending inside a half-created frame was not supported. The fix evaluates arguments first, then emits the frame, PUT_ARG, and FUNCTION_CALL. Callee and receiver values are captured into temporaries before argument evaluation to guard against argument side effects. Method properties are resolved via PROPERTY_GET before arguments. METHOD_FRAME is redefined from a composite opcode (property lookup + callability check + frame creation) to a pure frame-creation opcode that takes an already-resolved function and explicit "this" value. The parser always wraps call expressions in a NJS_TOKEN_FUNCTION_CALL node, removing the NJS_TOKEN_NAME special case. --- diff --git a/src/njs_disassembler.c b/src/njs_disassembler.c index b1e7aa50..e7de5ecd 100644 --- a/src/njs_disassembler.c +++ b/src/njs_disassembler.c @@ -53,6 +53,8 @@ static njs_code_name_t code_names[] = { { NJS_VMCODE_FUNCTION_CALL, sizeof(njs_vmcode_function_call_t), njs_str("FUNCTION CALL ") }, + { NJS_VMCODE_METHOD_FRAME, sizeof(njs_vmcode_method_frame_t), + njs_str("METHOD FRAME ") }, { NJS_VMCODE_RETURN, sizeof(njs_vmcode_return_t), njs_str("RETURN ") }, { NJS_VMCODE_STOP, sizeof(njs_vmcode_stop_t), @@ -354,8 +356,8 @@ njs_disassemble(u_char *start, u_char *end, njs_int_t count, njs_arr_t *lines) method = (njs_vmcode_method_frame_t *) p; njs_printf("%5uD | %05uz METHOD FRAME %04Xz %04Xz %uz%s\n", - line, p - start, (size_t) method->object, - (size_t) method->method, method->nargs, + line, p - start, (size_t) method->function, + (size_t) method->this_object, method->nargs, method->ctor ? " CTOR" : ""); p += sizeof(njs_vmcode_method_frame_t); diff --git a/src/njs_generator.c b/src/njs_generator.c index 8041abe6..89d08a11 100644 --- a/src/njs_generator.c +++ b/src/njs_generator.c @@ -454,18 +454,29 @@ static njs_int_t njs_generate_function_call(njs_vm_t *vm, njs_generator_t *generator, njs_parser_node_t *node); static njs_int_t njs_generate_function_call_arguments(njs_vm_t *vm, njs_generator_t *generator, njs_parser_node_t *node); +static njs_int_t njs_generate_function_call_frame(njs_vm_t *vm, + njs_generator_t *generator, njs_parser_node_t *node); static njs_int_t njs_generate_function_call_end(njs_vm_t *vm, njs_generator_t *generator, njs_parser_node_t *node); static njs_int_t njs_generate_method_call(njs_vm_t *vm, njs_generator_t *generator, njs_parser_node_t *node); static njs_int_t njs_generate_method_call_arguments(njs_vm_t *vm, njs_generator_t *generator, njs_parser_node_t *node); +static njs_int_t njs_generate_method_call_prepare(njs_vm_t *vm, + njs_generator_t *generator, njs_parser_node_t *node); +static njs_int_t njs_generate_method_call_frame(njs_vm_t *vm, + njs_generator_t *generator, njs_parser_node_t *node); +static njs_int_t njs_generate_call_argument_expressions(njs_vm_t *vm, + njs_generator_t *generator, njs_parser_node_t *node); +static njs_int_t njs_generate_call_argument_expressions_after(njs_vm_t *vm, + njs_generator_t *generator, njs_parser_node_t *node); +static njs_uint_t njs_generate_call_nargs(njs_parser_node_t *node); +static njs_int_t njs_generate_capture_stable_value(njs_vm_t *vm, + njs_generator_t *generator, njs_parser_node_t *node); static njs_int_t njs_generate_method_call_end(njs_vm_t *vm, njs_generator_t *generator, njs_parser_node_t *node); static njs_int_t njs_generate_call(njs_vm_t *vm, njs_generator_t *generator, njs_parser_node_t *node); -static njs_int_t njs_generate_move_arguments(njs_vm_t *vm, - njs_generator_t *generator, njs_parser_node_t *node); static njs_int_t njs_generate_try_statement(njs_vm_t *vm, njs_generator_t *generator, njs_parser_node_t *node); static njs_int_t njs_generate_try_left(njs_vm_t *vm, njs_generator_t *generator, @@ -5128,85 +5139,100 @@ static njs_int_t njs_generate_function_call(njs_vm_t *vm, njs_generator_t *generator, njs_parser_node_t *node) { - njs_int_t ret; - njs_variable_t *var; - njs_parser_node_t *this_object; + njs_parser_node_t *callee, *this_object; - var = NULL; + callee = node->left; this_object = njs_generate_function_call_this(node); - if (node->left != NULL) { - if (njs_generate_is_property_call_source(node->left)) { - njs_internal_error(vm, "unexpected function call source"); - return NJS_ERROR; - } + njs_assert(callee != NULL); - if (this_object != NULL - && node->left->token_type != NJS_TOKEN_OPTIONAL_CHAIN) - { - njs_internal_error(vm, "unexpected function call this"); - return NJS_ERROR; - } + if (njs_generate_is_property_call_source(callee)) { + njs_internal_error(vm, "unexpected function call source"); + return NJS_ERROR; + } - /* Generate function code in function expression. */ + if (this_object != NULL + && callee->token_type != NJS_TOKEN_OPTIONAL_CHAIN) + { + njs_internal_error(vm, "unexpected function call this"); + return NJS_ERROR; + } - njs_generator_next(generator, njs_generate, node->left); + njs_generator_next(generator, njs_generate, callee); - return njs_generator_after(vm, generator, - njs_queue_first(&generator->stack), node, - njs_generate_function_call_arguments, - NULL, 0); + return njs_generator_after(vm, generator, + njs_queue_first(&generator->stack), node, + njs_generate_function_call_arguments, + NULL, 0); +} + + +static njs_int_t +njs_generate_function_call_arguments(njs_vm_t *vm, njs_generator_t *generator, + njs_parser_node_t *node) +{ + njs_int_t ret; + + ret = njs_generate_capture_stable_value(vm, generator, node->left); + if (njs_slow_path(ret != NJS_OK)) { + return ret; } - ret = njs_generate_variable(vm, generator, node, NJS_REFERENCE, &var); + if (node->right == NULL) { + return njs_generate_function_call_frame(vm, generator, node); + } + + ret = njs_generator_after(vm, generator, + njs_queue_first(&generator->stack), node, + njs_generate_function_call_frame, NULL, 0); if (njs_slow_path(ret != NJS_OK)) { return ret; } - return njs_generate_function_call_arguments(vm, generator, node); + return njs_generate_call_argument_expressions(vm, generator, node->right); } static njs_int_t -njs_generate_function_call_arguments(njs_vm_t *vm, njs_generator_t *generator, +njs_generate_function_call_frame(njs_vm_t *vm, njs_generator_t *generator, njs_parser_node_t *node) { - njs_int_t ret; - njs_jump_off_t func_offset; - njs_parser_node_t *name; + njs_uint_t nargs; + njs_parser_node_t *callee, *this_object; + njs_parser_node_t *arg; + njs_vmcode_1addr_t *put_arg; + njs_vmcode_method_frame_t *method_frame; njs_vmcode_function_frame_t *func; - name = node; + callee = node->left; + njs_assert(callee != NULL); - if (node->left != NULL) { - name = node->left; - } - - njs_generate_code(generator, njs_vmcode_function_frame_t, func, - NJS_VMCODE_FUNCTION_FRAME, node); - func_offset = njs_code_offset(generator, func); - func->ctor = node->ctor; - func->name = name->index; - func->nargs = 0; + this_object = njs_generate_function_call_this(node); + nargs = njs_generate_call_nargs(node->right); - njs_generator_next(generator, njs_generate, - (node->right != NULL ? node->right->left : NULL)); + if (this_object != NULL) { + njs_generate_code(generator, njs_vmcode_method_frame_t, method_frame, + NJS_VMCODE_METHOD_FRAME, node); + method_frame->ctor = node->ctor; + method_frame->function = callee->index; + method_frame->this_object = this_object->index; + method_frame->nargs = nargs; - ret = njs_generator_after(vm, generator, - njs_queue_first(&generator->stack), node, - njs_generate_function_call_end, NULL, 0); - if (njs_slow_path(ret != NJS_OK)) { - return ret; + } else { + njs_generate_code(generator, njs_vmcode_function_frame_t, func, + NJS_VMCODE_FUNCTION_FRAME, node); + func->ctor = node->ctor; + func->name = callee->index; + func->nargs = nargs; } - if (node->right == NULL) { - return NJS_OK; + for (arg = node->right; arg != NULL; arg = arg->right) { + njs_generate_code(generator, njs_vmcode_1addr_t, put_arg, + NJS_VMCODE_PUT_ARG, arg); + put_arg->index = arg->left->index; } - return njs_generator_after(vm, generator, - njs_queue_first(&generator->stack), node->right, - njs_generate_move_arguments, - &func_offset, sizeof(njs_jump_off_t)); + return njs_generate_function_call_end(vm, generator, node); } @@ -5214,8 +5240,8 @@ static njs_int_t njs_generate_function_call_end(njs_vm_t *vm, njs_generator_t *generator, njs_parser_node_t *node) { - njs_int_t ret; - njs_parser_node_t *this_object; + njs_int_t ret; + njs_parser_node_t *this_object; ret = njs_generate_call(vm, generator, node); if (njs_fast_path(ret != NJS_OK)) { @@ -5230,7 +5256,7 @@ njs_generate_function_call_end(njs_vm_t *vm, njs_generator_t *generator, } } - return njs_generator_stack_pop(vm, generator, generator->context); + return njs_generator_stack_pop(vm, generator, NULL); } @@ -5275,44 +5301,105 @@ static njs_int_t njs_generate_method_call_arguments(njs_vm_t *vm, njs_generator_t *generator, njs_parser_node_t *node) { - njs_int_t ret; - njs_jump_off_t method_offset; - njs_parser_node_t *prop; - njs_vmcode_method_frame_t *method; + njs_int_t ret; + njs_parser_node_t *prop, *property; prop = node->left; + property = prop->right; if (!njs_generate_is_property_call_source(prop)) { njs_internal_error(vm, "unexpected method call source"); return NJS_ERROR; } - njs_generate_code(generator, njs_vmcode_method_frame_t, method, - NJS_VMCODE_METHOD_FRAME, prop); - method_offset = njs_code_offset(generator, method); - method->ctor = node->ctor; - method->object = prop->left->index; - method->method = prop->right->index; - method->nargs = 0; + if (node->right == NULL) { + prop->index = njs_generate_node_temp_index_get(vm, generator, prop); + if (njs_slow_path(prop->index == NJS_INDEX_ERROR)) { + return NJS_ERROR; + } + + ret = njs_generate_property_get(vm, generator, property, prop->index, + prop->left->index, property->index); + if (njs_slow_path(ret != NJS_OK)) { + return ret; + } + + return njs_generate_method_call_frame(vm, generator, node); + } - njs_generator_next(generator, njs_generate, - (node->right != NULL ? node->right->left : node->right)); + ret = njs_generate_method_call_prepare(vm, generator, node); + if (njs_slow_path(ret != NJS_OK)) { + return ret; + } ret = njs_generator_after(vm, generator, njs_queue_first(&generator->stack), node, - njs_generate_method_call_end, NULL, 0); + njs_generate_method_call_frame, NULL, 0); if (njs_slow_path(ret != NJS_OK)) { return ret; } - if (node->right == NULL) { - return NJS_OK; + return njs_generate_call_argument_expressions(vm, generator, node->right); +} + + +static njs_int_t +njs_generate_method_call_prepare(njs_vm_t *vm, njs_generator_t *generator, + njs_parser_node_t *node) +{ + njs_int_t ret; + njs_parser_node_t *prop, *property; + + prop = node->left; + property = prop->right; + + ret = njs_generate_capture_stable_value(vm, generator, prop->left); + if (njs_slow_path(ret != NJS_OK)) { + return ret; } - return njs_generator_after(vm, generator, - njs_queue_first(&generator->stack), node->right, - njs_generate_move_arguments, - &method_offset, sizeof(njs_jump_off_t)); + prop->index = njs_generate_node_temp_index_get(vm, generator, prop); + if (njs_slow_path(prop->index == NJS_INDEX_ERROR)) { + return NJS_ERROR; + } + + return njs_generate_property_get(vm, generator, property, prop->index, + prop->left->index, property->index); +} + + +static njs_int_t +njs_generate_method_call_frame(njs_vm_t *vm, njs_generator_t *generator, + njs_parser_node_t *node) +{ + njs_uint_t nargs; + njs_parser_node_t *arg; + njs_parser_node_t *prop; + njs_vmcode_1addr_t *put_arg; + njs_vmcode_method_frame_t *method_frame; + + prop = node->left; + nargs = njs_generate_call_nargs(node->right); + + if (!njs_generate_is_property_call_source(prop)) { + njs_internal_error(vm, "unexpected method call source"); + return NJS_ERROR; + } + + njs_generate_code(generator, njs_vmcode_method_frame_t, method_frame, + NJS_VMCODE_METHOD_FRAME, node); + method_frame->ctor = node->ctor; + method_frame->function = prop->index; + method_frame->this_object = prop->left->index; + method_frame->nargs = nargs; + + for (arg = node->right; arg != NULL; arg = arg->right) { + njs_generate_code(generator, njs_vmcode_1addr_t, put_arg, + NJS_VMCODE_PUT_ARG, arg); + put_arg->index = arg->left->index; + } + + return njs_generate_method_call_end(vm, generator, node); } @@ -5327,7 +5414,7 @@ njs_generate_method_call_end(njs_vm_t *vm, njs_generator_t *generator, return ret; } - return njs_generator_stack_pop(vm, generator, generator->context); + return njs_generator_stack_pop(vm, generator, NULL); } @@ -5354,36 +5441,76 @@ njs_generate_call(njs_vm_t *vm, njs_generator_t *generator, static njs_int_t -njs_generate_move_arguments(njs_vm_t *vm, njs_generator_t *generator, +njs_generate_call_argument_expressions(njs_vm_t *vm, njs_generator_t *generator, njs_parser_node_t *node) { - njs_jump_off_t func_offset; - njs_vmcode_1addr_t *put_arg; - njs_vmcode_function_frame_t *func; - if (node == NULL) { - return njs_generator_stack_pop(vm, generator, generator->context); + return njs_generator_stack_pop(vm, generator, NULL); } - njs_generate_code(generator, njs_vmcode_1addr_t, put_arg, - NJS_VMCODE_PUT_ARG, node); - put_arg->index = node->left->index; + njs_generator_next(generator, njs_generate, node->left); - func_offset = *((njs_jump_off_t *) generator->context); - func = njs_code_ptr(generator, njs_vmcode_function_frame_t, func_offset); + return njs_generator_after(vm, generator, + njs_queue_first(&generator->stack), node, + njs_generate_call_argument_expressions_after, + NULL, 0); +} - func->nargs++; +static njs_int_t +njs_generate_call_argument_expressions_after(njs_vm_t *vm, + njs_generator_t *generator, njs_parser_node_t *node) +{ if (node->right == NULL) { - return njs_generator_stack_pop(vm, generator, generator->context); + return njs_generator_stack_pop(vm, generator, NULL); } njs_generator_next(generator, njs_generate, node->right->left); return njs_generator_after(vm, generator, njs_queue_first(&generator->stack), node->right, - njs_generate_move_arguments, - generator->context, 0); + njs_generate_call_argument_expressions_after, + NULL, 0); +} + + +static njs_uint_t +njs_generate_call_nargs(njs_parser_node_t *node) +{ + njs_uint_t nargs; + + nargs = 0; + + while (node != NULL) { + nargs++; + node = node->right; + } + + return nargs; +} + + +static njs_int_t +njs_generate_capture_stable_value(njs_vm_t *vm, njs_generator_t *generator, + njs_parser_node_t *node) +{ + njs_index_t src; + njs_vmcode_move_t *move; + + if (node->temporary) { + return NJS_OK; + } + + src = node->index; + + node->index = njs_generate_node_temp_index_get(vm, generator, node); + if (njs_slow_path(node->index == NJS_INDEX_ERROR)) { + return NJS_ERROR; + } + + njs_generate_code_move(generator, move, node->index, src, node); + + return NJS_OK; } diff --git a/src/njs_parser.c b/src/njs_parser.c index 9177ac26..0ca33486 100644 --- a/src/njs_parser.c +++ b/src/njs_parser.c @@ -2761,30 +2761,20 @@ njs_parser_create_call(njs_parser_t *parser, njs_parser_node_t *node, this_object = njs_parser_optional_chain_call_this(node); - switch (node->token_type) { - case NJS_TOKEN_NAME: - func = node; - func->token_type = NJS_TOKEN_FUNCTION_CALL; - - break; - - default: - /* - * NJS_TOKEN_METHOD_CALL, - * NJS_TOKEN_FUNCTION_CALL, - * NJS_TOKEN_FUNCTION_EXPRESSION, - * NJS_TOKEN_OPEN_PARENTHESIS, - * NJS_TOKEN_EVAL. - */ - func = njs_parser_node_new(parser, NJS_TOKEN_FUNCTION_CALL); - if (func == NULL) { - return NULL; - } - - func->left = node; - break; + /* + * NJS_TOKEN_NAME, + * NJS_TOKEN_METHOD_CALL, + * NJS_TOKEN_FUNCTION_CALL, + * NJS_TOKEN_FUNCTION_EXPRESSION, + * NJS_TOKEN_OPEN_PARENTHESIS, + * NJS_TOKEN_EVAL. + */ + func = njs_parser_node_new(parser, NJS_TOKEN_FUNCTION_CALL); + if (func == NULL) { + return NULL; } + func->left = node; func->ctor = ctor; njs_parser_set_call_this(func, this_object); diff --git a/src/njs_vmcode.c b/src/njs_vmcode.c index 32a1890d..c4bbeff6 100644 --- a/src/njs_vmcode.c +++ b/src/njs_vmcode.c @@ -87,7 +87,6 @@ njs_vmcode_interpreter(njs_vm_t *vm, u_char *pc, njs_value_t *rval, double num, exponent; int32_t i32; uint32_t u32; - njs_str_t string; njs_bool_t valid, lambda_call; njs_value_t *retval, *value1, *value2; njs_value_t *src, *s1, *s2, dst; @@ -1509,39 +1508,8 @@ NEXT_LBL; method_frame = (njs_vmcode_method_frame_t *) pc; - if (njs_slow_path(!njs_is_key(value2))) { - if (njs_slow_path(njs_is_null_or_undefined(value1))) { - (void) njs_throw_cannot_property(vm, value1, value2, "get"); - goto error; - } - - ret = njs_value_to_key(vm, &primitive1, value2); - if (njs_slow_path(ret != NJS_OK)) { - goto error; - } - - value2 = &primitive1; - } - - ret = njs_value_property_val(vm, value1, value2, &dst); - if (njs_slow_path(ret == NJS_ERROR)) { - goto error; - } - - if (njs_slow_path(!njs_is_function(&dst))) { - ret = njs_value_to_key(vm, &dst, value2); - if (njs_slow_path(ret != NJS_OK)) { - goto error; - } - - njs_key_string_get(vm, &dst, &string); - njs_type_error(vm, - "(intermediate value)[\"%V\"] is not a function", - &string); - goto error; - } - - ret = njs_function_frame_create(vm, &dst, value1, method_frame->nargs, + ret = njs_function_frame_create(vm, value1, value2, + method_frame->nargs, method_frame->ctor); if (njs_slow_path(ret != NJS_OK)) { diff --git a/src/njs_vmcode.h b/src/njs_vmcode.h index 2cdfd23b..077eb745 100644 --- a/src/njs_vmcode.h +++ b/src/njs_vmcode.h @@ -296,8 +296,8 @@ typedef struct { typedef struct { njs_vmcode_t code; njs_index_t nargs; - njs_index_t object; - njs_index_t method; + njs_index_t function; + njs_index_t this_object; uint8_t ctor; /* 1 bit */ } njs_vmcode_method_frame_t; diff --git a/src/test/njs_unit_test.c b/src/test/njs_unit_test.c index 38120516..e718c147 100644 --- a/src/test/njs_unit_test.c +++ b/src/test/njs_unit_test.c @@ -168,6 +168,77 @@ static njs_unit_test_t njs_test[] = { njs_str("function f(a) {return function (x) {return a(x)}} f(1)(0)"), njs_str("TypeError: number is not a function") }, + { njs_str("var fooCalled = false;" + "function foo(){ fooCalled = true; }" + "var o = {}, r;" + "try { o.bar(foo()) } catch (e) { r = e.name + ':' + fooCalled }" + "r"), + njs_str("TypeError:true") }, + + { njs_str("var o = {}, r;" + "Object.defineProperty(o, 'bar', {" + " get: function() { this.barGetter = true; return 42; }" + "});" + "try { o.foo(o.bar) } catch (e) { r = e.name + ':' + o.barGetter }" + "r"), + njs_str("TypeError:true") }, + + { njs_str("var o = {}, r;" + "Object.defineProperty(o, 'bar', {" + " get: function() { this.barGetter = true; return 42; }" + "});" + "try { o.foo(o['bar']) } catch (e) {" + " r = e.name + ':' + o.barGetter" + "}" + "r"), + njs_str("TypeError:true") }, + + { njs_str("var fooCalled = false;" + "function foo(){ fooCalled = true; }" + "var o = {}, r;" + "try { o.bar.gar(foo()) } catch (e) {" + " r = e.name + ':' + fooCalled" + "}" + "r"), + njs_str("TypeError:false") }, + + { njs_str("var x = function() { this.foo = 42; };" + "var result = new x(x = 1);" + "[x, result.foo]"), + njs_str("1,42") }, + + { njs_str("function fn() {" + " var x = function() { this.foo = 42; };" + " var result = new x(x = 1);" + " return [x, result.foo];" + "}" + "fn()"), + njs_str("1,42") }, + + { njs_str("var C = {}; var ran = false, r;" + "try { new C((ran = true, 1)) } catch (e) {" + " r = e.name + ':' + ran" + "}" + "r"), + njs_str("TypeError:true") }, + + { njs_str("var o = {" + " get f() { this.hit = (this.hit || 0) + 1; return 1; }" + "};" + "var ran = false, r;" + "try { o.f((ran = true, 1)) } catch (e) {" + " r = ran + ':' + o.hit" + "}" + "r"), + njs_str("true:1") }, + + { njs_str("var o = {" + " get f() { return function(v) { return this.x + v } }," + " x: 7" + "};" + "o.f(5)"), + njs_str("12") }, + { njs_str("var x = 0;" "" "function f1() {" @@ -1866,6 +1937,30 @@ static njs_unit_test_t njs_test[] = { njs_str("var o = {m: function() {return 42}}; (o?.m)()"), njs_str("42") }, + { njs_str("var o = {x: 5, m: function() {return this.x}}; (o?.m)()"), + njs_str("5") }, + + { njs_str("var o = {x: 3, m: function() {return {c: this.x}}};" + "o.m?.().c"), + njs_str("3") }, + + { njs_str("var o = {x: 4, m: function() {return {c: this.x}}};" + "(o.m)?.().c"), + njs_str("4") }, + + { njs_str("var o = {x: 6, m: function() {return {c: this.x}}};" + "o?.m?.().c"), + njs_str("6") }, + + { njs_str("var o = {x: 8, m: function() {return {c: this.x}}};" + "(o?.m)?.().c"), + njs_str("8") }, + + { njs_str("var k = 'm';" + "var o = {x: 9, m: function() {return this.x}};" + "(o?.[k])()"), + njs_str("9") }, + { njs_str("var o = null; (o?.m)()"), njs_str("TypeError: undefined is not a function") }, @@ -2630,10 +2725,10 @@ static njs_unit_test_t njs_test[] = njs_str("false") }, { njs_str("new 0[isNaN]"), - njs_str("TypeError: (intermediate value)[\"[object Function]\"] is not a function") }, + njs_str("TypeError: undefined is not a function") }, { njs_str("new 0[undefined]"), - njs_str("TypeError: (intermediate value)[\"undefined\"] is not a function") }, + njs_str("TypeError: undefined is not a function") }, /**/ @@ -4016,7 +4111,7 @@ static njs_unit_test_t njs_test[] = { njs_str("function f() { Object.prototype.toString = 1; };" "Object.prototype.toString = f;" "(function () { try { 's'[{}](); } catch (e) { throw e; } })()"), - njs_str("TypeError: (intermediate value)[\"undefined\"] is not a function") }, + njs_str("TypeError: undefined is not a function") }, { njs_str("var i; for (i = 0; i < 10; i++) { i += 1 } i"), njs_str("10") }, @@ -10825,7 +10920,7 @@ static njs_unit_test_t njs_test[] = njs_str("TypeError: number is not a function") }, { njs_str("var o = {a:1}; o.a()"), - njs_str("TypeError: (intermediate value)[\"a\"] is not a function") }, + njs_str("TypeError: number is not a function") }, { njs_str("(function(){})()"), njs_str("undefined") }, @@ -12864,10 +12959,10 @@ static njs_unit_test_t njs_test[] = njs_str("SyntaxError: Unexpected token \"null\"") }, { njs_str("'a'.f()"), - njs_str("TypeError: (intermediate value)[\"f\"] is not a function") }, + njs_str("TypeError: undefined is not a function") }, { njs_str("1..f()"), - njs_str("TypeError: (intermediate value)[\"f\"] is not a function") }, + njs_str("TypeError: undefined is not a function") }, { njs_str("try {}"), njs_str("SyntaxError: Missing catch or finally after try") }, @@ -21689,7 +21784,7 @@ static njs_unit_test_t njs_shared_test[] = " at main (:1)\n") }, { njs_str("preload.a.push(2)"), - njs_str("TypeError: (intermediate value)[\"push\"] is not a function\n" + njs_str("TypeError: undefined is not a function\n" " at main (:1)\n") }, { njs_str("Array.prototype.push.call(preload.a, 'waka')"), @@ -22058,7 +22153,6 @@ static njs_unit_test_t njs_backtraces_test[] = { njs_str("[].concat({}.a.a)"), njs_str("TypeError: cannot get property \"a\" of undefined\n" - " at concat (native)\n" " at main (:1)\n") }, { njs_str("''.repeat(-1)"), @@ -22068,7 +22162,6 @@ static njs_unit_test_t njs_backtraces_test[] = { njs_str("Math.log({}.a.a)"), njs_str("TypeError: cannot get property \"a\" of undefined\n" - " at log (native)\n" " at main (:1)\n") }, { njs_str("var bound = Math.max.bind(null, {toString(){return {}}}); bound(1)"), @@ -22084,7 +22177,7 @@ static njs_unit_test_t njs_backtraces_test[] = " at main (:1)\n") }, { njs_str("Object.prototype()"), - njs_str("TypeError: (intermediate value)[\"prototype\"] is not a function\n" + njs_str("TypeError: object is not a function\n" " at main (:1)\n") }, { njs_str("eval()"), @@ -22094,7 +22187,6 @@ static njs_unit_test_t njs_backtraces_test[] = { njs_str("$shared.method({}.a.a)"), njs_str("TypeError: cannot get property \"a\" of undefined\n" - " at method (native)\n" " at main (:1)\n") }, { njs_str("new Function(\n\n@)"), @@ -22227,7 +22319,7 @@ static njs_unit_test_t njs_backtraces_test[] = { njs_str("function log(v) {}\nlog({}\n.a\n.a)"), njs_str("TypeError: cannot get property \"a\" of undefined\n" - " at main (:4)\n") }, + " at main (:2)\n") }, { njs_str("\nfor (var i = 0;\n i < a;\n i++) { }\n"), njs_str("ReferenceError: \"a\" is not defined\n" @@ -22239,7 +22331,6 @@ static njs_unit_test_t njs_backtraces_test[] = { njs_str("Math\n.min(1,\na)"), njs_str("ReferenceError: \"a\" is not defined\n" - " at min (native)\n" " at main (:3)\n") }, }; diff --git a/test/shell_test_njs.exp b/test/shell_test_njs.exp index d0f2d775..56d3f158 100644 --- a/test/shell_test_njs.exp +++ b/test/shell_test_njs.exp @@ -56,7 +56,7 @@ njs_test { njs_test { {"console.ll()\r\n" - "console.ll()\r\nThrown:\r\nTypeError: (intermediate value)\\\[\"ll\"] is not a function"} + "console.ll()\r\nThrown:\r\nTypeError: undefined is not a function"} } njs_test { @@ -67,7 +67,7 @@ njs_test { # Backtraces for external objects njs_test { {"console.info(console.a.a)\r\n" - "console.info(console.a.a)\r\nThrown:\r\nTypeError:*at info (native)"} + "console.info(console.a.a)\r\nThrown:\r\nTypeError:*at main (shell:1)"} } # dumper