/** * Handle calling [[Construct]] of built-in object * * @return ecma value */ ecma_value_t ecma_builtin_dispatch_construct (ecma_object_t *obj_p, /**< built-in object */ const ecma_value_t *arguments_list_p, /**< arguments list */ ecma_length_t arguments_list_len) /**< arguments list length */ { JERRY_ASSERT (ecma_get_object_type (obj_p) == ECMA_OBJECT_TYPE_FUNCTION); JERRY_ASSERT (ecma_get_object_is_builtin (obj_p)); ecma_value_t ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY); 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 */ } } JERRY_ASSERT (!ecma_is_value_empty (ret_value)); return ret_value; } /* ecma_builtin_dispatch_construct */
/** * 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)); 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 */
/** * Get [[Class]] string of specified object * * @return class name magic string */ lit_magic_string_id_t ecma_object_get_class_name (ecma_object_t *obj_p) /**< object */ { ecma_object_type_t type = ecma_get_object_type (obj_p); switch (type) { case ECMA_OBJECT_TYPE_ARRAY: { return LIT_MAGIC_STRING_ARRAY_UL; } case ECMA_OBJECT_TYPE_STRING: { return LIT_MAGIC_STRING_STRING_UL; } case ECMA_OBJECT_TYPE_ARGUMENTS: { return LIT_MAGIC_STRING_ARGUMENTS_UL; } case ECMA_OBJECT_TYPE_FUNCTION: case ECMA_OBJECT_TYPE_BOUND_FUNCTION: case ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION: case ECMA_OBJECT_TYPE_BUILT_IN_FUNCTION: { return LIT_MAGIC_STRING_FUNCTION_UL; } default: { JERRY_ASSERT (type == ECMA_OBJECT_TYPE_GENERAL); if (ecma_get_object_is_builtin (obj_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; switch (builtin_id) { case ECMA_BUILTIN_ID_OBJECT_PROTOTYPE: { return LIT_MAGIC_STRING_OBJECT_UL; } #ifndef CONFIG_ECMA_COMPACT_PROFILE_DISABLE_STRING_BUILTIN case ECMA_BUILTIN_ID_STRING_PROTOTYPE: { return LIT_MAGIC_STRING_STRING_UL; } #endif /* !CONFIG_ECMA_COMPACT_PROFILE_DISABLE_STRING_BUILTIN */ #ifndef CONFIG_ECMA_COMPACT_PROFILE_DISABLE_BOOLEAN_BUILTIN case ECMA_BUILTIN_ID_BOOLEAN_PROTOTYPE: { return LIT_MAGIC_STRING_BOOLEAN_UL; } #endif /* !CONFIG_ECMA_COMPACT_PROFILE_DISABLE_BOOLEAN_BUILTIN */ #ifndef CONFIG_ECMA_COMPACT_PROFILE_DISABLE_NUMBER_BUILTIN case ECMA_BUILTIN_ID_NUMBER_PROTOTYPE: { return LIT_MAGIC_STRING_NUMBER_UL; } #endif /* !CONFIG_ECMA_COMPACT_PROFILE_DISABLE_NUMBER_BUILTIN */ #ifndef CONFIG_ECMA_COMPACT_PROFILE_DISABLE_MATH_BUILTIN case ECMA_BUILTIN_ID_MATH: { return LIT_MAGIC_STRING_MATH_UL; } #endif /* !CONFIG_ECMA_COMPACT_PROFILE_DISABLE_MATH_BUILTIN */ #ifndef CONFIG_ECMA_COMPACT_PROFILE_DISABLE_JSON_BUILTIN case ECMA_BUILTIN_ID_JSON: { return LIT_MAGIC_STRING_JSON_U; } #endif /* !CONFIG_ECMA_COMPACT_PROFILE_DISABLE_JSON_BUILTIN */ #ifndef CONFIG_ECMA_COMPACT_PROFILE_DISABLE_ERROR_BUILTINS case ECMA_BUILTIN_ID_ERROR_PROTOTYPE: case ECMA_BUILTIN_ID_EVAL_ERROR_PROTOTYPE: case ECMA_BUILTIN_ID_RANGE_ERROR_PROTOTYPE: case ECMA_BUILTIN_ID_REFERENCE_ERROR_PROTOTYPE: case ECMA_BUILTIN_ID_SYNTAX_ERROR_PROTOTYPE: case ECMA_BUILTIN_ID_TYPE_ERROR_PROTOTYPE: case ECMA_BUILTIN_ID_URI_ERROR_PROTOTYPE: { return LIT_MAGIC_STRING_ERROR_UL; } #endif /* !CONFIG_ECMA_COMPACT_PROFILE_DISABLE_ERROR_BUILTINS */ #ifndef CONFIG_ECMA_COMPACT_PROFILE_DISABLE_DATE_BUILTIN case ECMA_BUILTIN_ID_DATE_PROTOTYPE: { return LIT_MAGIC_STRING_DATE_UL; } #endif /* CONFIG_ECMA_COMPACT_PROFILE_DISABLE_DATE_BUILTIN */ #ifndef CONFIG_ECMA_COMPACT_PROFILE_DISABLE_REGEXP_BUILTIN case ECMA_BUILTIN_ID_REGEXP_PROTOTYPE: { return LIT_MAGIC_STRING_REGEXP_UL; } #endif /* CONFIG_ECMA_COMPACT_PROFILE_DISABLE_REGEXP_BUILTIN */ default: { JERRY_ASSERT (ecma_builtin_is (obj_p, ECMA_BUILTIN_ID_GLOBAL)); return LIT_MAGIC_STRING_OBJECT_UL; } } } else { ecma_property_t *class_name_prop_p = ecma_find_internal_property (obj_p, ECMA_INTERNAL_PROPERTY_CLASS); if (class_name_prop_p == NULL) { return LIT_MAGIC_STRING_OBJECT_UL; } else { return (lit_magic_string_id_t) class_name_prop_p->u.internal_property.value; } } } } } /* ecma_object_get_class_name */
/** * Handle calling [[Call]] of built-in object * * @return ecma value */ ecma_value_t ecma_builtin_dispatch_call (ecma_object_t *obj_p, /**< built-in object */ ecma_value_t this_arg_value, /**< 'this' argument value */ const ecma_value_t *arguments_list_p, /**< arguments list */ ecma_length_t arguments_list_len) /**< arguments list length */ { JERRY_ASSERT (ecma_get_object_is_builtin (obj_p)); ecma_value_t ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY); if (ecma_get_object_type (obj_p) == ECMA_OBJECT_TYPE_BUILT_IN_FUNCTION) { ecma_property_t *desc_prop_p = ecma_get_internal_property (obj_p, ECMA_INTERNAL_PROPERTY_BUILT_IN_ROUTINE_DESC); uint64_t builtin_routine_desc = desc_prop_p->u.internal_property.value; uint64_t built_in_id_field = jrt_extract_bit_field (builtin_routine_desc, ECMA_BUILTIN_ROUTINE_ID_BUILT_IN_OBJECT_ID_POS, ECMA_BUILTIN_ROUTINE_ID_BUILT_IN_OBJECT_ID_WIDTH); JERRY_ASSERT (built_in_id_field < ECMA_BUILTIN_ID__COUNT); uint64_t routine_id_field = jrt_extract_bit_field (builtin_routine_desc, ECMA_BUILTIN_ROUTINE_ID_BUILT_IN_ROUTINE_ID_POS, ECMA_BUILTIN_ROUTINE_ID_BUILT_IN_ROUTINE_ID_WIDTH); JERRY_ASSERT ((uint16_t) routine_id_field == routine_id_field); ecma_builtin_id_t built_in_id = (ecma_builtin_id_t) built_in_id_field; uint16_t routine_id = (uint16_t) routine_id_field; ret_value = ecma_builtin_dispatch_routine (built_in_id, routine_id, this_arg_value, arguments_list_p, arguments_list_len); } else { JERRY_ASSERT (ecma_get_object_type (obj_p) == ECMA_OBJECT_TYPE_FUNCTION); 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)); 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_call (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 */ } } } JERRY_ASSERT (!ecma_is_value_empty (ret_value)); return ret_value; } /* ecma_builtin_dispatch_call */
/** * List names of a built-in object's lazy instantiated properties * * See also: * ecma_builtin_try_to_instantiate_property */ void ecma_builtin_list_lazy_property_names (ecma_object_t *object_p, /**< a built-in object */ bool separate_enumerable, /**< true - list enumerable properties into * main collection, and non-enumerable * to collection of 'skipped non-enumerable' * properties, * false - list all properties into main collection. */ ecma_collection_header_t *main_collection_p, /**< 'main' collection */ ecma_collection_header_t *non_enum_collection_p) /**< skipped 'non-enumerable' * collection */ { const ecma_object_type_t type = ecma_get_object_type (object_p); if (type == ECMA_OBJECT_TYPE_BUILT_IN_FUNCTION) { ecma_collection_header_t *for_enumerable_p = main_collection_p; (void) for_enumerable_p; ecma_collection_header_t *for_non_enumerable_p = separate_enumerable ? non_enum_collection_p : main_collection_p; /* 'length' property is non-enumerable (ECMA-262 v5, 15) */ ecma_string_t *name_p = ecma_get_magic_string (LIT_MAGIC_STRING_LENGTH); ecma_append_to_values_collection (for_non_enumerable_p, ecma_make_string_value (name_p), true); ecma_deref_ecma_string (name_p); } 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: \ { \ ecma_builtin_ ## lowercase_name ## _list_lazy_property_names (object_p, \ separate_enumerable, \ main_collection_p, \ non_enum_collection_p); \ return; \ } #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_list_lazy_property_names */
/** * 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, bits_in_uint8_t_must_be_equal_to_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 */
/** * List names of a built-in object's lazy instantiated properties * * See also: * ecma_builtin_try_to_instantiate_property */ void ecma_builtin_list_lazy_property_names (ecma_object_t *object_p, /**< a built-in object */ bool separate_enumerable, /**< true - list enumerable properties into * main collection, and non-enumerable * to collection of 'skipped non-enumerable' * properties, * false - list all properties into main collection. */ ecma_collection_header_t *main_collection_p, /**< 'main' collection */ ecma_collection_header_t *non_enum_collection_p) /**< skipped 'non-enumerable' * collection */ { JERRY_ASSERT (ecma_get_object_is_builtin (object_p)); ecma_extended_object_t *ext_obj_p = (ecma_extended_object_t *) object_p; if (ecma_get_object_type (object_p) == ECMA_OBJECT_TYPE_FUNCTION && ecma_builtin_function_is_routine (object_p)) { ecma_collection_header_t *for_enumerable_p = main_collection_p; JERRY_UNUSED (for_enumerable_p); ecma_collection_header_t *for_non_enumerable_p = separate_enumerable ? non_enum_collection_p : main_collection_p; /* 'length' property is non-enumerable (ECMA-262 v5, 15) */ ecma_string_t *name_p = ecma_new_ecma_length_string (); ecma_append_to_values_collection (for_non_enumerable_p, ecma_make_string_value (name_p), true); ecma_deref_ecma_string (name_p); } else { ecma_builtin_id_t builtin_id = (ecma_builtin_id_t) ext_obj_p->u.built_in.id; JERRY_ASSERT (builtin_id < ECMA_BUILTIN_ID__COUNT); JERRY_ASSERT (ecma_builtin_is (object_p, builtin_id)); const ecma_builtin_property_descriptor_t *curr_property_p = ecma_builtin_property_list_references[builtin_id]; ecma_length_t index = 0; uint32_t instantiated_bitset = ext_obj_p->u.built_in.instantiated_bitset; ecma_collection_header_t *for_non_enumerable_p = (separate_enumerable ? non_enum_collection_p : main_collection_p); while (curr_property_p->magic_string_id != LIT_MAGIC_STRING__COUNT) { JERRY_ASSERT (index < 64); if (index == 32) { ecma_value_t *mask_prop_p = ecma_find_internal_property (object_p, ECMA_INTERNAL_PROPERTY_INSTANTIATED_MASK_32_63); if (mask_prop_p == NULL) { instantiated_bitset = 0; } else { instantiated_bitset = *mask_prop_p; } } uint32_t bit_for_index; if (index >= 32) { bit_for_index = (uint32_t) 1u << (index - 32); } else { bit_for_index = (uint32_t) 1u << index; } bool was_instantiated = false; if (instantiated_bitset & bit_for_index) { was_instantiated = true; } ecma_string_t *name_p = ecma_get_magic_string (curr_property_p->magic_string_id); if (!was_instantiated || ecma_op_object_has_own_property (object_p, name_p)) { ecma_append_to_values_collection (for_non_enumerable_p, ecma_make_string_value (name_p), true); } ecma_deref_ecma_string (name_p); curr_property_p++; index++; } } } /* ecma_builtin_list_lazy_property_names */
/** * 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)); ecma_extended_object_t *ext_obj_p = (ecma_extended_object_t *) object_p; if (ecma_get_object_type (object_p) == ECMA_OBJECT_TYPE_FUNCTION && ecma_builtin_function_is_routine (object_p)) { if (ecma_string_is_length (string_p)) { /* * 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 *len_prop_p = ecma_create_named_data_property (object_p, string_p, ECMA_PROPERTY_FIXED); ecma_set_named_data_property_value (len_prop_p, ecma_make_integer_value (ext_obj_p->u.built_in.length)); JERRY_ASSERT (!ecma_is_property_configurable (len_prop_p)); return len_prop_p; } return NULL; } lit_magic_string_id_t magic_string_id; if (!ecma_is_string_magic (string_p, &magic_string_id)) { return NULL; } ecma_builtin_id_t builtin_id = (ecma_builtin_id_t) ext_obj_p->u.built_in.id; JERRY_ASSERT (builtin_id < ECMA_BUILTIN_ID__COUNT); JERRY_ASSERT (ecma_builtin_is (object_p, builtin_id)); const ecma_builtin_property_descriptor_t *property_list_p = ecma_builtin_property_list_references[builtin_id]; const ecma_builtin_property_descriptor_t *curr_property_p = property_list_p; while (curr_property_p->magic_string_id != magic_string_id) { if (curr_property_p->magic_string_id == LIT_MAGIC_STRING__COUNT) { return NULL; } curr_property_p++; } uint32_t index = (uint32_t) (curr_property_p - property_list_p); JERRY_ASSERT (index < 64); if (likely (index < 32)) { uint32_t bit_for_index = (uint32_t) 1u << index; if (ext_obj_p->u.built_in.instantiated_bitset & bit_for_index) { /* This property was instantiated before. */ return NULL; } ext_obj_p->u.built_in.instantiated_bitset |= bit_for_index; } else { uint32_t bit_for_index = (uint32_t) 1u << (index - 32); ecma_value_t *mask_prop_p = ecma_find_internal_property (object_p, ECMA_INTERNAL_PROPERTY_INSTANTIATED_MASK_32_63); uint32_t instantiated_bitset; if (mask_prop_p == NULL) { mask_prop_p = ecma_create_internal_property (object_p, ECMA_INTERNAL_PROPERTY_INSTANTIATED_MASK_32_63); instantiated_bitset = 0; } else { instantiated_bitset = *mask_prop_p; if (instantiated_bitset & bit_for_index) { /* This property was instantiated before. */ return NULL; } } *mask_prop_p = (instantiated_bitset | bit_for_index); } ecma_value_t value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY); switch (curr_property_p->type) { case ECMA_BUILTIN_PROPERTY_SIMPLE: { value = ecma_make_simple_value (curr_property_p->value); break; } case ECMA_BUILTIN_PROPERTY_NUMBER: { ecma_number_t num = 0.0; if (curr_property_p->value < ECMA_BUILTIN_NUMBER_MAX) { num = curr_property_p->value; } else if (curr_property_p->value < ECMA_BUILTIN_NUMBER_NAN) { static const ecma_number_t builtin_number_list[] = { ECMA_NUMBER_MAX_VALUE, ECMA_NUMBER_MIN_VALUE, ECMA_NUMBER_E, ECMA_NUMBER_PI, ECMA_NUMBER_LN10, ECMA_NUMBER_LN2, ECMA_NUMBER_LOG2E, ECMA_NUMBER_LOG10E, ECMA_NUMBER_SQRT2, ECMA_NUMBER_SQRT_1_2 }; num = builtin_number_list[curr_property_p->value - ECMA_BUILTIN_NUMBER_MAX]; } else { switch (curr_property_p->value) { case ECMA_BUILTIN_NUMBER_NAN: { num = ecma_number_make_nan (); break; } case ECMA_BUILTIN_NUMBER_POSITIVE_INFINITY: { num = ecma_number_make_infinity (false); break; } case ECMA_BUILTIN_NUMBER_NEGATIVE_INFINITY: { num = ecma_number_make_infinity (true); break; } default: { JERRY_UNREACHABLE (); break; } } } value = ecma_make_number_value (num); break; } case ECMA_BUILTIN_PROPERTY_STRING: { value = ecma_make_string_value (ecma_get_magic_string (curr_property_p->value)); break; } case ECMA_BUILTIN_PROPERTY_OBJECT: { value = ecma_make_object_value (ecma_builtin_get (curr_property_p->value)); break; } case ECMA_BUILTIN_PROPERTY_ROUTINE: { ecma_object_t *func_obj_p; func_obj_p = ecma_builtin_make_function_object_for_routine (builtin_id, ECMA_GET_ROUTINE_ID (curr_property_p->value), ECMA_GET_ROUTINE_LENGTH (curr_property_p->value)); value = ecma_make_object_value (func_obj_p); break; } default: { JERRY_UNREACHABLE (); return NULL; } } ecma_property_t *prop_p = ecma_create_named_data_property (object_p, string_p, curr_property_p->attributes); ecma_set_named_data_property_value (prop_p, value); /* Reference count of objects must be decreased. */ if (ecma_is_value_object (value)) { ecma_free_value (value); } return prop_p; } /* ecma_builtin_try_to_instantiate_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 */