Introduce generic backtrace capturing (#4555)

Remove jerry_get_backtrace_from function

JerryScript-DCO-1.0-Signed-off-by: Zoltan Herczeg zherczeg.u-szeged@partner.samsung.com
This commit is contained in:
Zoltan Herczeg
2021-02-04 16:33:59 +01:00
committed by GitHub
parent feb2855f0c
commit 3623ac789d
8 changed files with 673 additions and 297 deletions
+107 -89
View File
@@ -33,14 +33,109 @@ backtrace_handler (const jerry_value_t function_obj, /**< function object */
max_depth = (uint32_t) jerry_get_number_value (args_p[0]);
}
if (args_count >= 2)
{
return jerry_get_backtrace_from (max_depth, args_p[1]);
}
return jerry_get_backtrace (max_depth);
} /* backtrace_handler */
static void
compare_string (jerry_value_t left_value, /* string value */
const char *right_p) /* string to compare */
{
jerry_char_t buffer[64];
size_t length = strlen (right_p);
TEST_ASSERT (length <= sizeof (buffer));
TEST_ASSERT (jerry_value_is_string (left_value));
TEST_ASSERT (jerry_get_string_size (left_value) == length);
TEST_ASSERT (jerry_string_to_char_buffer (left_value, buffer, sizeof (buffer)) == length);
TEST_ASSERT (memcmp (buffer, right_p, length) == 0);
} /* compare_string */
static const jerry_value_t *handler_args_p;
static int frame_index;
static bool
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, "capture_test.js");
++frame_index;
if (frame_index == 1)
{
TEST_ASSERT (!jerry_backtrace_is_strict (frame_p));
TEST_ASSERT (location_p->line == 2);
TEST_ASSERT (location_p->column == 1);
TEST_ASSERT (handler_args_p[0] == *function_p);
return true;
}
if (frame_index == 2)
{
TEST_ASSERT (jerry_backtrace_is_strict (frame_p));
TEST_ASSERT (location_p->line == 7);
TEST_ASSERT (location_p->column == 1);
TEST_ASSERT (handler_args_p[1] == *function_p);
return true;
}
TEST_ASSERT (frame_index == 3);
TEST_ASSERT (!jerry_backtrace_is_strict (frame_p));
TEST_ASSERT (location_p->line == 11);
TEST_ASSERT (location_p->column == 1);
TEST_ASSERT (handler_args_p[2] == *function_p);
return false;
} /* backtrace_callback */
static jerry_value_t
capture_handler (const jerry_value_t function_obj, /**< function object */
const jerry_value_t this_val, /**< this value */
const jerry_value_t args_p[], /**< argument list */
const jerry_length_t args_count) /**< argument count */
{
JERRY_UNUSED (function_obj);
JERRY_UNUSED (this_val);
JERRY_UNUSED (args_p);
JERRY_UNUSED (args_count);
TEST_ASSERT (args_count == 3);
frame_index = 0;
handler_args_p = args_p;
jerry_backtrace_capture (backtrace_callback, (void *) args_p);
TEST_ASSERT (frame_index == 3);
return jerry_create_undefined ();
} /* capture_handler */
static void
register_callback (jerry_external_handler_t handler_p, /**< callback function */
char *name_p) /**< name of the function */
{
jerry_value_t global = jerry_get_global_object ();
jerry_value_t func = jerry_create_external_function (handler_p);
jerry_value_t name = jerry_create_string ((const jerry_char_t *) name_p);
jerry_value_t result = jerry_set_property (global, name, func);
TEST_ASSERT (!jerry_value_is_error (result));
jerry_release_value (result);
jerry_release_value (name);
jerry_release_value (func);
jerry_release_value (global);
} /* register_callback */
static jerry_value_t
run (const char *resource_name_p, /**< resource name */
const char *source_p) /**< source code */
@@ -89,18 +184,8 @@ test_get_backtrace_api_call (void)
{
jerry_init (JERRY_INIT_EMPTY);
jerry_value_t global = jerry_get_global_object ();
jerry_value_t func = jerry_create_external_function (backtrace_handler);
jerry_value_t name = jerry_create_string ((const jerry_char_t *) "backtrace");
jerry_value_t result = jerry_set_property (global, name, func);
TEST_ASSERT (!jerry_value_is_error (result));
jerry_release_value (result);
jerry_release_value (name);
jerry_release_value (func);
jerry_release_value (global);
register_callback (backtrace_handler, "backtrace");
register_callback (capture_handler, "capture");
const char *source = ("function f() {\n"
" return backtrace(0);\n"
@@ -158,13 +243,14 @@ test_get_backtrace_api_call (void)
jerry_release_value (backtrace);
/* Ignore f and g this time. */
/* Test frame capturing. */
source = ("function f() {\n"
" return backtrace(0, g);\n"
" return capture(f, g, h);\n"
"}\n"
"\n"
"function g() {\n"
" 'use strict';\n"
" return f();\n"
"}\n"
"\n"
@@ -174,77 +260,9 @@ test_get_backtrace_api_call (void)
"\n"
"h();\n");
backtrace = run ("something_ignore.js", source);
TEST_ASSERT (!jerry_value_is_error (backtrace)
&& jerry_value_is_array (backtrace));
TEST_ASSERT (jerry_get_array_length (backtrace) == 2);
compare (backtrace, 0, "something_ignore.js:10");
compare (backtrace, 1, "something_ignore.js:13");
jerry_release_value (backtrace);
/* Use bound function this time. */
source = ("function f() {\n"
" return backtrace(0, i);\n"
"}\n"
"\n"
"function g(u, v) {\n"
" return v();\n"
"}\n"
"\n"
"var h = g.bind(null, 0)\n"
"var i = h.bind(null, f)\n"
"\n"
"function j() {\n"
" return i();\n"
"}\n"
"\n"
"j();\n");
backtrace = run ("something_bound.js", source);
TEST_ASSERT (!jerry_value_is_error (backtrace)
&& jerry_value_is_array (backtrace));
TEST_ASSERT (jerry_get_array_length (backtrace) == 2);
compare (backtrace, 0, "something_bound.js:13");
compare (backtrace, 1, "something_bound.js:16");
jerry_release_value (backtrace);
/* Use invalid function this time. */
source = ("function f() {\n"
" return backtrace(0, ':)');\n"
"}\n"
"\n"
"function g() {\n"
" return f();\n"
"}\n"
"\n"
"function h() {\n"
" return g();\n"
"}\n"
"\n"
"h();\n");
backtrace = run ("nothing_ignore.js", source);
TEST_ASSERT (!jerry_value_is_error (backtrace)
&& jerry_value_is_array (backtrace));
TEST_ASSERT (jerry_get_array_length (backtrace) == 4);
compare (backtrace, 0, "nothing_ignore.js:2");
compare (backtrace, 1, "nothing_ignore.js:6");
compare (backtrace, 2, "nothing_ignore.js:10");
compare (backtrace, 3, "nothing_ignore.js:13");
backtrace = run ("capture_test.js", source);
TEST_ASSERT (jerry_value_is_undefined (backtrace));
jerry_release_value (backtrace);
jerry_cleanup ();