/** * Helper function for increase or decrease the remaining count. * * @return the current remaining count after increase or decrease. */ static ecma_length_t ecma_builtin_promise_remaining_inc_or_dec (ecma_value_t remaining, /**< the remaining count */ bool is_inc) /**< whether to increase the count */ { JERRY_ASSERT (ecma_is_value_object (remaining)); ecma_object_t *remaining_p = ecma_get_object_from_value (remaining); ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) remaining_p; JERRY_ASSERT (ext_object_p->u.class_prop.class_id == LIT_MAGIC_STRING_NUMBER_UL); JERRY_ASSERT (ecma_is_value_integer_number (ext_object_p->u.class_prop.u.value)); ecma_length_t current = (ecma_length_t) ecma_get_integer_from_value (ext_object_p->u.class_prop.u.value); if (is_inc) { current++; } else { current--; } ext_object_p->u.class_prop.u.value = ecma_make_uint32_value (current); return current; } /* ecma_builtin_promise_remaining_inc_or_dec */
/** * 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 */