diff --git a/jerry-core/api/jerry-snapshot.c b/jerry-core/api/jerry-snapshot.c index f1858abd0..e166ab585 100644 --- a/jerry-core/api/jerry-snapshot.c +++ b/jerry-core/api/jerry-snapshot.c @@ -1067,7 +1067,7 @@ jerry_exec_snapshot (const uint32_t *snapshot_p, /**< snapshot */ } else { - ret_val = vm_run_global (bytecode_p); + ret_val = vm_run_global (bytecode_p, NULL); if (!(bytecode_p->status_flags & CBC_CODE_FLAGS_STATIC_FUNCTION)) { ecma_bytecode_deref (bytecode_p); diff --git a/jerry-core/api/jerry.c b/jerry-core/api/jerry.c index 821800b77..3a3c39a3e 100644 --- a/jerry-core/api/jerry.c +++ b/jerry-core/api/jerry.c @@ -573,24 +573,19 @@ jerry_run (const jerry_value_t func_val) /**< function to run */ ecma_object_t *object_p = ecma_get_object_from_value (func_val); - if (ecma_get_object_type (object_p) != ECMA_OBJECT_TYPE_CLASS) + if (!ecma_object_class_is (object_p, ECMA_OBJECT_CLASS_SCRIPT)) { return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG (ecma_error_wrong_args_msg_p))); } ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) object_p; - if (ext_object_p->u.cls.type != ECMA_OBJECT_CLASS_SCRIPT) - { - return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG (ecma_error_wrong_args_msg_p))); - } - const ecma_compiled_code_t *bytecode_data_p; bytecode_data_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_compiled_code_t, ext_object_p->u.cls.u3.value); JERRY_ASSERT (CBC_FUNCTION_GET_TYPE (bytecode_data_p->status_flags) == CBC_FUNCTION_SCRIPT); - return jerry_return (vm_run_global (bytecode_data_p)); + return jerry_return (vm_run_global (bytecode_data_p, object_p)); } /* jerry_run */ /** diff --git a/jerry-core/vm/vm.c b/jerry-core/vm/vm.c index 3707a9608..75e5f6d07 100644 --- a/jerry-core/vm/vm.c +++ b/jerry-core/vm/vm.c @@ -271,7 +271,8 @@ static const uint16_t vm_decode_table[] JERRY_ATTR_CONST_DATA = * @return ecma value */ ecma_value_t -vm_run_global (const ecma_compiled_code_t *bytecode_p) /**< pointer to bytecode to run */ +vm_run_global (const ecma_compiled_code_t *bytecode_p, /**< pointer to bytecode to run */ + ecma_object_t *function_object_p) /**< function object if available */ { #if JERRY_BUILTIN_REALMS ecma_object_t *global_obj_p = (ecma_object_t *) ecma_op_function_get_realm (bytecode_p); @@ -290,7 +291,7 @@ vm_run_global (const ecma_compiled_code_t *bytecode_p) /**< pointer to bytecode vm_frame_ctx_shared_t shared; shared.bytecode_header_p = bytecode_p; - shared.function_object_p = NULL; + shared.function_object_p = function_object_p; shared.status_flags = 0; #if JERRY_BUILTIN_REALMS diff --git a/jerry-core/vm/vm.h b/jerry-core/vm/vm.h index 978f1b453..c9fad67a2 100644 --- a/jerry-core/vm/vm.h +++ b/jerry-core/vm/vm.h @@ -479,7 +479,7 @@ typedef enum VM_EXEC_CONSTRUCT, /**< construct a new object */ } vm_call_operation; -ecma_value_t vm_run_global (const ecma_compiled_code_t *bytecode_p); +ecma_value_t vm_run_global (const ecma_compiled_code_t *bytecode_p, ecma_object_t *function_object_p); ecma_value_t vm_run_eval (ecma_compiled_code_t *bytecode_data_p, uint32_t parse_opts); #if JERRY_MODULE_SYSTEM diff --git a/tests/unit-core/test-backtrace.c b/tests/unit-core/test-backtrace.c index 7a04f0590..e50864293 100644 --- a/tests/unit-core/test-backtrace.c +++ b/tests/unit-core/test-backtrace.c @@ -176,8 +176,6 @@ capture_handler (const jerry_call_info_t *call_info_p, /**< call information */ const jerry_length_t args_count) /**< argument count */ { JERRY_UNUSED (call_info_p); - JERRY_UNUSED (args_p); - JERRY_UNUSED (args_count); TEST_ASSERT (args_count == 0 || args_count == 2 || args_count == 4); TEST_ASSERT (args_count == 0 || frame_index == 0); @@ -201,6 +199,38 @@ capture_handler (const jerry_call_info_t *call_info_p, /**< call information */ return jerry_create_undefined (); } /* capture_handler */ +static bool +global_backtrace_callback (jerry_backtrace_frame_t *frame_p, /* frame information */ + void *user_p) /* user data */ +{ + TEST_ASSERT (user_p != NULL && frame_index == 0); + frame_index++; + + const jerry_value_t *function_p = jerry_backtrace_get_function (frame_p); + jerry_value_t *result_p = ((jerry_value_t *) user_p); + + TEST_ASSERT (function_p != NULL); + jerry_release_value (*result_p); + *result_p = jerry_acquire_value (*function_p); + return true; +} /* global_backtrace_callback */ + +static jerry_value_t +global_capture_handler (const jerry_call_info_t *call_info_p, /**< call information */ + const jerry_value_t args_p[], /**< argument list */ + const jerry_length_t args_count) /**< argument count */ +{ + JERRY_UNUSED (call_info_p); + JERRY_UNUSED (args_p); + JERRY_UNUSED (args_count); + + jerry_value_t result = jerry_create_undefined (); + jerry_backtrace_capture (global_backtrace_callback, &result); + + TEST_ASSERT (jerry_value_is_object (result)); + return result; +} /* global_capture_handler */ + static void register_callback (jerry_external_handler_t handler_p, /**< callback function */ char *name_p) /**< name of the function */ @@ -421,6 +451,24 @@ test_get_backtrace_api_call (void) jerry_release_value (result); + register_callback (global_capture_handler, "global_capture"); + + frame_index = 0; + + source_p = "global_capture()"; + + jerry_value_t code = jerry_parse ((const jerry_char_t *) source_p, strlen (source_p), NULL); + TEST_ASSERT (!jerry_value_is_error (code)); + + result = jerry_run (code); + + jerry_value_t compare_value = jerry_binary_operation (JERRY_BIN_OP_STRICT_EQUAL, result, code); + TEST_ASSERT (jerry_value_is_true (compare_value)); + + jerry_release_value (compare_value); + jerry_release_value (result); + jerry_release_value (code); + jerry_cleanup (); } /* test_get_backtrace_api_call */