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:
+12
-15
@@ -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 */
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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, ®exp_value);
|
||||
|
||||
if (ECMA_IS_VALUE_ERROR (ret_value))
|
||||
if (ECMA_IS_VALUE_ERROR (ecma_builtin_string_prepare_search (regexp_arg, ®exp_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);
|
||||
|
||||
@@ -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
@@ -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."));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user