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 (); jerry_assert_api_available ();
if (!jerry_value_is_array (value)) if (!jerry_value_is_object (value))
{ {
return 0; return 0;
} }
ecma_value_t len_value = ecma_op_object_get_by_magic_id (ecma_get_object_from_value (value), ecma_object_t *object_p = ecma_get_object_from_value (value);
LIT_MAGIC_STRING_LENGTH);
jerry_length_t length = ecma_number_to_uint32 (ecma_get_number_from_value (len_value)); if (JERRY_LIKELY (ecma_get_object_type (object_p) == ECMA_OBJECT_TYPE_ARRAY))
ecma_free_value (len_value); {
return ecma_array_get_length (object_p);
}
return length; return 0;
} /* jerry_get_array_length */ } /* 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))); 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_by_uint32_index (ecma_get_object_from_value (obj_val), 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);
return jerry_return (ret_value); return jerry_return (ret_value);
} /* jerry_get_property_by_index */ } /* 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))); 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_by_uint32_index (ecma_get_object_from_value (obj_val),
ecma_value_t ret_value = ecma_op_object_put (ecma_get_object_from_value (obj_val), index,
str_idx_p, value_to_set,
value_to_set, true);
true);
ecma_deref_ecma_string (str_idx_p);
return jerry_return (ret_value); return jerry_return (ret_value);
} /* jerry_set_property_by_index */ } /* 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)); 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; 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_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_CLASS = 1, /**< Objects with class property */
ECMA_OBJECT_TYPE_FUNCTION = 2, /**< Function objects (15.3), created through 13.2 routine */ ECMA_OBJECT_TYPE_ARRAY = 2, /**< Array object (15.4) */
ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION = 3, /**< External (host) function object */ ECMA_OBJECT_TYPE_PSEUDO_ARRAY = 3, /**< Array-like object, such as Arguments object (10.6) */
ECMA_OBJECT_TYPE_ARRAY = 4, /**< Array object (15.4) */ /* Note: these 4 types must be in this order. See IsCallable operation. */
ECMA_OBJECT_TYPE_BOUND_FUNCTION = 5, /**< Function objects (15.3), created through 15.3.4.5 routine */ ECMA_OBJECT_TYPE_FUNCTION = 4, /**< Function objects (15.3), created through 13.2 routine */
ECMA_OBJECT_TYPE_PSEUDO_ARRAY = 6, /**< Array-like object, such as Arguments object (10.6) */
#if ENABLED (JERRY_ES2015) #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) */ #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. */ /* Types between 13-15 cannot have a built-in flag. See ecma_lexical_environment_type_t. */
ECMA_OBJECT_TYPE__MAX /**< maximum value */ 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); ecma_object_t *array_object_p = ecma_get_object_from_value (iterated_value);
uint32_t length;
/* 8 - 9. */ /* 8 - 9. */
#if ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) uint32_t length;
if (ecma_is_typedarray (ecma_make_object_value (array_object_p))) 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; 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); 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. */ /* 14. */
ecma_value_t get_value = ecma_op_object_get (array_object_p, index_string_p); ecma_value_t get_value = ecma_op_object_get_by_uint32_index (array_object_p, index);
ecma_deref_ecma_string (index_string_p);
/* 15. */ /* 15. */
if (ECMA_IS_VALUE_ERROR (get_value)) 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. */ /* 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_stringbuilder_t builder = ecma_stringbuilder_create_from (first_string_p);
ecma_deref_ecma_string (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. */ /* 4. Implementation-defined: set the separator to a single comma character. */
ecma_stringbuilder_append_byte (&builder, LIT_CHAR_COMMA); 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); 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_stringbuilder_append (&builder, next_string_p);
ecma_deref_ecma_string (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 */ ecma_op_array_get_to_string_at_index (ecma_object_t *obj_p, /**< this object */
uint32_t index) /**< array index */ 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_by_uint32_index (obj_p, index);
ecma_value_t index_value = ecma_op_object_get (obj_p, index_string_p);
ecma_deref_ecma_string (index_string_p);
if (ECMA_IS_VALUE_ERROR (index_value)) 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; 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 */ /* 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)) if (ECMA_IS_VALUE_ERROR (get_value))
{ {
ecma_deref_ecma_string (index_str_p);
return get_value; return get_value;
} }
@@ -448,9 +439,7 @@ ecma_builtin_array_prototype_object_pop (ecma_object_t *obj_p, /**< array object
} }
/* 5.c */ /* 5.c */
ecma_value_t del_value = ecma_op_object_delete (obj_p, index_str_p, true); ecma_value_t del_value = ecma_op_object_delete_by_uint32_index (obj_p, len, true);
ecma_deref_ecma_string (index_str_p);
if (ECMA_IS_VALUE_ERROR (del_value)) 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. */ /* 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)) 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) */ #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)) 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; return len_value;
} }
uint32_t length = 0; ecma_value_t ret_value;
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 routine_arg_1 = arguments_list_p[0]; ecma_value_t routine_arg_1 = arguments_list_p[0];
ecma_value_t routine_arg_2 = arguments_list_p[1]; 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 */ ecma_value_t arg) /**< first argument */
{ {
JERRY_UNUSED (this_arg); JERRY_UNUSED (this_arg);
ecma_value_t is_array = ECMA_VALUE_FALSE;
if (ecma_is_value_object (arg)) if (ecma_is_value_object (arg))
{ {
ecma_object_t *obj_p = ecma_get_object_from_value (arg); if (ecma_get_object_type (ecma_get_object_from_value (arg)) == ECMA_OBJECT_TYPE_ARRAY)
if (ecma_object_get_class_name (obj_p) == LIT_MAGIC_STRING_ARRAY_UL)
{ {
is_array = ECMA_VALUE_TRUE; return ECMA_VALUE_TRUE;
} }
} }
return is_array; return ECMA_VALUE_FALSE;
} /* ecma_builtin_array_object_is_array */ } /* 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); ecma_object_t *obj_p = ecma_get_object_from_value (arg2);
/* 4. */ /* 4-5. */
ecma_value_t length_value = ecma_op_object_get_by_magic_id (obj_p, LIT_MAGIC_STRING_LENGTH); uint32_t length;
if (ECMA_IS_VALUE_ERROR (length_value)) 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) if (length >= ECMA_FUNCTION_APPLY_ARGUMENT_COUNT_LIMIT)
{ {
return ecma_raise_range_error (ECMA_ERR_MSG ("Too many arguments declared for Function.apply().")); 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. */ /* 7. */
for (index = 0; index < length; index++) 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_by_uint32_index (obj_p, index);
ecma_value_t get_value = ecma_op_object_get (obj_p, curr_idx_str_p);
ecma_deref_ecma_string (curr_idx_str_p);
if (ECMA_IS_VALUE_ERROR (get_value)) 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 * @return ecma value
* Returned value must be freed with ecma_free_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 */ ecma_builtin_helper_get_to_locale_string_at_index (ecma_object_t *obj_p, /**< this object */
uint32_t index) /**< array index */ uint32_t index) /**< array index */
{ {
ecma_value_t ret_value = ECMA_VALUE_EMPTY; ecma_value_t index_value = ecma_op_object_get_by_uint32_index (obj_p, 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);
if (ECMA_IS_VALUE_ERROR (index_value)) 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)) if (ecma_is_value_undefined (index_value) || ecma_is_value_null (index_value))
{ {
ecma_free_value (index_value); return ecma_get_magic_string (LIT_MAGIC_STRING__EMPTY);
return ecma_make_magic_string_value (LIT_MAGIC_STRING__EMPTY);
} }
ecma_value_t index_obj_value = ecma_op_to_object (index_value); 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)) 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_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); 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)) if (ECMA_IS_VALUE_ERROR (to_locale_value))
{ {
ecma_deref_object (index_obj_p); goto cleanup;
return to_locale_value;
} }
if (ecma_op_is_callable (to_locale_value)) 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
{ {
ecma_free_value (to_locale_value); ecma_free_value (to_locale_value);
ecma_deref_object (index_obj_p); ecma_raise_type_error (ECMA_ERR_MSG ("'toLocaleString' is missing or not a function."));
ret_value = 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 */ } /* 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. * Returned value must be freed with ecma_free_value.
*/ */
ecma_value_t 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 */ uint32_t *length_p, /**< [in,out] array's length */
ecma_value_t value) /**< value to concat */ ecma_value_t value) /**< value to concat */
{ {
ecma_value_t ret_value = ECMA_VALUE_EMPTY;
/* 5.b */ /* 5.b */
if (ecma_is_value_object (value) if (ecma_is_value_object (value))
&& (ecma_object_get_class_name (ecma_get_object_from_value (value)) == LIT_MAGIC_STRING_ARRAY_UL))
{ {
/* 5.b.ii */ ecma_object_t *obj_p = ecma_get_object_from_value (value);
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);
uint32_t arg_len = ecma_number_to_uint32 (arg_len_number); if (ecma_get_object_type (obj_p) == ECMA_OBJECT_TYPE_ARRAY)
/* 5.b.iii */
for (uint32_t array_index = 0;
array_index < arg_len && ecma_is_value_empty (ret_value);
array_index++)
{ {
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 */ /* 5.b.iii */
ECMA_TRY_CATCH (get_value, for (uint32_t array_index = 0; array_index < arg_len; array_index++)
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.3.a */ /* 5.b.iii.2 */
ecma_string_t *new_array_index_string_p = ecma_new_ecma_string_from_uint32 (*length_p + array_index); 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 */ /* 5.b.iii.3.b */
/* This will always be a simple value since 'is_throw' is false, so no need to free. */ /* 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, ecma_value_t put_comp = ecma_builtin_helper_def_prop_by_index (array_obj_p,
new_array_index_string_p, *length_p + array_index,
get_value, get_value,
ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE); ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE);
JERRY_ASSERT (ecma_is_value_true (put_comp)); 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); *length_p += arg_len;
return ECMA_VALUE_EMPTY;
ecma_deref_ecma_string (array_index_string_p);
} }
*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 */ } /* ecma_builtin_helper_array_concat_value */
/** /**
@@ -41,7 +41,7 @@ typedef enum
ecma_value_t ecma_value_t
ecma_builtin_helper_object_to_string (const ecma_value_t this_arg); 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_builtin_helper_get_to_locale_string_at_index (ecma_object_t *obj_p, uint32_t index);
ecma_value_t ecma_value_t
ecma_builtin_helper_object_get_properties (ecma_object_t *obj_p, uint32_t opts); 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; break;
} }
ecma_string_t *index_str_p = ecma_new_ecma_string_from_uint32 (length); ecma_value_t completion;
ecma_value_t completion = ecma_builtin_helper_def_prop (array_p, completion = ecma_builtin_helper_def_prop_by_index (array_p,
index_str_p, length,
value, value,
ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE); ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE);
JERRY_ASSERT (ecma_is_value_true (completion)); JERRY_ASSERT (ecma_is_value_true (completion));
ecma_deref_ecma_string (index_str_p);
ecma_free_value (value); ecma_free_value (value);
ecma_builtin_json_parse_next_token (token_p, false); 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)) if (ecma_is_value_object (value) && !ecma_op_is_callable (value))
{ {
ecma_object_t *obj_p = ecma_get_object_from_value (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; ecma_value_t ret_value;
/* 10.a */ /* 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); 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; context.replacer_function_p = obj_p;
} }
/* 4.b */ /* 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; ecma_extended_object_t *array_object_p = (ecma_extended_object_t *) obj_p;
uint32_t array_length = array_object_p->u.array.length; 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 */ /* 4.b.iii.5 */
while (index < array_length) 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_by_uint32_index (obj_p, index);
ecma_value_t value = ecma_op_object_get (obj_p, index_str_p);
ecma_deref_ecma_string (index_str_p);
if (ECMA_IS_VALUE_ERROR (value)) 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); item = ecma_make_string_value (number_str_p);
} }
/* 4.b.iii.5.f */ /* 4.b.iii.5.f */
else if (ecma_is_value_object (value) 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))
{ {
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_string_t *str_p = ecma_op_to_string (value);
ecma_free_value (value);
return ECMA_VALUE_ERROR;
}
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); ecma_free_value (value);
@@ -228,9 +228,7 @@ ecma_builtin_promise_do_race (ecma_value_t array, /**< the array for race */
} }
/* e. */ /* e. */
ecma_string_t *index_to_str_p = ecma_new_ecma_string_from_uint32 (index); ecma_value_t array_item = ecma_op_object_get_by_uint32_index (array_p, index);
ecma_value_t array_item = ecma_op_object_get (array_p, index_to_str_p);
ecma_deref_ecma_string (index_to_str_p);
/* f. */ /* f. */
if (ECMA_IS_VALUE_ERROR (array_item)) 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)); JERRY_ASSERT (ecma_is_value_integer_number (index_val));
/* 8. */ /* 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. */ /* 9-10. */
if (ecma_builtin_promise_remaining_inc_or_dec (remaining, false) == 0) if (ecma_builtin_promise_remaining_inc_or_dec (remaining, false) == 0)
@@ -26,7 +26,6 @@
#include "ecma-iterator-object.h" #include "ecma-iterator-object.h"
#include "ecma-objects.h" #include "ecma-objects.h"
#include "ecma-string-object.h" #include "ecma-string-object.h"
#include "ecma-try-catch-macro.h"
#include "jcontext.h" #include "jcontext.h"
#include "jrt.h" #include "jrt.h"
#include "jrt-libc-includes.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_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 *regexp_value) /**< [out] ptr to store the regexp object */
{ {
ecma_value_t ret_value = ECMA_VALUE_EMPTY;
/* 3. */ /* 3. */
if (ecma_is_value_object (regexp_arg) if (ecma_is_value_object (regexp_arg)
&& ecma_object_class_is (ecma_get_object_from_value (regexp_arg), LIT_MAGIC_STRING_REGEXP_UL)) && ecma_object_class_is (ecma_get_object_from_value (regexp_arg), LIT_MAGIC_STRING_REGEXP_UL))
{ {
*regexp_value = ecma_copy_value (regexp_arg); *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. */ *regexp_value = new_regexp_value;
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);
} }
return ret_value; return new_regexp_value;
} /* ecma_builtin_string_prepare_search */ } /* ecma_builtin_string_prepare_search */
/** /**
@@ -390,8 +385,10 @@ ecma_builtin_string_prototype_object_match (ecma_value_t this_to_string_value, /
/* 8.e. */ /* 8.e. */
bool last_match = true; bool last_match = true;
ret_value = ECMA_VALUE_ERROR;
/* 8.f. */ /* 8.f. */
while (last_match && ecma_is_value_empty (ret_value)) while (last_match)
{ {
/* 8.f.i. */ /* 8.f.i. */
ecma_value_t exec_value = ecma_regexp_exec_helper (regexp_value, this_to_string_value, false); 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. */ /* 8.f.iii. */
ECMA_TRY_CATCH (this_index_value, ecma_value_t this_index_value = ecma_op_object_get_by_magic_id (regexp_obj_p, LIT_MAGIC_STRING_LASTINDEX_UL);
ecma_op_object_get_by_magic_id (regexp_obj_p, LIT_MAGIC_STRING_LASTINDEX_UL),
ret_value);
ECMA_TRY_CATCH (this_index_number, if (ECMA_IS_VALUE_ERROR (this_index_value))
ecma_op_to_number (this_index_value), {
ret_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); 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) if (this_index == previous_last_index)
{ {
/* 8.f.iii.2.a. */ /* 8.f.iii.2.a. */
ECMA_TRY_CATCH (index_put_value, ecma_value_t index_put_value = ecma_op_object_put (regexp_obj_p,
ecma_op_object_put (regexp_obj_p, ecma_get_magic_string (LIT_MAGIC_STRING_LASTINDEX_UL),
ecma_get_magic_string (LIT_MAGIC_STRING_LASTINDEX_UL), ecma_make_number_value (this_index + 1),
ecma_make_number_value (this_index + 1), true);
true), if (ECMA_IS_VALUE_ERROR (index_put_value))
ret_value); {
ecma_free_value (this_index_value);
ecma_free_number (this_index_number);
goto cleanup;
}
/* 8.f.iii.2.b. */ /* 8.f.iii.2.b. */
previous_last_index = this_index + 1; previous_last_index = this_index + 1;
ECMA_FINALIZE (index_put_value);
} }
else else
{ {
@@ -440,55 +446,44 @@ ecma_builtin_string_prototype_object_match (ecma_value_t this_to_string_value, /
previous_last_index = this_index; previous_last_index = this_index;
} }
if (ecma_is_value_empty (ret_value)) /* 8.f.iii.4. */
{ JERRY_ASSERT (ecma_is_value_object (exec_value));
/* 8.f.iii.4. */ ecma_object_t *exec_obj_p = ecma_get_object_from_value (exec_value);
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_value_t match_string_value = ecma_op_object_get (exec_obj_p, index_zero_string_p);
ecma_op_object_get (exec_obj_p, index_zero_string_p), JERRY_ASSERT (!ECMA_IS_VALUE_ERROR (match_string_value));
ret_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. */ JERRY_ASSERT (ecma_is_value_true (completion));
ecma_value_t completion = ecma_builtin_helper_def_prop (new_array_obj_p, /* 8.f.iii.6. */
current_index_str_p, n++;
match_string_value,
ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE);
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); ecma_deref_object (exec_obj_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);
} }
if (ecma_is_value_empty (ret_value)) if (n == 0)
{ {
if (n == 0) /* 8.g. */
{ ret_value = ECMA_VALUE_NULL;
/* 8.g. */ }
ret_value = ECMA_VALUE_NULL; else
} {
else /* 8.h. */
{ ecma_ref_object (new_array_obj_p);
/* 8.h. */ ret_value = new_array_value;
ret_value = ecma_copy_value (new_array_value);
}
} }
cleanup:
ecma_deref_object (new_array_obj_p); ecma_deref_object (new_array_obj_p);
ecma_deref_object (regexp_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)); 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)) 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 */ * context */
ecma_value_t match_value) /**< returned match value */ 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); 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); JERRY_ASSERT (match_length >= 1);
if (context_p->is_replace_callable) 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, JMEM_DEFINE_LOCAL_ARRAY (arguments_list,
match_length + 2, match_length + 2,
ecma_value_t); 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. */ * uninitalized elements must not be freed. */
ecma_length_t values_copied = 0; 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_by_uint32_index (match_object_p, i);
ecma_value_t current_value = ecma_op_object_get (match_object_p, index_p);
ecma_deref_ecma_string (index_p);
if (ECMA_IS_VALUE_ERROR (current_value)) 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_string_t *to_string_p = ecma_op_to_string (result_value);
ecma_free_value (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); ret_value = ecma_make_string_value (to_string_p);
} }
@@ -727,203 +707,192 @@ cleanup:
} }
JMEM_FINALIZE_LOCAL_ARRAY (arguments_list); 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 ecma_char_t action = LIT_CHAR_NULL;
* 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); if (*replace_str_curr_p != LIT_CHAR_DOLLAR_SIGN)
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)
{ {
ecma_char_t action = LIT_CHAR_NULL; /* if not a continuation byte */
if ((*replace_str_curr_p & LIT_UTF8_EXTRA_BYTE_MASK) != LIT_UTF8_EXTRA_BYTE_MARKER)
if (*replace_str_curr_p != LIT_CHAR_DOLLAR_SIGN)
{ {
/* if not a continuation byte */ current_position++;
if ((*replace_str_curr_p & LIT_UTF8_EXTRA_BYTE_MASK) != LIT_UTF8_EXTRA_BYTE_MARKER)
{
current_position++;
}
replace_str_curr_p++;
continue;
} }
replace_str_curr_p++; 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) index = (uint32_t) (action - LIT_CHAR_0);
{
current_position++;
}
else if (action >= LIT_CHAR_0 && action <= LIT_CHAR_9)
{
uint32_t index = 0;
index = (uint32_t) (action - LIT_CHAR_0); if (index >= match_length)
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)
{ {
action = LIT_CHAR_NULL; action = LIT_CHAR_NULL;
} }
} else if (index == 0 || match_length > 10)
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)
{ {
current_position--; replace_str_curr_p++;
}
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 (replace_str_curr_p < replace_str_end_p)
if (action >= LIT_CHAR_0 && action <= LIT_CHAR_9)
{ {
index = (uint32_t) (action - LIT_CHAR_0); ecma_char_t next_character = *replace_str_curr_p;
if ((match_length > 10 || index == 0) if (next_character >= LIT_CHAR_0 && next_character <= LIT_CHAR_9)
&& replace_str_curr_p < replace_str_end_p)
{ {
action = *replace_str_curr_p; uint32_t full_index = index * 10 + (uint32_t) (next_character - LIT_CHAR_0);
if (action >= LIT_CHAR_0 && action <= LIT_CHAR_9) if (full_index > 0 && full_index < match_length)
{ {
uint32_t full_index = index * 10 + (uint32_t) (action - LIT_CHAR_0); index = match_length;
if (full_index < match_length)
{
index = full_index;
replace_str_curr_p++;
current_position++;
}
} }
} }
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, if (index == 0)
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))
{ {
JERRY_ASSERT (ecma_is_value_string (submatch_value)); action = LIT_CHAR_NULL;
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;
} }
} }
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, result_string_p = ecma_builtin_string_prototype_object_replace_append_substr (result_string_p,
context_p->replace_string_p, context_p->replace_string_p,
previous_start, previous_start,
current_position); 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 */ } /* 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 String.prototype object's 'replace' routine
* *
* The replace algorithm is splitted into several helper functions. * 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 * To share data between these helper functions, we created a
* structure called ecma_builtin_replace_search_ctx_t, which * 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 regexp_value = ECMA_VALUE_EMPTY;
ecma_value_t ret_value = ecma_builtin_string_prepare_search (regexp_arg, &regexp_value); if (ECMA_IS_VALUE_ERROR (ecma_builtin_string_prepare_search (regexp_arg, &regexp_value)))
if (ECMA_IS_VALUE_ERROR (ret_value))
{ {
return ret_value; return ECMA_VALUE_ERROR;
} }
/* 5. */ /* 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 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)) if (ECMA_IS_VALUE_ERROR (match_result))
{ {
ecma_free_value (regexp_value); goto cleanup;
ecma_deref_ecma_string (this_string_p);
return match_result;
} }
ecma_number_t offset = -1; 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_object_t *match_object_p = ecma_get_object_from_value (match_result);
ECMA_TRY_CATCH (index_value, ecma_value_t index_value = ecma_op_object_get_by_magic_id (match_object_p, LIT_MAGIC_STRING_INDEX);
ecma_op_object_get_by_magic_id (match_object_p, LIT_MAGIC_STRING_INDEX),
ret_value);
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); 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_free_value (regexp_value);
ecma_deref_ecma_string (this_string_p); 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; return new_array;
} }
ecma_value_t ret_value = ECMA_VALUE_EMPTY;
ecma_object_t *new_array_p = ecma_get_object_from_value (new_array); ecma_object_t *new_array_p = ecma_get_object_from_value (new_array);
/* 10. */ /* 10. */
if (ecma_is_value_undefined (arg1)) 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_by_index (new_array_p,
0,
ecma_value_t put_comp = ecma_builtin_helper_def_prop (new_array_p, this_to_string_val,
zero_str_p, ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE);
this_to_string_val,
ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE);
JERRY_ASSERT (ecma_is_value_true (put_comp)); JERRY_ASSERT (ecma_is_value_true (put_comp));
ecma_deref_ecma_string (zero_str_p);
return new_array; 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); const ecma_string_t *this_to_string_p = ecma_get_string_from_value (this_to_string_val);
/* 11. */ /* 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; bool should_return = false;
@@ -1423,15 +1380,12 @@ ecma_builtin_string_prototype_object_split (ecma_value_t this_to_string_val, /**
if (!should_return) if (!should_return)
{ {
/* 11.c */ /* 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_by_index (new_array_p,
0,
ecma_value_t put_comp = ecma_builtin_helper_def_prop (new_array_p, this_to_string_val,
zero_str_p, ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE);
this_to_string_val,
ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE);
JERRY_ASSERT (ecma_is_value_true (put_comp)); JERRY_ASSERT (ecma_is_value_true (put_comp));
ecma_deref_ecma_string (zero_str_p);
} }
} }
else else
@@ -1451,7 +1405,7 @@ ecma_builtin_string_prototype_object_split (ecma_value_t this_to_string_val, /**
/* 6. */ /* 6. */
const ecma_length_t string_length = ecma_string_get_length (this_to_string_p); 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; 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, start_pos,
end_pos); end_pos);
ecma_string_t *array_length_str_p = ecma_new_ecma_string_from_uint32 (new_array_length); ecma_value_t put_comp;
put_comp = ecma_builtin_helper_def_prop_by_index (new_array_p,
ecma_value_t put_comp = ecma_builtin_helper_def_prop (new_array_p, new_array_length,
array_length_str_p, ecma_make_string_value (substr_str_p),
ecma_make_string_value (substr_str_p), ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE);
ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE);
JERRY_ASSERT (ecma_is_value_true (put_comp)); 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++; new_array_length++;
/* 13.c.iii.4 */ /* 13.c.iii.4 */
if (new_array_length == limit && ecma_is_value_empty (ret_value)) if (new_array_length == limit)
{ {
should_return = true; should_return = true;
} }
@@ -1583,35 +1536,25 @@ ecma_builtin_string_prototype_object_split (ecma_value_t this_to_string_val, /**
/* 13.c.iii.5 */ /* 13.c.iii.5 */
start_pos = end_pos + match_str_length; start_pos = end_pos + match_str_length;
ECMA_TRY_CATCH (array_length_val, const uint32_t match_result_array_length = ecma_array_get_length (match_obj_p) - 1;
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;
/* 13.c.iii.6 */ /* 13.c.iii.6 */
uint32_t i = 0; uint32_t i = 0;
/* 13.c.iii.7 */ /* 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 */ /* 13.c.iii.7.a */
i++; i++;
ecma_string_t *idx_str_p = ecma_new_ecma_string_from_uint32 (i); match_comp_value = ecma_op_object_get_by_uint32_index (match_obj_p, 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);
JERRY_ASSERT (!ECMA_IS_VALUE_ERROR (match_comp_value)); JERRY_ASSERT (!ECMA_IS_VALUE_ERROR (match_comp_value));
/* 13.c.iii.7.b */ /* 13.c.iii.7.b */
put_comp = ecma_builtin_helper_def_prop (new_array_p, put_comp = ecma_builtin_helper_def_prop_by_index (new_array_p,
new_array_idx_str_p, new_array_length,
match_comp_value, match_comp_value,
ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE); ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE);
JERRY_ASSERT (ecma_is_value_true (put_comp)); 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++; new_array_length++;
/* 13.c.iii.7.d */ /* 13.c.iii.7.d */
if (new_array_length == limit && ecma_is_value_empty (ret_value)) if (new_array_length == limit)
{ {
should_return = true; should_return = true;
} }
ecma_free_value (match_comp_value); 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 */ /* 13.c.iii.8 */
curr_pos = start_pos; 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); 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. */ /* 14. */
ecma_string_t *substr_str_p; 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); string_length);
/* 15. */ /* 15. */
ecma_string_t *array_length_string_p = ecma_new_ecma_string_from_uint32 (new_array_length); ecma_value_t put_comp;
put_comp = ecma_builtin_helper_def_prop_by_index (new_array_p,
ecma_value_t put_comp = ecma_builtin_helper_def_prop (new_array_p, new_array_length,
array_length_string_p, ecma_make_string_value (substr_str_p),
ecma_make_string_value (substr_str_p), ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE);
ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE);
JERRY_ASSERT (ecma_is_value_true (put_comp)); JERRY_ASSERT (ecma_is_value_true (put_comp));
ecma_deref_ecma_string (array_length_string_p);
ecma_deref_ecma_string (substr_str_p); ecma_deref_ecma_string (substr_str_p);
} }
} }
ecma_free_value (separator); ecma_free_value (separator);
if (ecma_is_value_empty (ret_value)) return new_array;
{
ret_value = new_array;
}
else
{
ecma_deref_object (new_array_p);
}
return ret_value;
} /* ecma_builtin_string_prototype_object_split */ } /* 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_number_t element_num = typedarray_getter_cb (info.buffer_p + byte_pos);
ecma_value_t get_value = ecma_make_number_value (element_num); 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_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 (mode == TYPEDARRAY_ROUTINE_EVERY)
{ {
if (!ecma_op_to_boolean (call_value)) if (!ecma_op_to_boolean (call_value))
{ {
ret_value = ECMA_VALUE_FALSE; return ECMA_VALUE_FALSE;
} }
} }
else if (mode == TYPEDARRAY_ROUTINE_SOME else if (mode == TYPEDARRAY_ROUTINE_SOME
&& ecma_op_to_boolean (call_value)) && ecma_op_to_boolean (call_value))
{ {
ret_value = ECMA_VALUE_TRUE; return ECMA_VALUE_TRUE;
} }
byte_pos += info.element_size; byte_pos += info.element_size;
ECMA_FINALIZE (call_value); ecma_free_value (call_value);
ecma_fast_free_value (current_index);
ecma_fast_free_value (get_value);
} }
if (ecma_is_value_empty (ret_value)) if (mode == TYPEDARRAY_ROUTINE_EVERY)
{ {
if (mode == TYPEDARRAY_ROUTINE_EVERY) ret_value = ECMA_VALUE_TRUE;
{ }
ret_value = ECMA_VALUE_TRUE; else if (mode == TYPEDARRAY_ROUTINE_SOME)
} {
else if (mode == TYPEDARRAY_ROUTINE_SOME) ret_value = ECMA_VALUE_FALSE;
{ }
ret_value = ECMA_VALUE_FALSE; else
} {
else ret_value = ECMA_VALUE_UNDEFINED;
{
ret_value = ECMA_VALUE_UNDEFINED;
}
} }
return ret_value; 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_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_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) 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; lit_utf8_byte_t *pass_value_p = pass_value_list_p;
ecma_length_t byte_pos = 0; 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_value_t current_index = ecma_make_uint32_value (index);
ecma_number_t get_num = getter_cb (info.buffer_p + byte_pos); 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_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)) 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; byte_pos += info.element_size;
ECMA_FINALIZE (call_value); ecma_free_value (call_value);
ecma_fast_free_value (current_index);
ecma_fast_free_value (get_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)) memcpy (ecma_typedarray_get_buffer (obj_p),
{ pass_value_list_p,
obj_p = ecma_get_object_from_value (ret_value); (size_t) (pass_value_p - pass_value_list_p));
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));
}
} }
cleanup:
JMEM_FINALIZE_LOCAL_ARRAY (pass_value_list_p); JMEM_FINALIZE_LOCAL_ARRAY (pass_value_list_p);
return ret_value; 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)) 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_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); ret_val);
ECMA_OP_TO_NUMBER_TRY_CATCH (elem_num, elem, 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_OP_TO_NUMBER_FINALIZE (elem_num);
ECMA_FINALIZE (elem); ECMA_FINALIZE (elem);
ecma_deref_ecma_string (k_str_p);
k++; k++;
target_byte_index += target_info.element_size; 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 */ ecma_op_typedarray_get_to_string_at_index (ecma_object_t *obj_p, /**< this object */
uint32_t index) /**< array index */ 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_by_uint32_index (obj_p, index);
ecma_value_t index_value = ecma_op_object_get (obj_p, index_string_p);
ecma_deref_ecma_string (index_string_p);
if (ECMA_IS_VALUE_ERROR (index_value)) 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; return ECMA_VALUE_TRUE;
} /* ecma_op_array_object_define_own_property */ } /* 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 * 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, 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); const ecma_property_descriptor_t *property_desc_p);
uint32_t ecma_array_get_length (ecma_object_t *array_p);
void void
ecma_op_array_list_lazy_property_names (ecma_object_t *obj_p, bool separate_enumerable, ecma_op_array_list_lazy_property_names (ecma_object_t *obj_p, bool separate_enumerable,
ecma_collection_t *main_collection_p, 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_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)) 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; 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)) 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) */ #endif /* ENABLED (JERRY_ES2015) */
} /* ecma_is_normal_or_arrow_function */ } /* 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. * IsCallable operation.
* *
@@ -61,25 +77,30 @@ ecma_is_normal_or_arrow_function (ecma_object_type_t type) /**< object type */
bool bool
ecma_op_is_callable (ecma_value_t value) /**< ecma value */ ecma_op_is_callable (ecma_value_t value) /**< ecma value */
{ {
if (!ecma_is_value_object (value)) return (ecma_is_value_object (value)
{ && ecma_op_object_is_callable (ecma_get_object_from_value (value)));
return false; } /* ecma_op_is_callable */
}
ecma_object_t *obj_p = ecma_get_object_from_value (value); /**
* Checks whether the given object implements [[Construct]].
JERRY_ASSERT (obj_p != NULL); *
* @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)); JERRY_ASSERT (!ecma_is_lexical_environment (obj_p));
ecma_object_type_t type = ecma_get_object_type (obj_p); ecma_object_type_t type = ecma_get_object_type (obj_p);
return (type == ECMA_OBJECT_TYPE_FUNCTION if (type == ECMA_OBJECT_TYPE_FUNCTION)
#if ENABLED (JERRY_ES2015) {
|| type == ECMA_OBJECT_TYPE_ARROW_FUNCTION return (!ecma_get_object_is_builtin (obj_p) || !ecma_builtin_function_is_routine (obj_p));
#endif /* ENABLED (JERRY_ES2015) */ }
|| type == ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION
|| type == ECMA_OBJECT_TYPE_BOUND_FUNCTION); return (type >= ECMA_OBJECT_TYPE_BOUND_FUNCTION);
} /* ecma_op_is_callable */ } /* ecma_object_is_constructor */
/** /**
* Checks whether the value is Object that implements [[Construct]]. * Checks whether the value is Object that implements [[Construct]].
@@ -90,24 +111,8 @@ ecma_op_is_callable (ecma_value_t value) /**< ecma value */
bool bool
ecma_is_constructor (ecma_value_t value) /**< ecma value */ ecma_is_constructor (ecma_value_t value) /**< ecma value */
{ {
if (!ecma_is_value_object (value)) return (ecma_is_value_object (value)
{ && ecma_object_is_constructor (ecma_get_object_from_value (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);
} /* ecma_is_constructor */ } /* ecma_is_constructor */
/** /**
@@ -29,7 +29,9 @@
bool ecma_is_normal_or_arrow_function (ecma_object_type_t type); bool ecma_is_normal_or_arrow_function (ecma_object_type_t type);
bool ecma_op_is_callable (ecma_value_t value); 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_is_constructor (ecma_value_t value);
bool ecma_object_is_constructor (ecma_object_t *obj_p);
ecma_object_t * ecma_object_t *
ecma_op_create_function_object (ecma_object_t *scope_p, const ecma_compiled_code_t *bytecode_data_p); 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: case ECMA_OBJECT_TYPE_PSEUDO_ARRAY:
{ {
/* ES2015 9.4.5.1 */ /* 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 ENABLED (JERRY_ES2015)
if (ecma_prop_name_is_symbol (property_name_p)) 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) #if ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY)
/* ES2015 9.4.5.4 */ /* 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 ENABLED (JERRY_ES2015)
if (ecma_prop_name_is_symbol (property_name_p)) 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; return ECMA_VALUE_UNDEFINED;
} /* ecma_op_object_get */ } /* 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 * [[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) #if ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY)
/* ES2015 9.4.5.5 */ /* 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 ENABLED (JERRY_ES2015)
if (ecma_prop_name_is_symbol (property_name_p)) 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) #if ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY)
} }
/* ES2015 9.4.5.3 */ /* 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 ENABLED (JERRY_ES2015)
if (ecma_prop_name_is_symbol (property_name_p)) 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: case ECMA_OBJECT_TYPE_PSEUDO_ARRAY:
{ {
#if ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) #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); 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_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_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 (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); 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) #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); 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_typedarray_type_t
ecma_get_typedarray_id (ecma_object_t *obj_p) /**< typedarray object **/ 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; 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 */ uint8_t element_size_shift, /**< the size shift of the element length */
ecma_typedarray_type_t typedarray_id) /**< id of the typedarray */ ecma_typedarray_type_t typedarray_id) /**< id of the typedarray */
{ {
ecma_value_t ret_value = ECMA_VALUE_EMPTY;
/* 3 */ /* 3 */
JERRY_ASSERT (ecma_op_is_callable (map_fn_val) || ecma_is_value_undefined (map_fn_val)); 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 */ /* 10 */
ECMA_TRY_CATCH (arraylike_object_val, ecma_value_t arraylike_object_val = ecma_op_to_object (items_val);
ecma_op_to_object (items_val),
ret_value); 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); ecma_object_t *arraylike_object_p = ecma_get_object_from_value (arraylike_object_val);
/* 12 */ /* 12 */
ECMA_TRY_CATCH (len_value, uint32_t len;
ecma_op_object_get_by_magic_id (arraylike_object_p, LIT_MAGIC_STRING_LENGTH), ecma_value_t len_value = ecma_op_object_get_length (arraylike_object_p, &len);
ret_value);
ECMA_OP_TO_NUMBER_TRY_CATCH (len_number, len_value, ret_value); ecma_value_t ret_value = ECMA_VALUE_ERROR;
if (ECMA_IS_VALUE_ERROR (len_value))
uint32_t len = ecma_number_to_uint32 (len_number); {
ecma_deref_object (arraylike_object_p);
return len_value;
}
/* 14 */ /* 14 */
ecma_value_t new_typedarray = ecma_typedarray_create_object_with_length (len, 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)) 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); /* 17.b */
ecma_typedarray_info_t info = ecma_typedarray_get_info (new_typedarray_p); ecma_value_t current_value = ecma_op_object_find_by_uint32_index (arraylike_object_p, index);
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 */ if (ECMA_IS_VALUE_ERROR (current_value))
ecma_value_t current_index;
for (uint32_t index = 0; index < len && ecma_is_value_empty (ret_value); index++)
{ {
/* 17.a */ goto cleanup;
ecma_string_t *index_str_p = ecma_new_ecma_string_from_uint32 (index); }
/* 17.b */ if (ecma_is_value_found (current_value))
ECMA_TRY_CATCH (current_value, ecma_op_object_find (arraylike_object_p, index_str_p), ret_value); {
ecma_value_t mapped_value;
if (ecma_is_value_found (current_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 */ goto cleanup;
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);
} }
else
{
error = ecma_get_number (current_value, &num_var);
if (ECMA_IS_VALUE_ERROR (error)) mapped_value = cb_value;
{ }
ret_value = ECMA_VALUE_ERROR; else
} {
mapped_value = current_value;
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 (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)) if (index >= info.length)
{ {
ret_value = ecma_make_object_value (new_typedarray_p); ecma_raise_type_error (ECMA_ERR_MSG ("Invalid argument type."));
} goto cleanup;
else }
{
ecma_deref_object (new_typedarray_p); 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_ref_object (new_typedarray_p);
ECMA_FINALIZE (len_value); ret_value = ecma_make_object_value (new_typedarray_p);
ECMA_FINALIZE (arraylike_object_val);
cleanup:
ecma_deref_object (new_typedarray_p);
ecma_deref_object (arraylike_object_p);
return ret_value; return ret_value;
} /* ecma_op_typedarray_from */ } /* 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 inline ecma_object_t * JERRY_ATTR_ALWAYS_INLINE
ecma_typedarray_get_arraybuffer (ecma_object_t *typedarray_p) /**< the pointer to the typedarray object */ 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; 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 uint8_t
ecma_typedarray_get_element_size_shift (ecma_object_t *typedarray_p) /**< the pointer to the typedarray object */ 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)); return ecma_typedarray_helper_get_shift_size (ecma_get_typedarray_id (typedarray_p));
} /* ecma_typedarray_get_element_size_shift */ } /* 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_length_t
ecma_typedarray_get_length (ecma_object_t *typedarray_p) /**< the pointer to the typedarray object */ 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; 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_length_t
ecma_typedarray_get_offset (ecma_object_t *typedarray_p) /**< the pointer to the typedarray object */ 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; 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])) 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 */ /* 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, ret = ecma_typedarray_create_object_with_typedarray (typedarray_p,
proto_p, proto_p,
element_size_shift, element_size_shift,
typedarray_id); 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 */ /* 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_t arg2 = ((arguments_list_len > 1) ? arguments_list_p[1]
: ECMA_VALUE_UNDEFINED); : ECMA_VALUE_UNDEFINED);
@@ -1043,6 +1033,28 @@ ecma_op_create_typedarray (const ecma_value_t *arguments_list_p, /**< the arg li
return ret; return ret;
} /* ecma_op_create_typedarray */ } /* 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 * 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; return false;
} }
ecma_object_t *obj_p = ecma_get_object_from_value (value); return ecma_object_is_typedarray (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;
} /* ecma_is_typedarray */ } /* ecma_is_typedarray */
/** /**
@@ -1079,7 +1081,7 @@ void
ecma_op_typedarray_list_lazy_property_names (ecma_object_t *obj_p, /**< a TypedArray object */ ecma_op_typedarray_list_lazy_property_names (ecma_object_t *obj_p, /**< a TypedArray object */
ecma_collection_t *main_collection_p) /**< 'main' collection */ 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); 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 const ecma_property_descriptor_t *property_desc_p) /**< the description of
the prop */ 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); 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 */ * indicates the type */
ecma_length_t array_length) /**< length of the typedarray */ 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) #if ENABLED (JERRY_ES2015)
ecma_value_t constructor_value = ecma_op_object_get_by_magic_id (obj_p, LIT_MAGIC_STRING_CONSTRUCTOR); 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) if (ECMA_IS_VALUE_ERROR (constructor_value)
|| !ecma_is_value_object (constructor_value)
|| !ecma_is_constructor (constructor_value)) || !ecma_is_constructor (constructor_value))
{ {
ecma_free_value (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, ecma_object_t *proto_p,
uint8_t element_size_shift, uint8_t element_size_shift,
ecma_typedarray_type_t typedarray_id); ecma_typedarray_type_t typedarray_id);
bool ecma_object_is_typedarray (ecma_object_t *obj_p);
bool ecma_is_typedarray (ecma_value_t target); bool ecma_is_typedarray (ecma_value_t target);
void ecma_op_typedarray_list_lazy_property_names (ecma_object_t *obj_p, void ecma_op_typedarray_list_lazy_property_names (ecma_object_t *obj_p,
ecma_collection_t *main_collection_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 func_value = stack_top_p[-1];
ecma_value_t completion_value; 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.")); 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 constructor_value = stack_top_p[-1];
ecma_value_t completion_value; 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.")); completion_value = ecma_raise_type_error (ECMA_ERR_MSG ("Expected a constructor."));
} }