Introduce ecma_op_object_get_length and ecma_op_object_get_by_index operations (#3245)

These two functions helps to reduce code duplication, also invokes the elimination of several ECMA_TRY_CATCH macros.

JerryScript-DCO-1.0-Signed-off-by: Robert Fancsik frobert@inf.u-szeged.hu
This commit is contained in:
Robert Fancsik
2019-10-29 10:07:20 +01:00
committed by GitHub
parent 11818f1cb0
commit 42ab062441
23 changed files with 679 additions and 776 deletions
+12 -15
View File
@@ -1740,18 +1740,19 @@ jerry_get_array_length (const jerry_value_t value) /**< api value */
{
jerry_assert_api_available ();
if (!jerry_value_is_array (value))
if (!jerry_value_is_object (value))
{
return 0;
}
ecma_value_t len_value = ecma_op_object_get_by_magic_id (ecma_get_object_from_value (value),
LIT_MAGIC_STRING_LENGTH);
ecma_object_t *object_p = ecma_get_object_from_value (value);
jerry_length_t length = ecma_number_to_uint32 (ecma_get_number_from_value (len_value));
ecma_free_value (len_value);
if (JERRY_LIKELY (ecma_get_object_type (object_p) == ECMA_OBJECT_TYPE_ARRAY))
{
return ecma_array_get_length (object_p);
}
return length;
return 0;
} /* jerry_get_array_length */
/**
@@ -2217,9 +2218,7 @@ jerry_get_property_by_index (const jerry_value_t obj_val, /**< object value */
return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG (wrong_args_msg_p)));
}
ecma_string_t *str_idx_p = ecma_new_ecma_string_from_uint32 (index);
ecma_value_t ret_value = ecma_op_object_get (ecma_get_object_from_value (obj_val), str_idx_p);
ecma_deref_ecma_string (str_idx_p);
ecma_value_t ret_value = ecma_op_object_get_by_uint32_index (ecma_get_object_from_value (obj_val), index);
return jerry_return (ret_value);
} /* jerry_get_property_by_index */
@@ -2325,12 +2324,10 @@ jerry_set_property_by_index (const jerry_value_t obj_val, /**< object value */
return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG (wrong_args_msg_p)));
}
ecma_string_t *str_idx_p = ecma_new_ecma_string_from_uint32 ((uint32_t) index);
ecma_value_t ret_value = ecma_op_object_put (ecma_get_object_from_value (obj_val),
str_idx_p,
value_to_set,
true);
ecma_deref_ecma_string (str_idx_p);
ecma_value_t ret_value = ecma_op_object_put_by_uint32_index (ecma_get_object_from_value (obj_val),
index,
value_to_set,
true);
return jerry_return (ret_value);
} /* jerry_set_property_by_index */
+1 -1
View File
@@ -304,7 +304,7 @@ jerry_debugger_get_variable_type (ecma_value_t value) /**< input ecma value */
{
JERRY_ASSERT (ecma_is_value_object (value));
if (ecma_object_get_class_name (ecma_get_object_from_value (value)) == LIT_MAGIC_STRING_ARRAY_UL)
if (ecma_get_object_type (ecma_get_object_from_value (value)) == ECMA_OBJECT_TYPE_ARRAY)
{
ret_value = JERRY_DEBUGGER_VALUE_ARRAY;
}
+7 -7
View File
@@ -602,15 +602,15 @@ typedef enum
{
ECMA_OBJECT_TYPE_GENERAL = 0, /**< all objects that are not belongs to the sub-types below. */
ECMA_OBJECT_TYPE_CLASS = 1, /**< Objects with class property */
ECMA_OBJECT_TYPE_FUNCTION = 2, /**< Function objects (15.3), created through 13.2 routine */
ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION = 3, /**< External (host) function object */
ECMA_OBJECT_TYPE_ARRAY = 4, /**< Array object (15.4) */
ECMA_OBJECT_TYPE_BOUND_FUNCTION = 5, /**< Function objects (15.3), created through 15.3.4.5 routine */
ECMA_OBJECT_TYPE_PSEUDO_ARRAY = 6, /**< Array-like object, such as Arguments object (10.6) */
ECMA_OBJECT_TYPE_ARRAY = 2, /**< Array object (15.4) */
ECMA_OBJECT_TYPE_PSEUDO_ARRAY = 3, /**< Array-like object, such as Arguments object (10.6) */
/* Note: these 4 types must be in this order. See IsCallable operation. */
ECMA_OBJECT_TYPE_FUNCTION = 4, /**< Function objects (15.3), created through 13.2 routine */
#if ENABLED (JERRY_ES2015)
ECMA_OBJECT_TYPE_ARROW_FUNCTION = 7, /**< arrow function objects */
ECMA_OBJECT_TYPE_ARROW_FUNCTION = 5, /**< arrow function objects */
#endif /* ENABLED (JERRY_ES2015) */
ECMA_OBJECT_TYPE_BOUND_FUNCTION = 6, /**< Function objects (15.3), created through 15.3.4.5 routine */
ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION = 7, /**< External (host) function object */
/* Types between 13-15 cannot have a built-in flag. See ecma_lexical_environment_type_t. */
ECMA_OBJECT_TYPE__MAX /**< maximum value */
@@ -78,40 +78,14 @@ ecma_builtin_array_iterator_prototype_object_next (ecma_value_t this_val) /**< t
ecma_object_t *array_object_p = ecma_get_object_from_value (iterated_value);
uint32_t length;
/* 8 - 9. */
#if ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY)
if (ecma_is_typedarray (ecma_make_object_value (array_object_p)))
uint32_t length;
ecma_value_t len_value = ecma_op_object_get_length (array_object_p, &length);
if (ECMA_IS_VALUE_ERROR (len_value))
{
length = ecma_typedarray_get_length (array_object_p);
return len_value;
}
else
{
#endif /* ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) */
ecma_value_t len_value = ecma_op_object_get (array_object_p,
ecma_get_magic_string (LIT_MAGIC_STRING_LENGTH));
if (ECMA_IS_VALUE_ERROR (len_value))
{
return len_value;
}
ecma_number_t length_number;
ecma_value_t length_value = ecma_get_number (len_value, &length_number);
if (ECMA_IS_VALUE_ERROR (length_value))
{
ecma_free_value (len_value);
return length_value;
}
length = ecma_number_to_uint32 (length_number);
ecma_free_value (len_value);
#if ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY)
}
#endif /* ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) */
uint32_t index = ext_obj_p->u.pseudo_array.u1.iterator_index;
@@ -157,12 +131,8 @@ ecma_builtin_array_iterator_prototype_object_next (ecma_value_t this_val) /**< t
return ecma_create_iter_result_object (ecma_make_uint32_value (index), ECMA_VALUE_FALSE);
}
/* 13. */
ecma_string_t *index_string_p = ecma_new_ecma_string_from_uint32 (index);
/* 14. */
ecma_value_t get_value = ecma_op_object_get (array_object_p, index_string_p);
ecma_deref_ecma_string (index_string_p);
ecma_value_t get_value = ecma_op_object_get_by_uint32_index (array_object_p, index);
/* 15. */
if (ECMA_IS_VALUE_ERROR (get_value))
@@ -176,14 +176,13 @@ ecma_builtin_array_prototype_object_to_locale_string (ecma_object_t *obj_p, /**<
}
/* 7-8. */
ecma_value_t first_value = ecma_builtin_helper_get_to_locale_string_at_index (obj_p, 0);
ecma_string_t *first_string_p = ecma_builtin_helper_get_to_locale_string_at_index (obj_p, 0);
if (ECMA_IS_VALUE_ERROR (first_value))
if (JERRY_UNLIKELY (first_string_p == NULL))
{
return first_value;
return ECMA_VALUE_ERROR;
}
ecma_string_t *first_string_p = ecma_get_string_from_value (first_value);
ecma_stringbuilder_t builder = ecma_stringbuilder_create_from (first_string_p);
ecma_deref_ecma_string (first_string_p);
@@ -193,15 +192,14 @@ ecma_builtin_array_prototype_object_to_locale_string (ecma_object_t *obj_p, /**<
/* 4. Implementation-defined: set the separator to a single comma character. */
ecma_stringbuilder_append_byte (&builder, LIT_CHAR_COMMA);
ecma_value_t next_string_value = ecma_builtin_helper_get_to_locale_string_at_index (obj_p, k);
ecma_string_t *next_string_p = ecma_builtin_helper_get_to_locale_string_at_index (obj_p, k);
if (ECMA_IS_VALUE_ERROR (next_string_value))
if (JERRY_UNLIKELY (next_string_p == NULL))
{
ecma_stringbuilder_destroy (&builder);
return next_string_value;
return ECMA_VALUE_ERROR;
}
ecma_string_t *next_string_p = ecma_get_string_from_value (next_string_value);
ecma_stringbuilder_append (&builder, next_string_p);
ecma_deref_ecma_string (next_string_p);
}
@@ -310,11 +308,7 @@ static ecma_string_t *
ecma_op_array_get_to_string_at_index (ecma_object_t *obj_p, /**< this object */
uint32_t index) /**< array index */
{
ecma_string_t *index_string_p = ecma_new_ecma_string_from_uint32 (index);
ecma_value_t index_value = ecma_op_object_get (obj_p, index_string_p);
ecma_deref_ecma_string (index_string_p);
ecma_value_t index_value = ecma_op_object_get_by_uint32_index (obj_p, index);
if (ECMA_IS_VALUE_ERROR (index_value))
{
@@ -422,15 +416,12 @@ ecma_builtin_array_prototype_object_pop (ecma_object_t *obj_p, /**< array object
return ECMA_IS_VALUE_ERROR (set_length_value) ? set_length_value : ECMA_VALUE_UNDEFINED;
}
/* 5.a */
ecma_string_t *index_str_p = ecma_new_ecma_string_from_uint32 (--len);
/* 5.b */
ecma_value_t get_value = ecma_op_object_get (obj_p, index_str_p);
len--;
ecma_value_t get_value = ecma_op_object_get_by_uint32_index (obj_p, len);
if (ECMA_IS_VALUE_ERROR (get_value))
{
ecma_deref_ecma_string (index_str_p);
return get_value;
}
@@ -448,9 +439,7 @@ ecma_builtin_array_prototype_object_pop (ecma_object_t *obj_p, /**< array object
}
/* 5.c */
ecma_value_t del_value = ecma_op_object_delete (obj_p, index_str_p, true);
ecma_deref_ecma_string (index_str_p);
ecma_value_t del_value = ecma_op_object_delete_by_uint32_index (obj_p, len, true);
if (ECMA_IS_VALUE_ERROR (del_value))
{
@@ -684,7 +673,7 @@ ecma_builtin_array_prototype_object_shift (ecma_object_t *obj_p, /**< array obje
}
/* 5. */
ecma_value_t first_value = ecma_op_object_get (obj_p, ecma_get_ecma_string_from_uint32 (0));
ecma_value_t first_value = ecma_op_object_get_by_uint32_index (obj_p, 0);
if (ECMA_IS_VALUE_ERROR (first_value))
{
@@ -2227,7 +2216,8 @@ ecma_builtin_array_prototype_dispatch_routine (uint16_t builtin_routine_id, /**<
}
#endif /* ENABLED (JERRY_ES2015_BUILTIN_ITERATOR) */
ecma_value_t len_value = ecma_op_object_get_by_magic_id (obj_p, LIT_MAGIC_STRING_LENGTH);
uint32_t length;
ecma_value_t len_value = ecma_op_object_get_length (obj_p, &length);
if (ECMA_IS_VALUE_ERROR (len_value))
{
@@ -2235,16 +2225,7 @@ ecma_builtin_array_prototype_dispatch_routine (uint16_t builtin_routine_id, /**<
return len_value;
}
uint32_t length = 0;
ecma_value_t ret_value = ecma_op_to_length (len_value, &length);
if (ECMA_IS_VALUE_ERROR (ret_value))
{
ecma_free_value (len_value);
ecma_deref_object (obj_p);
return ret_value;
}
ecma_value_t ret_value;
ecma_value_t routine_arg_1 = arguments_list_p[0];
ecma_value_t routine_arg_2 = arguments_list_p[1];
@@ -58,19 +58,16 @@ ecma_builtin_array_object_is_array (ecma_value_t this_arg, /**< 'this' argument
ecma_value_t arg) /**< first argument */
{
JERRY_UNUSED (this_arg);
ecma_value_t is_array = ECMA_VALUE_FALSE;
if (ecma_is_value_object (arg))
{
ecma_object_t *obj_p = ecma_get_object_from_value (arg);
if (ecma_object_get_class_name (obj_p) == LIT_MAGIC_STRING_ARRAY_UL)
if (ecma_get_object_type (ecma_get_object_from_value (arg)) == ECMA_OBJECT_TYPE_ARRAY)
{
is_array = ECMA_VALUE_TRUE;
return ECMA_VALUE_TRUE;
}
}
return is_array;
return ECMA_VALUE_FALSE;
} /* ecma_builtin_array_object_is_array */
/**
@@ -112,27 +112,15 @@ ecma_builtin_function_prototype_object_apply (ecma_object_t *func_obj_p, /**< th
ecma_object_t *obj_p = ecma_get_object_from_value (arg2);
/* 4. */
ecma_value_t length_value = ecma_op_object_get_by_magic_id (obj_p, LIT_MAGIC_STRING_LENGTH);
if (ECMA_IS_VALUE_ERROR (length_value))
/* 4-5. */
uint32_t length;
ecma_value_t len_value = ecma_op_object_get_length (obj_p, &length);
if (ECMA_IS_VALUE_ERROR (len_value))
{
return length_value;
return len_value;
}
ecma_number_t length_number;
ecma_value_t get_result = ecma_get_number (length_value, &length_number);
ecma_free_value (length_value);
if (ECMA_IS_VALUE_ERROR (get_result))
{
return get_result;
}
JERRY_ASSERT (ecma_is_value_empty (get_result));
/* 5. */
const uint32_t length = ecma_number_to_uint32 (length_number);
if (length >= ECMA_FUNCTION_APPLY_ARGUMENT_COUNT_LIMIT)
{
return ecma_raise_range_error (ECMA_ERR_MSG ("Too many arguments declared for Function.apply()."));
@@ -146,9 +134,7 @@ ecma_builtin_function_prototype_object_apply (ecma_object_t *func_obj_p, /**< th
/* 7. */
for (index = 0; index < length; index++)
{
ecma_string_t *curr_idx_str_p = ecma_new_ecma_string_from_uint32 (index);
ecma_value_t get_value = ecma_op_object_get (obj_p, curr_idx_str_p);
ecma_deref_ecma_string (curr_idx_str_p);
ecma_value_t get_value = ecma_op_object_get_by_uint32_index (obj_p, index);
if (ECMA_IS_VALUE_ERROR (get_value))
{
@@ -201,80 +201,67 @@ ecma_builtin_helper_object_to_string (const ecma_value_t this_arg) /**< this arg
* @return ecma value
* Returned value must be freed with ecma_free_value.
*/
ecma_value_t
ecma_string_t *
ecma_builtin_helper_get_to_locale_string_at_index (ecma_object_t *obj_p, /**< this object */
uint32_t index) /**< array index */
{
ecma_value_t ret_value = ECMA_VALUE_EMPTY;
ecma_string_t *index_string_p = ecma_new_ecma_string_from_uint32 (index);
ecma_value_t index_value = ecma_op_object_get (obj_p, index_string_p);
ecma_deref_ecma_string (index_string_p);
ecma_value_t index_value = ecma_op_object_get_by_uint32_index (obj_p, index);
if (ECMA_IS_VALUE_ERROR (index_value))
{
return index_value;
return NULL;
}
if (ecma_is_value_undefined (index_value) || ecma_is_value_null (index_value))
{
ecma_free_value (index_value);
return ecma_make_magic_string_value (LIT_MAGIC_STRING__EMPTY);
return ecma_get_magic_string (LIT_MAGIC_STRING__EMPTY);
}
ecma_value_t index_obj_value = ecma_op_to_object (index_value);
ecma_free_value (index_value);
if (ECMA_IS_VALUE_ERROR (index_obj_value))
{
return index_obj_value;
ecma_free_value (index_value);
return NULL;
}
ecma_string_t *ret_string_p = NULL;
ecma_object_t *index_obj_p = ecma_get_object_from_value (index_obj_value);
ecma_value_t to_locale_value = ecma_op_object_get_by_magic_id (index_obj_p, LIT_MAGIC_STRING_TO_LOCALE_STRING_UL);
if (ECMA_IS_VALUE_ERROR (to_locale_value))
{
ecma_deref_object (index_obj_p);
return to_locale_value;
goto cleanup;
}
if (ecma_op_is_callable (to_locale_value))
{
ecma_object_t *locale_func_obj_p = ecma_get_object_from_value (to_locale_value);
ecma_value_t call_value = ecma_op_function_call (locale_func_obj_p,
ecma_make_object_value (index_obj_p),
NULL,
0);
ecma_deref_object (locale_func_obj_p);
ecma_deref_object (index_obj_p);
if (ECMA_IS_VALUE_ERROR (call_value))
{
return call_value;
}
ecma_string_t *call_str_p = ecma_op_to_string (call_value);
ecma_free_value (call_value);
if (JERRY_UNLIKELY (call_str_p == NULL))
{
return ECMA_VALUE_ERROR;
}
ret_value = ecma_make_string_value (call_str_p);
}
else
if (!ecma_op_is_callable (to_locale_value))
{
ecma_free_value (to_locale_value);
ecma_deref_object (index_obj_p);
ret_value = ecma_raise_type_error (ECMA_ERR_MSG ("'toLocaleString' is missing or not a function."));
ecma_raise_type_error (ECMA_ERR_MSG ("'toLocaleString' is missing or not a function."));
goto cleanup;
}
return ret_value;
ecma_object_t *locale_func_obj_p = ecma_get_object_from_value (to_locale_value);
ecma_value_t call_value = ecma_op_function_call (locale_func_obj_p,
index_obj_value,
NULL,
0);
ecma_deref_object (locale_func_obj_p);
if (ECMA_IS_VALUE_ERROR (call_value))
{
goto cleanup;
}
ret_string_p = ecma_op_to_string (call_value);
ecma_free_value (call_value);
cleanup:
ecma_deref_object (index_obj_p);
ecma_free_value (index_value);
return ret_string_p;
} /* ecma_builtin_helper_get_to_locale_string_at_index */
@@ -423,80 +410,61 @@ ecma_builtin_helper_array_index_normalize (ecma_number_t index, /**< index */
* Returned value must be freed with ecma_free_value.
*/
ecma_value_t
ecma_builtin_helper_array_concat_value (ecma_object_t *obj_p, /**< array */
ecma_builtin_helper_array_concat_value (ecma_object_t *array_obj_p, /**< array */
uint32_t *length_p, /**< [in,out] array's length */
ecma_value_t value) /**< value to concat */
{
ecma_value_t ret_value = ECMA_VALUE_EMPTY;
/* 5.b */
if (ecma_is_value_object (value)
&& (ecma_object_get_class_name (ecma_get_object_from_value (value)) == LIT_MAGIC_STRING_ARRAY_UL))
if (ecma_is_value_object (value))
{
/* 5.b.ii */
ECMA_TRY_CATCH (arg_len_value,
ecma_op_object_get_by_magic_id (ecma_get_object_from_value (value),
LIT_MAGIC_STRING_LENGTH),
ret_value);
ECMA_OP_TO_NUMBER_TRY_CATCH (arg_len_number, arg_len_value, ret_value);
ecma_object_t *obj_p = ecma_get_object_from_value (value);
uint32_t arg_len = ecma_number_to_uint32 (arg_len_number);
/* 5.b.iii */
for (uint32_t array_index = 0;
array_index < arg_len && ecma_is_value_empty (ret_value);
array_index++)
if (ecma_get_object_type (obj_p) == ECMA_OBJECT_TYPE_ARRAY)
{
ecma_string_t *array_index_string_p = ecma_new_ecma_string_from_uint32 (array_index);
/* 5.b.ii */
uint32_t arg_len = ecma_array_get_length (obj_p);
/* 5.b.iii.2 */
ECMA_TRY_CATCH (get_value,
ecma_op_object_find (ecma_get_object_from_value (value),
array_index_string_p),
ret_value);
if (ecma_is_value_found (get_value))
/* 5.b.iii */
for (uint32_t array_index = 0; array_index < arg_len; array_index++)
{
/* 5.b.iii.3.a */
ecma_string_t *new_array_index_string_p = ecma_new_ecma_string_from_uint32 (*length_p + array_index);
/* 5.b.iii.2 */
ecma_value_t get_value = ecma_op_object_find_by_uint32_index (obj_p, array_index);
if (ECMA_IS_VALUE_ERROR (get_value))
{
return get_value;
}
if (!ecma_is_value_found (get_value))
{
continue;
}
/* 5.b.iii.3.b */
/* This will always be a simple value since 'is_throw' is false, so no need to free. */
ecma_value_t put_comp = ecma_builtin_helper_def_prop (obj_p,
new_array_index_string_p,
get_value,
ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE);
ecma_value_t put_comp = ecma_builtin_helper_def_prop_by_index (array_obj_p,
*length_p + array_index,
get_value,
ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE);
JERRY_ASSERT (ecma_is_value_true (put_comp));
ecma_deref_ecma_string (new_array_index_string_p);
ecma_free_value (get_value);
}
ECMA_FINALIZE (get_value);
ecma_deref_ecma_string (array_index_string_p);
*length_p += arg_len;
return ECMA_VALUE_EMPTY;
}
*length_p += arg_len;
ECMA_OP_TO_NUMBER_FINALIZE (arg_len_number);
ECMA_FINALIZE (arg_len_value);
}
else
{
ecma_string_t *new_array_index_string_p = ecma_new_ecma_string_from_uint32 ((*length_p)++);
/* 5.c.i */
/* This will always be a simple value since 'is_throw' is false, so no need to free. */
ecma_value_t put_comp = ecma_builtin_helper_def_prop (obj_p,
new_array_index_string_p,
value,
ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE);
JERRY_ASSERT (ecma_is_value_true (put_comp));
ecma_deref_ecma_string (new_array_index_string_p);
}
return ret_value;
/* 5.c.i */
/* This will always be a simple value since 'is_throw' is false, so no need to free. */
ecma_value_t put_comp = ecma_builtin_helper_def_prop_by_index (array_obj_p,
(*length_p)++,
value,
ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE);
JERRY_ASSERT (ecma_is_value_true (put_comp));
return ECMA_VALUE_EMPTY;
} /* ecma_builtin_helper_array_concat_value */
/**
@@ -41,7 +41,7 @@ typedef enum
ecma_value_t
ecma_builtin_helper_object_to_string (const ecma_value_t this_arg);
ecma_value_t
ecma_string_t *
ecma_builtin_helper_get_to_locale_string_at_index (ecma_object_t *obj_p, uint32_t index);
ecma_value_t
ecma_builtin_helper_object_get_properties (ecma_object_t *obj_p, uint32_t opts);
@@ -571,13 +571,12 @@ ecma_builtin_json_parse_value (ecma_json_token_t *token_p) /**< token argument *
break;
}
ecma_string_t *index_str_p = ecma_new_ecma_string_from_uint32 (length);
ecma_value_t completion = ecma_builtin_helper_def_prop (array_p,
index_str_p,
value,
ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE);
ecma_value_t completion;
completion = ecma_builtin_helper_def_prop_by_index (array_p,
length,
value,
ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE);
JERRY_ASSERT (ecma_is_value_true (completion));
ecma_deref_ecma_string (index_str_p);
ecma_free_value (value);
ecma_builtin_json_parse_next_token (token_p, false);
@@ -1255,11 +1254,10 @@ ecma_builtin_json_serialize_property (ecma_json_stringify_context_t *context_p,
if (ecma_is_value_object (value) && !ecma_op_is_callable (value))
{
ecma_object_t *obj_p = ecma_get_object_from_value (value);
lit_magic_string_id_t class_name = ecma_object_get_class_name (obj_p);
ecma_value_t ret_value;
/* 10.a */
if (class_name == LIT_MAGIC_STRING_ARRAY_UL)
if (ecma_get_object_type (obj_p) == ECMA_OBJECT_TYPE_ARRAY)
{
ret_value = ecma_builtin_json_serialize_array (context_p, obj_p);
}
@@ -1373,7 +1371,7 @@ ecma_builtin_json_stringify (ecma_value_t this_arg, /**< 'this' argument */
context.replacer_function_p = obj_p;
}
/* 4.b */
else if (ecma_object_get_class_name (obj_p) == LIT_MAGIC_STRING_ARRAY_UL)
else if (ecma_get_object_type (obj_p) == ECMA_OBJECT_TYPE_ARRAY)
{
ecma_extended_object_t *array_object_p = (ecma_extended_object_t *) obj_p;
uint32_t array_length = array_object_p->u.array.length;
@@ -1382,9 +1380,7 @@ ecma_builtin_json_stringify (ecma_value_t this_arg, /**< 'this' argument */
/* 4.b.iii.5 */
while (index < array_length)
{
ecma_string_t *index_str_p = ecma_new_ecma_string_from_uint32 (index);
ecma_value_t value = ecma_op_object_get (obj_p, index_str_p);
ecma_deref_ecma_string (index_str_p);
ecma_value_t value = ecma_op_object_get_by_uint32_index (obj_p, index);
if (ECMA_IS_VALUE_ERROR (value))
{
@@ -1409,20 +1405,24 @@ ecma_builtin_json_stringify (ecma_value_t this_arg, /**< 'this' argument */
item = ecma_make_string_value (number_str_p);
}
/* 4.b.iii.5.f */
else if (ecma_is_value_object (value)
&& (ecma_object_get_class_name (ecma_get_object_from_value (value)) == LIT_MAGIC_STRING_NUMBER_UL
|| ecma_object_get_class_name (ecma_get_object_from_value (value)) == LIT_MAGIC_STRING_STRING_UL))
else if (ecma_is_value_object (value))
{
ecma_string_t *str_p = ecma_op_to_string (value);
ecma_object_t *value_obj_p = ecma_get_object_from_value (value);
lit_magic_string_id_t class_id = ecma_object_get_class_name (value_obj_p);
if (JERRY_UNLIKELY (str_p == NULL))
if (class_id == LIT_MAGIC_STRING_NUMBER_UL || class_id == LIT_MAGIC_STRING_STRING_UL)
{
ecma_collection_free (context.property_list_p);
ecma_free_value (value);
return ECMA_VALUE_ERROR;
}
ecma_string_t *str_p = ecma_op_to_string (value);
item = ecma_make_string_value (str_p);
if (JERRY_UNLIKELY (str_p == NULL))
{
ecma_collection_free (context.property_list_p);
ecma_free_value (value);
return ECMA_VALUE_ERROR;
}
item = ecma_make_string_value (str_p);
}
}
ecma_free_value (value);
@@ -228,9 +228,7 @@ ecma_builtin_promise_do_race (ecma_value_t array, /**< the array for race */
}
/* e. */
ecma_string_t *index_to_str_p = ecma_new_ecma_string_from_uint32 (index);
ecma_value_t array_item = ecma_op_object_get (array_p, index_to_str_p);
ecma_deref_ecma_string (index_to_str_p);
ecma_value_t array_item = ecma_op_object_get_by_uint32_index (array_p, index);
/* f. */
if (ECMA_IS_VALUE_ERROR (array_item))
@@ -359,13 +357,11 @@ ecma_builtin_promise_all_handler (const ecma_value_t function, /**< the function
JERRY_ASSERT (ecma_is_value_integer_number (index_val));
/* 8. */
ecma_string_t *index_to_str_p = ecma_new_ecma_string_from_uint32 ((uint32_t) ecma_get_integer_from_value (index_val));
ecma_op_object_put_by_uint32_index (ecma_get_object_from_value (value_array),
(uint32_t) ecma_get_integer_from_value (index_val),
argv[0],
false);
ecma_op_object_put (ecma_get_object_from_value (value_array),
index_to_str_p,
argv[0],
false);
ecma_deref_ecma_string (index_to_str_p);
/* 9-10. */
if (ecma_builtin_promise_remaining_inc_or_dec (remaining, false) == 0)
@@ -26,7 +26,6 @@
#include "ecma-iterator-object.h"
#include "ecma-objects.h"
#include "ecma-string-object.h"
#include "ecma-try-catch-macro.h"
#include "jcontext.h"
#include "jrt.h"
#include "jrt-libc-includes.h"
@@ -284,28 +283,24 @@ static ecma_value_t
ecma_builtin_string_prepare_search (ecma_value_t regexp_arg, /**< regex argument */
ecma_value_t *regexp_value) /**< [out] ptr to store the regexp object */
{
ecma_value_t ret_value = ECMA_VALUE_EMPTY;
/* 3. */
if (ecma_is_value_object (regexp_arg)
&& ecma_object_class_is (ecma_get_object_from_value (regexp_arg), LIT_MAGIC_STRING_REGEXP_UL))
{
*regexp_value = ecma_copy_value (regexp_arg);
return ECMA_VALUE_EMPTY;
}
else
/* 4. */
ecma_value_t regexp_arguments[1] = { regexp_arg };
ecma_value_t new_regexp_value = ecma_builtin_regexp_dispatch_construct (regexp_arguments, 1);
if (!ECMA_IS_VALUE_ERROR (new_regexp_value))
{
/* 4. */
ecma_value_t regexp_arguments[1] = { regexp_arg };
ECMA_TRY_CATCH (new_regexp_value,
ecma_builtin_regexp_dispatch_construct (regexp_arguments, 1),
ret_value);
*regexp_value = ecma_copy_value (new_regexp_value);
ECMA_FINALIZE (new_regexp_value);
*regexp_value = new_regexp_value;
}
return ret_value;
return new_regexp_value;
} /* ecma_builtin_string_prepare_search */
/**
@@ -390,8 +385,10 @@ ecma_builtin_string_prototype_object_match (ecma_value_t this_to_string_value, /
/* 8.e. */
bool last_match = true;
ret_value = ECMA_VALUE_ERROR;
/* 8.f. */
while (last_match && ecma_is_value_empty (ret_value))
while (last_match)
{
/* 8.f.i. */
ecma_value_t exec_value = ecma_regexp_exec_helper (regexp_value, this_to_string_value, false);
@@ -408,13 +405,20 @@ ecma_builtin_string_prototype_object_match (ecma_value_t this_to_string_value, /
}
/* 8.f.iii. */
ECMA_TRY_CATCH (this_index_value,
ecma_op_object_get_by_magic_id (regexp_obj_p, LIT_MAGIC_STRING_LASTINDEX_UL),
ret_value);
ecma_value_t this_index_value = ecma_op_object_get_by_magic_id (regexp_obj_p, LIT_MAGIC_STRING_LASTINDEX_UL);
ECMA_TRY_CATCH (this_index_number,
ecma_op_to_number (this_index_value),
ret_value);
if (ECMA_IS_VALUE_ERROR (this_index_value))
{
goto cleanup;
}
ecma_value_t this_index_number = ecma_op_to_number (this_index_value);
if (ECMA_IS_VALUE_ERROR (this_index_value))
{
ecma_free_value (this_index_value);
goto cleanup;
}
ecma_number_t this_index = ecma_get_number_from_value (this_index_number);
@@ -422,17 +426,19 @@ ecma_builtin_string_prototype_object_match (ecma_value_t this_to_string_value, /
if (this_index == previous_last_index)
{
/* 8.f.iii.2.a. */
ECMA_TRY_CATCH (index_put_value,
ecma_op_object_put (regexp_obj_p,
ecma_get_magic_string (LIT_MAGIC_STRING_LASTINDEX_UL),
ecma_make_number_value (this_index + 1),
true),
ret_value);
ecma_value_t index_put_value = ecma_op_object_put (regexp_obj_p,
ecma_get_magic_string (LIT_MAGIC_STRING_LASTINDEX_UL),
ecma_make_number_value (this_index + 1),
true);
if (ECMA_IS_VALUE_ERROR (index_put_value))
{
ecma_free_value (this_index_value);
ecma_free_number (this_index_number);
goto cleanup;
}
/* 8.f.iii.2.b. */
previous_last_index = this_index + 1;
ECMA_FINALIZE (index_put_value);
}
else
{
@@ -440,55 +446,44 @@ ecma_builtin_string_prototype_object_match (ecma_value_t this_to_string_value, /
previous_last_index = this_index;
}
if (ecma_is_value_empty (ret_value))
{
/* 8.f.iii.4. */
JERRY_ASSERT (ecma_is_value_object (exec_value));
ecma_object_t *exec_obj_p = ecma_get_object_from_value (exec_value);
/* 8.f.iii.4. */
JERRY_ASSERT (ecma_is_value_object (exec_value));
ecma_object_t *exec_obj_p = ecma_get_object_from_value (exec_value);
ECMA_TRY_CATCH (match_string_value,
ecma_op_object_get (exec_obj_p, index_zero_string_p),
ret_value);
ecma_value_t match_string_value = ecma_op_object_get (exec_obj_p, index_zero_string_p);
JERRY_ASSERT (!ECMA_IS_VALUE_ERROR (match_string_value));
ecma_string_t *current_index_str_p = ecma_new_ecma_string_from_uint32 (n);
/* 8.f.iii.5. */
ecma_value_t completion;
completion = ecma_builtin_helper_def_prop_by_index (new_array_obj_p,
n,
match_string_value,
ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE);
/* 8.f.iii.5. */
ecma_value_t completion = ecma_builtin_helper_def_prop (new_array_obj_p,
current_index_str_p,
match_string_value,
ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE);
JERRY_ASSERT (ecma_is_value_true (completion));
/* 8.f.iii.6. */
n++;
JERRY_ASSERT (ecma_is_value_true (completion));
ecma_free_value (match_string_value);
ecma_free_value (this_index_value);
ecma_free_number (this_index_number);
ecma_deref_ecma_string (current_index_str_p);
/* 8.f.iii.6. */
n++;
ECMA_FINALIZE (match_string_value);
}
ECMA_FINALIZE (this_index_number);
ECMA_FINALIZE (this_index_value);
ecma_free_value (exec_value);
ecma_deref_object (exec_obj_p);
}
if (ecma_is_value_empty (ret_value))
if (n == 0)
{
if (n == 0)
{
/* 8.g. */
ret_value = ECMA_VALUE_NULL;
}
else
{
/* 8.h. */
ret_value = ecma_copy_value (new_array_value);
}
/* 8.g. */
ret_value = ECMA_VALUE_NULL;
}
else
{
/* 8.h. */
ecma_ref_object (new_array_obj_p);
ret_value = new_array_value;
}
cleanup:
ecma_deref_object (new_array_obj_p);
ecma_deref_object (regexp_obj_p);
@@ -590,7 +585,7 @@ ecma_builtin_string_prototype_object_replace_match (ecma_builtin_replace_search_
}
JERRY_ASSERT (ecma_is_value_number (index_value));
ecma_value_t result_string_value = ecma_op_object_get (match_object_p, ecma_get_ecma_string_from_uint32 (0));
ecma_value_t result_string_value = ecma_op_object_get_by_uint32_index (match_object_p, 0);
if (ECMA_IS_VALUE_ERROR (result_string_value))
{
@@ -650,29 +645,16 @@ ecma_builtin_string_prototype_object_replace_get_string (ecma_builtin_replace_se
* context */
ecma_value_t match_value) /**< returned match value */
{
ecma_value_t ret_value = ECMA_VALUE_EMPTY;
ecma_object_t *match_object_p = ecma_get_object_from_value (match_value);
JERRY_ASSERT (ecma_get_object_type (match_object_p) == ECMA_OBJECT_TYPE_ARRAY);
ecma_value_t match_length_value = ecma_op_object_get_by_magic_id (match_object_p, LIT_MAGIC_STRING_LENGTH);
ecma_length_t match_length = ecma_array_get_length (match_object_p);
if (ECMA_IS_VALUE_ERROR (match_length_value))
{
return match_length_value;
}
JERRY_ASSERT (ecma_is_value_number (match_length_value));
ecma_number_t match_length_number = ecma_get_number_from_value (match_length_value);
ecma_length_t match_length = (ecma_length_t) (match_length_number);
ecma_free_number (match_length_value);
JERRY_ASSERT ((ecma_length_t) ecma_number_to_uint32 (match_length_number) == match_length);
JERRY_ASSERT (match_length >= 1);
if (context_p->is_replace_callable)
{
ret_value = ECMA_VALUE_ERROR;
ecma_value_t ret_value = ECMA_VALUE_ERROR;
JMEM_DEFINE_LOCAL_ARRAY (arguments_list,
match_length + 2,
ecma_value_t);
@@ -681,11 +663,9 @@ ecma_builtin_string_prototype_object_replace_get_string (ecma_builtin_replace_se
* uninitalized elements must not be freed. */
ecma_length_t values_copied = 0;
for (ecma_length_t i = 0; i < match_length; i++)
for (ecma_length_t i = 0; i < match_length ;i++)
{
ecma_string_t *index_p = ecma_new_ecma_string_from_uint32 (i);
ecma_value_t current_value = ecma_op_object_get (match_object_p, index_p);
ecma_deref_ecma_string (index_p);
ecma_value_t current_value = ecma_op_object_get_by_uint32_index (match_object_p, i);
if (ECMA_IS_VALUE_ERROR (current_value))
{
@@ -715,7 +695,7 @@ ecma_builtin_string_prototype_object_replace_get_string (ecma_builtin_replace_se
ecma_string_t *to_string_p = ecma_op_to_string (result_value);
ecma_free_value (result_value);
if (JERRY_UNLIKELY (to_string_p != NULL))
if (JERRY_LIKELY (to_string_p != NULL))
{
ret_value = ecma_make_string_value (to_string_p);
}
@@ -727,203 +707,192 @@ cleanup:
}
JMEM_FINALIZE_LOCAL_ARRAY (arguments_list);
return ret_value;
}
else
/* Although the ECMA standard does not specify how $nn (n is a decimal
* number) captures should be replaced if nn is greater than the maximum
* capture index, we follow the test-262 expected behaviour:
*
* if maximum capture index is < 10
* we replace only those $n and $0n captures, where n < maximum capture index
* otherwise
* we replace only those $nn captures, where nn < maximum capture index
*
* other $n $nn sequences left unchanged
*
* example: "<xy>".replace(/(x)y/, "$1,$2,$01,$12") === "<x,$2,x,x2>"
*/
ecma_string_t *result_string_p = ecma_get_magic_string (LIT_MAGIC_STRING__EMPTY);
ecma_length_t previous_start = 0;
ecma_length_t current_position = 0;
lit_utf8_byte_t *replace_str_curr_p = context_p->replace_str_curr_p;
lit_utf8_byte_t *replace_str_end_p = replace_str_curr_p + ecma_string_get_size (context_p->replace_string_p);
while (replace_str_curr_p < replace_str_end_p)
{
/* Although the ECMA standard does not specify how $nn (n is a decimal
* number) captures should be replaced if nn is greater than the maximum
* capture index, we follow the test-262 expected behaviour:
*
* if maximum capture index is < 10
* we replace only those $n and $0n captures, where n < maximum capture index
* otherwise
* we replace only those $nn captures, where nn < maximum capture index
*
* other $n $nn sequences left unchanged
*
* example: "<xy>".replace(/(x)y/, "$1,$2,$01,$12") === "<x,$2,x,x2>"
*/
ecma_char_t action = LIT_CHAR_NULL;
ecma_string_t *result_string_p = ecma_get_magic_string (LIT_MAGIC_STRING__EMPTY);
ecma_length_t previous_start = 0;
ecma_length_t current_position = 0;
lit_utf8_byte_t *replace_str_curr_p = context_p->replace_str_curr_p;
lit_utf8_byte_t *replace_str_end_p = replace_str_curr_p + ecma_string_get_size (context_p->replace_string_p);
while (replace_str_curr_p < replace_str_end_p)
if (*replace_str_curr_p != LIT_CHAR_DOLLAR_SIGN)
{
ecma_char_t action = LIT_CHAR_NULL;
if (*replace_str_curr_p != LIT_CHAR_DOLLAR_SIGN)
/* if not a continuation byte */
if ((*replace_str_curr_p & LIT_UTF8_EXTRA_BYTE_MASK) != LIT_UTF8_EXTRA_BYTE_MARKER)
{
/* if not a continuation byte */
if ((*replace_str_curr_p & LIT_UTF8_EXTRA_BYTE_MASK) != LIT_UTF8_EXTRA_BYTE_MARKER)
{
current_position++;
}
replace_str_curr_p++;
continue;
current_position++;
}
replace_str_curr_p++;
continue;
}
if (replace_str_curr_p < replace_str_end_p)
replace_str_curr_p++;
if (replace_str_curr_p < replace_str_end_p)
{
action = *replace_str_curr_p;
if (action == LIT_CHAR_DOLLAR_SIGN)
{
action = *replace_str_curr_p;
current_position++;
}
else if (action >= LIT_CHAR_0 && action <= LIT_CHAR_9)
{
uint32_t index = 0;
if (action == LIT_CHAR_DOLLAR_SIGN)
{
current_position++;
}
else if (action >= LIT_CHAR_0 && action <= LIT_CHAR_9)
{
uint32_t index = 0;
index = (uint32_t) (action - LIT_CHAR_0);
index = (uint32_t) (action - LIT_CHAR_0);
if (index >= match_length)
{
action = LIT_CHAR_NULL;
}
else if (index == 0 || match_length > 10)
{
replace_str_curr_p++;
if (replace_str_curr_p < replace_str_end_p)
{
ecma_char_t next_character = *replace_str_curr_p;
if (next_character >= LIT_CHAR_0 && next_character <= LIT_CHAR_9)
{
uint32_t full_index = index * 10 + (uint32_t) (next_character - LIT_CHAR_0);
if (full_index > 0 && full_index < match_length)
{
index = match_length;
}
}
}
replace_str_curr_p--;
if (index == 0)
{
action = LIT_CHAR_NULL;
}
}
}
else if (action != LIT_CHAR_AMPERSAND
&& action != LIT_CHAR_GRAVE_ACCENT
&& action != LIT_CHAR_SINGLE_QUOTE)
if (index >= match_length)
{
action = LIT_CHAR_NULL;
}
}
if (action != LIT_CHAR_NULL)
{
result_string_p = ecma_builtin_string_prototype_object_replace_append_substr (result_string_p,
context_p->replace_string_p,
previous_start,
current_position);
replace_str_curr_p++;
current_position++;
if (action == LIT_CHAR_DOLLAR_SIGN)
else if (index == 0 || match_length > 10)
{
current_position--;
}
else if (action == LIT_CHAR_GRAVE_ACCENT)
{
ecma_string_t *input_string_p = ecma_get_string_from_value (context_p->input_string);
result_string_p = ecma_builtin_string_prototype_object_replace_append_substr (result_string_p,
input_string_p,
0,
context_p->match_start);
}
else if (action == LIT_CHAR_SINGLE_QUOTE)
{
ecma_string_t *input_string_p = ecma_get_string_from_value (context_p->input_string);
result_string_p = ecma_builtin_string_prototype_object_replace_append_substr (result_string_p,
input_string_p,
context_p->match_end,
context_p->input_length);
}
else
{
/* Everything else is submatch reading. */
uint32_t index = 0;
replace_str_curr_p++;
JERRY_ASSERT (action == LIT_CHAR_AMPERSAND || (action >= LIT_CHAR_0 && action <= LIT_CHAR_9));
if (action >= LIT_CHAR_0 && action <= LIT_CHAR_9)
if (replace_str_curr_p < replace_str_end_p)
{
index = (uint32_t) (action - LIT_CHAR_0);
ecma_char_t next_character = *replace_str_curr_p;
if ((match_length > 10 || index == 0)
&& replace_str_curr_p < replace_str_end_p)
if (next_character >= LIT_CHAR_0 && next_character <= LIT_CHAR_9)
{
action = *replace_str_curr_p;
if (action >= LIT_CHAR_0 && action <= LIT_CHAR_9)
uint32_t full_index = index * 10 + (uint32_t) (next_character - LIT_CHAR_0);
if (full_index > 0 && full_index < match_length)
{
uint32_t full_index = index * 10 + (uint32_t) (action - LIT_CHAR_0);
if (full_index < match_length)
{
index = full_index;
replace_str_curr_p++;
current_position++;
}
index = match_length;
}
}
JERRY_ASSERT (index > 0 && index < match_length);
}
ecma_string_t *index_string_p = ecma_new_ecma_string_from_uint32 (index);
replace_str_curr_p--;
ECMA_TRY_CATCH (submatch_value,
ecma_op_object_get (match_object_p, index_string_p),
ret_value);
/* Undefined values are converted to empty string. */
if (!ecma_is_value_undefined (submatch_value))
if (index == 0)
{
JERRY_ASSERT (ecma_is_value_string (submatch_value));
ecma_string_t *submatch_string_p = ecma_get_string_from_value (submatch_value);
result_string_p = ecma_concat_ecma_strings (result_string_p, submatch_string_p);
}
ECMA_FINALIZE (submatch_value);
ecma_deref_ecma_string (index_string_p);
if (!ecma_is_value_empty (ret_value))
{
break;
action = LIT_CHAR_NULL;
}
}
current_position++;
previous_start = current_position;
}
else
else if (action != LIT_CHAR_AMPERSAND
&& action != LIT_CHAR_GRAVE_ACCENT
&& action != LIT_CHAR_SINGLE_QUOTE)
{
current_position++;
action = LIT_CHAR_NULL;
}
}
if (ecma_is_value_empty (ret_value))
if (action != LIT_CHAR_NULL)
{
result_string_p = ecma_builtin_string_prototype_object_replace_append_substr (result_string_p,
context_p->replace_string_p,
previous_start,
current_position);
replace_str_curr_p++;
current_position++;
ret_value = ecma_make_string_value (result_string_p);
if (action == LIT_CHAR_DOLLAR_SIGN)
{
current_position--;
}
else if (action == LIT_CHAR_GRAVE_ACCENT)
{
ecma_string_t *input_string_p = ecma_get_string_from_value (context_p->input_string);
result_string_p = ecma_builtin_string_prototype_object_replace_append_substr (result_string_p,
input_string_p,
0,
context_p->match_start);
}
else if (action == LIT_CHAR_SINGLE_QUOTE)
{
ecma_string_t *input_string_p = ecma_get_string_from_value (context_p->input_string);
result_string_p = ecma_builtin_string_prototype_object_replace_append_substr (result_string_p,
input_string_p,
context_p->match_end,
context_p->input_length);
}
else
{
/* Everything else is submatch reading. */
uint32_t index = 0;
JERRY_ASSERT (action == LIT_CHAR_AMPERSAND || (action >= LIT_CHAR_0 && action <= LIT_CHAR_9));
if (action >= LIT_CHAR_0 && action <= LIT_CHAR_9)
{
index = (uint32_t) (action - LIT_CHAR_0);
if ((match_length > 10 || index == 0)
&& replace_str_curr_p < replace_str_end_p)
{
action = *replace_str_curr_p;
if (action >= LIT_CHAR_0 && action <= LIT_CHAR_9)
{
uint32_t full_index = index * 10 + (uint32_t) (action - LIT_CHAR_0);
if (full_index < match_length)
{
index = full_index;
replace_str_curr_p++;
current_position++;
}
}
}
JERRY_ASSERT (index > 0 && index < match_length);
}
ecma_value_t submatch_value = ecma_op_object_get_by_uint32_index (match_object_p, index);
if (ECMA_IS_VALUE_ERROR (submatch_value))
{
return submatch_value;
}
/* Undefined values are converted to empty string. */
if (!ecma_is_value_undefined (submatch_value))
{
JERRY_ASSERT (ecma_is_value_string (submatch_value));
ecma_string_t *submatch_string_p = ecma_get_string_from_value (submatch_value);
result_string_p = ecma_concat_ecma_strings (result_string_p, submatch_string_p);
ecma_free_value (submatch_value);
}
}
current_position++;
previous_start = current_position;
}
else
{
current_position++;
}
}
return ret_value;
result_string_p = ecma_builtin_string_prototype_object_replace_append_substr (result_string_p,
context_p->replace_string_p,
previous_start,
current_position);
return ecma_make_string_value (result_string_p);
} /* ecma_builtin_string_prototype_object_replace_get_string */
/**
@@ -1078,7 +1047,6 @@ ecma_builtin_string_prototype_object_replace_main (ecma_builtin_replace_search_c
* The String.prototype object's 'replace' routine
*
* The replace algorithm is splitted into several helper functions.
* This allows using ECMA_TRY_CATCH macros and avoiding early returns.
*
* To share data between these helper functions, we created a
* structure called ecma_builtin_replace_search_ctx_t, which
@@ -1189,11 +1157,9 @@ ecma_builtin_string_prototype_object_search (ecma_value_t to_string_value, /**<
ecma_value_t regexp_value = ECMA_VALUE_EMPTY;
ecma_value_t ret_value = ecma_builtin_string_prepare_search (regexp_arg, &regexp_value);
if (ECMA_IS_VALUE_ERROR (ret_value))
if (ECMA_IS_VALUE_ERROR (ecma_builtin_string_prepare_search (regexp_arg, &regexp_value)))
{
return ret_value;
return ECMA_VALUE_ERROR;
}
/* 5. */
@@ -1202,11 +1168,11 @@ ecma_builtin_string_prototype_object_search (ecma_value_t to_string_value, /**<
ecma_value_t match_result = ecma_regexp_exec_helper (regexp_value, to_string_value, true);
ecma_value_t ret_value = ECMA_VALUE_ERROR;
if (ECMA_IS_VALUE_ERROR (match_result))
{
ecma_free_value (regexp_value);
ecma_deref_ecma_string (this_string_p);
return match_result;
goto cleanup;
}
ecma_number_t offset = -1;
@@ -1217,23 +1183,20 @@ ecma_builtin_string_prototype_object_search (ecma_value_t to_string_value, /**<
ecma_object_t *match_object_p = ecma_get_object_from_value (match_result);
ECMA_TRY_CATCH (index_value,
ecma_op_object_get_by_magic_id (match_object_p, LIT_MAGIC_STRING_INDEX),
ret_value);
ecma_value_t index_value = ecma_op_object_get_by_magic_id (match_object_p, LIT_MAGIC_STRING_INDEX);
JERRY_ASSERT (ecma_is_value_number (index_value));
JERRY_ASSERT (!ECMA_IS_VALUE_ERROR (index_value) && ecma_is_value_number (index_value));
offset = ecma_get_number_from_value (index_value);
ECMA_FINALIZE (index_value);
ecma_free_number (index_value);
ecma_free_value (match_result);
}
if (ecma_is_value_empty (ret_value))
{
ret_value = ecma_make_number_value (offset);
}
ret_value = ecma_make_number_value (offset);
ecma_free_value (match_result);
cleanup:
ecma_free_value (regexp_value);
ecma_deref_ecma_string (this_string_p);
@@ -1338,24 +1301,18 @@ ecma_builtin_string_prototype_object_split (ecma_value_t this_to_string_val, /**
return new_array;
}
ecma_value_t ret_value = ECMA_VALUE_EMPTY;
ecma_object_t *new_array_p = ecma_get_object_from_value (new_array);
/* 10. */
if (ecma_is_value_undefined (arg1))
{
ecma_string_t *zero_str_p = ecma_new_ecma_string_from_number (ECMA_NUMBER_ZERO);
ecma_value_t put_comp = ecma_builtin_helper_def_prop (new_array_p,
zero_str_p,
this_to_string_val,
ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE);
ecma_value_t put_comp = ecma_builtin_helper_def_prop_by_index (new_array_p,
0,
this_to_string_val,
ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE);
JERRY_ASSERT (ecma_is_value_true (put_comp));
ecma_deref_ecma_string (zero_str_p);
return new_array;
}
@@ -1386,7 +1343,7 @@ ecma_builtin_string_prototype_object_split (ecma_value_t this_to_string_val, /**
const ecma_string_t *this_to_string_p = ecma_get_string_from_value (this_to_string_val);
/* 11. */
if (ecma_string_is_empty (this_to_string_p) && ecma_is_value_empty (ret_value))
if (ecma_string_is_empty (this_to_string_p))
{
bool should_return = false;
@@ -1423,15 +1380,12 @@ ecma_builtin_string_prototype_object_split (ecma_value_t this_to_string_val, /**
if (!should_return)
{
/* 11.c */
ecma_string_t *zero_str_p = ecma_new_ecma_string_from_number (ECMA_NUMBER_ZERO);
ecma_value_t put_comp = ecma_builtin_helper_def_prop (new_array_p,
zero_str_p,
this_to_string_val,
ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE);
ecma_value_t put_comp = ecma_builtin_helper_def_prop_by_index (new_array_p,
0,
this_to_string_val,
ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE);
JERRY_ASSERT (ecma_is_value_true (put_comp));
ecma_deref_ecma_string (zero_str_p);
}
}
else
@@ -1451,7 +1405,7 @@ ecma_builtin_string_prototype_object_split (ecma_value_t this_to_string_val, /**
/* 6. */
const ecma_length_t string_length = ecma_string_get_length (this_to_string_p);
while (curr_pos < string_length && !should_return && ecma_is_value_empty (ret_value))
while (curr_pos < string_length && !should_return)
{
ecma_value_t match_result = ECMA_VALUE_NULL;
@@ -1562,12 +1516,11 @@ ecma_builtin_string_prototype_object_split (ecma_value_t this_to_string_val, /**
start_pos,
end_pos);
ecma_string_t *array_length_str_p = ecma_new_ecma_string_from_uint32 (new_array_length);
ecma_value_t put_comp = ecma_builtin_helper_def_prop (new_array_p,
array_length_str_p,
ecma_make_string_value (substr_str_p),
ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE);
ecma_value_t put_comp;
put_comp = ecma_builtin_helper_def_prop_by_index (new_array_p,
new_array_length,
ecma_make_string_value (substr_str_p),
ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE);
JERRY_ASSERT (ecma_is_value_true (put_comp));
@@ -1575,7 +1528,7 @@ ecma_builtin_string_prototype_object_split (ecma_value_t this_to_string_val, /**
new_array_length++;
/* 13.c.iii.4 */
if (new_array_length == limit && ecma_is_value_empty (ret_value))
if (new_array_length == limit)
{
should_return = true;
}
@@ -1583,35 +1536,25 @@ ecma_builtin_string_prototype_object_split (ecma_value_t this_to_string_val, /**
/* 13.c.iii.5 */
start_pos = end_pos + match_str_length;
ECMA_TRY_CATCH (array_length_val,
ecma_op_object_get_by_magic_id (match_obj_p, LIT_MAGIC_STRING_LENGTH),
ret_value);
ECMA_OP_TO_NUMBER_TRY_CATCH (array_length_num, array_length_val, ret_value);
/* The first item is the match object, thus we should skip it. */
const uint32_t match_result_array_length = ecma_number_to_uint32 (array_length_num) - 1;
const uint32_t match_result_array_length = ecma_array_get_length (match_obj_p) - 1;
/* 13.c.iii.6 */
uint32_t i = 0;
/* 13.c.iii.7 */
while (i < match_result_array_length && ecma_is_value_empty (ret_value))
while (i < match_result_array_length)
{
/* 13.c.iii.7.a */
i++;
ecma_string_t *idx_str_p = ecma_new_ecma_string_from_uint32 (i);
ecma_string_t *new_array_idx_str_p = ecma_new_ecma_string_from_uint32 (new_array_length);
match_comp_value = ecma_op_object_get (match_obj_p, idx_str_p);
match_comp_value = ecma_op_object_get_by_uint32_index (match_obj_p, i);
JERRY_ASSERT (!ECMA_IS_VALUE_ERROR (match_comp_value));
/* 13.c.iii.7.b */
put_comp = ecma_builtin_helper_def_prop (new_array_p,
new_array_idx_str_p,
match_comp_value,
ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE);
put_comp = ecma_builtin_helper_def_prop_by_index (new_array_p,
new_array_length,
match_comp_value,
ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE);
JERRY_ASSERT (ecma_is_value_true (put_comp));
@@ -1619,22 +1562,17 @@ ecma_builtin_string_prototype_object_split (ecma_value_t this_to_string_val, /**
new_array_length++;
/* 13.c.iii.7.d */
if (new_array_length == limit && ecma_is_value_empty (ret_value))
if (new_array_length == limit)
{
should_return = true;
}
ecma_free_value (match_comp_value);
ecma_deref_ecma_string (new_array_idx_str_p);
ecma_deref_ecma_string (idx_str_p);
}
/* 13.c.iii.8 */
curr_pos = start_pos;
ECMA_OP_TO_NUMBER_FINALIZE (array_length_num);
ECMA_FINALIZE (array_length_val);
ecma_deref_ecma_string (array_length_str_p);
ecma_deref_ecma_string (substr_str_p);
}
@@ -1642,7 +1580,7 @@ ecma_builtin_string_prototype_object_split (ecma_value_t this_to_string_val, /**
}
if (!should_return && !separator_is_empty && ecma_is_value_empty (ret_value))
if (!should_return && !separator_is_empty)
{
/* 14. */
ecma_string_t *substr_str_p;
@@ -1651,32 +1589,20 @@ ecma_builtin_string_prototype_object_split (ecma_value_t this_to_string_val, /**
string_length);
/* 15. */
ecma_string_t *array_length_string_p = ecma_new_ecma_string_from_uint32 (new_array_length);
ecma_value_t put_comp = ecma_builtin_helper_def_prop (new_array_p,
array_length_string_p,
ecma_make_string_value (substr_str_p),
ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE);
ecma_value_t put_comp;
put_comp = ecma_builtin_helper_def_prop_by_index (new_array_p,
new_array_length,
ecma_make_string_value (substr_str_p),
ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE);
JERRY_ASSERT (ecma_is_value_true (put_comp));
ecma_deref_ecma_string (array_length_string_p);
ecma_deref_ecma_string (substr_str_p);
}
}
ecma_free_value (separator);
if (ecma_is_value_empty (ret_value))
{
ret_value = new_array;
}
else
{
ecma_deref_object (new_array_p);
}
return ret_value;
return new_array;
} /* ecma_builtin_string_prototype_object_split */
/**
@@ -225,47 +225,47 @@ ecma_builtin_typedarray_prototype_exec_routine (ecma_value_t this_arg, /**< this
ecma_number_t element_num = typedarray_getter_cb (info.buffer_p + byte_pos);
ecma_value_t get_value = ecma_make_number_value (element_num);
JERRY_ASSERT (ecma_is_value_number (get_value));
ecma_value_t call_args[] = { get_value, current_index, this_arg };
ECMA_TRY_CATCH (call_value, ecma_op_function_call (func_object_p, cb_this_arg, call_args, 3), ret_value);
ecma_value_t call_value = ecma_op_function_call (func_object_p, cb_this_arg, call_args, 3);
ecma_fast_free_value (current_index);
ecma_fast_free_value (get_value);
if (ECMA_IS_VALUE_ERROR (call_value))
{
return call_value;
}
if (mode == TYPEDARRAY_ROUTINE_EVERY)
{
if (!ecma_op_to_boolean (call_value))
{
ret_value = ECMA_VALUE_FALSE;
return ECMA_VALUE_FALSE;
}
}
else if (mode == TYPEDARRAY_ROUTINE_SOME
&& ecma_op_to_boolean (call_value))
{
ret_value = ECMA_VALUE_TRUE;
return ECMA_VALUE_TRUE;
}
byte_pos += info.element_size;
ECMA_FINALIZE (call_value);
ecma_fast_free_value (current_index);
ecma_fast_free_value (get_value);
ecma_free_value (call_value);
}
if (ecma_is_value_empty (ret_value))
if (mode == TYPEDARRAY_ROUTINE_EVERY)
{
if (mode == TYPEDARRAY_ROUTINE_EVERY)
{
ret_value = ECMA_VALUE_TRUE;
}
else if (mode == TYPEDARRAY_ROUTINE_SOME)
{
ret_value = ECMA_VALUE_FALSE;
}
else
{
ret_value = ECMA_VALUE_UNDEFINED;
}
ret_value = ECMA_VALUE_TRUE;
}
else if (mode == TYPEDARRAY_ROUTINE_SOME)
{
ret_value = ECMA_VALUE_FALSE;
}
else
{
ret_value = ECMA_VALUE_UNDEFINED;
}
return ret_value;
@@ -709,7 +709,7 @@ ecma_builtin_typedarray_prototype_filter (ecma_value_t this_arg, /**< this argum
ecma_typedarray_getter_fn_t getter_cb = ecma_get_typedarray_getter_fn (info.id);
ecma_object_t *func_object_p = ecma_get_object_from_value (cb_func_val);
ecma_value_t ret_value = ECMA_VALUE_EMPTY;
ecma_value_t ret_value = ECMA_VALUE_ERROR;
if (info.length == 0)
{
@@ -721,7 +721,7 @@ ecma_builtin_typedarray_prototype_filter (ecma_value_t this_arg, /**< this argum
lit_utf8_byte_t *pass_value_p = pass_value_list_p;
ecma_length_t byte_pos = 0;
for (uint32_t index = 0; index < info.length && ecma_is_value_empty (ret_value); index++)
for (uint32_t index = 0; index < info.length; index++)
{
ecma_value_t current_index = ecma_make_uint32_value (index);
ecma_number_t get_num = getter_cb (info.buffer_p + byte_pos);
@@ -731,7 +731,15 @@ ecma_builtin_typedarray_prototype_filter (ecma_value_t this_arg, /**< this argum
ecma_value_t call_args[] = { get_value, current_index, this_arg };
ECMA_TRY_CATCH (call_value, ecma_op_function_call (func_object_p, cb_this_arg, call_args, 3), ret_value);
ecma_fast_free_value (current_index);
ecma_fast_free_value (get_value);
ecma_value_t call_value = ecma_op_function_call (func_object_p, cb_this_arg, call_args, 3);
if (ECMA_IS_VALUE_ERROR (call_value))
{
goto cleanup;
}
if (ecma_op_to_boolean (call_value))
{
@@ -741,30 +749,25 @@ ecma_builtin_typedarray_prototype_filter (ecma_value_t this_arg, /**< this argum
byte_pos += info.element_size;
ECMA_FINALIZE (call_value);
ecma_fast_free_value (current_index);
ecma_fast_free_value (get_value);
ecma_free_value (call_value);
}
if (ecma_is_value_empty (ret_value))
uint32_t pass_num = (uint32_t) ((pass_value_p - pass_value_list_p) >> info.shift);
ret_value = ecma_op_create_typedarray_with_type_and_length (obj_p, pass_num);
if (!ECMA_IS_VALUE_ERROR (ret_value))
{
uint32_t pass_num = (uint32_t) ((pass_value_p - pass_value_list_p) >> info.shift);
obj_p = ecma_get_object_from_value (ret_value);
ret_value = ecma_op_create_typedarray_with_type_and_length (obj_p, pass_num);
JERRY_ASSERT (ecma_typedarray_get_offset (obj_p) == 0);
if (!ECMA_IS_VALUE_ERROR (ret_value))
{
obj_p = ecma_get_object_from_value (ret_value);
JERRY_ASSERT (ecma_typedarray_get_offset (obj_p) == 0);
memcpy (ecma_typedarray_get_buffer (obj_p),
pass_value_list_p,
(size_t) (pass_value_p - pass_value_list_p));
}
memcpy (ecma_typedarray_get_buffer (obj_p),
pass_value_list_p,
(size_t) (pass_value_p - pass_value_list_p));
}
cleanup:
JMEM_FINALIZE_LOCAL_ARRAY (pass_value_list_p);
return ret_value;
@@ -985,10 +988,8 @@ ecma_builtin_typedarray_prototype_set (ecma_value_t this_arg, /**< this argument
while (k < source_length_uint32 && ecma_is_value_empty (ret_val))
{
ecma_string_t *k_str_p = ecma_new_ecma_string_from_uint32 (k);
ECMA_TRY_CATCH (elem,
ecma_op_object_get (source_obj_p, k_str_p),
ecma_op_object_get_by_uint32_index (source_obj_p, k),
ret_val);
ECMA_OP_TO_NUMBER_TRY_CATCH (elem_num, elem, ret_val);
@@ -998,8 +999,6 @@ ecma_builtin_typedarray_prototype_set (ecma_value_t this_arg, /**< this argument
ECMA_OP_TO_NUMBER_FINALIZE (elem_num);
ECMA_FINALIZE (elem);
ecma_deref_ecma_string (k_str_p);
k++;
target_byte_index += target_info.element_size;
}
@@ -1029,9 +1028,7 @@ static ecma_string_t *
ecma_op_typedarray_get_to_string_at_index (ecma_object_t *obj_p, /**< this object */
uint32_t index) /**< array index */
{
ecma_string_t *index_string_p = ecma_new_ecma_string_from_uint32 (index);
ecma_value_t index_value = ecma_op_object_get (obj_p, index_string_p);
ecma_deref_ecma_string (index_string_p);
ecma_value_t index_value = ecma_op_object_get_by_uint32_index (obj_p, index);
if (ECMA_IS_VALUE_ERROR (index_value))
{
@@ -1088,6 +1088,19 @@ ecma_op_array_object_define_own_property (ecma_object_t *object_p, /**< the arra
return ECMA_VALUE_TRUE;
} /* ecma_op_array_object_define_own_property */
/**
* Get the length of the an array object
*
* @return the array length
*/
extern inline uint32_t JERRY_ATTR_ALWAYS_INLINE
ecma_array_get_length (ecma_object_t *array_p) /**< array object */
{
JERRY_ASSERT (ecma_get_object_type (array_p) == ECMA_OBJECT_TYPE_ARRAY);
return ((ecma_extended_object_t *) array_p)->u.array.length;
} /* ecma_array_get_length */
/**
* List names of a String object's lazy instantiated properties
*
@@ -88,6 +88,8 @@ ecma_value_t
ecma_op_array_object_define_own_property (ecma_object_t *object_p, ecma_string_t *property_name_p,
const ecma_property_descriptor_t *property_desc_p);
uint32_t ecma_array_get_length (ecma_object_t *array_p);
void
ecma_op_array_list_lazy_property_names (ecma_object_t *obj_p, bool separate_enumerable,
ecma_collection_t *main_collection_p,
@@ -129,7 +129,7 @@ ecma_op_container_create (const ecma_value_t *arguments_list_p, /**< arguments l
ecma_object_t *next_object_p = ecma_get_object_from_value (next_value);
ecma_value_t key = ecma_op_object_get (next_object_p, ecma_new_ecma_string_from_uint32 (0));
ecma_value_t key = ecma_op_object_get_by_uint32_index (next_object_p, 0);
if (ECMA_IS_VALUE_ERROR (key))
{
@@ -141,7 +141,7 @@ ecma_op_container_create (const ecma_value_t *arguments_list_p, /**< arguments l
return key;
}
ecma_value_t value = ecma_op_object_get (next_object_p, ecma_new_ecma_string_from_uint32 (1));
ecma_value_t value = ecma_op_object_get_by_uint32_index (next_object_p, 1);
if (ECMA_IS_VALUE_ERROR (value))
{
@@ -50,6 +50,22 @@ ecma_is_normal_or_arrow_function (ecma_object_type_t type) /**< object type */
#endif /* ENABLED (JERRY_ES2015) */
} /* ecma_is_normal_or_arrow_function */
/**
* IsCallable operation.
*
* See also: ECMA-262 v5, 9.11
*
* @return true - if the given object is callable;
* false - otherwise
*/
inline bool JERRY_ATTR_ALWAYS_INLINE
ecma_op_object_is_callable (ecma_object_t *obj_p) /**< ecma object */
{
JERRY_ASSERT (!ecma_is_lexical_environment (obj_p));
return ecma_get_object_type (obj_p) >= ECMA_OBJECT_TYPE_FUNCTION;
} /* ecma_op_object_is_callable */
/**
* IsCallable operation.
*
@@ -61,25 +77,30 @@ ecma_is_normal_or_arrow_function (ecma_object_type_t type) /**< object type */
bool
ecma_op_is_callable (ecma_value_t value) /**< ecma value */
{
if (!ecma_is_value_object (value))
{
return false;
}
return (ecma_is_value_object (value)
&& ecma_op_object_is_callable (ecma_get_object_from_value (value)));
} /* ecma_op_is_callable */
ecma_object_t *obj_p = ecma_get_object_from_value (value);
JERRY_ASSERT (obj_p != NULL);
/**
* Checks whether the given object implements [[Construct]].
*
* @return true - if the given object is constructor;
* false - otherwise
*/
inline bool JERRY_ATTR_ALWAYS_INLINE
ecma_object_is_constructor (ecma_object_t *obj_p) /**< ecma object */
{
JERRY_ASSERT (!ecma_is_lexical_environment (obj_p));
ecma_object_type_t type = ecma_get_object_type (obj_p);
return (type == ECMA_OBJECT_TYPE_FUNCTION
#if ENABLED (JERRY_ES2015)
|| type == ECMA_OBJECT_TYPE_ARROW_FUNCTION
#endif /* ENABLED (JERRY_ES2015) */
|| type == ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION
|| type == ECMA_OBJECT_TYPE_BOUND_FUNCTION);
} /* ecma_op_is_callable */
if (type == ECMA_OBJECT_TYPE_FUNCTION)
{
return (!ecma_get_object_is_builtin (obj_p) || !ecma_builtin_function_is_routine (obj_p));
}
return (type >= ECMA_OBJECT_TYPE_BOUND_FUNCTION);
} /* ecma_object_is_constructor */
/**
* Checks whether the value is Object that implements [[Construct]].
@@ -90,24 +111,8 @@ ecma_op_is_callable (ecma_value_t value) /**< ecma value */
bool
ecma_is_constructor (ecma_value_t value) /**< ecma value */
{
if (!ecma_is_value_object (value))
{
return false;
}
ecma_object_t *obj_p = ecma_get_object_from_value (value);
JERRY_ASSERT (obj_p != NULL);
JERRY_ASSERT (!ecma_is_lexical_environment (obj_p));
if (ecma_get_object_type (obj_p) == ECMA_OBJECT_TYPE_FUNCTION)
{
return (!ecma_get_object_is_builtin (obj_p)
|| !ecma_builtin_function_is_routine (obj_p));
}
return (ecma_get_object_type (obj_p) == ECMA_OBJECT_TYPE_BOUND_FUNCTION
|| ecma_get_object_type (obj_p) == ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION);
return (ecma_is_value_object (value)
&& ecma_object_is_constructor (ecma_get_object_from_value (value)));
} /* ecma_is_constructor */
/**
@@ -29,7 +29,9 @@
bool ecma_is_normal_or_arrow_function (ecma_object_type_t type);
bool ecma_op_is_callable (ecma_value_t value);
bool ecma_op_object_is_callable (ecma_object_t *obj_p);
bool ecma_is_constructor (ecma_value_t value);
bool ecma_object_is_constructor (ecma_object_t *obj_p);
ecma_object_t *
ecma_op_create_function_object (ecma_object_t *scope_p, const ecma_compiled_code_t *bytecode_data_p);
+62 -5
View File
@@ -171,7 +171,7 @@ ecma_op_object_get_own_property (ecma_object_t *object_p, /**< the object */
case ECMA_OBJECT_TYPE_PSEUDO_ARRAY:
{
/* ES2015 9.4.5.1 */
if (ecma_is_typedarray (ecma_make_object_value (object_p)))
if (ecma_object_is_typedarray (object_p))
{
#if ENABLED (JERRY_ES2015)
if (ecma_prop_name_is_symbol (property_name_p))
@@ -540,7 +540,7 @@ ecma_op_object_find_own (ecma_value_t base_value, /**< base value */
}
#if ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY)
/* ES2015 9.4.5.4 */
if (ecma_is_typedarray (ecma_make_object_value (object_p)))
if (ecma_object_is_typedarray (object_p))
{
#if ENABLED (JERRY_ES2015)
if (ecma_prop_name_is_symbol (property_name_p))
@@ -826,6 +826,63 @@ ecma_op_object_get (ecma_object_t *object_p, /**< the object */
return ECMA_VALUE_UNDEFINED;
} /* ecma_op_object_get */
/**
* [[Get]] operation of ecma object specified for uint32_t property index
*
* @return ecma value
* Returned value must be freed with ecma_free_value
*/
ecma_value_t
ecma_op_object_get_by_uint32_index (ecma_object_t *object_p, /**< the object */
uint32_t index) /**< property index */
{
if (JERRY_LIKELY (index <= ECMA_DIRECT_STRING_MAX_IMM))
{
return ecma_op_object_get (object_p, ECMA_CREATE_DIRECT_UINT32_STRING (index));
}
ecma_string_t *index_str_p = ecma_new_non_direct_string_from_uint32 (index);
ecma_value_t ret_value = ecma_op_object_get (object_p, index_str_p);
ecma_deref_ecma_string (index_str_p);
return ret_value;
} /* ecma_op_object_get_by_uint32_index */
/**
* Perform ToLength(O.[[Get]]("length")) operation
*
* The property is converted to uint32 during the operation
*
* @return ECMA_VALUE_ERROR - if there was any error during the operation
* ECMA_VALUE_EMPTY - otherwise
*/
ecma_value_t
ecma_op_object_get_length (ecma_object_t *object_p, /**< the object */
uint32_t *length_p) /**< [out] length value converted to uint32 */
{
if (JERRY_LIKELY (ecma_get_object_type (object_p) == ECMA_OBJECT_TYPE_ARRAY))
{
*length_p = ecma_array_get_length (object_p);
return ECMA_VALUE_EMPTY;
}
#if ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY)
if (ecma_object_is_typedarray (object_p))
{
*length_p = ecma_typedarray_get_length (object_p);
return ECMA_VALUE_EMPTY;
}
#endif /* ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) */
ecma_value_t len_value = ecma_op_object_get_by_magic_id (object_p, LIT_MAGIC_STRING_LENGTH);
ecma_value_t len_number = ecma_op_to_length (len_value, length_p);
ecma_free_value (len_value);
JERRY_ASSERT (ECMA_IS_VALUE_ERROR (len_number) || ecma_is_value_empty (len_number));
return len_number;
} /* ecma_op_object_get_length */
/**
* [[Get]] operation of ecma object where the property name is a magic string
*
@@ -1070,7 +1127,7 @@ ecma_op_object_put (ecma_object_t *object_p, /**< the object */
}
#if ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY)
/* ES2015 9.4.5.5 */
if (ecma_is_typedarray (ecma_make_object_value (object_p)))
if (ecma_object_is_typedarray (object_p))
{
#if ENABLED (JERRY_ES2015)
if (ecma_prop_name_is_symbol (property_name_p))
@@ -1483,7 +1540,7 @@ ecma_op_object_define_own_property (ecma_object_t *obj_p, /**< the object */
#if ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY)
}
/* ES2015 9.4.5.3 */
if (ecma_is_typedarray (ecma_make_object_value (obj_p)))
if (ecma_object_is_typedarray (obj_p))
{
#if ENABLED (JERRY_ES2015)
if (ecma_prop_name_is_symbol (property_name_p))
@@ -1755,7 +1812,7 @@ ecma_op_object_get_property_names (ecma_object_t *obj_p, /**< object */
case ECMA_OBJECT_TYPE_PSEUDO_ARRAY:
{
#if ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY)
if (ecma_is_typedarray (ecma_make_object_value (obj_p)))
if (ecma_object_is_typedarray (obj_p))
{
ecma_op_typedarray_list_lazy_property_names (obj_p, prop_names_p);
}
@@ -36,6 +36,8 @@ ecma_value_t ecma_op_object_find_by_uint32_index (ecma_object_t *object_p, uint3
ecma_value_t ecma_op_object_find_by_number_index (ecma_object_t *object_p, ecma_number_t index);
ecma_value_t ecma_op_object_get_own_data_prop (ecma_object_t *object_p, ecma_string_t *property_name_p);
ecma_value_t ecma_op_object_get (ecma_object_t *object_p, ecma_string_t *property_name_p);
ecma_value_t ecma_op_object_get_length (ecma_object_t *object_p, uint32_t *length_p);
ecma_value_t ecma_op_object_get_by_uint32_index (ecma_object_t *object_p, uint32_t index);
ecma_value_t ecma_op_object_get_by_magic_id (ecma_object_t *object_p, lit_magic_string_id_t property_id);
#if ENABLED (JERRY_ES2015)
ecma_value_t ecma_op_object_get_by_symbol_id (ecma_object_t *object_p, lit_magic_string_id_t property_id);
@@ -466,7 +466,7 @@ ecma_typedarray_helper_get_prototype_id (ecma_typedarray_type_t typedarray_id) /
ecma_typedarray_type_t
ecma_get_typedarray_id (ecma_object_t *obj_p) /**< typedarray object **/
{
JERRY_ASSERT (ecma_is_typedarray (ecma_make_object_value (obj_p)));
JERRY_ASSERT (ecma_object_is_typedarray (obj_p));
ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) obj_p;
@@ -659,8 +659,6 @@ ecma_op_typedarray_from (ecma_value_t items_val, /**< the source array-like obje
uint8_t element_size_shift, /**< the size shift of the element length */
ecma_typedarray_type_t typedarray_id) /**< id of the typedarray */
{
ecma_value_t ret_value = ECMA_VALUE_EMPTY;
/* 3 */
JERRY_ASSERT (ecma_op_is_callable (map_fn_val) || ecma_is_value_undefined (map_fn_val));
@@ -671,20 +669,25 @@ ecma_op_typedarray_from (ecma_value_t items_val, /**< the source array-like obje
}
/* 10 */
ECMA_TRY_CATCH (arraylike_object_val,
ecma_op_to_object (items_val),
ret_value);
ecma_value_t arraylike_object_val = ecma_op_to_object (items_val);
if (ECMA_IS_VALUE_ERROR (arraylike_object_val))
{
return arraylike_object_val;
}
ecma_object_t *arraylike_object_p = ecma_get_object_from_value (arraylike_object_val);
/* 12 */
ECMA_TRY_CATCH (len_value,
ecma_op_object_get_by_magic_id (arraylike_object_p, LIT_MAGIC_STRING_LENGTH),
ret_value);
uint32_t len;
ecma_value_t len_value = ecma_op_object_get_length (arraylike_object_p, &len);
ECMA_OP_TO_NUMBER_TRY_CATCH (len_number, len_value, ret_value);
uint32_t len = ecma_number_to_uint32 (len_number);
ecma_value_t ret_value = ECMA_VALUE_ERROR;
if (ECMA_IS_VALUE_ERROR (len_value))
{
ecma_deref_object (arraylike_object_p);
return len_value;
}
/* 14 */
ecma_value_t new_typedarray = ecma_typedarray_create_object_with_length (len,
@@ -694,91 +697,77 @@ ecma_op_typedarray_from (ecma_value_t items_val, /**< the source array-like obje
if (ECMA_IS_VALUE_ERROR (new_typedarray))
{
ret_value = new_typedarray;
ecma_deref_object (arraylike_object_p);
return new_typedarray;
}
else
ecma_object_t *new_typedarray_p = ecma_get_object_from_value (new_typedarray);
ecma_typedarray_info_t info = ecma_typedarray_get_info (new_typedarray_p);
ecma_typedarray_setter_fn_t setter_cb = ecma_get_typedarray_setter_fn (info.id);
ecma_number_t num_var;
/* 17 */
for (uint32_t index = 0; index < len; index++)
{
ecma_object_t *new_typedarray_p = ecma_get_object_from_value (new_typedarray);
ecma_typedarray_info_t info = ecma_typedarray_get_info (new_typedarray_p);
ecma_typedarray_setter_fn_t setter_cb = ecma_get_typedarray_setter_fn (info.id);
ecma_value_t error = ECMA_VALUE_EMPTY;
ecma_number_t num_var;
/* 17.b */
ecma_value_t current_value = ecma_op_object_find_by_uint32_index (arraylike_object_p, index);
/* 17 */
ecma_value_t current_index;
for (uint32_t index = 0; index < len && ecma_is_value_empty (ret_value); index++)
if (ECMA_IS_VALUE_ERROR (current_value))
{
/* 17.a */
ecma_string_t *index_str_p = ecma_new_ecma_string_from_uint32 (index);
goto cleanup;
}
/* 17.b */
ECMA_TRY_CATCH (current_value, ecma_op_object_find (arraylike_object_p, index_str_p), ret_value);
if (ecma_is_value_found (current_value))
if (ecma_is_value_found (current_value))
{
ecma_value_t mapped_value;
if (func_object_p != NULL)
{
if (func_object_p != NULL)
/* 17.d 17.f */
ecma_value_t current_index = ecma_make_uint32_value (index);
ecma_value_t call_args[] = { current_value, current_index };
ecma_value_t cb_value = ecma_op_function_call (func_object_p, this_val, call_args, 2);
ecma_free_value (current_index);
ecma_free_value (current_value);
if (ECMA_IS_VALUE_ERROR (cb_value))
{
/* 17.d 17.f */
current_index = ecma_make_uint32_value (index);
ecma_value_t call_args[] = { current_value, current_index};
ECMA_TRY_CATCH (mapped_value, ecma_op_function_call (func_object_p, this_val, call_args, 2), ret_value);
error = ecma_get_number (mapped_value, &num_var);
if (ECMA_IS_VALUE_ERROR (error))
{
ret_value = ECMA_VALUE_ERROR;
}
if (index >= info.length)
{
ret_value = ecma_raise_type_error (ECMA_ERR_MSG ("Invalid argument type."));
}
ecma_length_t byte_pos = index << info.shift;
setter_cb (info.buffer_p + byte_pos, num_var);
ECMA_FINALIZE (mapped_value);
goto cleanup;
}
else
{
error = ecma_get_number (current_value, &num_var);
if (ECMA_IS_VALUE_ERROR (error))
{
ret_value = ECMA_VALUE_ERROR;
}
if (index >= info.length)
{
ret_value = ecma_raise_type_error (ECMA_ERR_MSG ("Invalid argument type."));
}
ecma_length_t byte_pos = index << info.shift;
setter_cb (info.buffer_p + byte_pos, num_var);
}
mapped_value = cb_value;
}
else
{
mapped_value = current_value;
}
ECMA_FINALIZE (current_value);
ecma_value_t mapped_number = ecma_get_number (mapped_value, &num_var);
ecma_free_value (mapped_value);
ecma_deref_ecma_string (index_str_p);
}
if (ECMA_IS_VALUE_ERROR (mapped_number))
{
goto cleanup;
}
if (ecma_is_value_empty (ret_value))
{
ret_value = ecma_make_object_value (new_typedarray_p);
}
else
{
ecma_deref_object (new_typedarray_p);
if (index >= info.length)
{
ecma_raise_type_error (ECMA_ERR_MSG ("Invalid argument type."));
goto cleanup;
}
ecma_length_t byte_pos = (index << info.shift);
setter_cb (info.buffer_p + byte_pos, num_var);
}
}
ECMA_OP_TO_NUMBER_FINALIZE (len_number);
ECMA_FINALIZE (len_value);
ECMA_FINALIZE (arraylike_object_val);
ecma_ref_object (new_typedarray_p);
ret_value = ecma_make_object_value (new_typedarray_p);
cleanup:
ecma_deref_object (new_typedarray_p);
ecma_deref_object (arraylike_object_p);
return ret_value;
} /* ecma_op_typedarray_from */
@@ -791,7 +780,7 @@ ecma_op_typedarray_from (ecma_value_t items_val, /**< the source array-like obje
inline ecma_object_t * JERRY_ATTR_ALWAYS_INLINE
ecma_typedarray_get_arraybuffer (ecma_object_t *typedarray_p) /**< the pointer to the typedarray object */
{
JERRY_ASSERT (ecma_is_typedarray (ecma_make_object_value (typedarray_p)));
JERRY_ASSERT (ecma_object_is_typedarray (typedarray_p));
ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) typedarray_p;
@@ -806,7 +795,7 @@ ecma_typedarray_get_arraybuffer (ecma_object_t *typedarray_p) /**< the pointer t
uint8_t
ecma_typedarray_get_element_size_shift (ecma_object_t *typedarray_p) /**< the pointer to the typedarray object */
{
JERRY_ASSERT (ecma_is_typedarray (ecma_make_object_value (typedarray_p)));
JERRY_ASSERT (ecma_object_is_typedarray (typedarray_p));
return ecma_typedarray_helper_get_shift_size (ecma_get_typedarray_id (typedarray_p));
} /* ecma_typedarray_get_element_size_shift */
@@ -820,7 +809,7 @@ ecma_typedarray_get_element_size_shift (ecma_object_t *typedarray_p) /**< the po
ecma_length_t
ecma_typedarray_get_length (ecma_object_t *typedarray_p) /**< the pointer to the typedarray object */
{
JERRY_ASSERT (ecma_is_typedarray (ecma_make_object_value (typedarray_p)));
JERRY_ASSERT (ecma_object_is_typedarray (typedarray_p));
ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) typedarray_p;
@@ -852,7 +841,7 @@ ecma_typedarray_get_length (ecma_object_t *typedarray_p) /**< the pointer to the
ecma_length_t
ecma_typedarray_get_offset (ecma_object_t *typedarray_p) /**< the pointer to the typedarray object */
{
JERRY_ASSERT (ecma_is_typedarray (ecma_make_object_value (typedarray_p)));
JERRY_ASSERT (ecma_object_is_typedarray (typedarray_p));
ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) typedarray_p;
@@ -940,19 +929,20 @@ ecma_op_create_typedarray (const ecma_value_t *arguments_list_p, /**< the arg li
}
else if (ecma_is_value_object (arguments_list_p[0]))
{
if (ecma_is_typedarray (arguments_list_p[0]))
ecma_object_t *obj_p = ecma_get_object_from_value (arguments_list_p[0]);
if (ecma_object_is_typedarray (obj_p))
{
/* 22.2.1.3 */
ecma_object_t *typedarray_p = ecma_get_object_from_value (arguments_list_p[0]);
ecma_object_t *typedarray_p = obj_p;
ret = ecma_typedarray_create_object_with_typedarray (typedarray_p,
proto_p,
element_size_shift,
typedarray_id);
}
else if (ecma_is_arraybuffer (arguments_list_p[0]))
else if (ecma_object_class_is (obj_p, LIT_MAGIC_STRING_ARRAY_BUFFER_UL))
{
/* 22.2.1.5 */
ecma_object_t *arraybuffer_p = ecma_get_object_from_value (arguments_list_p[0]);
ecma_object_t *arraybuffer_p = obj_p;
ecma_value_t arg2 = ((arguments_list_len > 1) ? arguments_list_p[1]
: ECMA_VALUE_UNDEFINED);
@@ -1043,6 +1033,28 @@ ecma_op_create_typedarray (const ecma_value_t *arguments_list_p, /**< the arg li
return ret;
} /* ecma_op_create_typedarray */
/**
* Check if the object is typedarray
*
* @return true - if object is a TypedArray object
* false - otherwise
*/
bool
ecma_object_is_typedarray (ecma_object_t *obj_p) /**< the target object need to be checked */
{
JERRY_ASSERT (!ecma_is_lexical_environment (obj_p));
if (ecma_get_object_type (obj_p) == ECMA_OBJECT_TYPE_PSEUDO_ARRAY)
{
ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) obj_p;
return ((ext_object_p->u.pseudo_array.type == ECMA_PSEUDO_ARRAY_TYPEDARRAY)
|| (ext_object_p->u.pseudo_array.type == ECMA_PSEUDO_ARRAY_TYPEDARRAY_WITH_INFO));
}
return false;
} /* ecma_object_is_typedarray */
/**
* Check if the value is typedarray
*
@@ -1057,17 +1069,7 @@ ecma_is_typedarray (ecma_value_t value) /**< the target need to be checked */
return false;
}
ecma_object_t *obj_p = ecma_get_object_from_value (value);
if (ecma_get_object_type (obj_p) == ECMA_OBJECT_TYPE_PSEUDO_ARRAY)
{
ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) obj_p;
return ((ext_object_p->u.pseudo_array.type == ECMA_PSEUDO_ARRAY_TYPEDARRAY)
|| (ext_object_p->u.pseudo_array.type == ECMA_PSEUDO_ARRAY_TYPEDARRAY_WITH_INFO));
}
return false;
return ecma_object_is_typedarray (ecma_get_object_from_value (value));
} /* ecma_is_typedarray */
/**
@@ -1079,7 +1081,7 @@ void
ecma_op_typedarray_list_lazy_property_names (ecma_object_t *obj_p, /**< a TypedArray object */
ecma_collection_t *main_collection_p) /**< 'main' collection */
{
JERRY_ASSERT (ecma_is_typedarray (ecma_make_object_value (obj_p)));
JERRY_ASSERT (ecma_object_is_typedarray (obj_p));
ecma_length_t array_length = ecma_typedarray_get_length (obj_p);
@@ -1104,7 +1106,7 @@ ecma_op_typedarray_define_index_prop (ecma_object_t *obj_p, /**< a TypedArray ob
const ecma_property_descriptor_t *property_desc_p) /**< the description of
the prop */
{
JERRY_ASSERT (ecma_is_typedarray (ecma_make_object_value (obj_p)));
JERRY_ASSERT (ecma_object_is_typedarray (obj_p));
ecma_length_t array_length = ecma_typedarray_get_length (obj_p);
@@ -1155,13 +1157,12 @@ ecma_op_create_typedarray_with_type_and_length (ecma_object_t *obj_p, /**< Typed
* indicates the type */
ecma_length_t array_length) /**< length of the typedarray */
{
JERRY_ASSERT (ecma_is_typedarray (ecma_make_object_value (obj_p)));
JERRY_ASSERT (ecma_object_is_typedarray (obj_p));
#if ENABLED (JERRY_ES2015)
ecma_value_t constructor_value = ecma_op_object_get_by_magic_id (obj_p, LIT_MAGIC_STRING_CONSTRUCTOR);
if (ECMA_IS_VALUE_ERROR (constructor_value)
|| !ecma_is_value_object (constructor_value)
|| !ecma_is_constructor (constructor_value))
{
ecma_free_value (constructor_value);
@@ -57,6 +57,7 @@ ecma_value_t ecma_op_create_typedarray (const ecma_value_t *arguments_list_p,
ecma_object_t *proto_p,
uint8_t element_size_shift,
ecma_typedarray_type_t typedarray_id);
bool ecma_object_is_typedarray (ecma_object_t *obj_p);
bool ecma_is_typedarray (ecma_value_t target);
void ecma_op_typedarray_list_lazy_property_names (ecma_object_t *obj_p,
ecma_collection_t *main_collection_p);
+4 -2
View File
@@ -570,7 +570,8 @@ opfunc_call (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
ecma_value_t func_value = stack_top_p[-1];
ecma_value_t completion_value;
if (!ecma_op_is_callable (func_value))
if (!ecma_is_value_object (func_value)
|| !ecma_op_object_is_callable (ecma_get_object_from_value (func_value)))
{
completion_value = ecma_raise_type_error (ECMA_ERR_MSG ("Expected a function."));
}
@@ -654,7 +655,8 @@ opfunc_construct (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
ecma_value_t constructor_value = stack_top_p[-1];
ecma_value_t completion_value;
if (!ecma_is_constructor (constructor_value))
if (!ecma_is_value_object (constructor_value)
|| !ecma_object_is_constructor (ecma_get_object_from_value (constructor_value)))
{
completion_value = ecma_raise_type_error (ECMA_ERR_MSG ("Expected a constructor."));
}