mirror of
https://github.com/jerryscript-project/jerryscript.git
synced 2025-12-15 16:29:21 +00:00
Improve ecma_reject to give more detailed error messages (#4565)
Note: TypedArray.[[DefineOwnProperty]] has been slightly reworked (without semantical changes) for better error messages. JerryScript-DCO-1.0-Signed-off-by: Robert Fancsik frobert@inf.u-szeged.hu
This commit is contained in:
parent
1623c8db1e
commit
f0f2a28109
@ -970,9 +970,8 @@ ecma_delete_array_properties (ecma_object_t *object_p, /**< object */
|
||||
ecma_value_t
|
||||
ecma_op_array_object_set_length (ecma_object_t *object_p, /**< the array object */
|
||||
ecma_value_t new_value, /**< new length value */
|
||||
uint32_t flags) /**< configuration options */
|
||||
uint16_t flags) /**< property descriptor flags */
|
||||
{
|
||||
bool is_throw = (flags & ECMA_PROP_IS_THROW) != 0;
|
||||
ecma_number_t new_len_num;
|
||||
ecma_value_t completion = ecma_op_to_number (new_value, &new_len_num);
|
||||
|
||||
@ -1006,7 +1005,7 @@ ecma_op_array_object_set_length (ecma_object_t *object_p, /**< the array object
|
||||
| ECMA_PROP_IS_GET_DEFINED
|
||||
| ECMA_PROP_IS_SET_DEFINED))
|
||||
{
|
||||
return ecma_reject (is_throw);
|
||||
return ecma_raise_property_redefinition (ecma_get_magic_string (LIT_MAGIC_STRING_LENGTH), flags);
|
||||
}
|
||||
|
||||
ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) object_p;
|
||||
@ -1029,14 +1028,14 @@ ecma_op_array_object_set_length (ecma_object_t *object_p, /**< the array object
|
||||
}
|
||||
else if (!ecma_is_property_writable ((ecma_property_t) ext_object_p->u.array.length_prop_and_hole_count))
|
||||
{
|
||||
return ecma_reject (is_throw);
|
||||
return ecma_raise_property_redefinition (ecma_get_magic_string (LIT_MAGIC_STRING_LENGTH), flags);
|
||||
}
|
||||
}
|
||||
return ECMA_VALUE_TRUE;
|
||||
}
|
||||
else if (!ecma_is_property_writable ((ecma_property_t) ext_object_p->u.array.length_prop_and_hole_count))
|
||||
{
|
||||
return ecma_reject (is_throw);
|
||||
return ecma_raise_property_redefinition (ecma_get_magic_string (LIT_MAGIC_STRING_LENGTH), flags);
|
||||
}
|
||||
|
||||
uint32_t current_len_uint32 = new_len_uint32;
|
||||
@ -1067,7 +1066,8 @@ ecma_op_array_object_set_length (ecma_object_t *object_p, /**< the array object
|
||||
{
|
||||
return ECMA_VALUE_TRUE;
|
||||
}
|
||||
return ecma_reject (is_throw);
|
||||
|
||||
return ecma_raise_property_redefinition (ecma_get_magic_string (LIT_MAGIC_STRING_LENGTH), flags);
|
||||
} /* ecma_op_array_object_set_length */
|
||||
|
||||
/**
|
||||
@ -1159,7 +1159,7 @@ ecma_op_array_object_define_own_property (ecma_object_t *object_p, /**< the arra
|
||||
if (update_length
|
||||
&& !ecma_is_property_writable ((ecma_property_t) ext_object_p->u.array.length_prop_and_hole_count))
|
||||
{
|
||||
return ecma_reject (property_desc_p->flags & ECMA_PROP_IS_THROW);
|
||||
return ecma_raise_property_redefinition (property_name_p, property_desc_p->flags);
|
||||
}
|
||||
|
||||
ecma_property_descriptor_t prop_desc;
|
||||
@ -1174,7 +1174,7 @@ ecma_op_array_object_define_own_property (ecma_object_t *object_p, /**< the arra
|
||||
|
||||
if (ecma_is_value_false (completition))
|
||||
{
|
||||
return ecma_reject (property_desc_p->flags & ECMA_PROP_IS_THROW);
|
||||
return ecma_raise_property_redefinition (property_name_p, property_desc_p->flags);
|
||||
}
|
||||
|
||||
if (update_length)
|
||||
|
||||
@ -113,7 +113,7 @@ ecma_op_create_array_iterator (ecma_object_t *obj_p,
|
||||
#endif /* JERRY_ESNEXT */
|
||||
|
||||
ecma_value_t
|
||||
ecma_op_array_object_set_length (ecma_object_t *object_p, ecma_value_t new_value, uint32_t flags);
|
||||
ecma_op_array_object_set_length (ecma_object_t *object_p, ecma_value_t new_value, uint16_t flags);
|
||||
|
||||
ecma_value_t
|
||||
ecma_op_array_object_define_own_property (ecma_object_t *object_p, ecma_string_t *property_name_p,
|
||||
|
||||
@ -31,25 +31,6 @@
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Reject sequence
|
||||
*
|
||||
* @return ecma value
|
||||
* Returned value must be freed with ecma_free_value
|
||||
*/
|
||||
ecma_value_t
|
||||
ecma_reject (bool is_throw) /**< Throw flag */
|
||||
{
|
||||
if (is_throw)
|
||||
{
|
||||
return ecma_raise_type_error (ECMA_ERR_MSG ("Invalid argument type"));
|
||||
}
|
||||
else
|
||||
{
|
||||
return ECMA_VALUE_FALSE;
|
||||
}
|
||||
} /* ecma_reject */
|
||||
|
||||
/**
|
||||
* 'Object' object creation operation with no arguments.
|
||||
*
|
||||
@ -386,7 +367,9 @@ ecma_op_general_object_define_own_property (ecma_object_t *object_p, /**< the ob
|
||||
if (!ecma_op_ordinary_object_is_extensible (object_p))
|
||||
{
|
||||
/* 2. */
|
||||
return ecma_reject (property_desc_p->flags & ECMA_PROP_IS_THROW);
|
||||
return ECMA_REJECT_WITH_FORMAT (property_desc_p->flags & ECMA_PROP_IS_THROW,
|
||||
"Cannot define property '%', object is not extensible",
|
||||
ecma_make_prop_name_value (property_name_p));
|
||||
}
|
||||
|
||||
/* 4. */
|
||||
@ -436,7 +419,8 @@ ecma_op_general_object_define_own_property (ecma_object_t *object_p, /**< the ob
|
||||
{
|
||||
ecma_free_value (ext_property_ref.property_ref.virtual_value);
|
||||
}
|
||||
return ecma_reject (property_desc_p->flags & ECMA_PROP_IS_THROW);
|
||||
|
||||
return ecma_raise_property_redefinition (property_name_p, property_desc_p->flags);
|
||||
}
|
||||
|
||||
if (ECMA_PROPERTY_IS_VIRTUAL (current_prop))
|
||||
@ -451,7 +435,7 @@ ecma_op_general_object_define_own_property (ecma_object_t *object_p, /**< the ob
|
||||
&& !ecma_op_same_value (property_desc_p->value,
|
||||
ext_property_ref.property_ref.virtual_value)))
|
||||
{
|
||||
result = ecma_reject (property_desc_p->flags & ECMA_PROP_IS_THROW);
|
||||
result = ecma_raise_property_redefinition (property_name_p, property_desc_p->flags);
|
||||
}
|
||||
|
||||
ecma_free_value (ext_property_ref.property_ref.virtual_value);
|
||||
@ -477,7 +461,7 @@ ecma_op_general_object_define_own_property (ecma_object_t *object_p, /**< the ob
|
||||
&& !ecma_op_same_value (property_desc_p->value,
|
||||
ext_property_ref.property_ref.value_p->value))))
|
||||
{
|
||||
return ecma_reject (property_desc_p->flags & ECMA_PROP_IS_THROW);
|
||||
return ecma_raise_property_redefinition (property_name_p, property_desc_p->flags);
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -498,7 +482,7 @@ ecma_op_general_object_define_own_property (ecma_object_t *object_p, /**< the ob
|
||||
&& prop_desc_setter_cp != get_set_pair_p->setter_cp))
|
||||
{
|
||||
/* i., ii. */
|
||||
return ecma_reject (property_desc_p->flags & ECMA_PROP_IS_THROW);
|
||||
return ecma_raise_property_redefinition (property_name_p, property_desc_p->flags);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -509,7 +493,7 @@ ecma_op_general_object_define_own_property (ecma_object_t *object_p, /**< the ob
|
||||
if (!is_current_configurable)
|
||||
{
|
||||
/* a. */
|
||||
return ecma_reject (property_desc_p->flags & ECMA_PROP_IS_THROW);
|
||||
return ecma_raise_property_redefinition (property_name_p, property_desc_p->flags);
|
||||
}
|
||||
|
||||
ecma_property_value_t *value_p = ext_property_ref.property_ref.value_p;
|
||||
|
||||
@ -26,7 +26,6 @@
|
||||
* @{
|
||||
*/
|
||||
|
||||
ecma_value_t ecma_reject (bool is_throw);
|
||||
ecma_object_t *ecma_op_create_object_object_noarg (void);
|
||||
ecma_object_t *ecma_op_create_object_object_noarg_and_set_prototype (ecma_object_t *object_prototype_p);
|
||||
|
||||
|
||||
@ -1126,7 +1126,7 @@ ecma_op_object_put_apply_receiver (ecma_value_t receiver, /**< receiver */
|
||||
/* 5.b */
|
||||
if (!ecma_is_value_object (receiver))
|
||||
{
|
||||
return ecma_reject (is_throw);
|
||||
return ECMA_REJECT (is_throw, "Receiver must be an object");
|
||||
}
|
||||
|
||||
ecma_object_t *receiver_obj_p = ecma_get_object_from_value (receiver);
|
||||
@ -1152,7 +1152,7 @@ ecma_op_object_put_apply_receiver (ecma_value_t receiver, /**< receiver */
|
||||
if (prop_desc.flags & (ECMA_PROP_IS_GET_DEFINED | ECMA_PROP_IS_SET_DEFINED)
|
||||
|| !(prop_desc.flags & ECMA_PROP_IS_WRITABLE))
|
||||
{
|
||||
result = ecma_reject (is_throw);
|
||||
result = ecma_raise_property_redefinition (property_name_p, prop_desc.flags);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1164,9 +1164,9 @@ ecma_op_object_put_apply_receiver (ecma_value_t receiver, /**< receiver */
|
||||
/* 5.e.iv */
|
||||
result = ecma_op_object_define_own_property (receiver_obj_p, property_name_p, &prop_desc);
|
||||
|
||||
if (JERRY_UNLIKELY (ecma_is_value_false (result)) && is_throw)
|
||||
if (JERRY_UNLIKELY (ecma_is_value_false (result)))
|
||||
{
|
||||
result = ecma_raise_type_error (ECMA_ERR_MSG ("Proxy trap returned falsish"));
|
||||
result = ECMA_REJECT (is_throw, "Proxy trap returned falsish");
|
||||
}
|
||||
}
|
||||
|
||||
@ -1190,9 +1190,9 @@ ecma_op_object_put_apply_receiver (ecma_value_t receiver, /**< receiver */
|
||||
desc.value = value;
|
||||
ecma_value_t ret_value = ecma_proxy_object_define_own_property (receiver_obj_p, property_name_p, &desc);
|
||||
|
||||
if (JERRY_UNLIKELY (ecma_is_value_false (ret_value)) && is_throw)
|
||||
if (JERRY_UNLIKELY (ecma_is_value_false (ret_value)))
|
||||
{
|
||||
ret_value = ecma_raise_type_error (ECMA_ERR_MSG ("Proxy trap returned falsish"));
|
||||
ret_value = ECMA_REJECT (is_throw, "Proxy trap returned falsish");
|
||||
}
|
||||
|
||||
return ret_value;
|
||||
@ -1269,7 +1269,7 @@ ecma_op_object_put_with_receiver (ecma_object_t *object_p, /**< the object */
|
||||
return ecma_op_array_object_set_length (object_p, value, 0);
|
||||
}
|
||||
|
||||
return ecma_reject (is_throw);
|
||||
return ecma_raise_readonly_assignment (property_name_p, is_throw);
|
||||
}
|
||||
|
||||
if (JERRY_LIKELY (ecma_op_array_is_fast_array (ext_object_p)))
|
||||
@ -1391,7 +1391,7 @@ ecma_op_object_put_with_receiver (ecma_object_t *object_p, /**< the object */
|
||||
|
||||
if (index < ecma_string_get_length (prim_value_str_p))
|
||||
{
|
||||
return ecma_reject (is_throw);
|
||||
return ecma_raise_readonly_assignment (property_name_p, is_throw);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1399,19 +1399,16 @@ ecma_op_object_put_with_receiver (ecma_object_t *object_p, /**< the object */
|
||||
}
|
||||
case ECMA_OBJECT_TYPE_FUNCTION:
|
||||
{
|
||||
#if JERRY_ESNEXT
|
||||
/* Uninitialized 'length' property is non-writable (ECMA-262 v6, 19.2.4.1) */
|
||||
if ((ecma_string_is_length (property_name_p))
|
||||
&& (!ECMA_GET_FIRST_BIT_FROM_POINTER_TAG (((ecma_extended_object_t *) object_p)->u.function.scope_cp)))
|
||||
{
|
||||
return ecma_reject (is_throw);
|
||||
}
|
||||
#else /* !JERRY_ESNEXT */
|
||||
if (ecma_string_is_length (property_name_p))
|
||||
{
|
||||
return ecma_reject (is_throw);
|
||||
}
|
||||
/* Uninitialized 'length' property is non-writable (ECMA-262 v6, 19.2.4.1) */
|
||||
#if JERRY_ESNEXT
|
||||
if (!ECMA_GET_FIRST_BIT_FROM_POINTER_TAG (((ecma_extended_object_t *) object_p)->u.function.scope_cp))
|
||||
#endif /* JERRY_ESNEXT */
|
||||
{
|
||||
return ecma_raise_readonly_assignment (property_name_p, is_throw);
|
||||
}
|
||||
}
|
||||
|
||||
/* Get prototype physical property. */
|
||||
property_p = ecma_op_function_try_to_lazy_instantiate_property (object_p, property_name_p);
|
||||
@ -1568,7 +1565,7 @@ ecma_op_object_put_with_receiver (ecma_object_t *object_p, /**< the object */
|
||||
{
|
||||
if (!ecma_is_property_writable ((ecma_property_t) ext_object_p->u.array.length_prop_and_hole_count))
|
||||
{
|
||||
return ecma_reject (is_throw);
|
||||
return ecma_raise_readonly_assignment (property_name_p, is_throw);
|
||||
}
|
||||
|
||||
ext_object_p->u.array.length = index + 1;
|
||||
@ -1593,7 +1590,7 @@ ecma_op_object_put_with_receiver (ecma_object_t *object_p, /**< the object */
|
||||
|
||||
if (setter_cp == JMEM_CP_NULL)
|
||||
{
|
||||
return ecma_reject (is_throw);
|
||||
return ecma_raise_readonly_assignment (property_name_p, is_throw);
|
||||
}
|
||||
|
||||
ecma_value_t ret_value = ecma_op_function_call (ECMA_GET_NON_NULL_POINTER (ecma_object_t, setter_cp),
|
||||
@ -1741,99 +1738,44 @@ ecma_op_object_define_own_property (ecma_object_t *obj_p, /**< the object */
|
||||
|
||||
const ecma_object_type_t type = ecma_get_object_type (obj_p);
|
||||
|
||||
#if JERRY_BUILTIN_PROXY
|
||||
if (ECMA_OBJECT_IS_PROXY (obj_p))
|
||||
{
|
||||
return ecma_proxy_object_define_own_property (obj_p, property_name_p, property_desc_p);
|
||||
}
|
||||
#endif /* JERRY_BUILTIN_PROXY */
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case ECMA_OBJECT_TYPE_GENERAL:
|
||||
case ECMA_OBJECT_TYPE_CLASS:
|
||||
case ECMA_OBJECT_TYPE_FUNCTION:
|
||||
case ECMA_OBJECT_TYPE_NATIVE_FUNCTION:
|
||||
case ECMA_OBJECT_TYPE_BOUND_FUNCTION:
|
||||
#if JERRY_BUILTIN_PROXY
|
||||
case ECMA_OBJECT_TYPE_PROXY:
|
||||
{
|
||||
return ecma_op_general_object_define_own_property (obj_p,
|
||||
property_name_p,
|
||||
property_desc_p);
|
||||
return ecma_proxy_object_define_own_property (obj_p, property_name_p, property_desc_p);
|
||||
}
|
||||
|
||||
#endif /* JERRY_BUILTIN_PROXY */
|
||||
case ECMA_OBJECT_TYPE_ARRAY:
|
||||
{
|
||||
return ecma_op_array_object_define_own_property (obj_p,
|
||||
property_name_p,
|
||||
property_desc_p);
|
||||
return ecma_op_array_object_define_own_property (obj_p, property_name_p, property_desc_p);
|
||||
}
|
||||
|
||||
default:
|
||||
case ECMA_OBJECT_TYPE_PSEUDO_ARRAY:
|
||||
{
|
||||
JERRY_ASSERT (type == ECMA_OBJECT_TYPE_PSEUDO_ARRAY);
|
||||
|
||||
ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) obj_p;
|
||||
|
||||
#if JERRY_BUILTIN_TYPEDARRAY
|
||||
if (ext_object_p->u.pseudo_array.type == ECMA_PSEUDO_ARRAY_ARGUMENTS)
|
||||
{
|
||||
#else /* !JERRY_BUILTIN_TYPEDARRAY */
|
||||
JERRY_ASSERT (ext_object_p->u.pseudo_array.type == ECMA_PSEUDO_ARRAY_ARGUMENTS);
|
||||
#endif /* JERRY_BUILTIN_TYPEDARRAY */
|
||||
return ecma_op_arguments_object_define_own_property (obj_p,
|
||||
property_name_p,
|
||||
property_desc_p);
|
||||
#if JERRY_BUILTIN_TYPEDARRAY
|
||||
}
|
||||
/* ES2015 9.4.5.3 */
|
||||
if (ecma_object_is_typedarray (obj_p))
|
||||
{
|
||||
if (ecma_prop_name_is_symbol (property_name_p))
|
||||
{
|
||||
return ecma_op_general_object_define_own_property (obj_p,
|
||||
property_name_p,
|
||||
property_desc_p);
|
||||
}
|
||||
uint32_t array_index = ecma_string_get_array_index (property_name_p);
|
||||
|
||||
if (array_index != ECMA_STRING_NOT_ARRAY_INDEX)
|
||||
{
|
||||
ecma_value_t define_status = ecma_op_typedarray_define_index_prop (obj_p,
|
||||
array_index,
|
||||
property_desc_p);
|
||||
|
||||
if (ECMA_IS_VALUE_ERROR (define_status))
|
||||
{
|
||||
return define_status;
|
||||
}
|
||||
|
||||
if (ecma_is_value_true (define_status))
|
||||
{
|
||||
return ECMA_VALUE_TRUE;
|
||||
}
|
||||
|
||||
return ecma_reject (property_desc_p->flags & ECMA_PROP_IS_THROW);
|
||||
}
|
||||
|
||||
ecma_number_t num = ecma_string_to_number (property_name_p);
|
||||
ecma_string_t *num_to_str = ecma_new_ecma_string_from_number (num);
|
||||
bool is_same = ecma_compare_ecma_strings (property_name_p, num_to_str);
|
||||
ecma_deref_ecma_string (num_to_str);
|
||||
|
||||
if (is_same)
|
||||
{
|
||||
return ecma_reject (property_desc_p->flags & ECMA_PROP_IS_THROW);
|
||||
}
|
||||
return ecma_op_typedarray_define_own_property (obj_p, property_name_p, property_desc_p);
|
||||
}
|
||||
|
||||
return ecma_op_general_object_define_own_property (obj_p,
|
||||
property_name_p,
|
||||
property_desc_p);
|
||||
#else /* !JERRY_BUILTIN_TYPEDARRAY */
|
||||
break;
|
||||
#endif /* JERRY_BUILTIN_TYPEDARRAY */
|
||||
|
||||
#if JERRY_ESNEXT
|
||||
/* All iterators are pseudo arrays */
|
||||
if (((ecma_extended_object_t *) obj_p)->u.pseudo_array.type != ECMA_PSEUDO_ARRAY_ARGUMENTS)
|
||||
{
|
||||
break;
|
||||
}
|
||||
#endif /* JERRY_ESNEXT */
|
||||
|
||||
return ecma_op_arguments_object_define_own_property (obj_p, property_name_p, property_desc_p);
|
||||
}
|
||||
default:
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return ecma_op_general_object_define_own_property (obj_p, property_name_p, property_desc_p);
|
||||
} /* ecma_op_object_define_own_property */
|
||||
|
||||
/**
|
||||
@ -3297,6 +3239,40 @@ ecma_op_ordinary_object_has_own_property (ecma_object_t *object_p, /**< the obje
|
||||
return property != ECMA_PROPERTY_TYPE_NOT_FOUND && property != ECMA_PROPERTY_TYPE_NOT_FOUND_AND_STOP;
|
||||
} /* ecma_op_ordinary_object_has_own_property */
|
||||
|
||||
/**
|
||||
* Raise property redefinition error
|
||||
*
|
||||
* @return ECMA_VALUE_FALSE - if ECMA_IS_THROW is not set
|
||||
* raised TypeError - otherwise
|
||||
*/
|
||||
ecma_value_t
|
||||
ecma_raise_property_redefinition (ecma_string_t *property_name_p, /**< property name */
|
||||
uint16_t flags) /**< property descriptor flags */
|
||||
{
|
||||
JERRY_UNUSED (property_name_p);
|
||||
|
||||
return ECMA_REJECT_WITH_FORMAT (flags & ECMA_PROP_IS_THROW,
|
||||
"Cannot redefine property '%'",
|
||||
ecma_make_prop_name_value (property_name_p));
|
||||
} /* ecma_raise_property_redefinition */
|
||||
|
||||
/**
|
||||
* Raise readonly assignment error
|
||||
*
|
||||
* @return ECMA_VALUE_FALSE - if is_throw is true
|
||||
* raised TypeError - otherwise
|
||||
*/
|
||||
ecma_value_t
|
||||
ecma_raise_readonly_assignment (ecma_string_t *property_name_p, /**< property name */
|
||||
bool is_throw) /**< is throw flag */
|
||||
{
|
||||
JERRY_UNUSED (property_name_p);
|
||||
|
||||
return ECMA_REJECT_WITH_FORMAT (is_throw,
|
||||
"Cannot assign to read only property '%'",
|
||||
ecma_make_prop_name_value (property_name_p));
|
||||
} /* ecma_raise_readonly_assignment */
|
||||
|
||||
/**
|
||||
* @}
|
||||
* @}
|
||||
|
||||
@ -27,6 +27,35 @@
|
||||
* @{
|
||||
*/
|
||||
|
||||
#if JERRY_ERROR_MESSAGES
|
||||
/**
|
||||
* Reject with TypeError depending on 'is_throw' with the given format
|
||||
*/
|
||||
#define ECMA_REJECT_WITH_FORMAT(is_throw, msg, ...) \
|
||||
((is_throw) ? ecma_raise_standard_error_with_format (ECMA_ERROR_TYPE, (msg), __VA_ARGS__) : ECMA_VALUE_FALSE)
|
||||
|
||||
/**
|
||||
* Reject with TypeError depending on 'is_throw' with the given message
|
||||
*/
|
||||
#define ECMA_REJECT(is_throw, msg) \
|
||||
((is_throw) ? ecma_raise_type_error (msg) : ECMA_VALUE_FALSE)
|
||||
#else /* !JERRY_ERROR_MESSAGES */
|
||||
/**
|
||||
* Reject with TypeError depending on is_throw flags wit the given format
|
||||
*/
|
||||
#define ECMA_REJECT_WITH_FORMAT(is_throw, msg, ...) \
|
||||
ECMA_REJECT((is_throw), (msg))
|
||||
|
||||
/**
|
||||
* Reject with TypeError depending on is_throw flags wit the given message
|
||||
*/
|
||||
#define ECMA_REJECT(is_throw, msg) \
|
||||
((is_throw) ? ecma_raise_type_error (NULL) : ECMA_VALUE_FALSE)
|
||||
#endif /* JERRY_ERROR_MESSAGES */
|
||||
|
||||
ecma_value_t ecma_raise_property_redefinition (ecma_string_t *property_name_p, uint16_t flags);
|
||||
ecma_value_t ecma_raise_readonly_assignment (ecma_string_t *property_name_p, bool is_throw);
|
||||
|
||||
ecma_property_t ecma_op_object_get_own_property (ecma_object_t *object_p, ecma_string_t *property_name_p,
|
||||
ecma_property_ref_t *property_ref_p, uint32_t options);
|
||||
bool ecma_op_ordinary_object_has_own_property (ecma_object_t *object_p, ecma_string_t *property_name_p);
|
||||
|
||||
@ -23,6 +23,7 @@
|
||||
#include "ecma-big-uint.h"
|
||||
#include "ecma-builtin-helpers.h"
|
||||
#include "ecma-objects.h"
|
||||
#include "ecma-objects-general.h"
|
||||
#include "ecma-builtins.h"
|
||||
#include "ecma-exceptions.h"
|
||||
#include "ecma-gc.h"
|
||||
@ -1564,54 +1565,72 @@ ecma_op_typedarray_list_lazy_property_names (ecma_object_t *obj_p, /**< a TypedA
|
||||
} /* ecma_op_typedarray_list_lazy_property_names */
|
||||
|
||||
/**
|
||||
* Define the integer number property value of the typedarray
|
||||
* [[DefineOwnProperty]] operation for TypedArray objects
|
||||
*
|
||||
* See also: ES2015 9.4.5.3: 3.c
|
||||
* See also: ES2015 9.4.5.3
|
||||
*
|
||||
* @return ecma value,
|
||||
* @return ECMA_VALUE_TRUE - if the property is successfully defined
|
||||
* ECMA_VALUE_FALSE - if is ECMA_IS_THROW is not set
|
||||
* raised TypeError - otherwise
|
||||
*/
|
||||
ecma_value_t
|
||||
ecma_op_typedarray_define_index_prop (ecma_object_t *obj_p, /**< a TypedArray object */
|
||||
uint32_t index, /**< the index number */
|
||||
const ecma_property_descriptor_t *property_desc_p) /**< the description of
|
||||
the prop */
|
||||
ecma_op_typedarray_define_own_property (ecma_object_t *obj_p, /**< TypedArray object */
|
||||
ecma_string_t *prop_name_p, /**< property name */
|
||||
const ecma_property_descriptor_t *property_desc_p) /**< property descriptor */
|
||||
{
|
||||
JERRY_ASSERT (ecma_object_is_typedarray (obj_p));
|
||||
|
||||
uint32_t array_length = ecma_typedarray_get_length (obj_p);
|
||||
|
||||
if ((index >= array_length)
|
||||
|| (property_desc_p->flags & (ECMA_PROP_IS_GET_DEFINED | ECMA_PROP_IS_SET_DEFINED))
|
||||
|| ((property_desc_p->flags & (ECMA_PROP_IS_CONFIGURABLE_DEFINED | ECMA_PROP_IS_CONFIGURABLE))
|
||||
== (ECMA_PROP_IS_CONFIGURABLE_DEFINED | ECMA_PROP_IS_CONFIGURABLE))
|
||||
|| ((property_desc_p->flags & ECMA_PROP_IS_ENUMERABLE_DEFINED)
|
||||
&& !(property_desc_p->flags & ECMA_PROP_IS_ENUMERABLE))
|
||||
|| ((property_desc_p->flags & ECMA_PROP_IS_WRITABLE_DEFINED)
|
||||
&& !(property_desc_p->flags & ECMA_PROP_IS_WRITABLE)))
|
||||
if (!ecma_prop_name_is_symbol (prop_name_p))
|
||||
{
|
||||
return ECMA_VALUE_FALSE;
|
||||
}
|
||||
uint32_t array_index = ecma_string_get_array_index (prop_name_p);
|
||||
|
||||
if (property_desc_p->flags & ECMA_PROP_IS_VALUE_DEFINED)
|
||||
{
|
||||
ecma_typedarray_info_t info = ecma_typedarray_get_info (obj_p);
|
||||
|
||||
if (index >= info.length)
|
||||
if (array_index != ECMA_STRING_NOT_ARRAY_INDEX)
|
||||
{
|
||||
return ECMA_VALUE_FALSE;
|
||||
if ((property_desc_p->flags & (ECMA_PROP_IS_GET_DEFINED | ECMA_PROP_IS_SET_DEFINED))
|
||||
|| ((property_desc_p->flags & (ECMA_PROP_IS_CONFIGURABLE_DEFINED | ECMA_PROP_IS_CONFIGURABLE))
|
||||
== (ECMA_PROP_IS_CONFIGURABLE_DEFINED | ECMA_PROP_IS_CONFIGURABLE))
|
||||
|| ((property_desc_p->flags & ECMA_PROP_IS_ENUMERABLE_DEFINED)
|
||||
&& !(property_desc_p->flags & ECMA_PROP_IS_ENUMERABLE))
|
||||
|| ((property_desc_p->flags & ECMA_PROP_IS_WRITABLE_DEFINED)
|
||||
&& !(property_desc_p->flags & ECMA_PROP_IS_WRITABLE)))
|
||||
{
|
||||
return ecma_raise_property_redefinition (prop_name_p, property_desc_p->flags);
|
||||
}
|
||||
|
||||
ecma_typedarray_info_t info = ecma_typedarray_get_info (obj_p);
|
||||
|
||||
if (array_index >= info.length)
|
||||
{
|
||||
return ECMA_REJECT ((property_desc_p->flags & ECMA_PROP_IS_THROW), "Invalid typed array index");
|
||||
}
|
||||
|
||||
if (property_desc_p->flags & ECMA_PROP_IS_VALUE_DEFINED)
|
||||
{
|
||||
lit_utf8_byte_t *src_buffer = info.buffer_p + (array_index << info.shift);
|
||||
ecma_value_t set_element = ecma_set_typedarray_element (src_buffer, property_desc_p->value, info.id);
|
||||
|
||||
if (ECMA_IS_VALUE_ERROR (set_element))
|
||||
{
|
||||
return set_element;
|
||||
}
|
||||
}
|
||||
|
||||
return ECMA_VALUE_TRUE;
|
||||
}
|
||||
|
||||
lit_utf8_byte_t *src_buffer = info.buffer_p + (index << info.shift);
|
||||
ecma_value_t set_element = ecma_set_typedarray_element (src_buffer, property_desc_p->value, info.id);
|
||||
ecma_number_t num = ecma_string_to_number (prop_name_p);
|
||||
ecma_string_t *num_to_str = ecma_new_ecma_string_from_number (num);
|
||||
bool is_same = ecma_compare_ecma_strings (prop_name_p, num_to_str);
|
||||
ecma_deref_ecma_string (num_to_str);
|
||||
|
||||
if (ECMA_IS_VALUE_ERROR (set_element))
|
||||
if (is_same)
|
||||
{
|
||||
return set_element;
|
||||
return ECMA_REJECT ((property_desc_p->flags & ECMA_PROP_IS_THROW), "Invalid typed array index");
|
||||
}
|
||||
}
|
||||
|
||||
return ECMA_VALUE_TRUE;
|
||||
} /* ecma_op_typedarray_define_index_prop */
|
||||
return ecma_op_general_object_define_own_property (obj_p, prop_name_p, property_desc_p);
|
||||
} /* ecma_op_typedarray_define_own_property */
|
||||
|
||||
/**
|
||||
* Specify the creation of a new TypedArray
|
||||
|
||||
@ -66,9 +66,9 @@ bool ecma_is_typedarray (ecma_value_t target);
|
||||
void ecma_op_typedarray_list_lazy_property_names (ecma_object_t *obj_p,
|
||||
ecma_collection_t *prop_names_p,
|
||||
ecma_property_counter_t *prop_counter_p);
|
||||
ecma_value_t ecma_op_typedarray_define_index_prop (ecma_object_t *obj_p,
|
||||
uint32_t index,
|
||||
const ecma_property_descriptor_t *property_desc_p);
|
||||
ecma_value_t ecma_op_typedarray_define_own_property (ecma_object_t *obj_p,
|
||||
ecma_string_t *prop_name_p,
|
||||
const ecma_property_descriptor_t *property_desc_p);
|
||||
ecma_value_t ecma_op_create_typedarray_with_type_and_length (ecma_typedarray_type_t typedarray_id,
|
||||
uint32_t array_length);
|
||||
ecma_typedarray_info_t ecma_typedarray_get_info (ecma_object_t *typedarray_p);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user