/** * Number object creation operation. * * See also: ECMA-262 v5, 15.7.2.1 * * @return completion value * Returned value must be freed with ecma_free_completion_value */ ecma_completion_value_t ecma_op_create_number_object (ecma_value_t arg) /**< argument passed to the Number constructor */ { ecma_completion_value_t conv_to_num_completion = ecma_op_to_number (arg); if (!ecma_is_completion_value_normal (conv_to_num_completion)) { return conv_to_num_completion; } ecma_number_t *prim_value_p = ecma_get_number_from_completion_value (conv_to_num_completion); #ifndef CONFIG_ECMA_COMPACT_PROFILE_DISABLE_NUMBER_BUILTIN ecma_object_t *prototype_obj_p = ecma_builtin_get (ECMA_BUILTIN_ID_NUMBER_PROTOTYPE); #else /* !CONFIG_ECMA_COMPACT_PROFILE_DISABLE_NUMBER_BUILTIN */ ecma_object_t *prototype_obj_p = ecma_builtin_get (ECMA_BUILTIN_ID_OBJECT_PROTOTYPE); #endif /* CONFIG_ECMA_COMPACT_PROFILE_DISABLE_NUMBER_BUILTIN */ ecma_object_t *obj_p = ecma_create_object (prototype_obj_p, true, ECMA_OBJECT_TYPE_GENERAL); ecma_deref_object (prototype_obj_p); ecma_property_t *class_prop_p = ecma_create_internal_property (obj_p, ECMA_INTERNAL_PROPERTY_CLASS); class_prop_p->u.internal_property.value = LIT_MAGIC_STRING_NUMBER_UL; ecma_property_t *prim_value_prop_p = ecma_create_internal_property (obj_p, ECMA_INTERNAL_PROPERTY_PRIMITIVE_NUMBER_VALUE); ECMA_SET_POINTER (prim_value_prop_p->u.internal_property.value, prim_value_p); return ecma_make_normal_completion_value (ecma_make_object_value (obj_p)); } /* ecma_op_create_number_object */
/** * Number object creation operation. * * See also: ECMA-262 v5, 15.7.2.1 * * @return ecma value * Returned value must be freed with ecma_free_value */ ecma_value_t ecma_op_create_number_object (ecma_value_t arg) /**< argument passed to the Number constructor */ { ecma_value_t conv_to_num_completion = ecma_op_to_number (arg); if (ECMA_IS_VALUE_ERROR (conv_to_num_completion)) { return conv_to_num_completion; } #ifndef CONFIG_DISABLE_NUMBER_BUILTIN ecma_object_t *prototype_obj_p = ecma_builtin_get (ECMA_BUILTIN_ID_NUMBER_PROTOTYPE); #else /* CONFIG_DISABLE_NUMBER_BUILTIN */ ecma_object_t *prototype_obj_p = ecma_builtin_get (ECMA_BUILTIN_ID_OBJECT_PROTOTYPE); #endif /* !CONFIG_DISABLE_NUMBER_BUILTIN */ ecma_object_t *obj_p = ecma_create_object (prototype_obj_p, false, true, ECMA_OBJECT_TYPE_GENERAL); ecma_deref_object (prototype_obj_p); ecma_property_t *class_prop_p = ecma_create_internal_property (obj_p, ECMA_INTERNAL_PROPERTY_CLASS); ECMA_PROPERTY_VALUE_PTR (class_prop_p)->value = LIT_MAGIC_STRING_NUMBER_UL; ecma_property_t *prim_value_prop_p = ecma_create_internal_property (obj_p, ECMA_INTERNAL_PROPERTY_ECMA_VALUE); /* Pass reference (no need to free conv_to_num_completion). */ ecma_set_internal_property_value (prim_value_prop_p, conv_to_num_completion); return ecma_make_object_value (obj_p); } /* ecma_op_create_number_object */
/** * Boolean object creation operation. * * See also: ECMA-262 v5, 15.6.2.1 * * @return ecma value * Returned value must be freed with ecma_free_value */ ecma_value_t ecma_op_create_boolean_object (ecma_value_t arg) /**< argument passed to the Boolean constructor */ { bool boolean_value = ecma_op_to_boolean (arg); #ifndef CONFIG_ECMA_COMPACT_PROFILE_DISABLE_BOOLEAN_BUILTIN ecma_object_t *prototype_obj_p = ecma_builtin_get (ECMA_BUILTIN_ID_BOOLEAN_PROTOTYPE); #else /* CONFIG_ECMA_COMPACT_PROFILE_DISABLE_BOOLEAN_BUILTIN */ ecma_object_t *prototype_obj_p = ecma_builtin_get (ECMA_BUILTIN_ID_OBJECT_PROTOTYPE); #endif /* !CONFIG_ECMA_COMPACT_PROFILE_DISABLE_BOOLEAN_BUILTIN */ ecma_object_t *obj_p = ecma_create_object (prototype_obj_p, false, true, ECMA_OBJECT_TYPE_GENERAL); ecma_deref_object (prototype_obj_p); ecma_property_t *class_prop_p = ecma_create_internal_property (obj_p, ECMA_INTERNAL_PROPERTY_CLASS); ECMA_PROPERTY_VALUE_PTR (class_prop_p)->value = LIT_MAGIC_STRING_BOOLEAN_UL; ecma_property_t *prim_value_prop_p = ecma_create_internal_property (obj_p, ECMA_INTERNAL_PROPERTY_ECMA_VALUE); ecma_value_t prim_value = ecma_make_simple_value (boolean_value ? ECMA_SIMPLE_VALUE_TRUE : ECMA_SIMPLE_VALUE_FALSE); ecma_set_internal_property_value (prim_value_prop_p, prim_value); return ecma_make_object_value (obj_p); } /* ecma_op_create_boolean_object */
/** * RegExp object creation operation. * * See also: ECMA-262 v5, 15.10.4.1 * * @return completion value * Returned value must be freed with ecma_free_completion_value */ ecma_completion_value_t ecma_op_create_regexp_object (ecma_string_t *pattern_p, /**< input pattern */ ecma_string_t *flags_str_p) /**< flags */ { JERRY_ASSERT (pattern_p != NULL); ecma_completion_value_t ret_value = ecma_make_empty_completion_value (); uint8_t flags = 0; if (flags_str_p != NULL) { ECMA_TRY_CATCH (empty, re_parse_regexp_flags (flags_str_p, &flags), ret_value); ECMA_FINALIZE (empty); if (!ecma_is_completion_value_empty (ret_value)) { return ret_value; } } ecma_object_t *re_prototype_obj_p = ecma_builtin_get (ECMA_BUILTIN_ID_REGEXP_PROTOTYPE); ecma_object_t *obj_p = ecma_create_object (re_prototype_obj_p, true, ECMA_OBJECT_TYPE_GENERAL); ecma_deref_object (re_prototype_obj_p); /* Set the internal [[Class]] property */ ecma_property_t *class_prop_p = ecma_create_internal_property (obj_p, ECMA_INTERNAL_PROPERTY_CLASS); class_prop_p->u.internal_property.value = LIT_MAGIC_STRING_REGEXP_UL; re_initialize_props (obj_p, pattern_p, flags); /* Set bytecode internal property. */ ecma_property_t *bytecode_prop_p; bytecode_prop_p = ecma_create_internal_property (obj_p, ECMA_INTERNAL_PROPERTY_REGEXP_BYTECODE); /* Compile bytecode. */ re_bytecode_t *bc_p = NULL; ECMA_TRY_CATCH (empty, re_compile_bytecode (&bc_p, pattern_p, flags), ret_value); ECMA_SET_POINTER (bytecode_prop_p->u.internal_property.value, bc_p); ret_value = ecma_make_normal_completion_value (ecma_make_object_value (obj_p)); ECMA_FINALIZE (empty); if (ecma_is_completion_value_throw (ret_value)) { ecma_deref_object (obj_p); } return ret_value; } /* ecma_op_create_regexp_object */
/** * Create internal property with specified identifier and store external pointer in the property. * * Note: * property identifier should be one of the following: * - ECMA_INTERNAL_PROPERTY_NATIVE_CODE; * - ECMA_INTERNAL_PROPERTY_NATIVE_HANDLE; * - ECMA_INTERNAL_PROPERTY_FREE_CALLBACK. * * @return true - if property was just created with specified value, * false - otherwise, if property existed before the call, it's value was updated. */ bool ecma_create_external_pointer_property (ecma_object_t *obj_p, /**< object to create property in */ ecma_internal_property_id_t id, /**< identifier of internal * property to create */ ecma_external_pointer_t ptr_value) /**< value to store in the property */ { JERRY_ASSERT (id == ECMA_INTERNAL_PROPERTY_NATIVE_CODE || id == ECMA_INTERNAL_PROPERTY_NATIVE_HANDLE || id == ECMA_INTERNAL_PROPERTY_FREE_CALLBACK); bool is_new; ecma_property_t *prop_p = ecma_find_internal_property (obj_p, id); if (prop_p == NULL) { prop_p = ecma_create_internal_property (obj_p, id); is_new = true; } else { is_new = false; } JERRY_STATIC_ASSERT (sizeof (uint32_t) <= sizeof (ECMA_PROPERTY_VALUE_PTR (prop_p)->value), size_of_internal_property_value_must_be_greater_than_or_equal_to_4_bytes); if (sizeof (ecma_external_pointer_t) == sizeof (uint32_t)) { ECMA_PROPERTY_VALUE_PTR (prop_p)->value = (uint32_t) ptr_value; } else { ecma_external_pointer_t *handler_p; if (is_new) { handler_p = ecma_alloc_external_pointer (); ECMA_SET_NON_NULL_POINTER (ECMA_PROPERTY_VALUE_PTR (prop_p)->value, handler_p); } else { handler_p = ECMA_GET_NON_NULL_POINTER (ecma_external_pointer_t, ECMA_PROPERTY_VALUE_PTR (prop_p)->value); } *handler_p = ptr_value; } return is_new; } /* ecma_create_external_pointer_property */
/** * Construct a Function object for specified built-in routine * * See also: ECMA-262 v5, 15 * * @return pointer to constructed Function object */ ecma_object_t* ecma_builtin_make_function_object_for_routine (ecma_builtin_id_t builtin_id, /**< identifier of built-in object that initially contains property with the routine */ uint16_t routine_id, /**< builtin-wide identifier of the built-in object's routine property */ ecma_number_t length_prop_num_value) /**< ecma-number - value of 'length' property of function object to create */ { ecma_object_t *prototype_obj_p = ecma_builtin_get (ECMA_BUILTIN_ID_FUNCTION_PROTOTYPE); ecma_object_t *func_obj_p = ecma_create_object (prototype_obj_p, true, ECMA_OBJECT_TYPE_BUILT_IN_FUNCTION); ecma_deref_object (prototype_obj_p); ecma_set_object_is_builtin (func_obj_p, true); uint64_t packed_value = jrt_set_bit_field_value (0, builtin_id, ECMA_BUILTIN_ROUTINE_ID_BUILT_IN_OBJECT_ID_POS, ECMA_BUILTIN_ROUTINE_ID_BUILT_IN_OBJECT_ID_WIDTH); packed_value = jrt_set_bit_field_value (packed_value, routine_id, ECMA_BUILTIN_ROUTINE_ID_BUILT_IN_ROUTINE_ID_POS, ECMA_BUILTIN_ROUTINE_ID_BUILT_IN_ROUTINE_ID_WIDTH); ecma_property_t *routine_id_prop_p = ecma_create_internal_property (func_obj_p, ECMA_INTERNAL_PROPERTY_BUILT_IN_ROUTINE_ID); JERRY_ASSERT ((uint32_t) packed_value == packed_value); routine_id_prop_p->u.internal_property.value = (uint32_t) packed_value; ecma_string_t* magic_string_length_p = ecma_get_magic_string (LIT_MAGIC_STRING_LENGTH); ecma_property_t *len_prop_p = ecma_create_named_data_property (func_obj_p, magic_string_length_p, false, false, false); ecma_deref_ecma_string (magic_string_length_p); ecma_number_t* len_p = ecma_alloc_number (); *len_p = length_prop_num_value; ecma_set_named_data_property_value (len_prop_p, ecma_make_number_value (len_p)); return func_obj_p; } /* ecma_builtin_make_function_object_for_routine */
/** * Create internal property with specified identifier and store external pointer in the property. * * Note: * property identifier should be one of the following: * - ECMA_INTERNAL_PROPERTY_NATIVE_HANDLE; * - ECMA_INTERNAL_PROPERTY_FREE_CALLBACK. * * @return true - if property was just created with specified value, * false - otherwise, if property existed before the call, it's value was updated. */ bool ecma_create_external_pointer_property (ecma_object_t *obj_p, /**< object to create property in */ ecma_internal_property_id_t id, /**< identifier of internal * property to create */ ecma_external_pointer_t ptr_value) /**< value to store in the property */ { JERRY_ASSERT (id == ECMA_INTERNAL_PROPERTY_NATIVE_HANDLE || id == ECMA_INTERNAL_PROPERTY_FREE_CALLBACK); ecma_value_t *prop_p = ecma_find_internal_property (obj_p, id); bool is_new = (prop_p == NULL); if (is_new) { prop_p = ecma_create_internal_property (obj_p, id); } JERRY_STATIC_ASSERT (sizeof (uint32_t) <= sizeof (ECMA_PROPERTY_VALUE_PTR (prop_p)->value), size_of_internal_property_value_must_be_greater_than_or_equal_to_4_bytes); #ifdef ECMA_VALUE_CAN_STORE_UINTPTR_VALUE_DIRECTLY *prop_p = (ecma_value_t) ptr_value; #else /* !ECMA_VALUE_CAN_STORE_UINTPTR_VALUE_DIRECTLY */ ecma_external_pointer_t *handler_p; if (is_new) { handler_p = ecma_alloc_external_pointer (); ECMA_SET_NON_NULL_POINTER (*prop_p, handler_p); } else { handler_p = ECMA_GET_NON_NULL_POINTER (ecma_external_pointer_t, *prop_p); } *handler_p = ptr_value; #endif /* ECMA_VALUE_CAN_STORE_UINTPTR_VALUE_DIRECTLY */ return is_new; } /* ecma_create_external_pointer_property */
/** * Create internal property with specified identifier and store external pointer in the property. * * Note: * property identifier should be one of the following: * - ECMA_INTERNAL_PROPERTY_NATIVE_CODE; * - ECMA_INTERNAL_PROPERTY_NATIVE_HANDLE; * - ECMA_INTERNAL_PROPERTY_FREE_CALLBACK. * * @return true - if property was just created with specified value, * false - otherwise, if property existed before the call, it's value was updated. */ bool ecma_create_external_pointer_property (ecma_object_t *obj_p, /**< object to create property in */ ecma_internal_property_id_t id, /**< identifier of internal * property to create */ ecma_external_pointer_t ptr_value) /**< value to store in the property */ { JERRY_ASSERT (id == ECMA_INTERNAL_PROPERTY_NATIVE_CODE || id == ECMA_INTERNAL_PROPERTY_NATIVE_HANDLE || id == ECMA_INTERNAL_PROPERTY_FREE_CALLBACK); bool ret_val; ecma_property_t *prop_p = ecma_find_internal_property (obj_p, id); if (prop_p == NULL) { prop_p = ecma_create_internal_property (obj_p, id); ret_val = true; } else { ret_val = false; } JERRY_STATIC_ASSERT (sizeof (uint32_t) <= sizeof (prop_p->u.internal_property.value)); if (sizeof (ecma_external_pointer_t) == sizeof (uint32_t)) { prop_p->u.internal_property.value = (uint32_t) ptr_value; } else { ecma_external_pointer_t *handler_p = ecma_alloc_external_pointer (); *handler_p = ptr_value; ECMA_SET_NON_NULL_POINTER (prop_p->u.internal_property.value, handler_p); } return ret_val; } /* ecma_create_external_pointer_property */
/** * Construct a Function object for specified built-in routine * * See also: ECMA-262 v5, 15 * * @return pointer to constructed Function object */ ecma_object_t * ecma_builtin_make_function_object_for_routine (ecma_builtin_id_t builtin_id, /**< identifier of built-in object that initially contains property with the routine */ uint16_t routine_id, /**< builtin-wide identifier of the built-in object's routine property */ uint8_t length_prop_value) /**< value of 'length' property of function object to create */ { ecma_object_t *prototype_obj_p = ecma_builtin_get (ECMA_BUILTIN_ID_FUNCTION_PROTOTYPE); ecma_object_t *func_obj_p = ecma_create_object (prototype_obj_p, true, ECMA_OBJECT_TYPE_BUILT_IN_FUNCTION); ecma_deref_object (prototype_obj_p); ecma_set_object_is_builtin (func_obj_p, true); uint64_t packed_value = jrt_set_bit_field_value (0, builtin_id, ECMA_BUILTIN_ROUTINE_ID_BUILT_IN_OBJECT_ID_POS, ECMA_BUILTIN_ROUTINE_ID_BUILT_IN_OBJECT_ID_WIDTH); packed_value = jrt_set_bit_field_value (packed_value, routine_id, ECMA_BUILTIN_ROUTINE_ID_BUILT_IN_ROUTINE_ID_POS, ECMA_BUILTIN_ROUTINE_ID_BUILT_IN_ROUTINE_ID_WIDTH); packed_value = jrt_set_bit_field_value (packed_value, length_prop_value, ECMA_BUILTIN_ROUTINE_ID_LENGTH_VALUE_POS, ECMA_BUILTIN_ROUTINE_ID_LENGTH_VALUE_WIDTH); ecma_property_t *routine_desc_prop_p = ecma_create_internal_property (func_obj_p, ECMA_INTERNAL_PROPERTY_BUILT_IN_ROUTINE_DESC); JERRY_ASSERT ((uint32_t) packed_value == packed_value); routine_desc_prop_p->u.internal_property.value = (uint32_t) packed_value; return func_obj_p; } /* ecma_builtin_make_function_object_for_routine */
/** * Standard ecma-error object constructor. * * @return pointer to ecma-object representing specified error * with reference counter set to one. */ ecma_object_t * ecma_new_standard_error (ecma_standard_error_t error_type) /**< native error type */ { #ifndef CONFIG_ECMA_COMPACT_PROFILE_DISABLE_ERROR_BUILTINS ecma_builtin_id_t prototype_id = ECMA_BUILTIN_ID__COUNT; switch (error_type) { case ECMA_ERROR_COMMON: { prototype_id = ECMA_BUILTIN_ID_ERROR_PROTOTYPE; break; } case ECMA_ERROR_EVAL: { prototype_id = ECMA_BUILTIN_ID_EVAL_ERROR_PROTOTYPE; break; } case ECMA_ERROR_RANGE: { prototype_id = ECMA_BUILTIN_ID_RANGE_ERROR_PROTOTYPE; break; } case ECMA_ERROR_REFERENCE: { prototype_id = ECMA_BUILTIN_ID_REFERENCE_ERROR_PROTOTYPE; break; } case ECMA_ERROR_TYPE: { prototype_id = ECMA_BUILTIN_ID_TYPE_ERROR_PROTOTYPE; break; } case ECMA_ERROR_URI: { prototype_id = ECMA_BUILTIN_ID_URI_ERROR_PROTOTYPE; break; } case ECMA_ERROR_SYNTAX: { prototype_id = ECMA_BUILTIN_ID_SYNTAX_ERROR_PROTOTYPE; break; } } ecma_object_t *prototype_obj_p = ecma_builtin_get (prototype_id); ecma_object_t *new_error_obj_p = ecma_create_object (prototype_obj_p, true, ECMA_OBJECT_TYPE_GENERAL); ecma_deref_object (prototype_obj_p); ecma_property_t *class_prop_p = ecma_create_internal_property (new_error_obj_p, ECMA_INTERNAL_PROPERTY_CLASS); ECMA_PROPERTY_VALUE_PTR (class_prop_p)->value = LIT_MAGIC_STRING_ERROR_UL; return new_error_obj_p; #else /* CONFIG_ECMA_COMPACT_PROFILE_DISABLE_ERROR_BUILTINS */ (void) error_type; return ecma_builtin_get (ECMA_BUILTIN_ID_COMPACT_PROFILE_ERROR); #endif /* !CONFIG_ECMA_COMPACT_PROFILE_DISABLE_ERROR_BUILTINS */ } /* ecma_new_standard_error */
/** * String object creation operation. * * See also: ECMA-262 v5, 15.5.2.1 * * @return ecma value * Returned value must be freed with ecma_free_value */ ecma_value_t ecma_op_create_string_object (const ecma_value_t *arguments_list_p, /**< list of arguments that are passed to String constructor */ ecma_length_t arguments_list_len) /**< length of the arguments' list */ { JERRY_ASSERT (arguments_list_len == 0 || arguments_list_p != NULL); ecma_string_t *prim_prop_str_value_p; ecma_number_t length_value; if (arguments_list_len == 0) { prim_prop_str_value_p = ecma_new_ecma_string_from_magic_string_id (LIT_MAGIC_STRING__EMPTY); length_value = ECMA_NUMBER_ZERO; } else { ecma_value_t to_str_arg_value = ecma_op_to_string (arguments_list_p[0]); if (ECMA_IS_VALUE_ERROR (to_str_arg_value)) { return to_str_arg_value; } else { JERRY_ASSERT (!ECMA_IS_VALUE_ERROR (to_str_arg_value)); JERRY_ASSERT (ecma_is_value_string (to_str_arg_value)); prim_prop_str_value_p = ecma_get_string_from_value (to_str_arg_value); ecma_length_t string_len = ecma_string_get_length (prim_prop_str_value_p); length_value = ((ecma_number_t) (uint32_t) string_len); } } #ifndef CONFIG_DISABLE_STRING_BUILTIN ecma_object_t *prototype_obj_p = ecma_builtin_get (ECMA_BUILTIN_ID_STRING_PROTOTYPE); #else /* CONFIG_DISABLE_STRING_BUILTIN */ ecma_object_t *prototype_obj_p = ecma_builtin_get (ECMA_BUILTIN_ID_OBJECT_PROTOTYPE); #endif /* !CONFIG_DISABLE_STRING_BUILTIN */ ecma_object_t *obj_p = ecma_create_object (prototype_obj_p, false, true, ECMA_OBJECT_TYPE_STRING); ecma_deref_object (prototype_obj_p); /* * [[Class]] property is not stored explicitly for objects of ECMA_OBJECT_TYPE_STRING type. * * See also: ecma_object_get_class_name */ ecma_property_t *prim_value_prop_p = ecma_create_internal_property (obj_p, ECMA_INTERNAL_PROPERTY_ECMA_VALUE); ecma_set_internal_property_value (prim_value_prop_p, ecma_make_string_value (prim_prop_str_value_p)); // 15.5.5.1 ecma_string_t *length_magic_string_p = ecma_new_ecma_length_string (); ecma_property_t *length_prop_p = ecma_create_named_data_property (obj_p, length_magic_string_p, ECMA_PROPERTY_FIXED); ecma_set_named_data_property_value (length_prop_p, ecma_make_number_value (length_value)); ecma_deref_ecma_string (length_magic_string_p); return ecma_make_object_value (obj_p); } /* ecma_op_create_string_object */
/** * Initialize specified built-in object. * * Warning: * the routine should be called only from ecma_init_builtins * * @return pointer to the object */ static ecma_object_t * ecma_builtin_init_object (ecma_builtin_id_t obj_builtin_id, /**< built-in ID */ ecma_object_t *prototype_obj_p, /**< prototype object */ ecma_object_type_t obj_type, /**< object's type */ bool is_extensible) /**< value of object's [[Extensible]] property */ { ecma_object_t *object_obj_p = ecma_create_object (prototype_obj_p, is_extensible, obj_type); /* * [[Class]] property of built-in object is not stored explicitly. * * See also: ecma_object_get_class_name */ ecma_property_t *built_in_id_prop_p = ecma_create_internal_property (object_obj_p, ECMA_INTERNAL_PROPERTY_BUILT_IN_ID); built_in_id_prop_p->u.internal_property.value = obj_builtin_id; ecma_set_object_is_builtin (object_obj_p, true); /** Initializing [[PrimitiveValue]] properties of built-in prototype objects */ switch (obj_builtin_id) { #ifndef CONFIG_ECMA_COMPACT_PROFILE_DISABLE_STRING_BUILTIN case ECMA_BUILTIN_ID_STRING_PROTOTYPE: { ecma_string_t *prim_prop_str_value_p = ecma_get_magic_string (LIT_MAGIC_STRING__EMPTY); ecma_property_t *prim_value_prop_p; prim_value_prop_p = ecma_create_internal_property (object_obj_p, ECMA_INTERNAL_PROPERTY_PRIMITIVE_STRING_VALUE); ECMA_SET_POINTER (prim_value_prop_p->u.internal_property.value, prim_prop_str_value_p); break; } #endif /* !CONFIG_ECMA_COMPACT_PROFILE_DISABLE_STRING_BUILTIN */ #ifndef CONFIG_ECMA_COMPACT_PROFILE_DISABLE_NUMBER_BUILTIN case ECMA_BUILTIN_ID_NUMBER_PROTOTYPE: { ecma_number_t *prim_prop_num_value_p = ecma_alloc_number (); *prim_prop_num_value_p = ECMA_NUMBER_ZERO; ecma_property_t *prim_value_prop_p; prim_value_prop_p = ecma_create_internal_property (object_obj_p, ECMA_INTERNAL_PROPERTY_PRIMITIVE_NUMBER_VALUE); ECMA_SET_POINTER (prim_value_prop_p->u.internal_property.value, prim_prop_num_value_p); break; } #endif /* !CONFIG_ECMA_COMPACT_PROFILE_DISABLE_NUMBER_BUILTIN */ #ifndef CONFIG_ECMA_COMPACT_PROFILE_DISABLE_BOOLEAN_BUILTIN case ECMA_BUILTIN_ID_BOOLEAN_PROTOTYPE: { ecma_property_t *prim_value_prop_p; prim_value_prop_p = ecma_create_internal_property (object_obj_p, ECMA_INTERNAL_PROPERTY_PRIMITIVE_BOOLEAN_VALUE); prim_value_prop_p->u.internal_property.value = ECMA_SIMPLE_VALUE_FALSE; break; } #endif /* !CONFIG_ECMA_COMPACT_PROFILE_DISABLE_BOOLEAN_BUILTIN */ #ifndef CONFIG_ECMA_COMPACT_PROFILE_DISABLE_DATE_BUILTIN case ECMA_BUILTIN_ID_DATE_PROTOTYPE: { ecma_number_t *prim_prop_num_value_p = ecma_alloc_number (); *prim_prop_num_value_p = ecma_number_make_nan (); ecma_property_t *prim_value_prop_p; prim_value_prop_p = ecma_create_internal_property (object_obj_p, ECMA_INTERNAL_PROPERTY_PRIMITIVE_NUMBER_VALUE); ECMA_SET_POINTER (prim_value_prop_p->u.internal_property.value, prim_prop_num_value_p); break; } #endif /* !CONFIG_ECMA_COMPACT_PROFILE_DISABLE_DATE_BUILTIN */ #ifndef CONFIG_ECMA_COMPACT_PROFILE_DISABLE_REGEXP_BUILTIN case ECMA_BUILTIN_ID_REGEXP_PROTOTYPE: { ecma_property_t *bytecode_prop_p; bytecode_prop_p = ecma_create_internal_property (object_obj_p, ECMA_INTERNAL_PROPERTY_REGEXP_BYTECODE); bytecode_prop_p->u.internal_property.value = ECMA_NULL_POINTER; break; } #endif /* !CONFIG_ECMA_COMPACT_PROFILE_DISABLE_REGEXP_BUILTIN */ default: { break; } } return object_obj_p; } /* ecma_builtin_init_object */
/** * 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 */
/** * Initialize specified built-in object. * * @return pointer to the object */ static ecma_object_t * ecma_builtin_init_object (ecma_builtin_id_t obj_builtin_id, /**< built-in ID */ ecma_object_t *prototype_obj_p, /**< prototype object */ ecma_object_type_t obj_type, /**< object's type */ bool is_extensible) /**< value of object's [[Extensible]] property */ { ecma_object_t *obj_p = ecma_create_object (prototype_obj_p, true, is_extensible, obj_type); /* * [[Class]] property of built-in object is not stored explicitly. * * See also: ecma_object_get_class_name */ ecma_set_object_is_builtin (obj_p); ecma_extended_object_t *ext_obj_p = (ecma_extended_object_t *) obj_p; ext_obj_p->u.built_in.id = obj_builtin_id; ext_obj_p->u.built_in.routine_id = obj_builtin_id; ext_obj_p->u.built_in.instantiated_bitset = 0; /** Initializing [[PrimitiveValue]] properties of built-in prototype objects */ switch (obj_builtin_id) { #ifndef CONFIG_DISABLE_ARRAY_BUILTIN case ECMA_BUILTIN_ID_ARRAY_PROTOTYPE: { ecma_string_t *length_str_p = ecma_new_ecma_length_string (); ecma_property_t *length_prop_p = ecma_create_named_data_property (obj_p, length_str_p, ECMA_PROPERTY_FLAG_WRITABLE); ecma_set_named_data_property_value (length_prop_p, ecma_make_integer_value (0)); ecma_deref_ecma_string (length_str_p); break; } #endif /* !CONFIG_DISABLE_ARRAY_BUILTIN */ #ifndef CONFIG_DISABLE_STRING_BUILTIN case ECMA_BUILTIN_ID_STRING_PROTOTYPE: { ecma_string_t *prim_prop_str_value_p = ecma_get_magic_string (LIT_MAGIC_STRING__EMPTY); ecma_value_t *prim_value_p = ecma_create_internal_property (obj_p, ECMA_INTERNAL_PROPERTY_ECMA_VALUE); *prim_value_p = ecma_make_string_value (prim_prop_str_value_p); break; } #endif /* !CONFIG_DISABLE_STRING_BUILTIN */ #ifndef CONFIG_DISABLE_NUMBER_BUILTIN case ECMA_BUILTIN_ID_NUMBER_PROTOTYPE: { ecma_value_t *prim_value_p = ecma_create_internal_property (obj_p, ECMA_INTERNAL_PROPERTY_ECMA_VALUE); *prim_value_p = ecma_make_integer_value (0); break; } #endif /* !CONFIG_DISABLE_NUMBER_BUILTIN */ #ifndef CONFIG_DISABLE_BOOLEAN_BUILTIN case ECMA_BUILTIN_ID_BOOLEAN_PROTOTYPE: { ecma_value_t *prim_value_p = ecma_create_internal_property (obj_p, ECMA_INTERNAL_PROPERTY_ECMA_VALUE); *prim_value_p = ecma_make_simple_value (ECMA_SIMPLE_VALUE_FALSE); break; } #endif /* !CONFIG_DISABLE_BOOLEAN_BUILTIN */ #ifndef CONFIG_DISABLE_DATE_BUILTIN case ECMA_BUILTIN_ID_DATE_PROTOTYPE: { ecma_number_t *prim_prop_num_value_p = ecma_alloc_number (); *prim_prop_num_value_p = ecma_number_make_nan (); ecma_value_t *prim_value_p = ecma_create_internal_property (obj_p, ECMA_INTERNAL_PROPERTY_DATE_FLOAT); ECMA_SET_INTERNAL_VALUE_POINTER (*prim_value_p, prim_prop_num_value_p); break; } #endif /* !CONFIG_DISABLE_DATE_BUILTIN */ #ifndef CONFIG_DISABLE_REGEXP_BUILTIN case ECMA_BUILTIN_ID_REGEXP_PROTOTYPE: { ecma_value_t *bytecode_prop_p = ecma_create_internal_property (obj_p, ECMA_INTERNAL_PROPERTY_REGEXP_BYTECODE); *bytecode_prop_p = ECMA_NULL_POINTER; break; } #endif /* !CONFIG_DISABLE_REGEXP_BUILTIN */ default: { break; } } return obj_p; } /* ecma_builtin_init_object */
/** * Function object creation operation. * * See also: ECMA-262 v5, 13.2 * * @return pointer to newly created Function object */ ecma_object_t* ecma_op_create_function_object (ecma_string_t* formal_parameter_list_p[], /**< formal parameters list */ ecma_length_t formal_parameters_number, /**< formal parameters list's length */ ecma_object_t *scope_p, /**< function's scope */ bool is_strict, /**< 'strict' flag */ bool do_instantiate_arguments_object, /**< should an Arguments object be instantiated * for the function object upon call */ const vm_instr_t *instrs_p, /**< byte-code array */ vm_instr_counter_t first_instr_pos) /**< position of first instruction * of function's body */ { // 1., 4., 13. ecma_object_t *prototype_obj_p = ecma_builtin_get (ECMA_BUILTIN_ID_FUNCTION_PROTOTYPE); ecma_object_t *f = ecma_create_object (prototype_obj_p, true, ECMA_OBJECT_TYPE_FUNCTION); ecma_deref_object (prototype_obj_p); // 2., 6., 7., 8. /* * We don't setup [[Get]], [[Call]], [[Construct]], [[HasInstance]] for each function object. * Instead we set the object's type to ECMA_OBJECT_TYPE_FUNCTION * that defines which version of the routine should be used on demand. */ // 3. /* * [[Class]] property is not stored explicitly for objects of ECMA_OBJECT_TYPE_FUNCTION type. * * See also: ecma_object_get_class_name */ // 9. ecma_property_t *scope_prop_p = ecma_create_internal_property (f, ECMA_INTERNAL_PROPERTY_SCOPE); ECMA_SET_POINTER (scope_prop_p->u.internal_property.value, scope_p); // 10., 11. ecma_property_t *formal_parameters_prop_p = ecma_create_internal_property (f, ECMA_INTERNAL_PROPERTY_FORMAL_PARAMETERS); if (formal_parameters_number != 0) { /* * Reverse formal parameter list */ for (ecma_length_t i = 0; i < formal_parameters_number / 2; i++) { ecma_string_t *tmp_p = formal_parameter_list_p[i]; formal_parameter_list_p[i] = formal_parameter_list_p[formal_parameters_number - 1u - i]; formal_parameter_list_p[formal_parameters_number - 1u - i] = tmp_p; } ecma_collection_header_t *formal_parameters_collection_p = ecma_new_strings_collection (formal_parameter_list_p, formal_parameters_number); ECMA_SET_POINTER (formal_parameters_prop_p->u.internal_property.value, formal_parameters_collection_p); } else { JERRY_ASSERT (formal_parameters_prop_p->u.internal_property.value == ECMA_NULL_POINTER); } // 12. ecma_property_t *bytecode_prop_p = ecma_create_internal_property (f, ECMA_INTERNAL_PROPERTY_CODE_BYTECODE); MEM_CP_SET_NON_NULL_POINTER (bytecode_prop_p->u.internal_property.value, instrs_p); ecma_property_t *code_prop_p = ecma_create_internal_property (f, ECMA_INTERNAL_PROPERTY_CODE_FLAGS_AND_OFFSET); code_prop_p->u.internal_property.value = ecma_pack_code_internal_property_value (is_strict, do_instantiate_arguments_object, first_instr_pos); // 14. ecma_number_t* len_p = ecma_alloc_number (); *len_p = ecma_uint32_to_number (formal_parameters_number); // 15. ecma_property_descriptor_t length_prop_desc = ecma_make_empty_property_descriptor (); length_prop_desc.is_value_defined = true; length_prop_desc.value = ecma_make_number_value (len_p); ecma_string_t* magic_string_length_p = ecma_get_magic_string (LIT_MAGIC_STRING_LENGTH); ecma_completion_value_t completion = ecma_op_object_define_own_property (f, magic_string_length_p, &length_prop_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)); ecma_dealloc_number (len_p); len_p = NULL; // 16. ecma_object_t *proto_p = ecma_op_create_object_object_noarg (); // 17. ecma_property_descriptor_t prop_desc = ecma_make_empty_property_descriptor (); { prop_desc.is_value_defined = true; prop_desc.value = ecma_make_object_value (f); prop_desc.is_writable_defined = true; prop_desc.is_writable = true; prop_desc.is_enumerable_defined = true; prop_desc.is_enumerable = false; prop_desc.is_configurable_defined = true; prop_desc.is_configurable = true; } ecma_string_t *magic_string_constructor_p = ecma_get_magic_string (LIT_MAGIC_STRING_CONSTRUCTOR); ecma_op_object_define_own_property (proto_p, magic_string_constructor_p, &prop_desc, false); ecma_deref_ecma_string (magic_string_constructor_p); // 18. prop_desc.value = ecma_make_object_value (proto_p); prop_desc.is_configurable = false; ecma_string_t *magic_string_prototype_p = ecma_get_magic_string (LIT_MAGIC_STRING_PROTOTYPE); ecma_op_object_define_own_property (f, magic_string_prototype_p, &prop_desc, false); ecma_deref_ecma_string (magic_string_prototype_p); ecma_deref_object (proto_p); // 19. if (is_strict) { ecma_object_t *thrower_p = ecma_builtin_get (ECMA_BUILTIN_ID_TYPE_ERROR_THROWER); prop_desc = ecma_make_empty_property_descriptor (); { prop_desc.is_enumerable_defined = true; prop_desc.is_enumerable = false; prop_desc.is_configurable_defined = true; prop_desc.is_configurable = false; prop_desc.is_get_defined = true; prop_desc.get_p = thrower_p; prop_desc.is_set_defined = true; prop_desc.set_p = thrower_p; } ecma_string_t *magic_string_caller_p = ecma_get_magic_string (LIT_MAGIC_STRING_CALLER); ecma_op_object_define_own_property (f, magic_string_caller_p, &prop_desc, false); ecma_deref_ecma_string (magic_string_caller_p); ecma_string_t *magic_string_arguments_p = ecma_get_magic_string (LIT_MAGIC_STRING_ARGUMENTS); ecma_op_object_define_own_property (f, magic_string_arguments_p, &prop_desc, false); ecma_deref_ecma_string (magic_string_arguments_p); ecma_deref_object (thrower_p); } return f; } /* ecma_op_create_function_object */
/** * The Function.prototype object's 'bind' routine * * See also: * ECMA-262 v5, 15.3.4.5 * * @return ecma value * Returned value must be freed with ecma_free_value. */ static ecma_value_t ecma_builtin_function_prototype_object_bind (ecma_value_t this_arg, /**< this argument */ const ecma_value_t *arguments_list_p, /**< list of arguments */ ecma_length_t arguments_number) /**< number of arguments */ { ecma_value_t ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY); /* 2. */ if (!ecma_op_is_callable (this_arg)) { ret_value = ecma_raise_type_error (ECMA_ERR_MSG ("")); } else { /* 4. 11. 18. */ ecma_object_t *prototype_obj_p = ecma_builtin_get (ECMA_BUILTIN_ID_FUNCTION_PROTOTYPE); ecma_object_t *function_p = ecma_create_object (prototype_obj_p, false, true, ECMA_OBJECT_TYPE_BOUND_FUNCTION); ecma_deref_object (prototype_obj_p); /* 7. */ ecma_value_t *target_function_prop_p; target_function_prop_p = ecma_create_internal_property (function_p, ECMA_INTERNAL_PROPERTY_BOUND_FUNCTION_TARGET_FUNCTION); ecma_object_t *this_arg_obj_p = ecma_get_object_from_value (this_arg); ECMA_SET_INTERNAL_VALUE_POINTER (*target_function_prop_p, this_arg_obj_p); /* 8. */ ecma_value_t *bound_this_prop_p; bound_this_prop_p = ecma_create_internal_property (function_p, ECMA_INTERNAL_PROPERTY_BOUND_FUNCTION_BOUND_THIS); const ecma_length_t arg_count = arguments_number; if (arg_count > 0) { *bound_this_prop_p = ecma_copy_value_if_not_object (arguments_list_p[0]); } else { *bound_this_prop_p = ecma_make_simple_value (ECMA_SIMPLE_VALUE_UNDEFINED); } if (arg_count > 1) { ecma_collection_header_t *bound_args_collection_p; bound_args_collection_p = ecma_new_values_collection (&arguments_list_p[1], arg_count - 1, false); ecma_value_t *bound_args_prop_p; bound_args_prop_p = ecma_create_internal_property (function_p, ECMA_INTERNAL_PROPERTY_BOUND_FUNCTION_BOUND_ARGS); ECMA_SET_INTERNAL_VALUE_POINTER (*bound_args_prop_p, bound_args_collection_p); } /* * [[Class]] property is not stored explicitly for objects of ECMA_OBJECT_TYPE_FUNCTION type. * * See also: ecma_object_get_class_name */ /* 16. */ ecma_number_t length = ECMA_NUMBER_ZERO; ecma_string_t *magic_string_length_p = ecma_new_ecma_length_string (); /* 15. */ if (ecma_object_get_class_name (this_arg_obj_p) == LIT_MAGIC_STRING_FUNCTION_UL) { ecma_value_t get_len_value = ecma_op_object_get (this_arg_obj_p, magic_string_length_p); JERRY_ASSERT (!ECMA_IS_VALUE_ERROR (get_len_value)); JERRY_ASSERT (ecma_is_value_number (get_len_value)); const ecma_length_t bound_arg_count = arg_count > 1 ? arg_count - 1 : 0; /* 15.a */ length = ecma_get_number_from_value (get_len_value) - ((ecma_number_t) bound_arg_count); ecma_free_value (get_len_value); /* 15.b */ if (ecma_number_is_negative (length)) { length = ECMA_NUMBER_ZERO; } } /* 17. */ ecma_value_t completion = ecma_builtin_helper_def_prop (function_p, magic_string_length_p, ecma_make_number_value (length), false, /* Writable */ false, /* Enumerable */ false, /* Configurable */ false); /* Failure handling */ JERRY_ASSERT (ecma_is_value_boolean (completion)); ecma_deref_ecma_string (magic_string_length_p); /* 19-21. */ ecma_object_t *thrower_p = ecma_builtin_get (ECMA_BUILTIN_ID_TYPE_ERROR_THROWER); ecma_property_descriptor_t prop_desc = ecma_make_empty_property_descriptor (); { prop_desc.is_enumerable_defined = true; prop_desc.is_enumerable = false; prop_desc.is_configurable_defined = true; prop_desc.is_configurable = false; prop_desc.is_get_defined = true; prop_desc.get_p = thrower_p; prop_desc.is_set_defined = true; prop_desc.set_p = thrower_p; } ecma_string_t *magic_string_caller_p = ecma_get_magic_string (LIT_MAGIC_STRING_CALLER); completion = ecma_op_object_define_own_property (function_p, magic_string_caller_p, &prop_desc, false); JERRY_ASSERT (ecma_is_value_boolean (completion)); ecma_deref_ecma_string (magic_string_caller_p); ecma_string_t *magic_string_arguments_p = ecma_get_magic_string (LIT_MAGIC_STRING_ARGUMENTS); completion = ecma_op_object_define_own_property (function_p, magic_string_arguments_p, &prop_desc, false); JERRY_ASSERT (ecma_is_value_boolean (completion)); ecma_deref_ecma_string (magic_string_arguments_p); ecma_deref_object (thrower_p); /* 22. */ ret_value = ecma_make_object_value (function_p); } return ret_value; } /* ecma_builtin_function_prototype_object_bind */
/** * Arguments object creation operation. * * See also: ECMA-262 v5, 10.6 */ void ecma_op_create_arguments_object (ecma_object_t *func_obj_p, /**< callee function */ ecma_object_t *lex_env_p, /**< lexical environment the Arguments object is created for */ const ecma_value_t *arguments_list_p, /**< arguments list */ ecma_length_t arguments_number, /**< length of arguments list */ const ecma_compiled_code_t *bytecode_data_p) /**< byte code */ { // 2., 3., 6. ecma_object_t *prototype_p = ecma_builtin_get (ECMA_BUILTIN_ID_OBJECT_PROTOTYPE); ecma_object_t *obj_p = ecma_create_object (prototype_p, false, true, ECMA_OBJECT_TYPE_GENERAL); ecma_deref_object (prototype_p); // 11.a, 11.b for (ecma_length_t indx = 0; indx < arguments_number; indx++) { ecma_value_t completion; ecma_string_t *indx_string_p = ecma_new_ecma_string_from_uint32 (indx); completion = ecma_builtin_helper_def_prop (obj_p, indx_string_p, arguments_list_p[indx], true, /* Writable */ true, /* Enumerable */ true, /* Configurable */ false); /* Failure handling */ JERRY_ASSERT (ecma_is_value_true (completion)); ecma_deref_ecma_string (indx_string_p); } bool is_strict = (bytecode_data_p->status_flags & CBC_CODE_FLAGS_STRICT_MODE) != 0; // 1. // 4. ecma_property_t *class_prop_p = ecma_create_internal_property (obj_p, ECMA_INTERNAL_PROPERTY_CLASS); ECMA_PROPERTY_VALUE_PTR (class_prop_p)->value = LIT_MAGIC_STRING_ARGUMENTS_UL; // 7. ecma_string_t *length_magic_string_p = ecma_new_ecma_length_string (); ecma_value_t completion = ecma_builtin_helper_def_prop (obj_p, length_magic_string_p, ecma_make_uint32_value (arguments_number), true, /* Writable */ false, /* Enumerable */ true, /* Configurable */ false); /* Failure handling */ JERRY_ASSERT (ecma_is_value_true (completion)); ecma_deref_ecma_string (length_magic_string_p); ecma_property_descriptor_t prop_desc = ecma_make_empty_property_descriptor (); if (bytecode_data_p != NULL) { ecma_length_t formal_params_number; jmem_cpointer_t *literal_p; if (bytecode_data_p->status_flags & CBC_CODE_FLAGS_UINT16_ARGUMENTS) { cbc_uint16_arguments_t *args_p = (cbc_uint16_arguments_t *) bytecode_data_p; uint8_t *byte_p = (uint8_t *) bytecode_data_p; formal_params_number = args_p->argument_end; literal_p = (jmem_cpointer_t *) (byte_p + sizeof (cbc_uint16_arguments_t)); } else { cbc_uint8_arguments_t *args_p = (cbc_uint8_arguments_t *) bytecode_data_p; uint8_t *byte_p = (uint8_t *) bytecode_data_p; formal_params_number = args_p->argument_end; literal_p = (jmem_cpointer_t *) (byte_p + sizeof (cbc_uint8_arguments_t)); } if (!is_strict && arguments_number > 0 && formal_params_number > 0) { // 8. ecma_object_t *map_p = ecma_op_create_object_object_noarg (); // 11.c for (uint32_t indx = 0; indx < formal_params_number; indx++) { // i. if (literal_p[indx] == JMEM_CP_NULL) { continue; } ecma_string_t *name_p = JMEM_CP_GET_NON_NULL_POINTER (ecma_string_t, literal_p[indx]); ecma_string_t *indx_string_p = ecma_new_ecma_string_from_uint32 ((uint32_t) indx); prop_desc.is_value_defined = true; prop_desc.value = ecma_make_string_value (name_p); prop_desc.is_configurable_defined = true; prop_desc.is_configurable = true; completion = ecma_op_object_define_own_property (map_p, indx_string_p, &prop_desc, false); JERRY_ASSERT (ecma_is_value_true (completion)); ecma_deref_ecma_string (indx_string_p); } // 12. ecma_set_object_type (obj_p, ECMA_OBJECT_TYPE_ARGUMENTS); /* * [[Class]] property is not stored explicitly for objects of ECMA_OBJECT_TYPE_ARGUMENTS type. * * See also: ecma_object_get_class_name */ ecma_delete_property (obj_p, class_prop_p); ecma_property_t *parameters_map_prop_p = ecma_create_internal_property (obj_p, ECMA_INTERNAL_PROPERTY_PARAMETERS_MAP); ECMA_SET_INTERNAL_VALUE_POINTER (ECMA_PROPERTY_VALUE_PTR (parameters_map_prop_p)->value, map_p); ecma_property_t *scope_prop_p = ecma_create_internal_property (map_p, ECMA_INTERNAL_PROPERTY_SCOPE); ECMA_SET_INTERNAL_VALUE_POINTER (ECMA_PROPERTY_VALUE_PTR (scope_prop_p)->value, lex_env_p); ecma_deref_object (map_p); } } // 13. if (!is_strict) { ecma_string_t *callee_magic_string_p = ecma_get_magic_string (LIT_MAGIC_STRING_CALLEE); completion = ecma_builtin_helper_def_prop (obj_p, callee_magic_string_p, ecma_make_object_value (func_obj_p), true, /* Writable */ false, /* Enumerable */ true, /* Configurable */ false); /* Failure handling */ JERRY_ASSERT (ecma_is_value_true (completion)); ecma_deref_ecma_string (callee_magic_string_p); } else { ecma_object_t *thrower_p = ecma_builtin_get (ECMA_BUILTIN_ID_TYPE_ERROR_THROWER); // 14. prop_desc = ecma_make_empty_property_descriptor (); { prop_desc.is_get_defined = true; prop_desc.get_p = thrower_p; prop_desc.is_set_defined = true; prop_desc.set_p = thrower_p; prop_desc.is_enumerable_defined = true; prop_desc.is_enumerable = false; prop_desc.is_configurable_defined = true; prop_desc.is_configurable = false; } ecma_string_t *callee_magic_string_p = ecma_get_magic_string (LIT_MAGIC_STRING_CALLEE); completion = ecma_op_object_define_own_property (obj_p, callee_magic_string_p, &prop_desc, false); JERRY_ASSERT (ecma_is_value_true (completion)); ecma_deref_ecma_string (callee_magic_string_p); ecma_string_t *caller_magic_string_p = ecma_get_magic_string (LIT_MAGIC_STRING_CALLER); completion = ecma_op_object_define_own_property (obj_p, caller_magic_string_p, &prop_desc, false); JERRY_ASSERT (ecma_is_value_true (completion)); ecma_deref_ecma_string (caller_magic_string_p); ecma_deref_object (thrower_p); } ecma_string_t *arguments_string_p = ecma_get_magic_string (LIT_MAGIC_STRING_ARGUMENTS); if (is_strict) { ecma_op_create_immutable_binding (lex_env_p, arguments_string_p); ecma_op_initialize_immutable_binding (lex_env_p, arguments_string_p, ecma_make_object_value (obj_p)); } else { ecma_value_t completion = ecma_op_create_mutable_binding (lex_env_p, arguments_string_p, false); JERRY_ASSERT (ecma_is_value_empty (completion)); completion = ecma_op_set_mutable_binding (lex_env_p, arguments_string_p, ecma_make_object_value (obj_p), false); JERRY_ASSERT (ecma_is_value_empty (completion)); } ecma_deref_ecma_string (arguments_string_p); ecma_deref_object (obj_p); } /* ecma_op_create_arguments_object */