Rework the public API (#4829)

Related to #4186.

Some notable changes:
  - The term 'Error' now strictly refers to native Error objects defined in
    the ECMA standard, which are ordinary objects. All other uses of
    'error' or 'error reference' where the term refers to a thrown value is
    now called 'exception'.

  - Simplified the naming scheme of many String API functions. These functions
    will now also take an 'encoding' argument to specify the desired
    encoding in which to operate.

  - Removed the substring-copy-to-buffer functions. These functions
    behaved awkwardly, as they use character index to specify the
    start/end positions, and were mostly used incorrectly with byte
    offsets instead. The functionality can still be replicated with
    other functions if necessary.

  - String-to-buffer functions will no longer fail if the buffer is not
    sufficiently large, the string will instead be cropped.

  - Fixed the usage of the '_sz' prefix in many API functions. The term
    'sz' means zero-terminated string in hungarian notation, this was
    used incorrectly in many cases.

  - Renamed most of the public API functions to have shorter, more on-point
    names, rather than the often too long descriptive names. Functions are now
    also grouped by the type of value they operate on, where this makes
    sense.

JerryScript-DCO-1.0-Signed-off-by: Dániel Bátyai dbatyai@inf.u-szeged.hu
This commit is contained in:
Dániel Bátyai
2021-12-06 10:20:09 +01:00
committed by GitHub
parent 81d2319144
commit 9860d66a56
180 changed files with 10738 additions and 11025 deletions
+156 -174
View File
@@ -40,9 +40,9 @@ static void
main_register_global_function (const char *name_p, /**< name of the function */
jerry_external_handler_t handler_p) /**< function callback */
{
jerry_value_t result_val = jerryx_handler_register_global ((const jerry_char_t *) name_p, handler_p);
assert (!jerry_value_is_error (result_val));
jerry_release_value (result_val);
jerry_value_t result_val = jerryx_handler_register_global (name_p, handler_p);
assert (!jerry_value_is_exception (result_val));
jerry_value_free (result_val);
} /* main_register_global_function */
static jerry_value_t
@@ -53,7 +53,7 @@ main_create_realm (const jerry_call_info_t *call_info_p, /**< call information *
(void) call_info_p; /* unused */
(void) args_p; /* unused */
(void) args_cnt; /* unused */
return jerry_create_realm ();
return jerry_realm ();
} /* main_create_realm */
/**
@@ -64,16 +64,16 @@ test262_register_function (jerry_value_t test262_obj, /** $262 object */
const char *name_p, /**< name of the function */
jerry_external_handler_t handler_p) /**< function callback */
{
jerry_value_t function_name_val = jerry_create_string ((const jerry_char_t *) name_p);
jerry_value_t function_val = jerry_create_external_function (handler_p);
jerry_value_t function_name_val = jerry_string_sz (name_p);
jerry_value_t function_val = jerry_function_external (handler_p);
jerry_value_t result_val = jerry_set_property (test262_obj, function_name_val, function_val);
jerry_value_t result_val = jerry_object_set (test262_obj, function_name_val, function_val);
jerry_release_value (function_val);
jerry_release_value (function_name_val);
jerry_value_free (function_val);
jerry_value_free (function_name_val);
assert (!jerry_value_is_error (result_val));
jerry_release_value (result_val);
assert (!jerry_value_is_exception (result_val));
jerry_value_free (result_val);
} /* test262_register_function */
/**
@@ -93,12 +93,12 @@ test262_detach_array_buffer (const jerry_call_info_t *call_info_p, /**< call inf
if (args_cnt < 1 || !jerry_value_is_arraybuffer (args_p[0]))
{
return jerry_create_error (JERRY_ERROR_TYPE, (jerry_char_t *) "Expected an ArrayBuffer object");
return jerry_throw_sz (JERRY_ERROR_TYPE, "Expected an ArrayBuffer object");
}
/* TODO: support the optional 'key' argument */
return jerry_detach_arraybuffer (args_p[0]);
return jerry_arraybuffer_detach (args_p[0]);
} /* test262_detach_array_buffer */
/**
@@ -117,25 +117,26 @@ test262_eval_script (const jerry_call_info_t *call_info_p, /**< call information
if (args_cnt < 1 || !jerry_value_is_string (args_p[0]))
{
return jerry_create_error (JERRY_ERROR_TYPE, (jerry_char_t *) "Expected a string");
return jerry_throw_sz (JERRY_ERROR_TYPE, "Expected a string");
}
jerry_size_t str_size = jerry_get_utf8_string_size (args_p[0]);
jerry_size_t str_size = jerry_string_size (args_p[0], JERRY_ENCODING_UTF8);
jerry_char_t *str_buf_p = malloc (str_size * sizeof (jerry_char_t));
if (str_buf_p == NULL || jerry_string_to_utf8_char_buffer (args_p[0], str_buf_p, str_size) != str_size)
if (str_buf_p == NULL)
{
free (str_buf_p);
return jerry_create_error (JERRY_ERROR_RANGE, (jerry_char_t *) "Internal error");
return jerry_throw_sz (JERRY_ERROR_RANGE, "Internal allocation error");
}
jerry_string_to_buffer (args_p[0], JERRY_ENCODING_UTF8, str_buf_p, str_size);
jerry_value_t ret_value = jerry_parse (str_buf_p, str_size, NULL);
if (!jerry_value_is_error (ret_value))
if (!jerry_value_is_exception (ret_value))
{
jerry_value_t func_val = ret_value;
ret_value = jerry_run (func_val);
jerry_release_value (func_val);
jerry_value_free (func_val);
}
free (str_buf_p);
@@ -161,12 +162,12 @@ test262_create_realm (const jerry_call_info_t *call_info_p, /**< call informatio
(void) args_p; /* unused */
(void) args_cnt; /* unused */
jerry_value_t realm_object = jerry_create_realm ();
jerry_value_t realm_object = jerry_realm ();
jerry_value_t previous_realm = jerry_set_realm (realm_object);
assert (!jerry_value_is_error (previous_realm));
assert (!jerry_value_is_exception (previous_realm));
jerry_value_t test262_object = create_test262 (realm_object);
jerry_set_realm (previous_realm);
jerry_release_value (realm_object);
jerry_value_free (realm_object);
return test262_object;
} /* test262_create_realm */
@@ -179,24 +180,26 @@ test262_create_realm (const jerry_call_info_t *call_info_p, /**< call informatio
static jerry_value_t
create_test262 (jerry_value_t global_obj) /**< global object */
{
jerry_value_t test262_object = jerry_create_object ();
jerry_value_t test262_object = jerry_object ();
test262_register_function (test262_object, "detachArrayBuffer", test262_detach_array_buffer);
test262_register_function (test262_object, "evalScript", test262_eval_script);
test262_register_function (test262_object, "createRealm", test262_create_realm);
test262_register_function (test262_object, "gc", jerryx_handler_gc);
jerry_value_t prop_name = jerry_create_string ((const jerry_char_t *) "global");
jerry_value_t result = jerry_set_property (test262_object, prop_name, global_obj);
assert (!jerry_value_is_error (result));
jerry_release_value (prop_name);
jerry_release_value (result);
prop_name = jerry_create_string ((const jerry_char_t *) "$262");
result = jerry_set_property (global_obj, prop_name, test262_object);
jerry_value_t prop_name = jerry_string_sz ("global");
jerry_value_t result = jerry_object_set (test262_object, prop_name, global_obj);
assert (!jerry_value_is_exception (result));
jerry_release_value (prop_name);
assert (!jerry_value_is_error (result));
jerry_release_value (result);
jerry_value_free (prop_name);
jerry_value_free (result);
prop_name = jerry_string_sz ("$262");
result = jerry_object_set (global_obj, prop_name, test262_object);
assert (!jerry_value_is_exception (result));
jerry_value_free (prop_name);
jerry_value_free (result);
return test262_object;
} /* create_test262 */
@@ -216,12 +219,12 @@ promise_callback (jerry_promise_event_type_t event_type, /**< event type */
return;
}
jerry_value_t reason = jerry_get_promise_result (object);
jerry_value_t reason = jerry_promise_result (object);
jerry_value_t reason_to_string = jerry_value_to_string (reason);
if (!jerry_value_is_error (reason_to_string))
if (!jerry_value_is_exception (reason_to_string))
{
jerry_size_t buffer_size = jerry_get_utf8_string_size (reason_to_string);
jerry_size_t buffer_size = jerry_string_size (reason_to_string, JERRY_ENCODING_UTF8);
if (buffer_size > max_allowed_size)
{
@@ -229,7 +232,7 @@ promise_callback (jerry_promise_event_type_t event_type, /**< event type */
}
JERRY_VLA (jerry_char_t, str_buf_p, buffer_size + 1);
jerry_string_to_utf8_char_buffer (reason_to_string, str_buf_p, buffer_size);
jerry_string_to_buffer (reason_to_string, JERRY_ENCODING_UTF8, str_buf_p, buffer_size);
str_buf_p[buffer_size] = '\0';
jerry_port_log (JERRY_LOG_LEVEL_WARNING, "Uncaught Promise rejection: %s\n", str_buf_p);
@@ -239,8 +242,8 @@ promise_callback (jerry_promise_event_type_t event_type, /**< event type */
jerry_port_log (JERRY_LOG_LEVEL_WARNING, "Uncaught Promise rejection (reason cannot be converted to string)\n");
}
jerry_release_value (reason_to_string);
jerry_release_value (reason);
jerry_value_free (reason_to_string);
jerry_value_free (reason);
} /* promise_callback */
/**
@@ -251,7 +254,7 @@ main_init_engine (main_args_t *arguments_p) /**< main arguments */
{
jerry_init (arguments_p->init_flags);
jerry_promise_set_callback (JERRY_PROMISE_EVENT_FILTER_ERROR, promise_callback, NULL);
jerry_promise_on_event (JERRY_PROMISE_EVENT_FILTER_ERROR, promise_callback, NULL);
if (arguments_p->option_flags & OPT_FLAG_DEBUG_SERVER)
{
@@ -279,15 +282,15 @@ main_init_engine (main_args_t *arguments_p) /**< main arguments */
}
if (arguments_p->option_flags & OPT_FLAG_TEST262_OBJECT)
{
jerry_value_t global_obj = jerry_get_global_object ();
jerry_value_t global_obj = jerry_current_realm ();
jerry_value_t test262_object = create_test262 (global_obj);
jerry_release_value (test262_object);
jerry_release_value (global_obj);
jerry_value_free (test262_object);
jerry_value_free (global_obj);
}
main_register_global_function ("assert", jerryx_handler_assert);
main_register_global_function ("gc", jerryx_handler_gc);
main_register_global_function ("print", jerryx_handler_print);
main_register_global_function ("resourceName", jerryx_handler_resource_name);
main_register_global_function ("resourceName", jerryx_handler_source_name);
main_register_global_function ("createRealm", main_create_realm);
} /* main_init_engine */
@@ -299,129 +302,118 @@ main_init_engine (main_args_t *arguments_p) /**< main arguments */
void
main_print_unhandled_exception (jerry_value_t error_value) /**< error value */
{
assert (jerry_value_is_error (error_value));
error_value = jerry_get_value_from_error (error_value, true);
assert (jerry_value_is_exception (error_value));
error_value = jerry_exception_value (error_value, true);
jerry_char_t err_str_buf[256];
jerry_value_t err_str_val = jerry_value_to_string (error_value);
jerry_size_t err_str_size = jerry_get_utf8_string_size (err_str_val);
if (err_str_size >= 256)
{
const char msg[] = "[Error message too long]";
err_str_size = sizeof (msg) / sizeof (char) - 1;
memcpy (err_str_buf, msg, err_str_size + 1);
}
else
{
jerry_size_t string_end = jerry_string_to_utf8_char_buffer (err_str_val, err_str_buf, err_str_size);
assert (string_end == err_str_size);
err_str_buf[string_end] = 0;
jerry_size_t string_end =
jerry_string_to_buffer (err_str_val, JERRY_ENCODING_UTF8, err_str_buf, sizeof (err_str_buf) - 1);
err_str_buf[string_end] = '\0';
if (jerry_is_feature_enabled (JERRY_FEATURE_ERROR_MESSAGES)
&& jerry_get_error_type (error_value) == JERRY_ERROR_SYNTAX)
if (jerry_feature_enabled (JERRY_FEATURE_ERROR_MESSAGES) && jerry_error_type (error_value) == JERRY_ERROR_SYNTAX)
{
jerry_char_t *string_end_p = err_str_buf + string_end;
unsigned int err_line = 0;
unsigned int err_col = 0;
char *path_str_p = NULL;
char *path_str_end_p = NULL;
/* 1. parse column and line information */
for (jerry_char_t *current_p = err_str_buf; current_p < string_end_p; current_p++)
{
jerry_char_t *string_end_p = err_str_buf + string_end;
unsigned int err_line = 0;
unsigned int err_col = 0;
char *path_str_p = NULL;
char *path_str_end_p = NULL;
/* 1. parse column and line information */
for (jerry_char_t *current_p = err_str_buf; current_p < string_end_p; current_p++)
if (*current_p == '[')
{
if (*current_p == '[')
current_p++;
if (*current_p == '<')
{
current_p++;
if (*current_p == '<')
{
break;
}
path_str_p = (char *) current_p;
while (current_p < string_end_p && *current_p != ':')
{
current_p++;
}
path_str_end_p = (char *) current_p++;
err_line = (unsigned int) strtol ((char *) current_p, (char **) &current_p, 10);
current_p++;
err_col = (unsigned int) strtol ((char *) current_p, NULL, 10);
break;
}
} /* for */
if (err_line != 0 && err_col > 0 && err_col < SYNTAX_ERROR_MAX_LINE_LENGTH)
{
/* Temporarily modify the error message, so we can use the path. */
*path_str_end_p = '\0';
size_t source_size;
uint8_t *source_p = jerry_port_read_source (path_str_p, &source_size);
/* Revert the error message. */
*path_str_end_p = ':';
if (source_p != NULL)
path_str_p = (char *) current_p;
while (current_p < string_end_p && *current_p != ':')
{
uint32_t curr_line = 1;
uint32_t pos = 0;
/* 2. seek and print */
while (pos < source_size && curr_line < err_line)
{
if (source_p[pos] == '\n')
{
curr_line++;
}
pos++;
}
/* Print character if:
* - The max line length is not reached.
* - The current position is valid (it is not the end of the source).
* - The current character is not a newline.
**/
for (uint32_t char_count = 0;
(char_count < SYNTAX_ERROR_MAX_LINE_LENGTH) && (pos < source_size) && (source_p[pos] != '\n');
char_count++, pos++)
{
jerry_port_log (JERRY_LOG_LEVEL_ERROR, "%c", source_p[pos]);
}
jerry_port_log (JERRY_LOG_LEVEL_ERROR, "\n");
jerry_port_release_source (source_p);
while (--err_col)
{
jerry_port_log (JERRY_LOG_LEVEL_ERROR, "~");
}
jerry_port_log (JERRY_LOG_LEVEL_ERROR, "^\n\n");
current_p++;
}
path_str_end_p = (char *) current_p++;
err_line = (unsigned int) strtol ((char *) current_p, (char **) &current_p, 10);
current_p++;
err_col = (unsigned int) strtol ((char *) current_p, NULL, 10);
break;
}
} /* for */
if (err_line != 0 && err_col > 0 && err_col < SYNTAX_ERROR_MAX_LINE_LENGTH)
{
/* Temporarily modify the error message, so we can use the path. */
*path_str_end_p = '\0';
size_t source_size;
uint8_t *source_p = jerry_port_read_source (path_str_p, &source_size);
/* Revert the error message. */
*path_str_end_p = ':';
if (source_p != NULL)
{
uint32_t curr_line = 1;
uint32_t pos = 0;
/* 2. seek and print */
while (pos < source_size && curr_line < err_line)
{
if (source_p[pos] == '\n')
{
curr_line++;
}
pos++;
}
/* Print character if:
* - The max line length is not reached.
* - The current position is valid (it is not the end of the source).
* - The current character is not a newline.
**/
for (uint32_t char_count = 0;
(char_count < SYNTAX_ERROR_MAX_LINE_LENGTH) && (pos < source_size) && (source_p[pos] != '\n');
char_count++, pos++)
{
jerry_port_log (JERRY_LOG_LEVEL_ERROR, "%c", source_p[pos]);
}
jerry_port_log (JERRY_LOG_LEVEL_ERROR, "\n");
jerry_port_release_source (source_p);
while (--err_col)
{
jerry_port_log (JERRY_LOG_LEVEL_ERROR, "~");
}
jerry_port_log (JERRY_LOG_LEVEL_ERROR, "^\n\n");
}
}
}
jerry_port_log (JERRY_LOG_LEVEL_ERROR, "%s\n", err_str_buf);
jerry_release_value (err_str_val);
jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Unhandled exception: %s\n", err_str_buf);
jerry_value_free (err_str_val);
if (jerry_value_is_object (error_value))
{
jerry_value_t stack_str = jerry_create_string ((const jerry_char_t *) "stack");
jerry_value_t backtrace_val = jerry_get_property (error_value, stack_str);
jerry_release_value (stack_str);
jerry_value_t stack_str = jerry_string_sz ("stack");
jerry_value_t backtrace_val = jerry_object_get (error_value, stack_str);
jerry_value_free (stack_str);
if (jerry_value_is_array (backtrace_val))
{
uint32_t length = jerry_get_array_length (backtrace_val);
uint32_t length = jerry_array_length (backtrace_val);
/* This length should be enough. */
if (length > 32)
@@ -431,34 +423,24 @@ main_print_unhandled_exception (jerry_value_t error_value) /**< error value */
for (uint32_t i = 0; i < length; i++)
{
jerry_value_t item_val = jerry_get_property_by_index (backtrace_val, i);
jerry_value_t item_val = jerry_object_get_index (backtrace_val, i);
if (jerry_value_is_string (item_val))
{
jerry_size_t str_size = jerry_get_utf8_string_size (item_val);
string_end = jerry_string_to_buffer (item_val, JERRY_ENCODING_UTF8, err_str_buf, sizeof (err_str_buf) - 1);
err_str_buf[string_end] = '\0';
if (str_size >= 256)
{
printf ("%6u: [Backtrace string too long]\n", i);
}
else
{
jerry_size_t string_end = jerry_string_to_utf8_char_buffer (item_val, err_str_buf, str_size);
assert (string_end == str_size);
err_str_buf[string_end] = 0;
printf ("%6u: %s\n", i, err_str_buf);
}
printf ("%6u: %s\n", i, err_str_buf);
}
jerry_release_value (item_val);
jerry_value_free (item_val);
}
}
jerry_release_value (backtrace_val);
jerry_value_free (backtrace_val);
}
jerry_release_value (error_value);
jerry_value_free (error_value);
} /* main_print_unhandled_exception */
/**
@@ -467,8 +449,8 @@ main_print_unhandled_exception (jerry_value_t error_value) /**< error value */
* @return result fo the source code execution
*/
jerry_value_t
main_wait_for_source_callback (const jerry_char_t *resource_name_p, /**< resource name */
size_t resource_name_size, /**< size of resource name */
main_wait_for_source_callback (const jerry_char_t *source_name_p, /**< resource name */
size_t source_name_size, /**< size of resource name */
const jerry_char_t *source_p, /**< source code */
size_t source_size, /**< source code size */
void *user_p) /**< user pointer */
@@ -476,18 +458,18 @@ main_wait_for_source_callback (const jerry_char_t *resource_name_p, /**< resourc
(void) user_p; /* unused */
jerry_parse_options_t parse_options;
parse_options.options = JERRY_PARSE_HAS_RESOURCE;
parse_options.resource_name = jerry_create_string_sz (resource_name_p, (jerry_size_t) resource_name_size);
parse_options.options = JERRY_PARSE_HAS_SOURCE_NAME;
parse_options.source_name = jerry_string (source_name_p, (jerry_size_t) source_name_size, JERRY_ENCODING_UTF8);
jerry_value_t ret_val = jerry_parse (source_p, source_size, &parse_options);
jerry_release_value (parse_options.resource_name);
jerry_value_free (parse_options.source_name);
if (!jerry_value_is_error (ret_val))
if (!jerry_value_is_exception (ret_val))
{
jerry_value_t func_val = ret_val;
ret_val = jerry_run (func_val);
jerry_release_value (func_val);
jerry_value_free (func_val);
}
return ret_val;
@@ -509,32 +491,32 @@ main_is_value_reset (jerry_value_t value) /**< jerry value */
return false;
}
jerry_value_t abort_value = jerry_get_value_from_error (value, false);
jerry_value_t abort_value = jerry_exception_value (value, false);
if (!jerry_value_is_string (abort_value))
{
jerry_release_value (abort_value);
jerry_value_free (abort_value);
return false;
}
static const char restart_str[] = "r353t";
jerry_size_t str_size = jerry_get_string_size (abort_value);
jerry_size_t str_size = jerry_string_size (abort_value, JERRY_ENCODING_CESU8);
bool is_reset = false;
if (str_size == sizeof (restart_str) - 1)
{
JERRY_VLA (jerry_char_t, str_buf, str_size);
jerry_string_to_char_buffer (abort_value, str_buf, str_size);
jerry_string_to_buffer (abort_value, JERRY_ENCODING_CESU8, str_buf, str_size);
is_reset = memcmp (restart_str, (char *) (str_buf), str_size) == 0;
if (is_reset)
{
jerry_release_value (value);
jerry_value_free (value);
}
}
jerry_release_value (abort_value);
jerry_value_free (abort_value);
return is_reset;
} /* main_is_value_reset */