diff --git a/jerry-core/parser/js/js-parser.c b/jerry-core/parser/js/js-parser.c index 74abe4cb9..ee1d0d425 100644 --- a/jerry-core/parser/js/js-parser.c +++ b/jerry-core/parser/js/js-parser.c @@ -2578,6 +2578,13 @@ parser_parse_class_fields (parser_context_t *context_p) /**< context */ scanner_seek (context_p); } +#if JERRY_LINE_INFO + if (context_p->token.line != context_p->last_line_info_line) + { + parser_emit_line_info (context_p, context_p->token.line, true); + } +#endif /* JERRY_LINE_INFO */ + context_p->source_end_p = range.source_end_p; lexer_next_token (context_p); parser_parse_expression (context_p, PARSE_EXPR_NO_COMMA); diff --git a/jerry-core/vm/opcodes.c b/jerry-core/vm/opcodes.c index 6bb5ee7dc..48cbcc087 100644 --- a/jerry-core/vm/opcodes.c +++ b/jerry-core/vm/opcodes.c @@ -948,6 +948,7 @@ opfunc_init_class_fields (ecma_value_t class_object, /**< the function itself */ ecma_extended_object_t *ext_function_p; ext_function_p = (ecma_extended_object_t *) ecma_get_object_from_value (property_value_p->value); shared_class_fields.header.bytecode_header_p = ecma_op_function_get_compiled_code (ext_function_p); + shared_class_fields.header.function_object_p = &ext_function_p->object; ecma_object_t *scope_p = ECMA_GET_NON_NULL_POINTER_FROM_POINTER_TAG (ecma_object_t, ext_function_p->u.function.scope_cp); @@ -971,22 +972,22 @@ opfunc_init_static_class_fields (ecma_value_t function_object, /**< the function JERRY_ASSERT (ecma_op_is_callable (function_object)); JERRY_ASSERT (ecma_is_value_object (this_val)); - vm_frame_ctx_shared_class_fields_t shared_class_fields; - shared_class_fields.header.status_flags = VM_FRAME_CTX_SHARED_HAS_CLASS_FIELDS; - shared_class_fields.computed_class_fields_p = NULL; - ecma_string_t *name_p = ecma_get_internal_string (LIT_INTERNAL_MAGIC_STRING_CLASS_FIELD_COMPUTED); ecma_object_t *function_object_p = ecma_get_object_from_value (function_object); ecma_property_t *class_field_property_p = ecma_find_named_property (function_object_p, name_p); + vm_frame_ctx_shared_class_fields_t shared_class_fields; + shared_class_fields.header.function_object_p = function_object_p; + shared_class_fields.header.status_flags = VM_FRAME_CTX_SHARED_HAS_CLASS_FIELDS; + shared_class_fields.computed_class_fields_p = NULL; + if (class_field_property_p != NULL) { ecma_value_t value = ECMA_PROPERTY_VALUE_PTR (class_field_property_p)->value; shared_class_fields.computed_class_fields_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_value_t, value); } - ecma_extended_object_t *ext_function_p; - ext_function_p = (ecma_extended_object_t *) ecma_get_object_from_value (function_object); + ecma_extended_object_t *ext_function_p = (ecma_extended_object_t *) function_object_p; shared_class_fields.header.bytecode_header_p = ecma_op_function_get_compiled_code (ext_function_p); ecma_object_t *scope_p = ECMA_GET_NON_NULL_POINTER_FROM_POINTER_TAG (ecma_object_t, diff --git a/tests/unit-core/test-backtrace.c b/tests/unit-core/test-backtrace.c index 79fca6f16..b1492e586 100644 --- a/tests/unit-core/test-backtrace.c +++ b/tests/unit-core/test-backtrace.c @@ -129,6 +129,38 @@ async_backtrace_callback (jerry_backtrace_frame_t *frame_p, /* frame information return true; } /* async_backtrace_callback */ +static bool +class_backtrace_callback (jerry_backtrace_frame_t *frame_p, /* frame information */ + void *user_p) /* user data */ +{ + TEST_ASSERT ((void *) handler_args_p == user_p); + TEST_ASSERT (jerry_backtrace_get_frame_type (frame_p) == JERRY_BACKTRACE_FRAME_JS); + + const jerry_backtrace_location_t *location_p = jerry_backtrace_get_location (frame_p); + const jerry_value_t *function_p = jerry_backtrace_get_function (frame_p); + + TEST_ASSERT (location_p != NULL); + TEST_ASSERT (function_p != NULL); + + compare_string (location_p->resource_name, "class_capture_test.js"); + + ++frame_index; + + if (frame_index == 1) + { + TEST_ASSERT (jerry_backtrace_is_strict (frame_p)); + TEST_ASSERT (location_p->line == 3); + TEST_ASSERT (location_p->column == 1); + return false; + } + + TEST_ASSERT (frame_index == 2); + TEST_ASSERT (jerry_backtrace_is_strict (frame_p)); + TEST_ASSERT (location_p->line == 2); + TEST_ASSERT (location_p->column == 1); + return false; +} /* class_backtrace_callback */ + static jerry_value_t capture_handler (const jerry_call_info_t *call_info_p, /**< call information */ const jerry_value_t args_p[], /**< argument list */ @@ -138,14 +170,24 @@ capture_handler (const jerry_call_info_t *call_info_p, /**< call information */ JERRY_UNUSED (args_p); JERRY_UNUSED (args_count); - TEST_ASSERT (args_count == 2 || args_count == 3); - TEST_ASSERT (frame_index == 0); + TEST_ASSERT (args_count == 0 || args_count == 2 || args_count == 3); + TEST_ASSERT (args_count == 0 || frame_index == 0); + + jerry_backtrace_callback_t callback = backtrace_callback; + + if (args_count == 0) + { + callback = class_backtrace_callback; + } + else if (args_count == 2) + { + callback = async_backtrace_callback; + } handler_args_p = args_p; + jerry_backtrace_capture (callback, (void *) args_p); - jerry_backtrace_capture (args_count == 3 ? backtrace_callback : async_backtrace_callback, (void *) args_p); - - TEST_ASSERT (frame_index == (int) args_count); + TEST_ASSERT (args_count == 0 || frame_index == (int) args_count); return jerry_create_undefined (); } /* capture_handler */ @@ -343,6 +385,33 @@ test_get_backtrace_api_call (void) jerry_release_value (result); + /* Test class initializer frame capturing. */ + source_p = "class C {}"; + result = jerry_eval ((const jerry_char_t *) source_p, strlen (source_p), JERRY_PARSE_NO_OPTS); + + if (!jerry_value_is_error (result)) + { + jerry_release_value (result); + + frame_index = 0; + source_p = ("class C {\n" + " a = capture();\n" + " static b = capture();\n" + "}\n" + "new C;\n"); + + result = run ("class_capture_test.js", source_p); + + TEST_ASSERT (!jerry_value_is_error (result)); + TEST_ASSERT (frame_index == 2); + } + else + { + TEST_ASSERT (jerry_get_error_type (result) == JERRY_ERROR_SYNTAX); + } + + jerry_release_value (result); + jerry_cleanup (); } /* test_get_backtrace_api_call */