/** * [[DefineOwnProperty]] ecma array object's operation * * See also: * ECMA-262 v5, 8.6.2; ECMA-262 v5, Table 8 * ECMA-262 v5, 15.4.5.1 * * @return ecma value * Returned value must be freed with ecma_free_value */ ecma_value_t ecma_op_array_object_define_own_property (ecma_object_t *obj_p, /**< the array object */ ecma_string_t *property_name_p, /**< property name */ const ecma_property_descriptor_t *property_desc_p, /**< property descriptor */ bool is_throw) /**< flag that controls failure handling */ { JERRY_ASSERT (ecma_get_object_type (obj_p) == ECMA_OBJECT_TYPE_ARRAY); // 1. ecma_string_t *magic_string_length_p = ecma_get_magic_string (LIT_MAGIC_STRING_LENGTH); ecma_property_t *len_prop_p = ecma_op_object_get_own_property (obj_p, magic_string_length_p); JERRY_ASSERT (len_prop_p != NULL && ECMA_PROPERTY_GET_TYPE (len_prop_p) == ECMA_PROPERTY_TYPE_NAMEDDATA); // 2. ecma_value_t old_len_value = ecma_get_named_data_property_value (len_prop_p); uint32_t old_len_uint32 = ecma_get_uint32_from_value (old_len_value); // 3. bool is_property_name_equal_length = ecma_compare_ecma_strings (property_name_p, magic_string_length_p); ecma_deref_ecma_string (magic_string_length_p); if (is_property_name_equal_length) { // a. if (!property_desc_p->is_value_defined) { // i. return ecma_op_general_object_define_own_property (obj_p, property_name_p, property_desc_p, is_throw); } // c. ecma_value_t completion = ecma_op_to_number (property_desc_p->value); if (ECMA_IS_VALUE_ERROR (completion)) { return completion; } JERRY_ASSERT (!ECMA_IS_VALUE_ERROR (completion) && ecma_is_value_number (completion)); ecma_number_t new_len_num = ecma_get_number_from_value (completion); ecma_free_value (completion); uint32_t new_len_uint32 = ecma_number_to_uint32 (new_len_num); // d. if (((ecma_number_t) new_len_uint32) != new_len_num) { return ecma_raise_range_error (ECMA_ERR_MSG ("")); } else { // b., e. ecma_property_descriptor_t new_len_property_desc = *property_desc_p; new_len_property_desc.value = ecma_make_number_value (new_len_num); ecma_value_t ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY); // f. if (new_len_uint32 >= old_len_uint32) { // i. magic_string_length_p = ecma_get_magic_string (LIT_MAGIC_STRING_LENGTH); ret_value = ecma_op_general_object_define_own_property (obj_p, magic_string_length_p, &new_len_property_desc, is_throw); ecma_deref_ecma_string (magic_string_length_p); } else { // g. if (!ecma_is_property_writable (len_prop_p)) { ret_value = ecma_reject (is_throw); } else { // h. bool new_writable; if (!new_len_property_desc.is_writable_defined || new_len_property_desc.is_writable) { new_writable = true; } else { // ii. new_writable = false; // iii. new_len_property_desc.is_writable_defined = true; new_len_property_desc.is_writable = true; } // j. magic_string_length_p = ecma_get_magic_string (LIT_MAGIC_STRING_LENGTH); ecma_value_t succeeded = ecma_op_general_object_define_own_property (obj_p, magic_string_length_p, &new_len_property_desc, is_throw); ecma_deref_ecma_string (magic_string_length_p); /* Handling normal false and throw values */ if (!ecma_is_value_true (succeeded)) { JERRY_ASSERT (ecma_is_value_false (succeeded) || ECMA_IS_VALUE_ERROR (succeeded)); // k. ret_value = succeeded; } else { // l JERRY_ASSERT (new_len_uint32 < old_len_uint32); /* * Item i. is replaced with faster iteration: only indices that actually exist in the array, are iterated */ bool is_reduce_succeeded = true; ecma_collection_header_t *array_index_props_p = ecma_op_object_get_property_names (obj_p, true, false, false); ecma_length_t array_index_props_num = array_index_props_p->unit_number; JMEM_DEFINE_LOCAL_ARRAY (array_index_values_p, array_index_props_num, uint32_t); ecma_collection_iterator_t iter; ecma_collection_iterator_init (&iter, array_index_props_p); uint32_t array_index_values_pos = 0; while (ecma_collection_iterator_next (&iter)) { ecma_string_t *property_name_p = ecma_get_string_from_value (*iter.current_value_p); uint32_t index; bool is_index = ecma_string_get_array_index (property_name_p, &index); JERRY_ASSERT (is_index); JERRY_ASSERT (index < old_len_uint32); array_index_values_p[array_index_values_pos++] = index; } JERRY_ASSERT (array_index_values_pos == array_index_props_num); while (array_index_values_pos != 0 && array_index_values_p[--array_index_values_pos] >= new_len_uint32) { uint32_t index = array_index_values_p[array_index_values_pos]; // ii. ecma_string_t *index_string_p = ecma_new_ecma_string_from_uint32 (index); ecma_value_t delete_succeeded = ecma_op_object_delete (obj_p, index_string_p, false); ecma_deref_ecma_string (index_string_p); if (ecma_is_value_false (delete_succeeded)) { // iii. new_len_uint32 = (index + 1u); // 1. ecma_number_t new_len_num = ((ecma_number_t) index + 1u); ecma_value_assign_number (&new_len_property_desc.value, new_len_num); // 2. if (!new_writable) { new_len_property_desc.is_writable_defined = true; new_len_property_desc.is_writable = false; } // 3. ecma_string_t *magic_string_length_p = ecma_get_magic_string (LIT_MAGIC_STRING_LENGTH); ecma_value_t completion = ecma_op_general_object_define_own_property (obj_p, magic_string_length_p, &new_len_property_desc, false); ecma_deref_ecma_string (magic_string_length_p); JERRY_ASSERT (ecma_is_value_boolean (completion)); is_reduce_succeeded = false; break; } } JMEM_FINALIZE_LOCAL_ARRAY (array_index_values_p); ecma_free_values_collection (array_index_props_p, true); if (!is_reduce_succeeded) { ret_value = ecma_reject (is_throw); } else { // m. if (!new_writable) { ecma_property_descriptor_t prop_desc_not_writable = ecma_make_empty_property_descriptor (); prop_desc_not_writable.is_writable_defined = true; prop_desc_not_writable.is_writable = false; ecma_value_t completion_set_not_writable; magic_string_length_p = ecma_get_magic_string (LIT_MAGIC_STRING_LENGTH); completion_set_not_writable = ecma_op_general_object_define_own_property (obj_p, magic_string_length_p, &prop_desc_not_writable, false); ecma_deref_ecma_string (magic_string_length_p); JERRY_ASSERT (ecma_is_value_true (completion_set_not_writable)); } ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_TRUE); } } } } ecma_free_value (new_len_property_desc.value); return ret_value; } JERRY_UNREACHABLE (); } else { // 4.a. uint32_t index; if (!ecma_string_get_array_index (property_name_p, &index)) { // 5. return ecma_op_general_object_define_own_property (obj_p, property_name_p, property_desc_p, is_throw); } // 4. // b. if (index >= old_len_uint32 && !ecma_is_property_writable (len_prop_p)) { return ecma_reject (is_throw); } // c. ecma_value_t succeeded = ecma_op_general_object_define_own_property (obj_p, property_name_p, property_desc_p, false); // d. JERRY_ASSERT (ecma_is_value_boolean (succeeded)); if (ecma_is_value_false (succeeded)) { return ecma_reject (is_throw); } // e. if (index < UINT32_MAX && index >= old_len_uint32) { ecma_property_value_t *len_prop_value_p = ECMA_PROPERTY_VALUE_PTR (len_prop_p); // i., ii. /* Setting the length property is always successful. */ ecma_value_assign_uint32 (&len_prop_value_p->value, index + 1); } // f. return ecma_make_simple_value (ECMA_SIMPLE_VALUE_TRUE); } JERRY_UNREACHABLE (); } /* ecma_op_array_object_define_own_property */
/** * Handle calling [[Construct]] of built-in object * * @return completion-value */ ecma_completion_value_t ecma_builtin_dispatch_construct (ecma_object_t *obj_p, /**< built-in object */ ecma_collection_header_t* arg_collection_p) /**< arguments collection */ { JERRY_ASSERT (ecma_get_object_type (obj_p) == ECMA_OBJECT_TYPE_FUNCTION); JERRY_ASSERT (ecma_get_object_is_builtin (obj_p)); ecma_completion_value_t ret_value = ecma_make_empty_completion_value (); const ecma_length_t arguments_list_len = arg_collection_p != NULL ? arg_collection_p->unit_number : 0; MEM_DEFINE_LOCAL_ARRAY (arguments_list_p, arguments_list_len, ecma_value_t); ecma_collection_iterator_t arg_collection_iter; ecma_collection_iterator_init (&arg_collection_iter, arg_collection_p); for (ecma_length_t arg_index = 0; ecma_collection_iterator_next (&arg_collection_iter); arg_index++) { arguments_list_p[arg_index] = *arg_collection_iter.current_value_p; } ecma_property_t *built_in_id_prop_p = ecma_get_internal_property (obj_p, ECMA_INTERNAL_PROPERTY_BUILT_IN_ID); ecma_builtin_id_t builtin_id = (ecma_builtin_id_t) built_in_id_prop_p->u.internal_property.value; JERRY_ASSERT (ecma_builtin_is (obj_p, builtin_id)); JERRY_ASSERT (ecma_get_object_type (obj_p) == ECMA_OBJECT_TYPE_FUNCTION); switch (builtin_id) { #define BUILTIN(builtin_id, \ object_type, \ object_prototype_builtin_id, \ is_extensible, \ is_static, \ lowercase_name) \ case builtin_id: \ { \ if (object_type == ECMA_OBJECT_TYPE_FUNCTION) \ { \ ret_value = ecma_builtin_ ## lowercase_name ## _dispatch_construct (arguments_list_p, \ arguments_list_len); \ } \ break; \ } #include "ecma-builtins.inc.h" case ECMA_BUILTIN_ID__COUNT: { JERRY_UNREACHABLE (); } default: { #ifdef CONFIG_ECMA_COMPACT_PROFILE JERRY_UNREACHABLE (); #else /* CONFIG_ECMA_COMPACT_PROFILE */ JERRY_UNIMPLEMENTED ("The built-in is not implemented."); #endif /* !CONFIG_ECMA_COMPACT_PROFILE */ } } MEM_FINALIZE_LOCAL_ARRAY (arguments_list_p); JERRY_ASSERT (!ecma_is_completion_value_empty (ret_value)); return ret_value; } /* ecma_builtin_dispatch_construct */
/** * [[DefineOwnProperty]] ecma array object's operation * * See also: * ECMA-262 v5, 8.6.2; ECMA-262 v5, Table 8 * ECMA-262 v5, 15.4.5.1 * * @return completion value * Returned value must be freed with ecma_free_completion_value */ ecma_completion_value_t ecma_op_array_object_define_own_property (ecma_object_t *obj_p, /**< the array object */ ecma_string_t *property_name_p, /**< property name */ const ecma_property_descriptor_t* property_desc_p, /**< property descriptor */ bool is_throw) /**< flag that controls failure handling */ { JERRY_ASSERT (ecma_get_object_type (obj_p) == ECMA_OBJECT_TYPE_ARRAY); // 1. ecma_string_t* magic_string_length_p = ecma_get_magic_string (ECMA_MAGIC_STRING_LENGTH); ecma_property_t *len_prop_p = ecma_op_object_get_own_property (obj_p, magic_string_length_p); JERRY_ASSERT (len_prop_p != NULL && len_prop_p->type == ECMA_PROPERTY_NAMEDDATA); // 2. ecma_value_t old_len_value = ecma_get_named_data_property_value (len_prop_p); ecma_number_t *num_p = ecma_get_number_from_value (old_len_value); uint32_t old_len_uint32 = ecma_number_to_uint32 (*num_p); // 3. bool is_property_name_equal_length = ecma_compare_ecma_strings (property_name_p, magic_string_length_p); ecma_deref_ecma_string (magic_string_length_p); if (is_property_name_equal_length) { // a. if (!property_desc_p->is_value_defined) { // i. return ecma_op_general_object_define_own_property (obj_p, property_name_p, property_desc_p, is_throw); } ecma_number_t new_len_num; // c. ecma_completion_value_t completion = ecma_op_to_number (property_desc_p->value); if (ecma_is_completion_value_throw (completion)) { return completion; } JERRY_ASSERT (ecma_is_completion_value_normal (completion) && ecma_is_value_number (ecma_get_completion_value_value (completion))); new_len_num = *ecma_get_number_from_completion_value (completion); ecma_free_completion_value (completion); uint32_t new_len_uint32 = ecma_number_to_uint32 (new_len_num); // d. if (ecma_uint32_to_number (new_len_uint32) != new_len_num) { return ecma_make_throw_obj_completion_value (ecma_new_standard_error (ECMA_ERROR_RANGE)); } else { // b., e. ecma_number_t *new_len_num_p = ecma_alloc_number (); *new_len_num_p = new_len_num; ecma_property_descriptor_t new_len_property_desc = *property_desc_p; new_len_property_desc.value = ecma_make_number_value (new_len_num_p); ecma_completion_value_t ret_value = ecma_make_empty_completion_value (); // f. if (new_len_uint32 >= old_len_uint32) { // i. magic_string_length_p = ecma_get_magic_string (ECMA_MAGIC_STRING_LENGTH); ret_value = ecma_op_general_object_define_own_property (obj_p, magic_string_length_p, &new_len_property_desc, is_throw); ecma_deref_ecma_string (magic_string_length_p); } else { // g. if (!ecma_is_property_writable (len_prop_p)) { ret_value = ecma_reject (is_throw); } else { // h. bool new_writable; if (!new_len_property_desc.is_writable_defined || new_len_property_desc.is_writable) { new_writable = true; } else { // ii. new_writable = false; // iii. new_len_property_desc.is_writable_defined = true; new_len_property_desc.is_writable = true; } // j. magic_string_length_p = ecma_get_magic_string (ECMA_MAGIC_STRING_LENGTH); ecma_completion_value_t succeeded = ecma_op_general_object_define_own_property (obj_p, magic_string_length_p, &new_len_property_desc, is_throw); ecma_deref_ecma_string (magic_string_length_p); /* Handling normal false and throw values */ if (!ecma_is_completion_value_normal_true (succeeded)) { JERRY_ASSERT (ecma_is_completion_value_normal_false (succeeded) || ecma_is_completion_value_throw (succeeded)); // k. ret_value = succeeded; } else { // l JERRY_ASSERT (new_len_uint32 < old_len_uint32); bool reduce_succeeded = true; while (new_len_uint32 < old_len_uint32) { // i old_len_uint32--; // ii ecma_string_t *old_length_string_p = ecma_new_ecma_string_from_uint32 (old_len_uint32); ecma_completion_value_t delete_succeeded = ecma_op_object_delete (obj_p, old_length_string_p, false); ecma_deref_ecma_string (old_length_string_p); // iii if (ecma_is_completion_value_normal_false (delete_succeeded)) { JERRY_ASSERT (ecma_is_value_number (new_len_property_desc.value)); ecma_number_t *new_len_num_p = ecma_get_number_from_value (new_len_property_desc.value); // 1. *new_len_num_p = ecma_uint32_to_number (old_len_uint32 + 1); // 2. if (!new_writable) { new_len_property_desc.is_writable_defined = true; new_len_property_desc.is_writable = false; } // 3. ecma_string_t *magic_string_length_p = ecma_get_magic_string (ECMA_MAGIC_STRING_LENGTH); ecma_completion_value_t completion = ecma_op_general_object_define_own_property (obj_p, magic_string_length_p, &new_len_property_desc, false); ecma_deref_ecma_string (magic_string_length_p); JERRY_ASSERT (ecma_is_completion_value_normal_true (completion) || ecma_is_completion_value_normal_false (completion)); reduce_succeeded = false; break; } } if (!reduce_succeeded) { ret_value = ecma_reject (is_throw); } else { // m. if (!new_writable) { ecma_property_descriptor_t prop_desc_not_writable = ecma_make_empty_property_descriptor (); prop_desc_not_writable.is_writable_defined = true; prop_desc_not_writable.is_writable = false; ecma_completion_value_t completion_set_not_writable; magic_string_length_p = ecma_get_magic_string (ECMA_MAGIC_STRING_LENGTH); completion_set_not_writable = ecma_op_general_object_define_own_property (obj_p, magic_string_length_p, &prop_desc_not_writable, false); ecma_deref_ecma_string (magic_string_length_p); JERRY_ASSERT (ecma_is_completion_value_normal_true (completion_set_not_writable)); } ret_value = ecma_make_simple_completion_value (ECMA_SIMPLE_VALUE_TRUE); } } } } ecma_dealloc_number (new_len_num_p); return ret_value; } JERRY_UNREACHABLE (); } else { // 4.a. uint32_t index; bool is_index; if (property_name_p->container == ECMA_STRING_CONTAINER_UINT32_IN_DESC) { index = property_name_p->u.uint32_number; is_index = true; } else { ecma_number_t number = ecma_string_to_number (property_name_p); index = ecma_number_to_uint32 (number); ecma_string_t *to_uint32_to_string_p = ecma_new_ecma_string_from_uint32 (index); is_index = ecma_compare_ecma_strings (property_name_p, to_uint32_to_string_p); ecma_deref_ecma_string (to_uint32_to_string_p); } is_index = is_index && (index != ECMA_MAX_VALUE_OF_VALID_ARRAY_INDEX); if (!is_index) { // 5. return ecma_op_general_object_define_own_property (obj_p, property_name_p, property_desc_p, false); } // 4. // b. if (index >= old_len_uint32 && !ecma_is_property_writable (len_prop_p)) { return ecma_reject (is_throw); } // c. ecma_completion_value_t succeeded = ecma_op_general_object_define_own_property (obj_p, property_name_p, property_desc_p, false); // d. JERRY_ASSERT (ecma_is_completion_value_normal_true (succeeded) || ecma_is_completion_value_normal_false (succeeded)); if (ecma_is_completion_value_normal_false (succeeded)) { return ecma_reject (is_throw); } // e. if (index >= old_len_uint32) { // i., ii. ecma_number_t *num_p = ecma_alloc_number (); *num_p = ecma_number_add (ecma_uint32_to_number (index), ECMA_NUMBER_ONE); ecma_named_data_property_assign_value (obj_p, len_prop_p, ecma_make_number_value (num_p)); ecma_dealloc_number (num_p); } // f. return ecma_make_simple_completion_value (ECMA_SIMPLE_VALUE_TRUE); } JERRY_UNREACHABLE (); } /* ecma_op_array_object_define_own_property */
/** * If the property's name is one of built-in properties of the object * that is not instantiated yet, instantiate the property and * return pointer to the instantiated property. * * @return pointer property, if one was instantiated, * NULL - otherwise. */ ecma_property_t* ecma_builtin_try_to_instantiate_property (ecma_object_t *object_p, /**< object */ ecma_string_t *string_p) /**< property's name */ { JERRY_ASSERT (ecma_get_object_is_builtin (object_p)); const ecma_object_type_t type = ecma_get_object_type (object_p); if (type == ECMA_OBJECT_TYPE_BUILT_IN_FUNCTION) { ecma_string_t* magic_string_length_p = ecma_get_magic_string (LIT_MAGIC_STRING_LENGTH); bool is_length_property = ecma_compare_ecma_strings (string_p, magic_string_length_p); ecma_deref_ecma_string (magic_string_length_p); if (is_length_property) { /* * Lazy instantiation of 'length' property * * Note: * We don't need to mark that the property was already lazy instantiated, * as it is non-configurable and so can't be deleted */ ecma_property_t *desc_prop_p = ecma_get_internal_property (object_p, ECMA_INTERNAL_PROPERTY_BUILT_IN_ROUTINE_DESC); uint64_t builtin_routine_desc = desc_prop_p->u.internal_property.value; JERRY_STATIC_ASSERT (sizeof (uint8_t) * JERRY_BITSINBYTE == ECMA_BUILTIN_ROUTINE_ID_LENGTH_VALUE_WIDTH); uint8_t length_prop_value = (uint8_t) jrt_extract_bit_field (builtin_routine_desc, ECMA_BUILTIN_ROUTINE_ID_LENGTH_VALUE_POS, ECMA_BUILTIN_ROUTINE_ID_LENGTH_VALUE_WIDTH); ecma_property_t *len_prop_p = ecma_create_named_data_property (object_p, string_p, false, false, false); ecma_number_t *len_p = ecma_alloc_number (); *len_p = length_prop_value; ecma_set_named_data_property_value (len_prop_p, ecma_make_number_value (len_p)); JERRY_ASSERT (!ecma_is_property_configurable (len_prop_p)); return len_prop_p; } return NULL; } else { ecma_property_t *built_in_id_prop_p = ecma_get_internal_property (object_p, ECMA_INTERNAL_PROPERTY_BUILT_IN_ID); ecma_builtin_id_t builtin_id = (ecma_builtin_id_t) built_in_id_prop_p->u.internal_property.value; JERRY_ASSERT (ecma_builtin_is (object_p, builtin_id)); switch (builtin_id) { #define BUILTIN(builtin_id, \ object_type, \ object_prototype_builtin_id, \ is_extensible, \ is_static, \ lowercase_name) \ case builtin_id: \ { \ return ecma_builtin_ ## lowercase_name ## _try_to_instantiate_property (object_p, \ string_p); \ } #include "ecma-builtins.inc.h" case ECMA_BUILTIN_ID__COUNT: { JERRY_UNREACHABLE (); } default: { #ifdef CONFIG_ECMA_COMPACT_PROFILE JERRY_UNREACHABLE (); #else /* CONFIG_ECMA_COMPACT_PROFILE */ JERRY_UNIMPLEMENTED ("The built-in is not implemented."); #endif /* !CONFIG_ECMA_COMPACT_PROFILE */ } } JERRY_UNREACHABLE (); } } /* ecma_builtin_try_to_instantiate_property */
/** * [[Put]] ecma general object's operation * * See also: * ECMA-262 v5, 8.6.2; ECMA-262 v5, Table 8 * ECMA-262 v5, 8.12.5 * Also incorporates [[CanPut]] ECMA-262 v5, 8.12.4 * * @return ecma value * The returned value must be freed with ecma_free_value. * * Returns with ECMA_SIMPLE_VALUE_TRUE if the operation is * successful. Otherwise it returns with an error object * or ECMA_SIMPLE_VALUE_FALSE. * * Note: even if is_throw is false, the setter can throw an * error, and this function returns with that error. */ ecma_value_t ecma_op_general_object_put (ecma_object_t *obj_p, /**< the object */ ecma_string_t *property_name_p, /**< property name */ ecma_value_t value, /**< ecma value */ bool is_throw) /**< flag that controls failure handling */ { JERRY_ASSERT (obj_p != NULL && !ecma_is_lexical_environment (obj_p)); JERRY_ASSERT (property_name_p != NULL); ecma_object_t *setter_p = NULL; ecma_property_t *prop_p = ecma_op_object_get_own_property (obj_p, property_name_p); if (prop_p != NULL) { if (ECMA_PROPERTY_GET_TYPE (prop_p) == ECMA_PROPERTY_TYPE_NAMEDDATA) { if (ecma_is_property_writable (prop_p)) { const ecma_object_type_t type = ecma_get_object_type (obj_p); if (type == ECMA_OBJECT_TYPE_ARGUMENTS || (type == ECMA_OBJECT_TYPE_ARRAY && ecma_op_general_object_property_name_is_length (property_name_p))) { /* These cases cannot be optimized. */ ecma_property_descriptor_t value_desc = ecma_make_empty_property_descriptor (); value_desc.is_value_defined = true; value_desc.value = value; return ecma_op_object_define_own_property (obj_p, property_name_p, &value_desc, is_throw); } /* There is no need for special casing arrays here because changing the * value of an existing property never changes the length of an array. */ ecma_named_data_property_assign_value (obj_p, prop_p, value); return ecma_make_simple_value (ECMA_SIMPLE_VALUE_TRUE); } } else { JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (prop_p) == ECMA_PROPERTY_TYPE_NAMEDACCESSOR); setter_p = ecma_get_named_accessor_property_setter (prop_p); } } else { ecma_object_t *proto_p = ecma_get_object_prototype (obj_p); bool create_new_property = true; if (proto_p != NULL) { ecma_property_t *inherited_prop_p = ecma_op_object_get_property (proto_p, property_name_p); if (inherited_prop_p != NULL) { if (ECMA_PROPERTY_GET_TYPE (inherited_prop_p) == ECMA_PROPERTY_TYPE_NAMEDACCESSOR) { setter_p = ecma_get_named_accessor_property_setter (inherited_prop_p); create_new_property = false; } else { create_new_property = ecma_is_property_writable (inherited_prop_p); } } } if (create_new_property && ecma_get_object_extensible (obj_p)) { const ecma_object_type_t type = ecma_get_object_type (obj_p); if (type == ECMA_OBJECT_TYPE_ARGUMENTS) { return ecma_builtin_helper_def_prop (obj_p, property_name_p, value, true, /* Writable */ true, /* Enumerable */ true, /* Configurable */ is_throw); /* Failure handling */ } uint32_t index; if (type == ECMA_OBJECT_TYPE_ARRAY && ecma_string_get_array_index (property_name_p, &index)) { /* Since the length of an array is a non-configurable named data * property, the prop_p must be a non-NULL pointer for all arrays. */ JERRY_ASSERT (!ecma_op_general_object_property_name_is_length (property_name_p)); ecma_string_t *magic_string_length_p = ecma_get_magic_string (LIT_MAGIC_STRING_LENGTH); ecma_property_t *len_prop_p = ecma_op_object_get_own_property (obj_p, magic_string_length_p); ecma_deref_ecma_string (magic_string_length_p); JERRY_ASSERT (len_prop_p != NULL && ECMA_PROPERTY_GET_TYPE (len_prop_p) == ECMA_PROPERTY_TYPE_NAMEDDATA); uint32_t old_len = ecma_get_uint32_from_value (ecma_get_named_data_property_value (len_prop_p)); if (index < UINT32_MAX && index >= old_len) { if (!ecma_is_property_writable (len_prop_p)) { return ecma_reject (is_throw); } ecma_property_value_t *len_prop_value_p = ECMA_PROPERTY_VALUE_PTR (len_prop_p); ecma_value_assign_uint32 (&len_prop_value_p->value, index + 1); } } ecma_property_t *new_prop_p = ecma_create_named_data_property (obj_p, property_name_p, true, /* Writable */ true, /* Enumerable */ true); /* Configurable */ JERRY_ASSERT (ecma_is_value_undefined (ecma_get_named_data_property_value (new_prop_p))); ecma_set_named_data_property_value (new_prop_p, ecma_copy_value_if_not_object (value)); return ecma_make_simple_value (ECMA_SIMPLE_VALUE_TRUE); } } if (setter_p == NULL) { return ecma_reject (is_throw); } ecma_value_t ret_value = ecma_op_function_call (setter_p, ecma_make_object_value (obj_p), &value, 1); if (!ecma_is_value_error (ret_value)) { ecma_fast_free_value (ret_value); ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_TRUE); } return ret_value; } /* ecma_op_general_object_put */