diff --git a/jerry-core/jerry.c b/jerry-core/jerry.c index 80fdf0ee5..d140166a9 100644 --- a/jerry-core/jerry.c +++ b/jerry-core/jerry.c @@ -378,7 +378,11 @@ jerry_api_convert_ecma_value_to_api_value (jerry_api_value_t *out_value_p, /**< JERRY_ASSERT (out_value_p != NULL); - if (ecma_is_value_undefined (value)) + if (ecma_is_value_empty (value)) + { + out_value_p->type = JERRY_API_DATA_TYPE_VOID; + } + else if (ecma_is_value_undefined (value)) { out_value_p->type = JERRY_API_DATA_TYPE_UNDEFINED; } @@ -1715,6 +1719,9 @@ jerry_is_abort_on_fail (void) /** * Parse script for specified context * + * Note: + * returned error object should be freed with jerry_api_release_object + * * @return true - if script was parsed successfully, * false - otherwise (SyntaxError was raised). */ @@ -1760,14 +1767,25 @@ jerry_parse (const jerry_api_char_t *source_p, /**< script source */ /** * Run Jerry in specified run context * + * Note: + * returned error value should be freed with jerry_api_release_value + * just when the value becomes unnecessary. + * * @return completion status */ jerry_completion_code_t -jerry_run (jerry_api_object_t **error_obj_p) +jerry_run (jerry_api_value_t *error_value_p) /**< [out] error value */ { jerry_assert_api_available (); - return vm_run_global (error_obj_p); + ecma_value_t error_value; + jerry_completion_code_t ret_code = vm_run_global (&error_value); + + error_value &= ~(1u << ECMA_VALUE_ERROR_POS); + jerry_api_convert_ecma_value_to_api_value (error_value_p, error_value); + ecma_free_value (error_value); + + return ret_code; } /* jerry_run */ /** @@ -1790,12 +1808,13 @@ jerry_run_simple (const jerry_api_char_t *script_source, /**< script source */ /* unhandled SyntaxError */ ret_code = JERRY_COMPLETION_CODE_UNHANDLED_EXCEPTION; } - else + else if ((flags & JERRY_FLAG_PARSE_ONLY) == 0) { - if ((flags & JERRY_FLAG_PARSE_ONLY) == 0) - { - ret_code = jerry_run (&error_obj_p); - } + jerry_api_value_t error_value; + + ret_code = jerry_run (&error_value); + + jerry_api_release_value (&error_value); } jerry_cleanup (); @@ -2375,20 +2394,20 @@ jerry_exec_snapshot (const void *snapshot_p, /**< snapshot */ { vm_init (bytecode_p); - ecma_object_t *error_obj_p = NULL; + ecma_value_t error_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY); - ret_code = vm_run_global (&error_obj_p); + ret_code = vm_run_global (&error_value); if (ret_code == JERRY_COMPLETION_CODE_UNHANDLED_EXCEPTION) { - JERRY_ASSERT (error_obj_p != NULL); - - ecma_deref_object (error_obj_p); + JERRY_ASSERT (ecma_is_value_error (error_value)); + error_value = error_value & ~(1u << ECMA_VALUE_ERROR_POS); + ecma_free_value (error_value); } else { JERRY_ASSERT (ret_code == JERRY_COMPLETION_CODE_OK); - JERRY_ASSERT (error_obj_p == NULL); + JERRY_ASSERT (ecma_is_value_empty (error_value)); } vm_finalize (); diff --git a/jerry-core/jerry.h b/jerry-core/jerry.h index ca61da375..d04c95419 100644 --- a/jerry-core/jerry.h +++ b/jerry-core/jerry.h @@ -85,7 +85,7 @@ void jerry_cleanup (void); void jerry_get_memory_limits (size_t *, size_t *); bool jerry_parse (const jerry_api_char_t *, size_t, jerry_api_object_t **); -jerry_completion_code_t jerry_run (jerry_api_object_t **); +jerry_completion_code_t jerry_run (jerry_api_value_t *); jerry_completion_code_t jerry_run_simple (const jerry_api_char_t *, size_t, jerry_flag_t); /** diff --git a/jerry-core/parser/js/js-parser.c b/jerry-core/parser/js/js-parser.c index 1cbe78171..52a2a0be3 100644 --- a/jerry-core/parser/js/js-parser.c +++ b/jerry-core/parser/js/js-parser.c @@ -2238,6 +2238,9 @@ parser_set_show_instrs (int show_instrs) /**< flag indicating whether to dump by /** * Parse EcamScript source code + * + * Note: + * returned error object should be freed with jerry_api_release_object */ jsp_status_t parser_parse_script (const jerry_api_char_t *source_p, /**< source code */ @@ -2260,6 +2263,9 @@ parser_parse_script (const jerry_api_char_t *source_p, /**< source code */ /** * Parse EcamScript eval source code + * + * Note: + * returned error object should be freed with jerry_api_release_object */ jsp_status_t parser_parse_eval (const jerry_api_char_t *source_p, /**< source code */ diff --git a/jerry-core/vm/vm.c b/jerry-core/vm/vm.c index 84935f06b..c2dfa2ca0 100644 --- a/jerry-core/vm/vm.c +++ b/jerry-core/vm/vm.c @@ -171,10 +171,14 @@ static const uint32_t vm_ext_decode_table[] = /** * Run global code * + * Note: + * returned error value should be freed with jerry_api_release_value + * just when the value becomes unnecessary. + * * @return completion code */ jerry_completion_code_t -vm_run_global (ecma_object_t **error_obj_p) +vm_run_global (ecma_value_t *error_value_p) /**< [out] error value */ { jerry_completion_code_t ret_code; @@ -192,12 +196,13 @@ vm_run_global (ecma_object_t **error_obj_p) if (ecma_is_value_error (ret_value)) { - *error_obj_p = ecma_get_object_from_value (ret_value); + *error_value_p = ret_value; ret_code = JERRY_COMPLETION_CODE_UNHANDLED_EXCEPTION; } else { ecma_free_value (ret_value); + *error_value_p = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY); ret_code = JERRY_COMPLETION_CODE_OK; } diff --git a/jerry-core/vm/vm.h b/jerry-core/vm/vm.h index 82b53d71d..8ec6fa5f1 100644 --- a/jerry-core/vm/vm.h +++ b/jerry-core/vm/vm.h @@ -194,7 +194,7 @@ typedef enum extern void vm_init (ecma_compiled_code_t *); extern void vm_finalize (void); -extern jerry_completion_code_t vm_run_global (ecma_object_t **); +extern jerry_completion_code_t vm_run_global (ecma_value_t *); extern ecma_value_t vm_run_eval (ecma_compiled_code_t *, bool); extern ecma_value_t vm_run (const ecma_compiled_code_t *, ecma_value_t, diff --git a/main-unix.c b/main-unix.c index eb13c859d..7f43e1a84 100644 --- a/main-unix.c +++ b/main-unix.c @@ -408,6 +408,7 @@ main (int argc, } jerry_api_object_t *err_obj_p = NULL; + jerry_api_value_t err_value = jerry_api_create_void_value (); if (is_ok) { @@ -455,7 +456,7 @@ main (int argc, } else if ((flags & JERRY_FLAG_PARSE_ONLY) == 0) { - ret_code = jerry_run (&err_obj_p); + ret_code = jerry_run (&err_value); } } } @@ -547,12 +548,23 @@ main (int argc, } else if (ret_code == JERRY_COMPLETION_CODE_UNHANDLED_EXCEPTION) { + jerry_api_string_t *err_str_p = NULL; + if (err_obj_p != NULL) { - jerry_api_char_t err_str_buf[256]; - jerry_api_value_t err_value = jerry_api_create_object_value (err_obj_p); - jerry_api_string_t *err_str_p = jerry_api_value_to_string (&err_value); + err_str_p = jerry_api_value_to_string (&err_value); + jerry_api_release_object (err_obj_p); + } + else if (!jerry_api_value_is_void (&err_value)) + { + err_str_p = jerry_api_value_to_string (&err_value); + jerry_api_release_value (&err_value); + } + + if (likely (err_str_p != NULL)) + { + jerry_api_char_t err_str_buf[256]; jerry_api_size_t err_str_size = jerry_api_get_string_size (err_str_p); JERRY_ASSERT (err_str_size < 256); @@ -560,10 +572,9 @@ main (int argc, JERRY_ASSERT (sz == err_str_size); err_str_buf[err_str_size] = 0; - JERRY_ERROR_MSG ("%s\n", err_str_buf); + JERRY_ERROR_MSG ("Unhandled exception! %s\n", err_str_buf); jerry_api_release_string (err_str_p); - jerry_api_release_object (err_obj_p); } jerry_cleanup (); diff --git a/tests/jerry/fail/1/throw-error-object.js b/tests/jerry/fail/1/throw-error-object.js new file mode 100644 index 000000000..0c301694f --- /dev/null +++ b/tests/jerry/fail/1/throw-error-object.js @@ -0,0 +1 @@ +throw new SyntaxError("error"); diff --git a/tests/jerry/fail/1/throw-number.js b/tests/jerry/fail/1/throw-number.js new file mode 100644 index 000000000..dbc2e3d5d --- /dev/null +++ b/tests/jerry/fail/1/throw-number.js @@ -0,0 +1 @@ +throw 0.1234; diff --git a/tests/jerry/fail/1/throw-string.js b/tests/jerry/fail/1/throw-string.js new file mode 100644 index 000000000..29684289e --- /dev/null +++ b/tests/jerry/fail/1/throw-string.js @@ -0,0 +1 @@ +throw "SyntaxError" diff --git a/tests/unit/test-api.c b/tests/unit/test-api.c index 5afc6959e..876fb3382 100644 --- a/tests/unit/test-api.c +++ b/tests/unit/test-api.c @@ -339,8 +339,9 @@ main (void) is_ok = jerry_parse ((jerry_api_char_t *) test_source, strlen (test_source), &err_obj_p); JERRY_ASSERT (is_ok && err_obj_p == NULL); - is_ok = (jerry_run (&err_obj_p) == JERRY_COMPLETION_CODE_OK); - JERRY_ASSERT (is_ok && err_obj_p == NULL); + is_ok = (jerry_run (&res) == JERRY_COMPLETION_CODE_OK); + JERRY_ASSERT (is_ok); + JERRY_ASSERT (jerry_api_value_is_void (&res)); global_obj_p = jerry_api_get_global (); @@ -688,8 +689,9 @@ main (void) is_ok = jerry_parse ((jerry_api_char_t *) ms_code_src_p, strlen (ms_code_src_p), &err_obj_p); JERRY_ASSERT (is_ok && err_obj_p == NULL); - is_ok = (jerry_run (&err_obj_p) == JERRY_COMPLETION_CODE_OK); - JERRY_ASSERT (is_ok && err_obj_p == NULL); + is_ok = (jerry_run (&res) == JERRY_COMPLETION_CODE_OK); + JERRY_ASSERT (is_ok); + JERRY_ASSERT (jerry_api_value_is_void (&res)); jerry_cleanup ();