Add line info support. (#2286)
Add line info data to byte, which allows getting a backtrace info directly from the engine. Snapshots are not supported. JerryScript-DCO-1.0-Signed-off-by: Zoltan Herczeg zherczeg.u-szeged@partner.samsung.com
This commit is contained in:
@@ -0,0 +1,202 @@
|
||||
/* Copyright JS Foundation and other contributors, http://js.foundation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "jerryscript.h"
|
||||
#include "test-common.h"
|
||||
|
||||
static jerry_value_t
|
||||
backtrace_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);
|
||||
|
||||
uint32_t max_depth = 0;
|
||||
|
||||
if (args_count > 0 && jerry_value_is_number (args_p[0]))
|
||||
{
|
||||
max_depth = (uint32_t) jerry_get_number_value (args_p[0]);
|
||||
}
|
||||
|
||||
return jerry_get_backtrace (max_depth);
|
||||
} /* backtrace_handler */
|
||||
|
||||
static jerry_value_t
|
||||
run (const char *resource_name_p, /**< resource name */
|
||||
const char *source_p) /**< source code */
|
||||
{
|
||||
jerry_value_t code = jerry_parse ((const jerry_char_t *) resource_name_p,
|
||||
strlen (resource_name_p),
|
||||
(const jerry_char_t *) source_p,
|
||||
strlen (source_p),
|
||||
JERRY_PARSE_NO_OPTS);
|
||||
TEST_ASSERT (!jerry_value_has_error_flag (code));
|
||||
|
||||
jerry_value_t result = jerry_run (code);
|
||||
jerry_release_value (code);
|
||||
|
||||
return result;
|
||||
} /* run */
|
||||
|
||||
static void
|
||||
compare (jerry_value_t array, /**< array */
|
||||
uint32_t index, /**< item index */
|
||||
const char *str) /**< string to compare */
|
||||
{
|
||||
jerry_char_t buf[64];
|
||||
|
||||
size_t len = strlen (str);
|
||||
|
||||
TEST_ASSERT (len < sizeof (buf));
|
||||
|
||||
jerry_value_t value = jerry_get_property_by_index (array, index);
|
||||
|
||||
TEST_ASSERT (!jerry_value_has_error_flag (value)
|
||||
&& jerry_value_is_string (value));
|
||||
|
||||
TEST_ASSERT (jerry_get_string_size (value) == len);
|
||||
|
||||
jerry_size_t str_len = jerry_string_to_char_buffer (value, buf, (jerry_size_t) len);
|
||||
TEST_ASSERT (str_len == len);
|
||||
|
||||
jerry_release_value (value);
|
||||
|
||||
TEST_ASSERT (memcmp (buf, str, len) == 0);
|
||||
} /* compare */
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
TEST_INIT ();
|
||||
|
||||
TEST_ASSERT (jerry_is_feature_enabled (JERRY_FEATURE_LINE_INFO));
|
||||
|
||||
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_has_error_flag (result));
|
||||
|
||||
jerry_release_value (result);
|
||||
jerry_release_value (name);
|
||||
jerry_release_value (func);
|
||||
|
||||
jerry_release_value (global);
|
||||
|
||||
const char *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");
|
||||
|
||||
jerry_value_t backtrace = run ("something.js", source);
|
||||
|
||||
TEST_ASSERT (!jerry_value_has_error_flag (backtrace)
|
||||
&& jerry_value_is_array (backtrace));
|
||||
|
||||
TEST_ASSERT (jerry_get_array_length (backtrace) == 4);
|
||||
|
||||
compare (backtrace, 0, "something.js:2");
|
||||
compare (backtrace, 1, "something.js:6");
|
||||
compare (backtrace, 2, "something.js:10");
|
||||
compare (backtrace, 3, "something.js:13");
|
||||
|
||||
jerry_release_value (backtrace);
|
||||
|
||||
/* Depth set to 2 this time. */
|
||||
|
||||
source = ("function f() {\n"
|
||||
" return backtrace(2);\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
"function g() {\n"
|
||||
" return f();\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
"function h() {\n"
|
||||
" return g();\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
"h();\n");
|
||||
|
||||
backtrace = run ("something_else.js", source);
|
||||
|
||||
TEST_ASSERT (!jerry_value_has_error_flag (backtrace)
|
||||
&& jerry_value_is_array (backtrace));
|
||||
|
||||
TEST_ASSERT (jerry_get_array_length (backtrace) == 2);
|
||||
|
||||
compare (backtrace, 0, "something_else.js:2");
|
||||
compare (backtrace, 1, "something_else.js:6");
|
||||
|
||||
jerry_release_value (backtrace);
|
||||
|
||||
jerry_cleanup ();
|
||||
|
||||
jerry_init (JERRY_INIT_EMPTY);
|
||||
|
||||
source = ("function f() {\n"
|
||||
" undef_reference;\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
"function g() {\n"
|
||||
" return f();\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
"g();\n");
|
||||
|
||||
jerry_value_t error = run ("bad.js", source);
|
||||
|
||||
TEST_ASSERT (jerry_value_has_error_flag (error));
|
||||
|
||||
jerry_value_clear_error_flag (&error);
|
||||
|
||||
TEST_ASSERT (jerry_value_is_object (error));
|
||||
|
||||
name = jerry_create_string ((const jerry_char_t *) "stack");
|
||||
backtrace = jerry_get_property (error, name);
|
||||
|
||||
jerry_release_value (name);
|
||||
jerry_release_value (error);
|
||||
|
||||
TEST_ASSERT (!jerry_value_has_error_flag (backtrace)
|
||||
&& jerry_value_is_array (backtrace));
|
||||
|
||||
TEST_ASSERT (jerry_get_array_length (backtrace) == 3);
|
||||
|
||||
compare (backtrace, 0, "bad.js:2");
|
||||
compare (backtrace, 1, "bad.js:6");
|
||||
compare (backtrace, 2, "bad.js:9");
|
||||
|
||||
jerry_release_value (backtrace);
|
||||
|
||||
jerry_cleanup ();
|
||||
|
||||
return 0;
|
||||
} /* main */
|
||||
@@ -216,7 +216,7 @@ main (void)
|
||||
/* Check the snapshot data. Unused bytes should be filled with zeroes */
|
||||
const uint8_t expected_data[] =
|
||||
{
|
||||
0x4A, 0x52, 0x52, 0x59, 0x0B, 0x00, 0x00, 0x00,
|
||||
0x4A, 0x52, 0x52, 0x59, 0x0C, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00,
|
||||
0x01, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00,
|
||||
0x03, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
|
||||
|
||||
Reference in New Issue
Block a user