1425bb815Sopenharmony_ci/* Copyright JS Foundation and other contributors, http://js.foundation 2425bb815Sopenharmony_ci * 3425bb815Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4425bb815Sopenharmony_ci * you may not use this file except in compliance with the License. 5425bb815Sopenharmony_ci * You may obtain a copy of the License at 6425bb815Sopenharmony_ci * 7425bb815Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8425bb815Sopenharmony_ci * 9425bb815Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10425bb815Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS 11425bb815Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12425bb815Sopenharmony_ci * See the License for the specific language governing permissions and 13425bb815Sopenharmony_ci * limitations under the License. 14425bb815Sopenharmony_ci */ 15425bb815Sopenharmony_ci 16425bb815Sopenharmony_ci#include "ecma-array-object.h" 17425bb815Sopenharmony_ci#include "ecma-builtins.h" 18425bb815Sopenharmony_ci#include "ecma-builtin-helpers.h" 19425bb815Sopenharmony_ci#include "ecma-exceptions.h" 20425bb815Sopenharmony_ci#include "ecma-gc.h" 21425bb815Sopenharmony_ci#include "ecma-globals.h" 22425bb815Sopenharmony_ci#include "ecma-helpers.h" 23425bb815Sopenharmony_ci#include "ecma-function-object.h" 24425bb815Sopenharmony_ci#include "ecma-lex-env.h" 25425bb815Sopenharmony_ci#include "ecma-string-object.h" 26425bb815Sopenharmony_ci#include "ecma-objects-arguments.h" 27425bb815Sopenharmony_ci#include "ecma-objects-general.h" 28425bb815Sopenharmony_ci#include "ecma-objects.h" 29425bb815Sopenharmony_ci#include "ecma-proxy-object.h" 30425bb815Sopenharmony_ci#include "jcontext.h" 31425bb815Sopenharmony_ci 32425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) 33425bb815Sopenharmony_ci#include "ecma-typedarray-object.h" 34425bb815Sopenharmony_ci#include "ecma-arraybuffer-object.h" 35425bb815Sopenharmony_ci#include "ecma-try-catch-macro.h" 36425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) */ 37425bb815Sopenharmony_ci 38425bb815Sopenharmony_ci/** \addtogroup ecma ECMA 39425bb815Sopenharmony_ci * @{ 40425bb815Sopenharmony_ci * 41425bb815Sopenharmony_ci * \addtogroup ecmaobjectsinternalops ECMA objects' operations 42425bb815Sopenharmony_ci * @{ 43425bb815Sopenharmony_ci */ 44425bb815Sopenharmony_ci 45425bb815Sopenharmony_ci/** 46425bb815Sopenharmony_ci * Hash bitmap size for ecma objects 47425bb815Sopenharmony_ci */ 48425bb815Sopenharmony_ci#define ECMA_OBJECT_HASH_BITMAP_SIZE 256 49425bb815Sopenharmony_ci 50425bb815Sopenharmony_ci/** 51425bb815Sopenharmony_ci * Assert that specified object type value is valid 52425bb815Sopenharmony_ci * 53425bb815Sopenharmony_ci * @param type object's implementation-defined type 54425bb815Sopenharmony_ci */ 55425bb815Sopenharmony_ci#ifndef JERRY_NDEBUG 56425bb815Sopenharmony_ci#define JERRY_ASSERT_OBJECT_TYPE_IS_VALID(type) \ 57425bb815Sopenharmony_ci JERRY_ASSERT (type < ECMA_OBJECT_TYPE__MAX); 58425bb815Sopenharmony_ci#else /* JERRY_NDEBUG */ 59425bb815Sopenharmony_ci#define JERRY_ASSERT_OBJECT_TYPE_IS_VALID(type) 60425bb815Sopenharmony_ci#endif /* !JERRY_NDEBUG */ 61425bb815Sopenharmony_ci 62425bb815Sopenharmony_ci/** 63425bb815Sopenharmony_ci * [[GetOwnProperty]] ecma object's operation 64425bb815Sopenharmony_ci * 65425bb815Sopenharmony_ci * See also: 66425bb815Sopenharmony_ci * ECMA-262 v5, 8.6.2; ECMA-262 v5, Table 8 67425bb815Sopenharmony_ci * 68425bb815Sopenharmony_ci * @return pointer to a property - if it exists, 69425bb815Sopenharmony_ci * NULL (i.e. ecma-undefined) - otherwise. 70425bb815Sopenharmony_ci */ 71425bb815Sopenharmony_ciecma_property_t 72425bb815Sopenharmony_ciecma_op_object_get_own_property (ecma_object_t *object_p, /**< the object */ 73425bb815Sopenharmony_ci ecma_string_t *property_name_p, /**< property name */ 74425bb815Sopenharmony_ci ecma_property_ref_t *property_ref_p, /**< property reference */ 75425bb815Sopenharmony_ci uint32_t options) /**< option bits */ 76425bb815Sopenharmony_ci{ 77425bb815Sopenharmony_ci JERRY_ASSERT (object_p != NULL 78425bb815Sopenharmony_ci && !ecma_is_lexical_environment (object_p)); 79425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015_BUILTIN_PROXY) 80425bb815Sopenharmony_ci JERRY_ASSERT (!ECMA_OBJECT_IS_PROXY (object_p)); 81425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */ 82425bb815Sopenharmony_ci JERRY_ASSERT (property_name_p != NULL); 83425bb815Sopenharmony_ci JERRY_ASSERT (options == ECMA_PROPERTY_GET_NO_OPTIONS 84425bb815Sopenharmony_ci || options == ECMA_PROPERTY_GET_HAS_OWN_PROP 85425bb815Sopenharmony_ci || property_ref_p != NULL); 86425bb815Sopenharmony_ci 87425bb815Sopenharmony_ci ecma_object_type_t type = ecma_get_object_type (object_p); 88425bb815Sopenharmony_ci 89425bb815Sopenharmony_ci switch (type) 90425bb815Sopenharmony_ci { 91425bb815Sopenharmony_ci case ECMA_OBJECT_TYPE_CLASS: 92425bb815Sopenharmony_ci { 93425bb815Sopenharmony_ci ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) object_p; 94425bb815Sopenharmony_ci 95425bb815Sopenharmony_ci if (ext_object_p->u.class_prop.class_id == LIT_MAGIC_STRING_STRING_UL) 96425bb815Sopenharmony_ci { 97425bb815Sopenharmony_ci if (ecma_string_is_length (property_name_p)) 98425bb815Sopenharmony_ci { 99425bb815Sopenharmony_ci if (options & ECMA_PROPERTY_GET_VALUE) 100425bb815Sopenharmony_ci { 101425bb815Sopenharmony_ci ecma_value_t prim_value_p = ext_object_p->u.class_prop.u.value; 102425bb815Sopenharmony_ci ecma_string_t *prim_value_str_p = ecma_get_string_from_value (prim_value_p); 103425bb815Sopenharmony_ci 104425bb815Sopenharmony_ci ecma_length_t length = ecma_string_get_length (prim_value_str_p); 105425bb815Sopenharmony_ci property_ref_p->virtual_value = ecma_make_uint32_value (length); 106425bb815Sopenharmony_ci } 107425bb815Sopenharmony_ci 108425bb815Sopenharmony_ci return ECMA_PROPERTY_TYPE_VIRTUAL; 109425bb815Sopenharmony_ci } 110425bb815Sopenharmony_ci 111425bb815Sopenharmony_ci uint32_t index = ecma_string_get_array_index (property_name_p); 112425bb815Sopenharmony_ci 113425bb815Sopenharmony_ci if (index != ECMA_STRING_NOT_ARRAY_INDEX) 114425bb815Sopenharmony_ci { 115425bb815Sopenharmony_ci ecma_value_t prim_value_p = ext_object_p->u.class_prop.u.value; 116425bb815Sopenharmony_ci ecma_string_t *prim_value_str_p = ecma_get_string_from_value (prim_value_p); 117425bb815Sopenharmony_ci 118425bb815Sopenharmony_ci if (index < ecma_string_get_length (prim_value_str_p)) 119425bb815Sopenharmony_ci { 120425bb815Sopenharmony_ci if (options & ECMA_PROPERTY_GET_VALUE) 121425bb815Sopenharmony_ci { 122425bb815Sopenharmony_ci ecma_char_t char_at_idx = ecma_string_get_char_at_pos (prim_value_str_p, index); 123425bb815Sopenharmony_ci ecma_string_t *char_str_p = ecma_new_ecma_string_from_code_unit (char_at_idx); 124425bb815Sopenharmony_ci property_ref_p->virtual_value = ecma_make_string_value (char_str_p); 125425bb815Sopenharmony_ci } 126425bb815Sopenharmony_ci 127425bb815Sopenharmony_ci return ECMA_PROPERTY_FLAG_ENUMERABLE | ECMA_PROPERTY_TYPE_VIRTUAL; 128425bb815Sopenharmony_ci } 129425bb815Sopenharmony_ci } 130425bb815Sopenharmony_ci } 131425bb815Sopenharmony_ci break; 132425bb815Sopenharmony_ci } 133425bb815Sopenharmony_ci case ECMA_OBJECT_TYPE_ARRAY: 134425bb815Sopenharmony_ci { 135425bb815Sopenharmony_ci ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) object_p; 136425bb815Sopenharmony_ci 137425bb815Sopenharmony_ci if (ecma_string_is_length (property_name_p)) 138425bb815Sopenharmony_ci { 139425bb815Sopenharmony_ci if (options & ECMA_PROPERTY_GET_VALUE) 140425bb815Sopenharmony_ci { 141425bb815Sopenharmony_ci property_ref_p->virtual_value = ecma_make_uint32_value (ext_object_p->u.array.length); 142425bb815Sopenharmony_ci } 143425bb815Sopenharmony_ci 144425bb815Sopenharmony_ci return ext_object_p->u.array.u.length_prop & (ECMA_PROPERTY_TYPE_VIRTUAL | ECMA_PROPERTY_FLAG_WRITABLE); 145425bb815Sopenharmony_ci } 146425bb815Sopenharmony_ci 147425bb815Sopenharmony_ci if (ecma_op_array_is_fast_array (ext_object_p)) 148425bb815Sopenharmony_ci { 149425bb815Sopenharmony_ci uint32_t index = ecma_string_get_array_index (property_name_p); 150425bb815Sopenharmony_ci 151425bb815Sopenharmony_ci if (index != ECMA_STRING_NOT_ARRAY_INDEX) 152425bb815Sopenharmony_ci { 153425bb815Sopenharmony_ci if (JERRY_LIKELY (index < ext_object_p->u.array.length)) 154425bb815Sopenharmony_ci { 155425bb815Sopenharmony_ci ecma_value_t *values_p = ECMA_GET_NON_NULL_POINTER (ecma_value_t, object_p->u1.property_list_cp); 156425bb815Sopenharmony_ci 157425bb815Sopenharmony_ci if (ecma_is_value_array_hole (values_p[index])) 158425bb815Sopenharmony_ci { 159425bb815Sopenharmony_ci return ECMA_PROPERTY_TYPE_NOT_FOUND; 160425bb815Sopenharmony_ci } 161425bb815Sopenharmony_ci 162425bb815Sopenharmony_ci if (options & ECMA_PROPERTY_GET_VALUE) 163425bb815Sopenharmony_ci { 164425bb815Sopenharmony_ci property_ref_p->virtual_value = ecma_fast_copy_value (values_p[index]); 165425bb815Sopenharmony_ci } 166425bb815Sopenharmony_ci 167425bb815Sopenharmony_ci return (ecma_property_t) (ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE | ECMA_PROPERTY_TYPE_VIRTUAL); 168425bb815Sopenharmony_ci } 169425bb815Sopenharmony_ci } 170425bb815Sopenharmony_ci 171425bb815Sopenharmony_ci return ECMA_PROPERTY_TYPE_NOT_FOUND; 172425bb815Sopenharmony_ci } 173425bb815Sopenharmony_ci 174425bb815Sopenharmony_ci break; 175425bb815Sopenharmony_ci } 176425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) 177425bb815Sopenharmony_ci case ECMA_OBJECT_TYPE_PSEUDO_ARRAY: 178425bb815Sopenharmony_ci { 179425bb815Sopenharmony_ci /* ES2015 9.4.5.1 */ 180425bb815Sopenharmony_ci if (ecma_object_is_typedarray (object_p)) 181425bb815Sopenharmony_ci { 182425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 183425bb815Sopenharmony_ci if (ecma_prop_name_is_symbol (property_name_p)) 184425bb815Sopenharmony_ci { 185425bb815Sopenharmony_ci break; 186425bb815Sopenharmony_ci } 187425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 188425bb815Sopenharmony_ci 189425bb815Sopenharmony_ci uint32_t array_index = ecma_string_get_array_index (property_name_p); 190425bb815Sopenharmony_ci 191425bb815Sopenharmony_ci if (array_index != ECMA_STRING_NOT_ARRAY_INDEX) 192425bb815Sopenharmony_ci { 193425bb815Sopenharmony_ci ecma_typedarray_info_t info = ecma_typedarray_get_info (object_p); 194425bb815Sopenharmony_ci ecma_value_t value = ECMA_VALUE_UNDEFINED; 195425bb815Sopenharmony_ci 196425bb815Sopenharmony_ci if (array_index < info.length) 197425bb815Sopenharmony_ci { 198425bb815Sopenharmony_ci ecma_length_t byte_pos = array_index << info.shift; 199425bb815Sopenharmony_ci ecma_number_t num = ecma_get_typedarray_element (info.buffer_p + byte_pos, info.id); 200425bb815Sopenharmony_ci value = ecma_make_number_value (num); 201425bb815Sopenharmony_ci } 202425bb815Sopenharmony_ci 203425bb815Sopenharmony_ci if (!ecma_is_value_undefined (value)) 204425bb815Sopenharmony_ci { 205425bb815Sopenharmony_ci if (options & ECMA_PROPERTY_GET_VALUE) 206425bb815Sopenharmony_ci { 207425bb815Sopenharmony_ci property_ref_p->virtual_value = value; 208425bb815Sopenharmony_ci } 209425bb815Sopenharmony_ci else 210425bb815Sopenharmony_ci { 211425bb815Sopenharmony_ci ecma_fast_free_value (value); 212425bb815Sopenharmony_ci } 213425bb815Sopenharmony_ci 214425bb815Sopenharmony_ci return ECMA_PROPERTY_ENUMERABLE_WRITABLE | ECMA_PROPERTY_TYPE_VIRTUAL; 215425bb815Sopenharmony_ci } 216425bb815Sopenharmony_ci 217425bb815Sopenharmony_ci return ECMA_PROPERTY_TYPE_NOT_FOUND_AND_STOP; 218425bb815Sopenharmony_ci } 219425bb815Sopenharmony_ci 220425bb815Sopenharmony_ci ecma_number_t num = ecma_string_to_number (property_name_p); 221425bb815Sopenharmony_ci ecma_string_t *num_to_str = ecma_new_ecma_string_from_number (num); 222425bb815Sopenharmony_ci 223425bb815Sopenharmony_ci if (ecma_compare_ecma_strings (property_name_p, num_to_str)) 224425bb815Sopenharmony_ci { 225425bb815Sopenharmony_ci ecma_deref_ecma_string (num_to_str); 226425bb815Sopenharmony_ci 227425bb815Sopenharmony_ci return ECMA_PROPERTY_TYPE_NOT_FOUND_AND_STOP; 228425bb815Sopenharmony_ci } 229425bb815Sopenharmony_ci 230425bb815Sopenharmony_ci ecma_deref_ecma_string (num_to_str); 231425bb815Sopenharmony_ci } 232425bb815Sopenharmony_ci 233425bb815Sopenharmony_ci break; 234425bb815Sopenharmony_ci } 235425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) */ 236425bb815Sopenharmony_ci default: 237425bb815Sopenharmony_ci { 238425bb815Sopenharmony_ci break; 239425bb815Sopenharmony_ci } 240425bb815Sopenharmony_ci } 241425bb815Sopenharmony_ci 242425bb815Sopenharmony_ci ecma_property_t *property_p = ecma_find_named_property (object_p, property_name_p); 243425bb815Sopenharmony_ci 244425bb815Sopenharmony_ci if (property_p == NULL) 245425bb815Sopenharmony_ci { 246425bb815Sopenharmony_ci if (ecma_get_object_is_builtin (object_p)) 247425bb815Sopenharmony_ci { 248425bb815Sopenharmony_ci if (type == ECMA_OBJECT_TYPE_FUNCTION && ecma_builtin_function_is_routine (object_p)) 249425bb815Sopenharmony_ci { 250425bb815Sopenharmony_ci property_p = ecma_builtin_routine_try_to_instantiate_property (object_p, property_name_p); 251425bb815Sopenharmony_ci } 252425bb815Sopenharmony_ci else 253425bb815Sopenharmony_ci { 254425bb815Sopenharmony_ci property_p = ecma_builtin_try_to_instantiate_property (object_p, property_name_p); 255425bb815Sopenharmony_ci } 256425bb815Sopenharmony_ci } 257425bb815Sopenharmony_ci else if (type == ECMA_OBJECT_TYPE_FUNCTION) 258425bb815Sopenharmony_ci { 259425bb815Sopenharmony_ci#if !ENABLED (JERRY_ES2015) 260425bb815Sopenharmony_ci if (ecma_string_is_length (property_name_p)) 261425bb815Sopenharmony_ci { 262425bb815Sopenharmony_ci if (options & ECMA_PROPERTY_GET_VALUE) 263425bb815Sopenharmony_ci { 264425bb815Sopenharmony_ci /* Get length virtual property. */ 265425bb815Sopenharmony_ci ecma_extended_object_t *ext_func_p = (ecma_extended_object_t *) object_p; 266425bb815Sopenharmony_ci const ecma_compiled_code_t *bytecode_data_p = ecma_op_function_get_compiled_code (ext_func_p); 267425bb815Sopenharmony_ci 268425bb815Sopenharmony_ci uint32_t len; 269425bb815Sopenharmony_ci if (bytecode_data_p->status_flags & CBC_CODE_FLAGS_UINT16_ARGUMENTS) 270425bb815Sopenharmony_ci { 271425bb815Sopenharmony_ci cbc_uint16_arguments_t *args_p = (cbc_uint16_arguments_t *) bytecode_data_p; 272425bb815Sopenharmony_ci len = args_p->argument_end; 273425bb815Sopenharmony_ci } 274425bb815Sopenharmony_ci else 275425bb815Sopenharmony_ci { 276425bb815Sopenharmony_ci cbc_uint8_arguments_t *args_p = (cbc_uint8_arguments_t *) bytecode_data_p; 277425bb815Sopenharmony_ci len = args_p->argument_end; 278425bb815Sopenharmony_ci } 279425bb815Sopenharmony_ci 280425bb815Sopenharmony_ci property_ref_p->virtual_value = ecma_make_uint32_value (len); 281425bb815Sopenharmony_ci } 282425bb815Sopenharmony_ci 283425bb815Sopenharmony_ci return ECMA_PROPERTY_TYPE_VIRTUAL; 284425bb815Sopenharmony_ci } 285425bb815Sopenharmony_ci#endif /* !ENABLED (JERRY_ES2015) */ 286425bb815Sopenharmony_ci 287425bb815Sopenharmony_ci /* Get prototype physical property. */ 288425bb815Sopenharmony_ci property_p = ecma_op_function_try_to_lazy_instantiate_property (object_p, property_name_p); 289425bb815Sopenharmony_ci } 290425bb815Sopenharmony_ci else if (type == ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION) 291425bb815Sopenharmony_ci { 292425bb815Sopenharmony_ci property_p = ecma_op_external_function_try_to_lazy_instantiate_property (object_p, property_name_p); 293425bb815Sopenharmony_ci } 294425bb815Sopenharmony_ci else if (type == ECMA_OBJECT_TYPE_BOUND_FUNCTION) 295425bb815Sopenharmony_ci { 296425bb815Sopenharmony_ci property_p = ecma_op_bound_function_try_to_lazy_instantiate_property (object_p, property_name_p); 297425bb815Sopenharmony_ci } 298425bb815Sopenharmony_ci 299425bb815Sopenharmony_ci if (property_p == NULL) 300425bb815Sopenharmony_ci { 301425bb815Sopenharmony_ci return ECMA_PROPERTY_TYPE_NOT_FOUND; 302425bb815Sopenharmony_ci } 303425bb815Sopenharmony_ci } 304425bb815Sopenharmony_ci else if (type == ECMA_OBJECT_TYPE_PSEUDO_ARRAY 305425bb815Sopenharmony_ci && (options & ECMA_PROPERTY_GET_HAS_OWN_PROP)) 306425bb815Sopenharmony_ci { 307425bb815Sopenharmony_ci ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) object_p; 308425bb815Sopenharmony_ci 309425bb815Sopenharmony_ci if (ext_object_p->u.pseudo_array.type == ECMA_PSEUDO_ARRAY_ARGUMENTS) 310425bb815Sopenharmony_ci { 311425bb815Sopenharmony_ci uint32_t index = ecma_string_get_array_index (property_name_p); 312425bb815Sopenharmony_ci 313425bb815Sopenharmony_ci if (index != ECMA_STRING_NOT_ARRAY_INDEX 314425bb815Sopenharmony_ci && index < ext_object_p->u.pseudo_array.u1.length) 315425bb815Sopenharmony_ci { 316425bb815Sopenharmony_ci ecma_value_t *arg_Literal_p = (ecma_value_t *) (ext_object_p + 1); 317425bb815Sopenharmony_ci 318425bb815Sopenharmony_ci if (arg_Literal_p[index] != ECMA_VALUE_EMPTY) 319425bb815Sopenharmony_ci { 320425bb815Sopenharmony_ci ecma_string_t *arg_name_p = ecma_get_string_from_value (arg_Literal_p[index]); 321425bb815Sopenharmony_ci 322425bb815Sopenharmony_ci ecma_object_t *lex_env_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_object_t, 323425bb815Sopenharmony_ci ext_object_p->u.pseudo_array.u2.lex_env_cp); 324425bb815Sopenharmony_ci 325425bb815Sopenharmony_ci JERRY_ASSERT (lex_env_p != NULL 326425bb815Sopenharmony_ci && ecma_is_lexical_environment (lex_env_p)); 327425bb815Sopenharmony_ci 328425bb815Sopenharmony_ci ecma_value_t binding_value = ecma_op_get_binding_value (lex_env_p, arg_name_p, true); 329425bb815Sopenharmony_ci 330425bb815Sopenharmony_ci ecma_named_data_property_assign_value (object_p, 331425bb815Sopenharmony_ci ECMA_PROPERTY_VALUE_PTR (property_p), 332425bb815Sopenharmony_ci binding_value); 333425bb815Sopenharmony_ci ecma_free_value (binding_value); 334425bb815Sopenharmony_ci } 335425bb815Sopenharmony_ci } 336425bb815Sopenharmony_ci } 337425bb815Sopenharmony_ci } 338425bb815Sopenharmony_ci 339425bb815Sopenharmony_ci if (options & ECMA_PROPERTY_GET_EXT_REFERENCE) 340425bb815Sopenharmony_ci { 341425bb815Sopenharmony_ci ((ecma_extended_property_ref_t *) property_ref_p)->property_p = property_p; 342425bb815Sopenharmony_ci } 343425bb815Sopenharmony_ci 344425bb815Sopenharmony_ci if (property_ref_p != NULL) 345425bb815Sopenharmony_ci { 346425bb815Sopenharmony_ci property_ref_p->value_p = ECMA_PROPERTY_VALUE_PTR (property_p); 347425bb815Sopenharmony_ci } 348425bb815Sopenharmony_ci 349425bb815Sopenharmony_ci return *property_p; 350425bb815Sopenharmony_ci} /* ecma_op_object_get_own_property */ 351425bb815Sopenharmony_ci 352425bb815Sopenharmony_ci/** 353425bb815Sopenharmony_ci * [[GetProperty]] ecma object's operation 354425bb815Sopenharmony_ci * 355425bb815Sopenharmony_ci * See also: 356425bb815Sopenharmony_ci * ECMA-262 v5, 8.6.2; ECMA-262 v5, Table 8 357425bb815Sopenharmony_ci * 358425bb815Sopenharmony_ci * @return pointer to a property - if it exists, 359425bb815Sopenharmony_ci * NULL (i.e. ecma-undefined) - otherwise. 360425bb815Sopenharmony_ci */ 361425bb815Sopenharmony_cistatic ecma_property_t 362425bb815Sopenharmony_ciecma_op_object_get_property (ecma_object_t *object_p, /**< the object */ 363425bb815Sopenharmony_ci ecma_string_t *property_name_p, /**< property name */ 364425bb815Sopenharmony_ci ecma_property_ref_t *property_ref_p, /**< property reference */ 365425bb815Sopenharmony_ci uint32_t options) /**< option bits */ 366425bb815Sopenharmony_ci{ 367425bb815Sopenharmony_ci while (true) 368425bb815Sopenharmony_ci { 369425bb815Sopenharmony_ci ecma_property_t property = ecma_op_object_get_own_property (object_p, 370425bb815Sopenharmony_ci property_name_p, 371425bb815Sopenharmony_ci property_ref_p, 372425bb815Sopenharmony_ci options); 373425bb815Sopenharmony_ci 374425bb815Sopenharmony_ci if (property != ECMA_PROPERTY_TYPE_NOT_FOUND && property != ECMA_PROPERTY_TYPE_NOT_FOUND_AND_STOP) 375425bb815Sopenharmony_ci { 376425bb815Sopenharmony_ci return property; 377425bb815Sopenharmony_ci } 378425bb815Sopenharmony_ci 379425bb815Sopenharmony_ci if (property == ECMA_PROPERTY_TYPE_NOT_FOUND_AND_STOP) 380425bb815Sopenharmony_ci { 381425bb815Sopenharmony_ci break; 382425bb815Sopenharmony_ci } 383425bb815Sopenharmony_ci 384425bb815Sopenharmony_ci if (object_p->u2.prototype_cp == JMEM_CP_NULL) 385425bb815Sopenharmony_ci { 386425bb815Sopenharmony_ci break; 387425bb815Sopenharmony_ci } 388425bb815Sopenharmony_ci 389425bb815Sopenharmony_ci object_p = ECMA_GET_NON_NULL_POINTER (ecma_object_t, object_p->u2.prototype_cp); 390425bb815Sopenharmony_ci } 391425bb815Sopenharmony_ci 392425bb815Sopenharmony_ci return ECMA_PROPERTY_TYPE_NOT_FOUND; 393425bb815Sopenharmony_ci} /* ecma_op_object_get_property */ 394425bb815Sopenharmony_ci 395425bb815Sopenharmony_ci/** 396425bb815Sopenharmony_ci * Generic [[HasProperty]] operation 397425bb815Sopenharmony_ci * 398425bb815Sopenharmony_ci * See also: 399425bb815Sopenharmony_ci * ECMAScript v6, 9.1.7.1 400425bb815Sopenharmony_ci * 401425bb815Sopenharmony_ci * @return ECMA_VALUE_ERROR - if the operation fails 402425bb815Sopenharmony_ci * ECMA_VALUE_{TRUE_FALSE} - whether the property is found 403425bb815Sopenharmony_ci */ 404425bb815Sopenharmony_ciinline ecma_value_t JERRY_ATTR_ALWAYS_INLINE 405425bb815Sopenharmony_ciecma_op_object_has_property (ecma_object_t *object_p, /**< the object */ 406425bb815Sopenharmony_ci ecma_string_t *property_name_p) /**< property name */ 407425bb815Sopenharmony_ci{ 408425bb815Sopenharmony_ci while (true) 409425bb815Sopenharmony_ci { 410425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015_BUILTIN_PROXY) 411425bb815Sopenharmony_ci if (ECMA_OBJECT_IS_PROXY (object_p)) 412425bb815Sopenharmony_ci { 413425bb815Sopenharmony_ci return ecma_proxy_object_has (object_p, property_name_p); 414425bb815Sopenharmony_ci } 415425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */ 416425bb815Sopenharmony_ci 417425bb815Sopenharmony_ci /* 2 - 3. */ 418425bb815Sopenharmony_ci if (ecma_op_ordinary_object_has_own_property (object_p, property_name_p)) 419425bb815Sopenharmony_ci { 420425bb815Sopenharmony_ci return ECMA_VALUE_TRUE; 421425bb815Sopenharmony_ci } 422425bb815Sopenharmony_ci 423425bb815Sopenharmony_ci jmem_cpointer_t proto_cp = ecma_op_ordinary_object_get_prototype_of (object_p); 424425bb815Sopenharmony_ci 425425bb815Sopenharmony_ci /* 7. */ 426425bb815Sopenharmony_ci if (proto_cp == JMEM_CP_NULL) 427425bb815Sopenharmony_ci { 428425bb815Sopenharmony_ci return ECMA_VALUE_FALSE; 429425bb815Sopenharmony_ci } 430425bb815Sopenharmony_ci 431425bb815Sopenharmony_ci object_p = ECMA_GET_NON_NULL_POINTER (ecma_object_t, proto_cp); 432425bb815Sopenharmony_ci } 433425bb815Sopenharmony_ci} /* ecma_op_object_has_property */ 434425bb815Sopenharmony_ci 435425bb815Sopenharmony_ci/** 436425bb815Sopenharmony_ci * Search the value corresponding to a property name 437425bb815Sopenharmony_ci * 438425bb815Sopenharmony_ci * Note: search includes prototypes 439425bb815Sopenharmony_ci * 440425bb815Sopenharmony_ci * @return ecma value if property is found 441425bb815Sopenharmony_ci * ECMA_VALUE_NOT_FOUND if property is not found 442425bb815Sopenharmony_ci * Returned value must be freed with ecma_free_value 443425bb815Sopenharmony_ci */ 444425bb815Sopenharmony_ciecma_value_t 445425bb815Sopenharmony_ciecma_op_object_find_own (ecma_value_t base_value, /**< base value */ 446425bb815Sopenharmony_ci ecma_object_t *object_p, /**< target object */ 447425bb815Sopenharmony_ci ecma_string_t *property_name_p) /**< property name */ 448425bb815Sopenharmony_ci{ 449425bb815Sopenharmony_ci JERRY_ASSERT (object_p != NULL 450425bb815Sopenharmony_ci && !ecma_is_lexical_environment (object_p)); 451425bb815Sopenharmony_ci JERRY_ASSERT (property_name_p != NULL); 452425bb815Sopenharmony_ci JERRY_ASSERT (!ECMA_OBJECT_IS_PROXY (object_p)); 453425bb815Sopenharmony_ci 454425bb815Sopenharmony_ci ecma_object_type_t type = ecma_get_object_type (object_p); 455425bb815Sopenharmony_ci 456425bb815Sopenharmony_ci switch (type) 457425bb815Sopenharmony_ci { 458425bb815Sopenharmony_ci case ECMA_OBJECT_TYPE_CLASS: 459425bb815Sopenharmony_ci { 460425bb815Sopenharmony_ci ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) object_p; 461425bb815Sopenharmony_ci 462425bb815Sopenharmony_ci if (ext_object_p->u.class_prop.class_id == LIT_MAGIC_STRING_STRING_UL) 463425bb815Sopenharmony_ci { 464425bb815Sopenharmony_ci if (ecma_string_is_length (property_name_p)) 465425bb815Sopenharmony_ci { 466425bb815Sopenharmony_ci ecma_value_t prim_value_p = ext_object_p->u.class_prop.u.value; 467425bb815Sopenharmony_ci 468425bb815Sopenharmony_ci ecma_string_t *prim_value_str_p = ecma_get_string_from_value (prim_value_p); 469425bb815Sopenharmony_ci ecma_length_t length = ecma_string_get_length (prim_value_str_p); 470425bb815Sopenharmony_ci 471425bb815Sopenharmony_ci return ecma_make_uint32_value (length); 472425bb815Sopenharmony_ci } 473425bb815Sopenharmony_ci 474425bb815Sopenharmony_ci uint32_t index = ecma_string_get_array_index (property_name_p); 475425bb815Sopenharmony_ci 476425bb815Sopenharmony_ci if (index != ECMA_STRING_NOT_ARRAY_INDEX) 477425bb815Sopenharmony_ci { 478425bb815Sopenharmony_ci ecma_value_t prim_value_p = ext_object_p->u.class_prop.u.value; 479425bb815Sopenharmony_ci 480425bb815Sopenharmony_ci ecma_string_t *prim_value_str_p = ecma_get_string_from_value (prim_value_p); 481425bb815Sopenharmony_ci 482425bb815Sopenharmony_ci if (index < ecma_string_get_length (prim_value_str_p)) 483425bb815Sopenharmony_ci { 484425bb815Sopenharmony_ci ecma_char_t char_at_idx = ecma_string_get_char_at_pos (prim_value_str_p, index); 485425bb815Sopenharmony_ci return ecma_make_string_value (ecma_new_ecma_string_from_code_unit (char_at_idx)); 486425bb815Sopenharmony_ci } 487425bb815Sopenharmony_ci } 488425bb815Sopenharmony_ci } 489425bb815Sopenharmony_ci 490425bb815Sopenharmony_ci break; 491425bb815Sopenharmony_ci } 492425bb815Sopenharmony_ci case ECMA_OBJECT_TYPE_ARRAY: 493425bb815Sopenharmony_ci { 494425bb815Sopenharmony_ci ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) object_p; 495425bb815Sopenharmony_ci 496425bb815Sopenharmony_ci if (ecma_string_is_length (property_name_p)) 497425bb815Sopenharmony_ci { 498425bb815Sopenharmony_ci return ecma_make_uint32_value (ext_object_p->u.array.length); 499425bb815Sopenharmony_ci } 500425bb815Sopenharmony_ci 501425bb815Sopenharmony_ci if (JERRY_LIKELY (ecma_op_array_is_fast_array (ext_object_p))) 502425bb815Sopenharmony_ci { 503425bb815Sopenharmony_ci uint32_t index = ecma_string_get_array_index (property_name_p); 504425bb815Sopenharmony_ci 505425bb815Sopenharmony_ci if (JERRY_LIKELY (index != ECMA_STRING_NOT_ARRAY_INDEX)) 506425bb815Sopenharmony_ci { 507425bb815Sopenharmony_ci if (JERRY_LIKELY (index < ext_object_p->u.array.length)) 508425bb815Sopenharmony_ci { 509425bb815Sopenharmony_ci ecma_value_t *values_p = ECMA_GET_NON_NULL_POINTER (ecma_value_t, object_p->u1.property_list_cp); 510425bb815Sopenharmony_ci 511425bb815Sopenharmony_ci return (ecma_is_value_array_hole (values_p[index]) ? ECMA_VALUE_NOT_FOUND 512425bb815Sopenharmony_ci : ecma_fast_copy_value (values_p[index])); 513425bb815Sopenharmony_ci } 514425bb815Sopenharmony_ci } 515425bb815Sopenharmony_ci return ECMA_VALUE_NOT_FOUND; 516425bb815Sopenharmony_ci } 517425bb815Sopenharmony_ci 518425bb815Sopenharmony_ci break; 519425bb815Sopenharmony_ci } 520425bb815Sopenharmony_ci case ECMA_OBJECT_TYPE_PSEUDO_ARRAY: 521425bb815Sopenharmony_ci { 522425bb815Sopenharmony_ci ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) object_p; 523425bb815Sopenharmony_ci 524425bb815Sopenharmony_ci if (ext_object_p->u.pseudo_array.type == ECMA_PSEUDO_ARRAY_ARGUMENTS) 525425bb815Sopenharmony_ci { 526425bb815Sopenharmony_ci uint32_t index = ecma_string_get_array_index (property_name_p); 527425bb815Sopenharmony_ci 528425bb815Sopenharmony_ci if (index != ECMA_STRING_NOT_ARRAY_INDEX 529425bb815Sopenharmony_ci && index < ext_object_p->u.pseudo_array.u1.length) 530425bb815Sopenharmony_ci { 531425bb815Sopenharmony_ci ecma_value_t *arg_Literal_p = (ecma_value_t *) (ext_object_p + 1); 532425bb815Sopenharmony_ci 533425bb815Sopenharmony_ci if (arg_Literal_p[index] != ECMA_VALUE_EMPTY) 534425bb815Sopenharmony_ci { 535425bb815Sopenharmony_ci ecma_string_t *arg_name_p = ecma_get_string_from_value (arg_Literal_p[index]); 536425bb815Sopenharmony_ci 537425bb815Sopenharmony_ci ecma_object_t *lex_env_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_object_t, 538425bb815Sopenharmony_ci ext_object_p->u.pseudo_array.u2.lex_env_cp); 539425bb815Sopenharmony_ci 540425bb815Sopenharmony_ci JERRY_ASSERT (lex_env_p != NULL 541425bb815Sopenharmony_ci && ecma_is_lexical_environment (lex_env_p)); 542425bb815Sopenharmony_ci 543425bb815Sopenharmony_ci return ecma_op_get_binding_value (lex_env_p, arg_name_p, true); 544425bb815Sopenharmony_ci } 545425bb815Sopenharmony_ci } 546425bb815Sopenharmony_ci } 547425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) 548425bb815Sopenharmony_ci /* ES2015 9.4.5.4 */ 549425bb815Sopenharmony_ci if (ecma_object_is_typedarray (object_p)) 550425bb815Sopenharmony_ci { 551425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 552425bb815Sopenharmony_ci if (ecma_prop_name_is_symbol (property_name_p)) 553425bb815Sopenharmony_ci { 554425bb815Sopenharmony_ci break; 555425bb815Sopenharmony_ci } 556425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 557425bb815Sopenharmony_ci 558425bb815Sopenharmony_ci uint32_t array_index = ecma_string_get_array_index (property_name_p); 559425bb815Sopenharmony_ci 560425bb815Sopenharmony_ci if (array_index != ECMA_STRING_NOT_ARRAY_INDEX) 561425bb815Sopenharmony_ci { 562425bb815Sopenharmony_ci ecma_typedarray_info_t info = ecma_typedarray_get_info (object_p); 563425bb815Sopenharmony_ci 564425bb815Sopenharmony_ci if (array_index >= info.length) 565425bb815Sopenharmony_ci { 566425bb815Sopenharmony_ci return ECMA_VALUE_UNDEFINED; 567425bb815Sopenharmony_ci } 568425bb815Sopenharmony_ci 569425bb815Sopenharmony_ci ecma_length_t byte_pos = array_index << info.shift; 570425bb815Sopenharmony_ci ecma_number_t num = ecma_get_typedarray_element (info.buffer_p + byte_pos, info.id); 571425bb815Sopenharmony_ci return ecma_make_number_value (num); 572425bb815Sopenharmony_ci } 573425bb815Sopenharmony_ci 574425bb815Sopenharmony_ci ecma_number_t num = ecma_string_to_number (property_name_p); 575425bb815Sopenharmony_ci ecma_string_t *num_to_str = ecma_new_ecma_string_from_number (num); 576425bb815Sopenharmony_ci 577425bb815Sopenharmony_ci if (ecma_compare_ecma_strings (property_name_p, num_to_str)) 578425bb815Sopenharmony_ci { 579425bb815Sopenharmony_ci ecma_deref_ecma_string (num_to_str); 580425bb815Sopenharmony_ci 581425bb815Sopenharmony_ci return ECMA_VALUE_UNDEFINED; 582425bb815Sopenharmony_ci } 583425bb815Sopenharmony_ci 584425bb815Sopenharmony_ci ecma_deref_ecma_string (num_to_str); 585425bb815Sopenharmony_ci } 586425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) */ 587425bb815Sopenharmony_ci 588425bb815Sopenharmony_ci break; 589425bb815Sopenharmony_ci } 590425bb815Sopenharmony_ci default: 591425bb815Sopenharmony_ci { 592425bb815Sopenharmony_ci break; 593425bb815Sopenharmony_ci } 594425bb815Sopenharmony_ci } 595425bb815Sopenharmony_ci 596425bb815Sopenharmony_ci ecma_property_t *property_p = ecma_find_named_property (object_p, property_name_p); 597425bb815Sopenharmony_ci 598425bb815Sopenharmony_ci if (property_p == NULL) 599425bb815Sopenharmony_ci { 600425bb815Sopenharmony_ci if (ecma_get_object_is_builtin (object_p)) 601425bb815Sopenharmony_ci { 602425bb815Sopenharmony_ci if (type == ECMA_OBJECT_TYPE_FUNCTION && ecma_builtin_function_is_routine (object_p)) 603425bb815Sopenharmony_ci { 604425bb815Sopenharmony_ci property_p = ecma_builtin_routine_try_to_instantiate_property (object_p, property_name_p); 605425bb815Sopenharmony_ci } 606425bb815Sopenharmony_ci else 607425bb815Sopenharmony_ci { 608425bb815Sopenharmony_ci property_p = ecma_builtin_try_to_instantiate_property (object_p, property_name_p); 609425bb815Sopenharmony_ci } 610425bb815Sopenharmony_ci } 611425bb815Sopenharmony_ci else if (type == ECMA_OBJECT_TYPE_FUNCTION) 612425bb815Sopenharmony_ci { 613425bb815Sopenharmony_ci#if !ENABLED (JERRY_ES2015) 614425bb815Sopenharmony_ci if (ecma_string_is_length (property_name_p)) 615425bb815Sopenharmony_ci { 616425bb815Sopenharmony_ci /* Get length virtual property. */ 617425bb815Sopenharmony_ci ecma_extended_object_t *ext_func_p = (ecma_extended_object_t *) object_p; 618425bb815Sopenharmony_ci const ecma_compiled_code_t *bytecode_data_p = ecma_op_function_get_compiled_code (ext_func_p); 619425bb815Sopenharmony_ci 620425bb815Sopenharmony_ci uint32_t len; 621425bb815Sopenharmony_ci if (bytecode_data_p->status_flags & CBC_CODE_FLAGS_UINT16_ARGUMENTS) 622425bb815Sopenharmony_ci { 623425bb815Sopenharmony_ci cbc_uint16_arguments_t *args_p = (cbc_uint16_arguments_t *) bytecode_data_p; 624425bb815Sopenharmony_ci len = args_p->argument_end; 625425bb815Sopenharmony_ci } 626425bb815Sopenharmony_ci else 627425bb815Sopenharmony_ci { 628425bb815Sopenharmony_ci cbc_uint8_arguments_t *args_p = (cbc_uint8_arguments_t *) bytecode_data_p; 629425bb815Sopenharmony_ci len = args_p->argument_end; 630425bb815Sopenharmony_ci } 631425bb815Sopenharmony_ci 632425bb815Sopenharmony_ci return ecma_make_uint32_value (len); 633425bb815Sopenharmony_ci } 634425bb815Sopenharmony_ci#endif /* !ENABLED (JERRY_ES2015) */ 635425bb815Sopenharmony_ci 636425bb815Sopenharmony_ci /* Get prototype physical property. */ 637425bb815Sopenharmony_ci property_p = ecma_op_function_try_to_lazy_instantiate_property (object_p, property_name_p); 638425bb815Sopenharmony_ci } 639425bb815Sopenharmony_ci else if (type == ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION) 640425bb815Sopenharmony_ci { 641425bb815Sopenharmony_ci property_p = ecma_op_external_function_try_to_lazy_instantiate_property (object_p, property_name_p); 642425bb815Sopenharmony_ci } 643425bb815Sopenharmony_ci else if (type == ECMA_OBJECT_TYPE_BOUND_FUNCTION) 644425bb815Sopenharmony_ci { 645425bb815Sopenharmony_ci property_p = ecma_op_bound_function_try_to_lazy_instantiate_property (object_p, property_name_p); 646425bb815Sopenharmony_ci } 647425bb815Sopenharmony_ci 648425bb815Sopenharmony_ci if (property_p == NULL) 649425bb815Sopenharmony_ci { 650425bb815Sopenharmony_ci return ECMA_VALUE_NOT_FOUND; 651425bb815Sopenharmony_ci } 652425bb815Sopenharmony_ci } 653425bb815Sopenharmony_ci 654425bb815Sopenharmony_ci ecma_property_value_t *prop_value_p = ECMA_PROPERTY_VALUE_PTR (property_p); 655425bb815Sopenharmony_ci 656425bb815Sopenharmony_ci if (ECMA_PROPERTY_GET_TYPE (*property_p) == ECMA_PROPERTY_TYPE_NAMEDDATA) 657425bb815Sopenharmony_ci { 658425bb815Sopenharmony_ci return ecma_fast_copy_value (prop_value_p->value); 659425bb815Sopenharmony_ci } 660425bb815Sopenharmony_ci 661425bb815Sopenharmony_ci JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (*property_p) == ECMA_PROPERTY_TYPE_NAMEDACCESSOR); 662425bb815Sopenharmony_ci 663425bb815Sopenharmony_ci ecma_getter_setter_pointers_t *get_set_pair_p = ecma_get_named_accessor_property (prop_value_p); 664425bb815Sopenharmony_ci 665425bb815Sopenharmony_ci if (get_set_pair_p->getter_cp == JMEM_CP_NULL) 666425bb815Sopenharmony_ci { 667425bb815Sopenharmony_ci return ECMA_VALUE_UNDEFINED; 668425bb815Sopenharmony_ci } 669425bb815Sopenharmony_ci 670425bb815Sopenharmony_ci ecma_object_t *getter_p = ECMA_GET_NON_NULL_POINTER (ecma_object_t, get_set_pair_p->getter_cp); 671425bb815Sopenharmony_ci 672425bb815Sopenharmony_ci return ecma_op_function_call (getter_p, base_value, NULL, 0); 673425bb815Sopenharmony_ci} /* ecma_op_object_find_own */ 674425bb815Sopenharmony_ci 675425bb815Sopenharmony_ci/** 676425bb815Sopenharmony_ci * Search the value corresponding to an uint32_t property index 677425bb815Sopenharmony_ci * 678425bb815Sopenharmony_ci * Note: this method falls back to the general ecma_op_object_find 679425bb815Sopenharmony_ci * 680425bb815Sopenharmony_ci * @return ecma value if property is found 681425bb815Sopenharmony_ci * ECMA_VALUE_NOT_FOUND if property is not found 682425bb815Sopenharmony_ci * Returned value must be freed with ecma_free_value 683425bb815Sopenharmony_ci */ 684425bb815Sopenharmony_ciecma_value_t 685425bb815Sopenharmony_ciecma_op_object_find_by_uint32_index (ecma_object_t *object_p, /**< the object */ 686425bb815Sopenharmony_ci uint32_t index) /**< property index */ 687425bb815Sopenharmony_ci{ 688425bb815Sopenharmony_ci if (JERRY_LIKELY (index <= ECMA_DIRECT_STRING_MAX_IMM)) 689425bb815Sopenharmony_ci { 690425bb815Sopenharmony_ci return ecma_op_object_find (object_p, ECMA_CREATE_DIRECT_UINT32_STRING (index)); 691425bb815Sopenharmony_ci } 692425bb815Sopenharmony_ci 693425bb815Sopenharmony_ci ecma_string_t *index_str_p = ecma_new_non_direct_string_from_uint32 (index); 694425bb815Sopenharmony_ci ecma_value_t ret_value = ecma_op_object_find (object_p, index_str_p); 695425bb815Sopenharmony_ci ecma_deref_ecma_string (index_str_p); 696425bb815Sopenharmony_ci 697425bb815Sopenharmony_ci return ret_value; 698425bb815Sopenharmony_ci} /* ecma_op_object_find_by_uint32_index */ 699425bb815Sopenharmony_ci 700425bb815Sopenharmony_ci/** 701425bb815Sopenharmony_ci * Search the value corresponding to an ecma_number_t property index 702425bb815Sopenharmony_ci * 703425bb815Sopenharmony_ci * Note: this method falls back to the general ecma_op_object_find 704425bb815Sopenharmony_ci * 705425bb815Sopenharmony_ci * @return ecma value if property is found 706425bb815Sopenharmony_ci * ECMA_VALUE_NOT_FOUND if property is not found 707425bb815Sopenharmony_ci * Returned value must be freed with ecma_free_value 708425bb815Sopenharmony_ci */ 709425bb815Sopenharmony_ciecma_value_t 710425bb815Sopenharmony_ciecma_op_object_find_by_number_index (ecma_object_t *object_p, /**< the object */ 711425bb815Sopenharmony_ci ecma_number_t index) /**< property index */ 712425bb815Sopenharmony_ci{ 713425bb815Sopenharmony_ci ecma_string_t *index_str_p = ecma_new_ecma_string_from_number (index); 714425bb815Sopenharmony_ci ecma_value_t ret_value = ecma_op_object_find (object_p, index_str_p); 715425bb815Sopenharmony_ci ecma_deref_ecma_string (index_str_p); 716425bb815Sopenharmony_ci 717425bb815Sopenharmony_ci return ret_value; 718425bb815Sopenharmony_ci} /* ecma_op_object_find_by_number_index */ 719425bb815Sopenharmony_ci 720425bb815Sopenharmony_ci/** 721425bb815Sopenharmony_ci * Search the value corresponding to a property name 722425bb815Sopenharmony_ci * 723425bb815Sopenharmony_ci * Note: search includes prototypes 724425bb815Sopenharmony_ci * 725425bb815Sopenharmony_ci * @return ecma value if property is found 726425bb815Sopenharmony_ci * ECMA_VALUE_NOT_FOUND if property is not found 727425bb815Sopenharmony_ci * Returned value must be freed with ecma_free_value 728425bb815Sopenharmony_ci */ 729425bb815Sopenharmony_ciecma_value_t 730425bb815Sopenharmony_ciecma_op_object_find (ecma_object_t *object_p, /**< the object */ 731425bb815Sopenharmony_ci ecma_string_t *property_name_p) /**< property name */ 732425bb815Sopenharmony_ci{ 733425bb815Sopenharmony_ci ecma_value_t base_value = ecma_make_object_value (object_p); 734425bb815Sopenharmony_ci 735425bb815Sopenharmony_ci while (true) 736425bb815Sopenharmony_ci { 737425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015_BUILTIN_PROXY) 738425bb815Sopenharmony_ci if (ECMA_OBJECT_IS_PROXY (object_p)) 739425bb815Sopenharmony_ci { 740425bb815Sopenharmony_ci return ecma_proxy_object_find (object_p, property_name_p); 741425bb815Sopenharmony_ci } 742425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */ 743425bb815Sopenharmony_ci 744425bb815Sopenharmony_ci ecma_value_t value = ecma_op_object_find_own (base_value, object_p, property_name_p); 745425bb815Sopenharmony_ci 746425bb815Sopenharmony_ci if (ecma_is_value_found (value)) 747425bb815Sopenharmony_ci { 748425bb815Sopenharmony_ci return value; 749425bb815Sopenharmony_ci } 750425bb815Sopenharmony_ci 751425bb815Sopenharmony_ci if (object_p->u2.prototype_cp == JMEM_CP_NULL) 752425bb815Sopenharmony_ci { 753425bb815Sopenharmony_ci break; 754425bb815Sopenharmony_ci } 755425bb815Sopenharmony_ci 756425bb815Sopenharmony_ci object_p = ECMA_GET_NON_NULL_POINTER (ecma_object_t, object_p->u2.prototype_cp); 757425bb815Sopenharmony_ci } 758425bb815Sopenharmony_ci 759425bb815Sopenharmony_ci return ECMA_VALUE_NOT_FOUND; 760425bb815Sopenharmony_ci} /* ecma_op_object_find */ 761425bb815Sopenharmony_ci 762425bb815Sopenharmony_ci/** 763425bb815Sopenharmony_ci * Get own property by name 764425bb815Sopenharmony_ci * 765425bb815Sopenharmony_ci * Note: property must be an existing data property 766425bb815Sopenharmony_ci * 767425bb815Sopenharmony_ci * @return ecma value 768425bb815Sopenharmony_ci * Returned value must be freed with ecma_free_value 769425bb815Sopenharmony_ci */ 770425bb815Sopenharmony_ciinline ecma_value_t JERRY_ATTR_ALWAYS_INLINE 771425bb815Sopenharmony_ciecma_op_object_get_own_data_prop (ecma_object_t *object_p, /**< the object */ 772425bb815Sopenharmony_ci ecma_string_t *property_name_p) /**< property name */ 773425bb815Sopenharmony_ci{ 774425bb815Sopenharmony_ci JERRY_ASSERT (ecma_is_lexical_environment (object_p) 775425bb815Sopenharmony_ci || !ecma_op_object_is_fast_array (object_p)); 776425bb815Sopenharmony_ci 777425bb815Sopenharmony_ci ecma_value_t result = ecma_op_object_find_own (ecma_make_object_value (object_p), 778425bb815Sopenharmony_ci object_p, 779425bb815Sopenharmony_ci property_name_p); 780425bb815Sopenharmony_ci 781425bb815Sopenharmony_ci#ifndef JERRY_NDEBUG 782425bb815Sopenharmony_ci /* Because ecma_op_object_find_own might create a property 783425bb815Sopenharmony_ci * this check is executed after the function return. */ 784425bb815Sopenharmony_ci ecma_property_t *property_p = ecma_find_named_property (object_p, 785425bb815Sopenharmony_ci property_name_p); 786425bb815Sopenharmony_ci 787425bb815Sopenharmony_ci JERRY_ASSERT (property_p != NULL 788425bb815Sopenharmony_ci && ECMA_PROPERTY_GET_TYPE (*property_p) == ECMA_PROPERTY_TYPE_NAMEDDATA 789425bb815Sopenharmony_ci && !ecma_is_property_configurable (*property_p)); 790425bb815Sopenharmony_ci#endif /* !JERRY_NDEBUG */ 791425bb815Sopenharmony_ci 792425bb815Sopenharmony_ci return result; 793425bb815Sopenharmony_ci} /* ecma_op_object_get_own_data_prop */ 794425bb815Sopenharmony_ci 795425bb815Sopenharmony_ci/** 796425bb815Sopenharmony_ci * [[Get]] operation of ecma object 797425bb815Sopenharmony_ci * 798425bb815Sopenharmony_ci * This function returns the value of a named property, or undefined 799425bb815Sopenharmony_ci * if the property is not found in the prototype chain. If the property 800425bb815Sopenharmony_ci * is an accessor, it calls the "get" callback function and returns 801425bb815Sopenharmony_ci * with its result (including error throws). 802425bb815Sopenharmony_ci * 803425bb815Sopenharmony_ci * See also: 804425bb815Sopenharmony_ci * ECMA-262 v5, 8.6.2; ECMA-262 v5, Table 8 805425bb815Sopenharmony_ci * 806425bb815Sopenharmony_ci * @return ecma value 807425bb815Sopenharmony_ci * Returned value must be freed with ecma_free_value 808425bb815Sopenharmony_ci */ 809425bb815Sopenharmony_ciinline ecma_value_t JERRY_ATTR_ALWAYS_INLINE 810425bb815Sopenharmony_ciecma_op_object_get (ecma_object_t *object_p, /**< the object */ 811425bb815Sopenharmony_ci ecma_string_t *property_name_p) /**< property name */ 812425bb815Sopenharmony_ci{ 813425bb815Sopenharmony_ci return ecma_op_object_get_with_receiver (object_p, property_name_p, ecma_make_object_value (object_p)); 814425bb815Sopenharmony_ci} /* ecma_op_object_get */ 815425bb815Sopenharmony_ci 816425bb815Sopenharmony_ci/** 817425bb815Sopenharmony_ci * [[Get]] operation of ecma object with the specified receiver 818425bb815Sopenharmony_ci * 819425bb815Sopenharmony_ci * This function returns the value of a named property, or undefined 820425bb815Sopenharmony_ci * if the property is not found in the prototype chain. If the property 821425bb815Sopenharmony_ci * is an accessor, it calls the "get" callback function and returns 822425bb815Sopenharmony_ci * with its result (including error throws). 823425bb815Sopenharmony_ci * 824425bb815Sopenharmony_ci * See also: 825425bb815Sopenharmony_ci * ECMA-262 v5, 8.6.2; ECMA-262 v5, Table 8 826425bb815Sopenharmony_ci * 827425bb815Sopenharmony_ci * @return ecma value 828425bb815Sopenharmony_ci * Returned value must be freed with ecma_free_value 829425bb815Sopenharmony_ci */ 830425bb815Sopenharmony_ciecma_value_t 831425bb815Sopenharmony_ciecma_op_object_get_with_receiver (ecma_object_t *object_p, /**< the object */ 832425bb815Sopenharmony_ci ecma_string_t *property_name_p, /**< property name */ 833425bb815Sopenharmony_ci ecma_value_t receiver) /**< receiver to invoke getter function */ 834425bb815Sopenharmony_ci{ 835425bb815Sopenharmony_ci while (true) 836425bb815Sopenharmony_ci { 837425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015_BUILTIN_PROXY) 838425bb815Sopenharmony_ci if (ECMA_OBJECT_IS_PROXY (object_p)) 839425bb815Sopenharmony_ci { 840425bb815Sopenharmony_ci return ecma_proxy_object_get (object_p, property_name_p, receiver); 841425bb815Sopenharmony_ci } 842425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */ 843425bb815Sopenharmony_ci 844425bb815Sopenharmony_ci ecma_value_t value = ecma_op_object_find_own (receiver, object_p, property_name_p); 845425bb815Sopenharmony_ci 846425bb815Sopenharmony_ci if (ecma_is_value_found (value)) 847425bb815Sopenharmony_ci { 848425bb815Sopenharmony_ci return value; 849425bb815Sopenharmony_ci } 850425bb815Sopenharmony_ci 851425bb815Sopenharmony_ci jmem_cpointer_t proto_cp = ecma_op_ordinary_object_get_prototype_of (object_p); 852425bb815Sopenharmony_ci 853425bb815Sopenharmony_ci if (proto_cp == JMEM_CP_NULL) 854425bb815Sopenharmony_ci { 855425bb815Sopenharmony_ci break; 856425bb815Sopenharmony_ci } 857425bb815Sopenharmony_ci 858425bb815Sopenharmony_ci object_p = ECMA_GET_NON_NULL_POINTER (ecma_object_t, proto_cp); 859425bb815Sopenharmony_ci } 860425bb815Sopenharmony_ci 861425bb815Sopenharmony_ci return ECMA_VALUE_UNDEFINED; 862425bb815Sopenharmony_ci} /* ecma_op_object_get_with_receiver */ 863425bb815Sopenharmony_ci 864425bb815Sopenharmony_ci/** 865425bb815Sopenharmony_ci * [[Get]] operation of ecma object specified for uint32_t property index 866425bb815Sopenharmony_ci * 867425bb815Sopenharmony_ci * @return ecma value 868425bb815Sopenharmony_ci * Returned value must be freed with ecma_free_value 869425bb815Sopenharmony_ci */ 870425bb815Sopenharmony_ciecma_value_t 871425bb815Sopenharmony_ciecma_op_object_get_by_uint32_index (ecma_object_t *object_p, /**< the object */ 872425bb815Sopenharmony_ci uint32_t index) /**< property index */ 873425bb815Sopenharmony_ci{ 874425bb815Sopenharmony_ci if (JERRY_LIKELY (index <= ECMA_DIRECT_STRING_MAX_IMM)) 875425bb815Sopenharmony_ci { 876425bb815Sopenharmony_ci return ecma_op_object_get (object_p, ECMA_CREATE_DIRECT_UINT32_STRING (index)); 877425bb815Sopenharmony_ci } 878425bb815Sopenharmony_ci 879425bb815Sopenharmony_ci ecma_string_t *index_str_p = ecma_new_non_direct_string_from_uint32 (index); 880425bb815Sopenharmony_ci ecma_value_t ret_value = ecma_op_object_get (object_p, index_str_p); 881425bb815Sopenharmony_ci ecma_deref_ecma_string (index_str_p); 882425bb815Sopenharmony_ci 883425bb815Sopenharmony_ci return ret_value; 884425bb815Sopenharmony_ci} /* ecma_op_object_get_by_uint32_index */ 885425bb815Sopenharmony_ci 886425bb815Sopenharmony_ci/** 887425bb815Sopenharmony_ci * Perform ToLength(O.[[Get]]("length")) operation 888425bb815Sopenharmony_ci * 889425bb815Sopenharmony_ci * The property is converted to uint32 during the operation 890425bb815Sopenharmony_ci * 891425bb815Sopenharmony_ci * @return ECMA_VALUE_ERROR - if there was any error during the operation 892425bb815Sopenharmony_ci * ECMA_VALUE_EMPTY - otherwise 893425bb815Sopenharmony_ci */ 894425bb815Sopenharmony_ciecma_value_t 895425bb815Sopenharmony_ciecma_op_object_get_length (ecma_object_t *object_p, /**< the object */ 896425bb815Sopenharmony_ci uint32_t *length_p) /**< [out] length value converted to uint32 */ 897425bb815Sopenharmony_ci{ 898425bb815Sopenharmony_ci if (JERRY_LIKELY (ecma_get_object_type (object_p) == ECMA_OBJECT_TYPE_ARRAY)) 899425bb815Sopenharmony_ci { 900425bb815Sopenharmony_ci *length_p = ecma_array_get_length (object_p); 901425bb815Sopenharmony_ci return ECMA_VALUE_EMPTY; 902425bb815Sopenharmony_ci } 903425bb815Sopenharmony_ci 904425bb815Sopenharmony_ci ecma_value_t len_value = ecma_op_object_get_by_magic_id (object_p, LIT_MAGIC_STRING_LENGTH); 905425bb815Sopenharmony_ci ecma_value_t len_number = ecma_op_to_length (len_value, length_p); 906425bb815Sopenharmony_ci ecma_free_value (len_value); 907425bb815Sopenharmony_ci 908425bb815Sopenharmony_ci JERRY_ASSERT (ECMA_IS_VALUE_ERROR (len_number) || ecma_is_value_empty (len_number)); 909425bb815Sopenharmony_ci 910425bb815Sopenharmony_ci return len_number; 911425bb815Sopenharmony_ci} /* ecma_op_object_get_length */ 912425bb815Sopenharmony_ci 913425bb815Sopenharmony_ci/** 914425bb815Sopenharmony_ci * [[Get]] operation of ecma object where the property name is a magic string 915425bb815Sopenharmony_ci * 916425bb815Sopenharmony_ci * This function returns the value of a named property, or undefined 917425bb815Sopenharmony_ci * if the property is not found in the prototype chain. If the property 918425bb815Sopenharmony_ci * is an accessor, it calls the "get" callback function and returns 919425bb815Sopenharmony_ci * with its result (including error throws). 920425bb815Sopenharmony_ci * 921425bb815Sopenharmony_ci * See also: 922425bb815Sopenharmony_ci * ECMA-262 v5, 8.6.2; ECMA-262 v5, Table 8 923425bb815Sopenharmony_ci * 924425bb815Sopenharmony_ci * @return ecma value 925425bb815Sopenharmony_ci * Returned value must be freed with ecma_free_value 926425bb815Sopenharmony_ci */ 927425bb815Sopenharmony_ciinline ecma_value_t JERRY_ATTR_ALWAYS_INLINE 928425bb815Sopenharmony_ciecma_op_object_get_by_magic_id (ecma_object_t *object_p, /**< the object */ 929425bb815Sopenharmony_ci lit_magic_string_id_t property_id) /**< property magic string id */ 930425bb815Sopenharmony_ci{ 931425bb815Sopenharmony_ci return ecma_op_object_get (object_p, ecma_get_magic_string (property_id)); 932425bb815Sopenharmony_ci} /* ecma_op_object_get_by_magic_id */ 933425bb815Sopenharmony_ci 934425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 935425bb815Sopenharmony_ci/** 936425bb815Sopenharmony_ci * [[Get]] a well-known symbol by the given property id 937425bb815Sopenharmony_ci * 938425bb815Sopenharmony_ci * @return pointer to the requested well-known symbol 939425bb815Sopenharmony_ci */ 940425bb815Sopenharmony_ciecma_string_t * 941425bb815Sopenharmony_ciecma_op_get_global_symbol (lit_magic_string_id_t property_id) /**< property symbol id */ 942425bb815Sopenharmony_ci{ 943425bb815Sopenharmony_ci ecma_value_t symbol_value = ecma_op_object_get_by_magic_id (ecma_builtin_get (ECMA_BUILTIN_ID_INTRINSIC_OBJECT), 944425bb815Sopenharmony_ci property_id); 945425bb815Sopenharmony_ci JERRY_ASSERT (ecma_is_value_symbol (symbol_value)); 946425bb815Sopenharmony_ci 947425bb815Sopenharmony_ci return ecma_get_symbol_from_value (symbol_value); 948425bb815Sopenharmony_ci} /* ecma_op_get_global_symbol */ 949425bb815Sopenharmony_ci 950425bb815Sopenharmony_ci/** 951425bb815Sopenharmony_ci * [[Get]] operation of ecma object where the property is a well-known symbol 952425bb815Sopenharmony_ci * 953425bb815Sopenharmony_ci * @return ecma value 954425bb815Sopenharmony_ci * Returned value must be freed with ecma_free_value 955425bb815Sopenharmony_ci */ 956425bb815Sopenharmony_ciecma_value_t 957425bb815Sopenharmony_ciecma_op_object_get_by_symbol_id (ecma_object_t *object_p, /**< the object */ 958425bb815Sopenharmony_ci lit_magic_string_id_t property_id) /**< property symbol id */ 959425bb815Sopenharmony_ci{ 960425bb815Sopenharmony_ci ecma_string_t *symbol_p = ecma_op_get_global_symbol (property_id); 961425bb815Sopenharmony_ci ecma_value_t ret_value = ecma_op_object_get (object_p, symbol_p); 962425bb815Sopenharmony_ci ecma_deref_ecma_string (symbol_p); 963425bb815Sopenharmony_ci 964425bb815Sopenharmony_ci return ret_value; 965425bb815Sopenharmony_ci} /* ecma_op_object_get_by_symbol_id */ 966425bb815Sopenharmony_ci 967425bb815Sopenharmony_ci/** 968425bb815Sopenharmony_ci * GetMethod operation 969425bb815Sopenharmony_ci * 970425bb815Sopenharmony_ci * See also: ECMA-262 v6, 7.3.9 971425bb815Sopenharmony_ci * 972425bb815Sopenharmony_ci * Note: 973425bb815Sopenharmony_ci * Returned value must be freed with ecma_free_value. 974425bb815Sopenharmony_ci * 975425bb815Sopenharmony_ci * @return iterator function object - if success 976425bb815Sopenharmony_ci * raised error - otherwise 977425bb815Sopenharmony_ci */ 978425bb815Sopenharmony_cistatic ecma_value_t 979425bb815Sopenharmony_ciecma_op_get_method (ecma_value_t value, /**< ecma value */ 980425bb815Sopenharmony_ci ecma_string_t *prop_name_p) /** property name */ 981425bb815Sopenharmony_ci{ 982425bb815Sopenharmony_ci /* 2. */ 983425bb815Sopenharmony_ci ecma_value_t obj_value = ecma_op_to_object (value); 984425bb815Sopenharmony_ci 985425bb815Sopenharmony_ci if (ECMA_IS_VALUE_ERROR (obj_value)) 986425bb815Sopenharmony_ci { 987425bb815Sopenharmony_ci return obj_value; 988425bb815Sopenharmony_ci } 989425bb815Sopenharmony_ci 990425bb815Sopenharmony_ci ecma_object_t *obj_p = ecma_get_object_from_value (obj_value); 991425bb815Sopenharmony_ci ecma_value_t func; 992425bb815Sopenharmony_ci 993425bb815Sopenharmony_ci func = ecma_op_object_get (obj_p, prop_name_p); 994425bb815Sopenharmony_ci ecma_deref_object (obj_p); 995425bb815Sopenharmony_ci 996425bb815Sopenharmony_ci /* 3. */ 997425bb815Sopenharmony_ci if (ECMA_IS_VALUE_ERROR (func)) 998425bb815Sopenharmony_ci { 999425bb815Sopenharmony_ci return func; 1000425bb815Sopenharmony_ci } 1001425bb815Sopenharmony_ci 1002425bb815Sopenharmony_ci /* 4. */ 1003425bb815Sopenharmony_ci if (ecma_is_value_undefined (func) || ecma_is_value_null (func)) 1004425bb815Sopenharmony_ci { 1005425bb815Sopenharmony_ci return ECMA_VALUE_UNDEFINED; 1006425bb815Sopenharmony_ci } 1007425bb815Sopenharmony_ci 1008425bb815Sopenharmony_ci /* 5. */ 1009425bb815Sopenharmony_ci if (!ecma_op_is_callable (func)) 1010425bb815Sopenharmony_ci { 1011425bb815Sopenharmony_ci ecma_free_value (func); 1012425bb815Sopenharmony_ci return ecma_raise_type_error (ECMA_ERR_MSG ("Iterator is not callable.")); 1013425bb815Sopenharmony_ci } 1014425bb815Sopenharmony_ci 1015425bb815Sopenharmony_ci /* 6. */ 1016425bb815Sopenharmony_ci return func; 1017425bb815Sopenharmony_ci} /* ecma_op_get_method */ 1018425bb815Sopenharmony_ci 1019425bb815Sopenharmony_ci/** 1020425bb815Sopenharmony_ci * GetMethod operation when the property is a well-known symbol 1021425bb815Sopenharmony_ci * 1022425bb815Sopenharmony_ci * See also: ECMA-262 v6, 7.3.9 1023425bb815Sopenharmony_ci * 1024425bb815Sopenharmony_ci * Note: 1025425bb815Sopenharmony_ci * Returned value must be freed with ecma_free_value. 1026425bb815Sopenharmony_ci * 1027425bb815Sopenharmony_ci * @return iterator function object - if success 1028425bb815Sopenharmony_ci * raised error - otherwise 1029425bb815Sopenharmony_ci */ 1030425bb815Sopenharmony_ciecma_value_t 1031425bb815Sopenharmony_ciecma_op_get_method_by_symbol_id (ecma_value_t value, /**< ecma value */ 1032425bb815Sopenharmony_ci lit_magic_string_id_t symbol_id) /**< property symbol id */ 1033425bb815Sopenharmony_ci{ 1034425bb815Sopenharmony_ci ecma_string_t *prop_name_p = ecma_op_get_global_symbol (symbol_id); 1035425bb815Sopenharmony_ci ecma_value_t ret_value = ecma_op_get_method (value, prop_name_p); 1036425bb815Sopenharmony_ci ecma_deref_ecma_string (prop_name_p); 1037425bb815Sopenharmony_ci 1038425bb815Sopenharmony_ci return ret_value; 1039425bb815Sopenharmony_ci} /* ecma_op_get_method_by_symbol_id */ 1040425bb815Sopenharmony_ci 1041425bb815Sopenharmony_ci/** 1042425bb815Sopenharmony_ci * GetMethod operation when the property is a magic string 1043425bb815Sopenharmony_ci * 1044425bb815Sopenharmony_ci * See also: ECMA-262 v6, 7.3.9 1045425bb815Sopenharmony_ci * 1046425bb815Sopenharmony_ci * Note: 1047425bb815Sopenharmony_ci * Returned value must be freed with ecma_free_value. 1048425bb815Sopenharmony_ci * 1049425bb815Sopenharmony_ci * @return iterator function object - if success 1050425bb815Sopenharmony_ci * raised error - otherwise 1051425bb815Sopenharmony_ci */ 1052425bb815Sopenharmony_ciecma_value_t 1053425bb815Sopenharmony_ciecma_op_get_method_by_magic_id (ecma_value_t value, /**< ecma value */ 1054425bb815Sopenharmony_ci lit_magic_string_id_t magic_id) /**< property magic id */ 1055425bb815Sopenharmony_ci{ 1056425bb815Sopenharmony_ci return ecma_op_get_method (value, ecma_get_magic_string (magic_id)); 1057425bb815Sopenharmony_ci} /* ecma_op_get_method_by_magic_id */ 1058425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 1059425bb815Sopenharmony_ci 1060425bb815Sopenharmony_ci/** 1061425bb815Sopenharmony_ci * [[Put]] ecma general object's operation specialized for uint32_ property index 1062425bb815Sopenharmony_ci * 1063425bb815Sopenharmony_ci * Note: This function falls back to the general ecma_op_object_put 1064425bb815Sopenharmony_ci * 1065425bb815Sopenharmony_ci * @return ecma value 1066425bb815Sopenharmony_ci * The returned value must be freed with ecma_free_value. 1067425bb815Sopenharmony_ci */ 1068425bb815Sopenharmony_ciecma_value_t 1069425bb815Sopenharmony_ciecma_op_object_put_by_uint32_index (ecma_object_t *object_p, /**< the object */ 1070425bb815Sopenharmony_ci uint32_t index, /**< property index */ 1071425bb815Sopenharmony_ci ecma_value_t value, /**< ecma value */ 1072425bb815Sopenharmony_ci bool is_throw) /**< flag that controls failure handling */ 1073425bb815Sopenharmony_ci{ 1074425bb815Sopenharmony_ci if (JERRY_LIKELY (index <= ECMA_DIRECT_STRING_MAX_IMM)) 1075425bb815Sopenharmony_ci { 1076425bb815Sopenharmony_ci return ecma_op_object_put (object_p, 1077425bb815Sopenharmony_ci ECMA_CREATE_DIRECT_UINT32_STRING (index), 1078425bb815Sopenharmony_ci value, 1079425bb815Sopenharmony_ci is_throw); 1080425bb815Sopenharmony_ci } 1081425bb815Sopenharmony_ci 1082425bb815Sopenharmony_ci ecma_string_t *index_str_p = ecma_new_non_direct_string_from_uint32 (index); 1083425bb815Sopenharmony_ci ecma_value_t ret_value = ecma_op_object_put (object_p, index_str_p, value, is_throw); 1084425bb815Sopenharmony_ci ecma_deref_ecma_string (index_str_p); 1085425bb815Sopenharmony_ci 1086425bb815Sopenharmony_ci return ret_value; 1087425bb815Sopenharmony_ci} /* ecma_op_object_put_by_uint32_index */ 1088425bb815Sopenharmony_ci 1089425bb815Sopenharmony_ci/** 1090425bb815Sopenharmony_ci * [[Put]] ecma general object's operation specialized for ecma_number_ property index 1091425bb815Sopenharmony_ci * 1092425bb815Sopenharmony_ci * Note: This function falls back to the general ecma_op_object_put 1093425bb815Sopenharmony_ci * 1094425bb815Sopenharmony_ci * @return ecma value 1095425bb815Sopenharmony_ci * The returned value must be freed with ecma_free_value. 1096425bb815Sopenharmony_ci */ 1097425bb815Sopenharmony_ciecma_value_t 1098425bb815Sopenharmony_ciecma_op_object_put_by_number_index (ecma_object_t *object_p, /**< the object */ 1099425bb815Sopenharmony_ci ecma_number_t index, /**< property index */ 1100425bb815Sopenharmony_ci ecma_value_t value, /**< ecma value */ 1101425bb815Sopenharmony_ci bool is_throw) /**< flag that controls failure handling */ 1102425bb815Sopenharmony_ci{ 1103425bb815Sopenharmony_ci ecma_string_t *index_str_p = ecma_new_ecma_string_from_number (index); 1104425bb815Sopenharmony_ci ecma_value_t ret_value = ecma_op_object_put (object_p, index_str_p, value, is_throw); 1105425bb815Sopenharmony_ci ecma_deref_ecma_string (index_str_p); 1106425bb815Sopenharmony_ci 1107425bb815Sopenharmony_ci return ret_value; 1108425bb815Sopenharmony_ci} /* ecma_op_object_put_by_number_index */ 1109425bb815Sopenharmony_ci 1110425bb815Sopenharmony_ci/** 1111425bb815Sopenharmony_ci * [[Put]] ecma general object's operation 1112425bb815Sopenharmony_ci * 1113425bb815Sopenharmony_ci * See also: 1114425bb815Sopenharmony_ci * ECMA-262 v5, 8.6.2; ECMA-262 v5, Table 8 1115425bb815Sopenharmony_ci * ECMA-262 v5, 8.12.5 1116425bb815Sopenharmony_ci * Also incorporates [[CanPut]] ECMA-262 v5, 8.12.4 1117425bb815Sopenharmony_ci * 1118425bb815Sopenharmony_ci * @return ecma value 1119425bb815Sopenharmony_ci * The returned value must be freed with ecma_free_value. 1120425bb815Sopenharmony_ci * 1121425bb815Sopenharmony_ci * Returns with ECMA_VALUE_TRUE if the operation is 1122425bb815Sopenharmony_ci * successful. Otherwise it returns with an error object 1123425bb815Sopenharmony_ci * or ECMA_VALUE_FALSE. 1124425bb815Sopenharmony_ci * 1125425bb815Sopenharmony_ci * Note: even if is_throw is false, the setter can throw an 1126425bb815Sopenharmony_ci * error, and this function returns with that error. 1127425bb815Sopenharmony_ci */ 1128425bb815Sopenharmony_ciinline ecma_value_t JERRY_ATTR_ALWAYS_INLINE 1129425bb815Sopenharmony_ciecma_op_object_put (ecma_object_t *object_p, /**< the object */ 1130425bb815Sopenharmony_ci ecma_string_t *property_name_p, /**< property name */ 1131425bb815Sopenharmony_ci ecma_value_t value, /**< ecma value */ 1132425bb815Sopenharmony_ci bool is_throw) /**< flag that controls failure handling */ 1133425bb815Sopenharmony_ci{ 1134425bb815Sopenharmony_ci return ecma_op_object_put_with_receiver (object_p, 1135425bb815Sopenharmony_ci property_name_p, 1136425bb815Sopenharmony_ci value, 1137425bb815Sopenharmony_ci ecma_make_object_value (object_p), 1138425bb815Sopenharmony_ci is_throw); 1139425bb815Sopenharmony_ci} /* ecma_op_object_put */ 1140425bb815Sopenharmony_ci 1141425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 1142425bb815Sopenharmony_ci/** 1143425bb815Sopenharmony_ci * [[Set]] ( P, V, Receiver) operation part for ordinary objects 1144425bb815Sopenharmony_ci * 1145425bb815Sopenharmony_ci * See also: ECMAScript v6, 9.19.9 1146425bb815Sopenharmony_ci * 1147425bb815Sopenharmony_ci * @return ecma value 1148425bb815Sopenharmony_ci * The returned value must be freed with ecma_free_value. 1149425bb815Sopenharmony_ci */ 1150425bb815Sopenharmony_cistatic ecma_value_t 1151425bb815Sopenharmony_ciecma_op_object_put_apply_receiver (ecma_value_t receiver, /**< receiver */ 1152425bb815Sopenharmony_ci ecma_string_t *property_name_p, /**< property name */ 1153425bb815Sopenharmony_ci ecma_value_t value, /**< value to set */ 1154425bb815Sopenharmony_ci bool is_throw) /**< flag that controls failure handling */ 1155425bb815Sopenharmony_ci{ 1156425bb815Sopenharmony_ci /* 5.b */ 1157425bb815Sopenharmony_ci if (!ecma_is_value_object (receiver)) 1158425bb815Sopenharmony_ci { 1159425bb815Sopenharmony_ci return ecma_reject (is_throw); 1160425bb815Sopenharmony_ci } 1161425bb815Sopenharmony_ci 1162425bb815Sopenharmony_ci ecma_object_t *receiver_obj_p = ecma_get_object_from_value (receiver); 1163425bb815Sopenharmony_ci 1164425bb815Sopenharmony_ci ecma_property_descriptor_t prop_desc; 1165425bb815Sopenharmony_ci /* 5.c */ 1166425bb815Sopenharmony_ci ecma_value_t status = ecma_op_object_get_own_property_descriptor (receiver_obj_p, 1167425bb815Sopenharmony_ci property_name_p, 1168425bb815Sopenharmony_ci &prop_desc); 1169425bb815Sopenharmony_ci 1170425bb815Sopenharmony_ci /* 5.d */ 1171425bb815Sopenharmony_ci if (ECMA_IS_VALUE_ERROR (status)) 1172425bb815Sopenharmony_ci { 1173425bb815Sopenharmony_ci return status; 1174425bb815Sopenharmony_ci } 1175425bb815Sopenharmony_ci 1176425bb815Sopenharmony_ci /* 5.e */ 1177425bb815Sopenharmony_ci if (ecma_is_value_true (status)) 1178425bb815Sopenharmony_ci { 1179425bb815Sopenharmony_ci ecma_value_t result; 1180425bb815Sopenharmony_ci 1181425bb815Sopenharmony_ci /* 5.e.i - 5.e.ii */ 1182425bb815Sopenharmony_ci if (prop_desc.flags & (ECMA_PROP_IS_GET_DEFINED | ECMA_PROP_IS_SET_DEFINED) 1183425bb815Sopenharmony_ci || !(prop_desc.flags & ECMA_PROP_IS_WRITABLE)) 1184425bb815Sopenharmony_ci { 1185425bb815Sopenharmony_ci result = ecma_reject (is_throw); 1186425bb815Sopenharmony_ci } 1187425bb815Sopenharmony_ci else 1188425bb815Sopenharmony_ci { 1189425bb815Sopenharmony_ci /* 5.e.iii */ 1190425bb815Sopenharmony_ci JERRY_ASSERT (prop_desc.flags & ECMA_PROP_IS_VALUE_DEFINED); 1191425bb815Sopenharmony_ci ecma_free_value (prop_desc.value); 1192425bb815Sopenharmony_ci prop_desc.value = ecma_copy_value (value); 1193425bb815Sopenharmony_ci 1194425bb815Sopenharmony_ci /* 5.e.iv */ 1195425bb815Sopenharmony_ci result = ecma_op_object_define_own_property (receiver_obj_p, property_name_p, &prop_desc); 1196425bb815Sopenharmony_ci } 1197425bb815Sopenharmony_ci 1198425bb815Sopenharmony_ci ecma_free_property_descriptor (&prop_desc); 1199425bb815Sopenharmony_ci 1200425bb815Sopenharmony_ci return result; 1201425bb815Sopenharmony_ci } 1202425bb815Sopenharmony_ci 1203425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015_BUILTIN_PROXY) 1204425bb815Sopenharmony_ci if (ECMA_OBJECT_IS_PROXY (receiver_obj_p)) 1205425bb815Sopenharmony_ci { 1206425bb815Sopenharmony_ci ecma_property_descriptor_t desc; 1207425bb815Sopenharmony_ci desc.flags = ECMA_NAME_DATA_PROPERTY_DESCRIPTOR_BITS; 1208425bb815Sopenharmony_ci desc.value = value; 1209425bb815Sopenharmony_ci return ecma_proxy_object_define_own_property (receiver_obj_p, property_name_p, &desc); 1210425bb815Sopenharmony_ci } 1211425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */ 1212425bb815Sopenharmony_ci 1213425bb815Sopenharmony_ci if (JERRY_UNLIKELY (ecma_op_object_is_fast_array (receiver_obj_p))) 1214425bb815Sopenharmony_ci { 1215425bb815Sopenharmony_ci ecma_fast_array_convert_to_normal (receiver_obj_p); 1216425bb815Sopenharmony_ci } 1217425bb815Sopenharmony_ci 1218425bb815Sopenharmony_ci /* 5.f.i */ 1219425bb815Sopenharmony_ci ecma_property_value_t *new_prop_value_p; 1220425bb815Sopenharmony_ci new_prop_value_p = ecma_create_named_data_property (receiver_obj_p, 1221425bb815Sopenharmony_ci property_name_p, 1222425bb815Sopenharmony_ci ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE, 1223425bb815Sopenharmony_ci NULL); 1224425bb815Sopenharmony_ci JERRY_ASSERT (ecma_is_value_undefined (new_prop_value_p->value)); 1225425bb815Sopenharmony_ci new_prop_value_p->value = ecma_copy_value_if_not_object (value); 1226425bb815Sopenharmony_ci 1227425bb815Sopenharmony_ci return ECMA_VALUE_TRUE; 1228425bb815Sopenharmony_ci} /* ecma_op_object_put_apply_receiver */ 1229425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 1230425bb815Sopenharmony_ci 1231425bb815Sopenharmony_ci/** 1232425bb815Sopenharmony_ci * [[Put]] ecma general object's operation with given receiver 1233425bb815Sopenharmony_ci * 1234425bb815Sopenharmony_ci * See also: 1235425bb815Sopenharmony_ci * ECMA-262 v5, 8.6.2; ECMA-262 v5, Table 8 1236425bb815Sopenharmony_ci * ECMA-262 v5, 8.12.5 1237425bb815Sopenharmony_ci * ECMA-262 v6, 9.1.9 1238425bb815Sopenharmony_ci * Also incorporates [[CanPut]] ECMA-262 v5, 8.12.4 1239425bb815Sopenharmony_ci * 1240425bb815Sopenharmony_ci * @return ecma value 1241425bb815Sopenharmony_ci * The returned value must be freed with ecma_free_value. 1242425bb815Sopenharmony_ci * 1243425bb815Sopenharmony_ci * Returns with ECMA_VALUE_TRUE if the operation is 1244425bb815Sopenharmony_ci * successful. Otherwise it returns with an error object 1245425bb815Sopenharmony_ci * or ECMA_VALUE_FALSE. 1246425bb815Sopenharmony_ci * 1247425bb815Sopenharmony_ci * Note: even if is_throw is false, the setter can throw an 1248425bb815Sopenharmony_ci * error, and this function returns with that error. 1249425bb815Sopenharmony_ci */ 1250425bb815Sopenharmony_ciecma_value_t 1251425bb815Sopenharmony_ciecma_op_object_put_with_receiver (ecma_object_t *object_p, /**< the object */ 1252425bb815Sopenharmony_ci ecma_string_t *property_name_p, /**< property name */ 1253425bb815Sopenharmony_ci ecma_value_t value, /**< ecma value */ 1254425bb815Sopenharmony_ci ecma_value_t receiver, /**< receiver */ 1255425bb815Sopenharmony_ci bool is_throw) /**< flag that controls failure handling */ 1256425bb815Sopenharmony_ci{ 1257425bb815Sopenharmony_ci JERRY_ASSERT (object_p != NULL 1258425bb815Sopenharmony_ci && !ecma_is_lexical_environment (object_p)); 1259425bb815Sopenharmony_ci JERRY_ASSERT (property_name_p != NULL); 1260425bb815Sopenharmony_ci 1261425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015_BUILTIN_PROXY) 1262425bb815Sopenharmony_ci if (ECMA_OBJECT_IS_PROXY (object_p)) 1263425bb815Sopenharmony_ci { 1264425bb815Sopenharmony_ci return ecma_proxy_object_set (object_p, property_name_p, value, receiver); 1265425bb815Sopenharmony_ci } 1266425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */ 1267425bb815Sopenharmony_ci 1268425bb815Sopenharmony_ci#if defined(JERRY_FUNCTION_NAME) && !defined(__APPLE__) 1269425bb815Sopenharmony_ci if (ecma_is_value_object(value)) { 1270425bb815Sopenharmony_ci ecma_object_t* obj = ecma_get_object_from_value(value); 1271425bb815Sopenharmony_ci if (ecma_get_object_type(obj) == ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION) { 1272425bb815Sopenharmony_ci ecma_string_t* property_name = ecma_get_magic_string (LIT_MAGIC_STRING_NAME); 1273425bb815Sopenharmony_ci if (ecma_find_named_property (obj, property_name) == NULL) { 1274425bb815Sopenharmony_ci ecma_property_value_t* prop_val = ecma_create_named_data_property(obj, 1275425bb815Sopenharmony_ci property_name, 1276425bb815Sopenharmony_ci ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE, 1277425bb815Sopenharmony_ci NULL); 1278425bb815Sopenharmony_ci prop_val->value = ecma_copy_value(ecma_make_string_value(property_name_p)); 1279425bb815Sopenharmony_ci } else { 1280425bb815Sopenharmony_ci ecma_deref_ecma_string (property_name); 1281425bb815Sopenharmony_ci } 1282425bb815Sopenharmony_ci } 1283425bb815Sopenharmony_ci } 1284425bb815Sopenharmony_ci#endif 1285425bb815Sopenharmony_ci 1286425bb815Sopenharmony_ci ecma_object_type_t type = ecma_get_object_type (object_p); 1287425bb815Sopenharmony_ci 1288425bb815Sopenharmony_ci switch (type) 1289425bb815Sopenharmony_ci { 1290425bb815Sopenharmony_ci case ECMA_OBJECT_TYPE_ARRAY: 1291425bb815Sopenharmony_ci { 1292425bb815Sopenharmony_ci ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) object_p; 1293425bb815Sopenharmony_ci 1294425bb815Sopenharmony_ci if (ecma_string_is_length (property_name_p)) 1295425bb815Sopenharmony_ci { 1296425bb815Sopenharmony_ci if (ecma_is_property_writable (ext_object_p->u.array.u.length_prop)) 1297425bb815Sopenharmony_ci { 1298425bb815Sopenharmony_ci return ecma_op_array_object_set_length (object_p, value, 0); 1299425bb815Sopenharmony_ci } 1300425bb815Sopenharmony_ci 1301425bb815Sopenharmony_ci return ecma_reject (is_throw); 1302425bb815Sopenharmony_ci } 1303425bb815Sopenharmony_ci 1304425bb815Sopenharmony_ci if (JERRY_LIKELY (ecma_op_array_is_fast_array (ext_object_p))) 1305425bb815Sopenharmony_ci { 1306425bb815Sopenharmony_ci if (JERRY_UNLIKELY (!ecma_op_ordinary_object_is_extensible (object_p))) 1307425bb815Sopenharmony_ci { 1308425bb815Sopenharmony_ci return ecma_reject (is_throw); 1309425bb815Sopenharmony_ci } 1310425bb815Sopenharmony_ci 1311425bb815Sopenharmony_ci uint32_t index = ecma_string_get_array_index (property_name_p); 1312425bb815Sopenharmony_ci 1313425bb815Sopenharmony_ci if (JERRY_UNLIKELY (index == ECMA_STRING_NOT_ARRAY_INDEX)) 1314425bb815Sopenharmony_ci { 1315425bb815Sopenharmony_ci ecma_fast_array_convert_to_normal (object_p); 1316425bb815Sopenharmony_ci } 1317425bb815Sopenharmony_ci else if (ecma_fast_array_set_property (object_p, index, value)) 1318425bb815Sopenharmony_ci { 1319425bb815Sopenharmony_ci return ECMA_VALUE_TRUE; 1320425bb815Sopenharmony_ci } 1321425bb815Sopenharmony_ci } 1322425bb815Sopenharmony_ci 1323425bb815Sopenharmony_ci JERRY_ASSERT (!ecma_op_object_is_fast_array (object_p)); 1324425bb815Sopenharmony_ci 1325425bb815Sopenharmony_ci break; 1326425bb815Sopenharmony_ci } 1327425bb815Sopenharmony_ci case ECMA_OBJECT_TYPE_PSEUDO_ARRAY: 1328425bb815Sopenharmony_ci { 1329425bb815Sopenharmony_ci ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) object_p; 1330425bb815Sopenharmony_ci 1331425bb815Sopenharmony_ci if (ext_object_p->u.pseudo_array.type == ECMA_PSEUDO_ARRAY_ARGUMENTS) 1332425bb815Sopenharmony_ci { 1333425bb815Sopenharmony_ci uint32_t index = ecma_string_get_array_index (property_name_p); 1334425bb815Sopenharmony_ci 1335425bb815Sopenharmony_ci if (index != ECMA_STRING_NOT_ARRAY_INDEX 1336425bb815Sopenharmony_ci && index < ext_object_p->u.pseudo_array.u1.length) 1337425bb815Sopenharmony_ci { 1338425bb815Sopenharmony_ci ecma_value_t *arg_Literal_p = (ecma_value_t *) (ext_object_p + 1); 1339425bb815Sopenharmony_ci 1340425bb815Sopenharmony_ci if (arg_Literal_p[index] != ECMA_VALUE_EMPTY) 1341425bb815Sopenharmony_ci { 1342425bb815Sopenharmony_ci ecma_string_t *arg_name_p = ecma_get_string_from_value (arg_Literal_p[index]); 1343425bb815Sopenharmony_ci 1344425bb815Sopenharmony_ci ecma_object_t *lex_env_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_object_t, 1345425bb815Sopenharmony_ci ext_object_p->u.pseudo_array.u2.lex_env_cp); 1346425bb815Sopenharmony_ci 1347425bb815Sopenharmony_ci JERRY_ASSERT (lex_env_p != NULL 1348425bb815Sopenharmony_ci && ecma_is_lexical_environment (lex_env_p)); 1349425bb815Sopenharmony_ci 1350425bb815Sopenharmony_ci ecma_op_set_mutable_binding (lex_env_p, arg_name_p, value, true); 1351425bb815Sopenharmony_ci return ECMA_VALUE_TRUE; 1352425bb815Sopenharmony_ci } 1353425bb815Sopenharmony_ci } 1354425bb815Sopenharmony_ci } 1355425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) 1356425bb815Sopenharmony_ci /* ES2015 9.4.5.5 */ 1357425bb815Sopenharmony_ci if (ecma_object_is_typedarray (object_p)) 1358425bb815Sopenharmony_ci { 1359425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 1360425bb815Sopenharmony_ci if (ecma_prop_name_is_symbol (property_name_p)) 1361425bb815Sopenharmony_ci { 1362425bb815Sopenharmony_ci break; 1363425bb815Sopenharmony_ci } 1364425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 1365425bb815Sopenharmony_ci 1366425bb815Sopenharmony_ci uint32_t array_index = ecma_string_get_array_index (property_name_p); 1367425bb815Sopenharmony_ci 1368425bb815Sopenharmony_ci if (array_index != ECMA_STRING_NOT_ARRAY_INDEX) 1369425bb815Sopenharmony_ci { 1370425bb815Sopenharmony_ci ecma_number_t num_var; 1371425bb815Sopenharmony_ci ecma_value_t error = ecma_get_number (value, &num_var); 1372425bb815Sopenharmony_ci 1373425bb815Sopenharmony_ci if (ECMA_IS_VALUE_ERROR (error)) 1374425bb815Sopenharmony_ci { 1375425bb815Sopenharmony_ci jcontext_release_exception (); 1376425bb815Sopenharmony_ci return ecma_reject (is_throw); 1377425bb815Sopenharmony_ci } 1378425bb815Sopenharmony_ci 1379425bb815Sopenharmony_ci ecma_typedarray_info_t info = ecma_typedarray_get_info (object_p); 1380425bb815Sopenharmony_ci 1381425bb815Sopenharmony_ci if (array_index >= info.length) 1382425bb815Sopenharmony_ci { 1383425bb815Sopenharmony_ci return ecma_reject (is_throw); 1384425bb815Sopenharmony_ci } 1385425bb815Sopenharmony_ci 1386425bb815Sopenharmony_ci ecma_length_t byte_pos = array_index << info.shift; 1387425bb815Sopenharmony_ci ecma_set_typedarray_element (info.buffer_p + byte_pos, num_var, info.id); 1388425bb815Sopenharmony_ci 1389425bb815Sopenharmony_ci return ECMA_VALUE_TRUE; 1390425bb815Sopenharmony_ci } 1391425bb815Sopenharmony_ci 1392425bb815Sopenharmony_ci ecma_number_t num = ecma_string_to_number (property_name_p); 1393425bb815Sopenharmony_ci ecma_string_t *num_to_str = ecma_new_ecma_string_from_number (num); 1394425bb815Sopenharmony_ci 1395425bb815Sopenharmony_ci if (ecma_compare_ecma_strings (property_name_p, num_to_str)) 1396425bb815Sopenharmony_ci { 1397425bb815Sopenharmony_ci ecma_deref_ecma_string (num_to_str); 1398425bb815Sopenharmony_ci 1399425bb815Sopenharmony_ci return ecma_reject (is_throw); 1400425bb815Sopenharmony_ci } 1401425bb815Sopenharmony_ci 1402425bb815Sopenharmony_ci ecma_deref_ecma_string (num_to_str); 1403425bb815Sopenharmony_ci } 1404425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) */ 1405425bb815Sopenharmony_ci break; 1406425bb815Sopenharmony_ci } 1407425bb815Sopenharmony_ci default: 1408425bb815Sopenharmony_ci { 1409425bb815Sopenharmony_ci break; 1410425bb815Sopenharmony_ci } 1411425bb815Sopenharmony_ci } 1412425bb815Sopenharmony_ci 1413425bb815Sopenharmony_ci ecma_property_t *property_p = ecma_find_named_property (object_p, property_name_p); 1414425bb815Sopenharmony_ci 1415425bb815Sopenharmony_ci if (property_p == NULL) 1416425bb815Sopenharmony_ci { 1417425bb815Sopenharmony_ci if (type == ECMA_OBJECT_TYPE_CLASS) 1418425bb815Sopenharmony_ci { 1419425bb815Sopenharmony_ci ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) object_p; 1420425bb815Sopenharmony_ci 1421425bb815Sopenharmony_ci if (ext_object_p->u.class_prop.class_id == LIT_MAGIC_STRING_STRING_UL) 1422425bb815Sopenharmony_ci { 1423425bb815Sopenharmony_ci uint32_t index = ecma_string_get_array_index (property_name_p); 1424425bb815Sopenharmony_ci 1425425bb815Sopenharmony_ci if (index != ECMA_STRING_NOT_ARRAY_INDEX) 1426425bb815Sopenharmony_ci { 1427425bb815Sopenharmony_ci ecma_value_t prim_value_p = ext_object_p->u.class_prop.u.value; 1428425bb815Sopenharmony_ci ecma_string_t *prim_value_str_p = ecma_get_string_from_value (prim_value_p); 1429425bb815Sopenharmony_ci 1430425bb815Sopenharmony_ci if (index < ecma_string_get_length (prim_value_str_p)) 1431425bb815Sopenharmony_ci { 1432425bb815Sopenharmony_ci return ecma_reject (is_throw); 1433425bb815Sopenharmony_ci } 1434425bb815Sopenharmony_ci } 1435425bb815Sopenharmony_ci } 1436425bb815Sopenharmony_ci } 1437425bb815Sopenharmony_ci 1438425bb815Sopenharmony_ci if (ecma_get_object_is_builtin (object_p)) 1439425bb815Sopenharmony_ci { 1440425bb815Sopenharmony_ci if (type == ECMA_OBJECT_TYPE_FUNCTION && ecma_builtin_function_is_routine (object_p)) 1441425bb815Sopenharmony_ci { 1442425bb815Sopenharmony_ci property_p = ecma_builtin_routine_try_to_instantiate_property (object_p, property_name_p); 1443425bb815Sopenharmony_ci } 1444425bb815Sopenharmony_ci else 1445425bb815Sopenharmony_ci { 1446425bb815Sopenharmony_ci property_p = ecma_builtin_try_to_instantiate_property (object_p, property_name_p); 1447425bb815Sopenharmony_ci } 1448425bb815Sopenharmony_ci } 1449425bb815Sopenharmony_ci else if (type == ECMA_OBJECT_TYPE_FUNCTION) 1450425bb815Sopenharmony_ci { 1451425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 1452425bb815Sopenharmony_ci /* Uninitialized 'length' property is non-writable (ECMA-262 v6, 19.2.4.1) */ 1453425bb815Sopenharmony_ci if ((ecma_string_is_length (property_name_p)) 1454425bb815Sopenharmony_ci && (!ECMA_GET_FIRST_BIT_FROM_POINTER_TAG (((ecma_extended_object_t *) object_p)->u.function.scope_cp))) 1455425bb815Sopenharmony_ci { 1456425bb815Sopenharmony_ci return ecma_reject (is_throw); 1457425bb815Sopenharmony_ci } 1458425bb815Sopenharmony_ci#else /* !ENABLED (JERRY_ES2015) */ 1459425bb815Sopenharmony_ci if (ecma_string_is_length (property_name_p)) 1460425bb815Sopenharmony_ci { 1461425bb815Sopenharmony_ci return ecma_reject (is_throw); 1462425bb815Sopenharmony_ci } 1463425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 1464425bb815Sopenharmony_ci 1465425bb815Sopenharmony_ci /* Get prototype physical property. */ 1466425bb815Sopenharmony_ci property_p = ecma_op_function_try_to_lazy_instantiate_property (object_p, property_name_p); 1467425bb815Sopenharmony_ci } 1468425bb815Sopenharmony_ci else if (type == ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION) 1469425bb815Sopenharmony_ci { 1470425bb815Sopenharmony_ci property_p = ecma_op_external_function_try_to_lazy_instantiate_property (object_p, property_name_p); 1471425bb815Sopenharmony_ci } 1472425bb815Sopenharmony_ci else if (type == ECMA_OBJECT_TYPE_BOUND_FUNCTION) 1473425bb815Sopenharmony_ci { 1474425bb815Sopenharmony_ci property_p = ecma_op_bound_function_try_to_lazy_instantiate_property (object_p, property_name_p); 1475425bb815Sopenharmony_ci } 1476425bb815Sopenharmony_ci } 1477425bb815Sopenharmony_ci 1478425bb815Sopenharmony_ci jmem_cpointer_t setter_cp = JMEM_CP_NULL; 1479425bb815Sopenharmony_ci 1480425bb815Sopenharmony_ci if (property_p != NULL) 1481425bb815Sopenharmony_ci { 1482425bb815Sopenharmony_ci if (ECMA_PROPERTY_GET_TYPE (*property_p) == ECMA_PROPERTY_TYPE_NAMEDDATA) 1483425bb815Sopenharmony_ci { 1484425bb815Sopenharmony_ci if (ecma_is_property_writable (*property_p)) 1485425bb815Sopenharmony_ci { 1486425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 1487425bb815Sopenharmony_ci if (ecma_make_object_value (object_p) != receiver) 1488425bb815Sopenharmony_ci { 1489425bb815Sopenharmony_ci return ecma_op_object_put_apply_receiver (receiver, property_name_p, value, is_throw); 1490425bb815Sopenharmony_ci } 1491425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 1492425bb815Sopenharmony_ci 1493425bb815Sopenharmony_ci /* There is no need for special casing arrays here because changing the 1494425bb815Sopenharmony_ci * value of an existing property never changes the length of an array. */ 1495425bb815Sopenharmony_ci ecma_named_data_property_assign_value (object_p, 1496425bb815Sopenharmony_ci ECMA_PROPERTY_VALUE_PTR (property_p), 1497425bb815Sopenharmony_ci value); 1498425bb815Sopenharmony_ci return ECMA_VALUE_TRUE; 1499425bb815Sopenharmony_ci } 1500425bb815Sopenharmony_ci } 1501425bb815Sopenharmony_ci else 1502425bb815Sopenharmony_ci { 1503425bb815Sopenharmony_ci JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (*property_p) == ECMA_PROPERTY_TYPE_NAMEDACCESSOR); 1504425bb815Sopenharmony_ci 1505425bb815Sopenharmony_ci ecma_getter_setter_pointers_t *get_set_pair_p; 1506425bb815Sopenharmony_ci get_set_pair_p = ecma_get_named_accessor_property (ECMA_PROPERTY_VALUE_PTR (property_p)); 1507425bb815Sopenharmony_ci setter_cp = get_set_pair_p->setter_cp; 1508425bb815Sopenharmony_ci } 1509425bb815Sopenharmony_ci } 1510425bb815Sopenharmony_ci else 1511425bb815Sopenharmony_ci { 1512425bb815Sopenharmony_ci bool create_new_property = true; 1513425bb815Sopenharmony_ci 1514425bb815Sopenharmony_ci jmem_cpointer_t proto_cp = ecma_op_ordinary_object_get_prototype_of (object_p); 1515425bb815Sopenharmony_ci 1516425bb815Sopenharmony_ci if (proto_cp != JMEM_CP_NULL) 1517425bb815Sopenharmony_ci { 1518425bb815Sopenharmony_ci ecma_property_ref_t property_ref = { NULL }; 1519425bb815Sopenharmony_ci ecma_object_t *proto_p = ECMA_GET_NON_NULL_POINTER (ecma_object_t, proto_cp); 1520425bb815Sopenharmony_ci 1521425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015_BUILTIN_PROXY) 1522425bb815Sopenharmony_ci if (ECMA_OBJECT_IS_PROXY (proto_p)) 1523425bb815Sopenharmony_ci { 1524425bb815Sopenharmony_ci return ecma_op_object_put_with_receiver (proto_p, 1525425bb815Sopenharmony_ci property_name_p, 1526425bb815Sopenharmony_ci value, 1527425bb815Sopenharmony_ci receiver, 1528425bb815Sopenharmony_ci is_throw); 1529425bb815Sopenharmony_ci } 1530425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */ 1531425bb815Sopenharmony_ci 1532425bb815Sopenharmony_ci ecma_property_t inherited_property = ecma_op_object_get_property (proto_p, 1533425bb815Sopenharmony_ci property_name_p, 1534425bb815Sopenharmony_ci &property_ref, 1535425bb815Sopenharmony_ci ECMA_PROPERTY_GET_NO_OPTIONS); 1536425bb815Sopenharmony_ci 1537425bb815Sopenharmony_ci if (inherited_property != ECMA_PROPERTY_TYPE_NOT_FOUND) 1538425bb815Sopenharmony_ci { 1539425bb815Sopenharmony_ci if (ECMA_PROPERTY_GET_TYPE (inherited_property) == ECMA_PROPERTY_TYPE_NAMEDACCESSOR) 1540425bb815Sopenharmony_ci { 1541425bb815Sopenharmony_ci setter_cp = ecma_get_named_accessor_property (property_ref.value_p)->setter_cp; 1542425bb815Sopenharmony_ci create_new_property = false; 1543425bb815Sopenharmony_ci } 1544425bb815Sopenharmony_ci else 1545425bb815Sopenharmony_ci { 1546425bb815Sopenharmony_ci create_new_property = ecma_is_property_writable (inherited_property); 1547425bb815Sopenharmony_ci } 1548425bb815Sopenharmony_ci } 1549425bb815Sopenharmony_ci } 1550425bb815Sopenharmony_ci 1551425bb815Sopenharmony_ci if (create_new_property 1552425bb815Sopenharmony_ci && ecma_op_ordinary_object_is_extensible (object_p)) 1553425bb815Sopenharmony_ci { 1554425bb815Sopenharmony_ci const ecma_object_type_t obj_type = ecma_get_object_type (object_p); 1555425bb815Sopenharmony_ci 1556425bb815Sopenharmony_ci if (obj_type == ECMA_OBJECT_TYPE_PSEUDO_ARRAY) 1557425bb815Sopenharmony_ci { 1558425bb815Sopenharmony_ci ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) object_p; 1559425bb815Sopenharmony_ci 1560425bb815Sopenharmony_ci if (ext_object_p->u.pseudo_array.type == ECMA_PSEUDO_ARRAY_ARGUMENTS) 1561425bb815Sopenharmony_ci { 1562425bb815Sopenharmony_ci return ecma_builtin_helper_def_prop (object_p, 1563425bb815Sopenharmony_ci property_name_p, 1564425bb815Sopenharmony_ci value, 1565425bb815Sopenharmony_ci ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE | ECMA_IS_THROW); 1566425bb815Sopenharmony_ci } 1567425bb815Sopenharmony_ci } 1568425bb815Sopenharmony_ci 1569425bb815Sopenharmony_ci uint32_t index = ecma_string_get_array_index (property_name_p); 1570425bb815Sopenharmony_ci 1571425bb815Sopenharmony_ci if (obj_type == ECMA_OBJECT_TYPE_ARRAY 1572425bb815Sopenharmony_ci && index != ECMA_STRING_NOT_ARRAY_INDEX) 1573425bb815Sopenharmony_ci { 1574425bb815Sopenharmony_ci ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) object_p; 1575425bb815Sopenharmony_ci 1576425bb815Sopenharmony_ci if (index < UINT32_MAX 1577425bb815Sopenharmony_ci && index >= ext_object_p->u.array.length) 1578425bb815Sopenharmony_ci { 1579425bb815Sopenharmony_ci if (!ecma_is_property_writable (ext_object_p->u.array.u.length_prop)) 1580425bb815Sopenharmony_ci { 1581425bb815Sopenharmony_ci return ecma_reject (is_throw); 1582425bb815Sopenharmony_ci } 1583425bb815Sopenharmony_ci 1584425bb815Sopenharmony_ci ext_object_p->u.array.length = index + 1; 1585425bb815Sopenharmony_ci } 1586425bb815Sopenharmony_ci } 1587425bb815Sopenharmony_ci 1588425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 1589425bb815Sopenharmony_ci return ecma_op_object_put_apply_receiver (receiver, property_name_p, value, is_throw); 1590425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 1591425bb815Sopenharmony_ci 1592425bb815Sopenharmony_ci ecma_property_value_t *new_prop_value_p; 1593425bb815Sopenharmony_ci new_prop_value_p = ecma_create_named_data_property (object_p, 1594425bb815Sopenharmony_ci property_name_p, 1595425bb815Sopenharmony_ci ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE, 1596425bb815Sopenharmony_ci NULL); 1597425bb815Sopenharmony_ci 1598425bb815Sopenharmony_ci JERRY_ASSERT (ecma_is_value_undefined (new_prop_value_p->value)); 1599425bb815Sopenharmony_ci new_prop_value_p->value = ecma_copy_value_if_not_object (value); 1600425bb815Sopenharmony_ci return ECMA_VALUE_TRUE; 1601425bb815Sopenharmony_ci } 1602425bb815Sopenharmony_ci } 1603425bb815Sopenharmony_ci 1604425bb815Sopenharmony_ci if (setter_cp == JMEM_CP_NULL) 1605425bb815Sopenharmony_ci { 1606425bb815Sopenharmony_ci return ecma_reject (is_throw); 1607425bb815Sopenharmony_ci } 1608425bb815Sopenharmony_ci 1609425bb815Sopenharmony_ci ecma_value_t ret_value = ecma_op_function_call (ECMA_GET_NON_NULL_POINTER (ecma_object_t, setter_cp), 1610425bb815Sopenharmony_ci receiver, 1611425bb815Sopenharmony_ci &value, 1612425bb815Sopenharmony_ci 1); 1613425bb815Sopenharmony_ci 1614425bb815Sopenharmony_ci if (!ECMA_IS_VALUE_ERROR (ret_value)) 1615425bb815Sopenharmony_ci { 1616425bb815Sopenharmony_ci ecma_fast_free_value (ret_value); 1617425bb815Sopenharmony_ci ret_value = ECMA_VALUE_TRUE; 1618425bb815Sopenharmony_ci } 1619425bb815Sopenharmony_ci 1620425bb815Sopenharmony_ci return ret_value; 1621425bb815Sopenharmony_ci} /* ecma_op_object_put_with_receiver */ 1622425bb815Sopenharmony_ci 1623425bb815Sopenharmony_ci/** 1624425bb815Sopenharmony_ci * [[Delete]] ecma object's operation specialized for uint32_t property index 1625425bb815Sopenharmony_ci * 1626425bb815Sopenharmony_ci * Note: 1627425bb815Sopenharmony_ci * This method falls back to the general ecma_op_object_delete 1628425bb815Sopenharmony_ci * 1629425bb815Sopenharmony_ci * @return true - if deleted successfully 1630425bb815Sopenharmony_ci * false - or type error otherwise (based in 'is_throw') 1631425bb815Sopenharmony_ci */ 1632425bb815Sopenharmony_ciecma_value_t 1633425bb815Sopenharmony_ciecma_op_object_delete_by_uint32_index (ecma_object_t *obj_p, /**< the object */ 1634425bb815Sopenharmony_ci uint32_t index, /**< property index */ 1635425bb815Sopenharmony_ci bool is_throw) /**< flag that controls failure handling */ 1636425bb815Sopenharmony_ci{ 1637425bb815Sopenharmony_ci if (JERRY_LIKELY (index <= ECMA_DIRECT_STRING_MAX_IMM)) 1638425bb815Sopenharmony_ci { 1639425bb815Sopenharmony_ci return ecma_op_object_delete (obj_p, ECMA_CREATE_DIRECT_UINT32_STRING (index), is_throw); 1640425bb815Sopenharmony_ci } 1641425bb815Sopenharmony_ci 1642425bb815Sopenharmony_ci ecma_string_t *index_str_p = ecma_new_non_direct_string_from_uint32 (index); 1643425bb815Sopenharmony_ci ecma_value_t ret_value = ecma_op_object_delete (obj_p, index_str_p, is_throw); 1644425bb815Sopenharmony_ci ecma_deref_ecma_string (index_str_p); 1645425bb815Sopenharmony_ci 1646425bb815Sopenharmony_ci return ret_value; 1647425bb815Sopenharmony_ci} /* ecma_op_object_delete_by_uint32_index */ 1648425bb815Sopenharmony_ci 1649425bb815Sopenharmony_ci/** 1650425bb815Sopenharmony_ci * [[Delete]] ecma object's operation specialized for ecma_number_t property index 1651425bb815Sopenharmony_ci * 1652425bb815Sopenharmony_ci * Note: 1653425bb815Sopenharmony_ci * This method falls back to the general ecma_op_object_delete 1654425bb815Sopenharmony_ci * 1655425bb815Sopenharmony_ci * @return true - if deleted successfully 1656425bb815Sopenharmony_ci * false - or type error otherwise (based in 'is_throw') 1657425bb815Sopenharmony_ci */ 1658425bb815Sopenharmony_ciecma_value_t 1659425bb815Sopenharmony_ciecma_op_object_delete_by_number_index (ecma_object_t *obj_p, /**< the object */ 1660425bb815Sopenharmony_ci ecma_number_t index, /**< property index */ 1661425bb815Sopenharmony_ci bool is_throw) /**< flag that controls failure handling */ 1662425bb815Sopenharmony_ci{ 1663425bb815Sopenharmony_ci ecma_string_t *index_str_p = ecma_new_ecma_string_from_number (index); 1664425bb815Sopenharmony_ci ecma_value_t ret_value = ecma_op_object_delete (obj_p, index_str_p, is_throw); 1665425bb815Sopenharmony_ci ecma_deref_ecma_string (index_str_p); 1666425bb815Sopenharmony_ci 1667425bb815Sopenharmony_ci return ret_value; 1668425bb815Sopenharmony_ci} /* ecma_op_object_delete_by_number_index */ 1669425bb815Sopenharmony_ci 1670425bb815Sopenharmony_ci/** 1671425bb815Sopenharmony_ci * [[Delete]] ecma object's operation 1672425bb815Sopenharmony_ci * 1673425bb815Sopenharmony_ci * See also: 1674425bb815Sopenharmony_ci * ECMA-262 v5, 8.6.2; ECMA-262 v5, Table 8 1675425bb815Sopenharmony_ci * 1676425bb815Sopenharmony_ci * Note: 1677425bb815Sopenharmony_ci * returned value must be freed with ecma_free_value 1678425bb815Sopenharmony_ci * 1679425bb815Sopenharmony_ci * @return true - if deleted successfully 1680425bb815Sopenharmony_ci * false - or type error otherwise (based in 'is_throw') 1681425bb815Sopenharmony_ci */ 1682425bb815Sopenharmony_ciecma_value_t 1683425bb815Sopenharmony_ciecma_op_object_delete (ecma_object_t *obj_p, /**< the object */ 1684425bb815Sopenharmony_ci ecma_string_t *property_name_p, /**< property name */ 1685425bb815Sopenharmony_ci bool is_throw) /**< flag that controls failure handling */ 1686425bb815Sopenharmony_ci{ 1687425bb815Sopenharmony_ci JERRY_ASSERT (obj_p != NULL 1688425bb815Sopenharmony_ci && !ecma_is_lexical_environment (obj_p)); 1689425bb815Sopenharmony_ci JERRY_ASSERT (property_name_p != NULL); 1690425bb815Sopenharmony_ci 1691425bb815Sopenharmony_ci if (ecma_get_object_type (obj_p) == ECMA_OBJECT_TYPE_PSEUDO_ARRAY) 1692425bb815Sopenharmony_ci { 1693425bb815Sopenharmony_ci ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) obj_p; 1694425bb815Sopenharmony_ci 1695425bb815Sopenharmony_ci if (ext_object_p->u.pseudo_array.type == ECMA_PSEUDO_ARRAY_ARGUMENTS) 1696425bb815Sopenharmony_ci { 1697425bb815Sopenharmony_ci return ecma_op_arguments_object_delete (obj_p, 1698425bb815Sopenharmony_ci property_name_p, 1699425bb815Sopenharmony_ci is_throw); 1700425bb815Sopenharmony_ci } 1701425bb815Sopenharmony_ci } 1702425bb815Sopenharmony_ci 1703425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015_BUILTIN_PROXY) 1704425bb815Sopenharmony_ci if (ECMA_OBJECT_IS_PROXY (obj_p)) 1705425bb815Sopenharmony_ci { 1706425bb815Sopenharmony_ci return ecma_proxy_object_delete_property (obj_p, property_name_p); 1707425bb815Sopenharmony_ci } 1708425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */ 1709425bb815Sopenharmony_ci 1710425bb815Sopenharmony_ci JERRY_ASSERT_OBJECT_TYPE_IS_VALID (ecma_get_object_type (obj_p)); 1711425bb815Sopenharmony_ci 1712425bb815Sopenharmony_ci return ecma_op_general_object_delete (obj_p, 1713425bb815Sopenharmony_ci property_name_p, 1714425bb815Sopenharmony_ci is_throw); 1715425bb815Sopenharmony_ci} /* ecma_op_object_delete */ 1716425bb815Sopenharmony_ci 1717425bb815Sopenharmony_ci/** 1718425bb815Sopenharmony_ci * [[DefaultValue]] ecma object's operation 1719425bb815Sopenharmony_ci * 1720425bb815Sopenharmony_ci * See also: 1721425bb815Sopenharmony_ci * ECMA-262 v5, 8.6.2; ECMA-262 v5, Table 8 1722425bb815Sopenharmony_ci * 1723425bb815Sopenharmony_ci * @return ecma value 1724425bb815Sopenharmony_ci * Returned value must be freed with ecma_free_value 1725425bb815Sopenharmony_ci */ 1726425bb815Sopenharmony_ciecma_value_t 1727425bb815Sopenharmony_ciecma_op_object_default_value (ecma_object_t *obj_p, /**< the object */ 1728425bb815Sopenharmony_ci ecma_preferred_type_hint_t hint) /**< hint on preferred result type */ 1729425bb815Sopenharmony_ci{ 1730425bb815Sopenharmony_ci JERRY_ASSERT (obj_p != NULL 1731425bb815Sopenharmony_ci && !ecma_is_lexical_environment (obj_p)); 1732425bb815Sopenharmony_ci 1733425bb815Sopenharmony_ci JERRY_ASSERT_OBJECT_TYPE_IS_VALID (ecma_get_object_type (obj_p)); 1734425bb815Sopenharmony_ci 1735425bb815Sopenharmony_ci /* 1736425bb815Sopenharmony_ci * typedef ecma_property_t * (*default_value_ptr_t) (ecma_object_t *, ecma_string_t *); 1737425bb815Sopenharmony_ci * static const default_value_ptr_t default_value [ECMA_OBJECT_TYPE__COUNT] = 1738425bb815Sopenharmony_ci * { 1739425bb815Sopenharmony_ci * [ECMA_OBJECT_TYPE_GENERAL] = &ecma_op_general_object_default_value, 1740425bb815Sopenharmony_ci * [ECMA_OBJECT_TYPE_CLASS] = &ecma_op_general_object_default_value, 1741425bb815Sopenharmony_ci * [ECMA_OBJECT_TYPE_FUNCTION] = &ecma_op_general_object_default_value, 1742425bb815Sopenharmony_ci * [ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION] = &ecma_op_general_object_default_value, 1743425bb815Sopenharmony_ci * [ECMA_OBJECT_TYPE_ARRAY] = &ecma_op_general_object_default_value, 1744425bb815Sopenharmony_ci * [ECMA_OBJECT_TYPE_BOUND_FUNCTION] = &ecma_op_general_object_default_value, 1745425bb815Sopenharmony_ci * [ECMA_OBJECT_TYPE_PSEUDO_ARRAY] = &ecma_op_general_object_default_value 1746425bb815Sopenharmony_ci * }; 1747425bb815Sopenharmony_ci * 1748425bb815Sopenharmony_ci * return default_value[type] (obj_p, property_name_p); 1749425bb815Sopenharmony_ci */ 1750425bb815Sopenharmony_ci 1751425bb815Sopenharmony_ci return ecma_op_general_object_default_value (obj_p, hint); 1752425bb815Sopenharmony_ci} /* ecma_op_object_default_value */ 1753425bb815Sopenharmony_ci 1754425bb815Sopenharmony_ci/** 1755425bb815Sopenharmony_ci * [[DefineOwnProperty]] ecma object's operation 1756425bb815Sopenharmony_ci * 1757425bb815Sopenharmony_ci * See also: 1758425bb815Sopenharmony_ci * ECMA-262 v5, 8.6.2; ECMA-262 v5, Table 8 1759425bb815Sopenharmony_ci * 1760425bb815Sopenharmony_ci * @return ecma value 1761425bb815Sopenharmony_ci * Returned value must be freed with ecma_free_value 1762425bb815Sopenharmony_ci */ 1763425bb815Sopenharmony_ciecma_value_t 1764425bb815Sopenharmony_ciecma_op_object_define_own_property (ecma_object_t *obj_p, /**< the object */ 1765425bb815Sopenharmony_ci ecma_string_t *property_name_p, /**< property name */ 1766425bb815Sopenharmony_ci const ecma_property_descriptor_t *property_desc_p) /**< property 1767425bb815Sopenharmony_ci * descriptor */ 1768425bb815Sopenharmony_ci{ 1769425bb815Sopenharmony_ci JERRY_ASSERT (obj_p != NULL 1770425bb815Sopenharmony_ci && !ecma_is_lexical_environment (obj_p)); 1771425bb815Sopenharmony_ci JERRY_ASSERT (property_name_p != NULL); 1772425bb815Sopenharmony_ci 1773425bb815Sopenharmony_ci const ecma_object_type_t type = ecma_get_object_type (obj_p); 1774425bb815Sopenharmony_ci 1775425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015_BUILTIN_PROXY) 1776425bb815Sopenharmony_ci if (ECMA_OBJECT_IS_PROXY (obj_p)) 1777425bb815Sopenharmony_ci { 1778425bb815Sopenharmony_ci return ecma_proxy_object_define_own_property (obj_p, property_name_p, property_desc_p); 1779425bb815Sopenharmony_ci } 1780425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */ 1781425bb815Sopenharmony_ci 1782425bb815Sopenharmony_ci switch (type) 1783425bb815Sopenharmony_ci { 1784425bb815Sopenharmony_ci case ECMA_OBJECT_TYPE_GENERAL: 1785425bb815Sopenharmony_ci case ECMA_OBJECT_TYPE_CLASS: 1786425bb815Sopenharmony_ci case ECMA_OBJECT_TYPE_FUNCTION: 1787425bb815Sopenharmony_ci case ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION: 1788425bb815Sopenharmony_ci case ECMA_OBJECT_TYPE_BOUND_FUNCTION: 1789425bb815Sopenharmony_ci { 1790425bb815Sopenharmony_ci return ecma_op_general_object_define_own_property (obj_p, 1791425bb815Sopenharmony_ci property_name_p, 1792425bb815Sopenharmony_ci property_desc_p); 1793425bb815Sopenharmony_ci } 1794425bb815Sopenharmony_ci 1795425bb815Sopenharmony_ci case ECMA_OBJECT_TYPE_ARRAY: 1796425bb815Sopenharmony_ci { 1797425bb815Sopenharmony_ci return ecma_op_array_object_define_own_property (obj_p, 1798425bb815Sopenharmony_ci property_name_p, 1799425bb815Sopenharmony_ci property_desc_p); 1800425bb815Sopenharmony_ci } 1801425bb815Sopenharmony_ci 1802425bb815Sopenharmony_ci default: 1803425bb815Sopenharmony_ci { 1804425bb815Sopenharmony_ci JERRY_ASSERT (type == ECMA_OBJECT_TYPE_PSEUDO_ARRAY); 1805425bb815Sopenharmony_ci 1806425bb815Sopenharmony_ci ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) obj_p; 1807425bb815Sopenharmony_ci 1808425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) 1809425bb815Sopenharmony_ci if (ext_object_p->u.pseudo_array.type == ECMA_PSEUDO_ARRAY_ARGUMENTS) 1810425bb815Sopenharmony_ci { 1811425bb815Sopenharmony_ci#else /* !ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) */ 1812425bb815Sopenharmony_ci JERRY_ASSERT (ext_object_p->u.pseudo_array.type == ECMA_PSEUDO_ARRAY_ARGUMENTS); 1813425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) */ 1814425bb815Sopenharmony_ci return ecma_op_arguments_object_define_own_property (obj_p, 1815425bb815Sopenharmony_ci property_name_p, 1816425bb815Sopenharmony_ci property_desc_p); 1817425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) 1818425bb815Sopenharmony_ci } 1819425bb815Sopenharmony_ci /* ES2015 9.4.5.3 */ 1820425bb815Sopenharmony_ci if (ecma_object_is_typedarray (obj_p)) 1821425bb815Sopenharmony_ci { 1822425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 1823425bb815Sopenharmony_ci if (ecma_prop_name_is_symbol (property_name_p)) 1824425bb815Sopenharmony_ci { 1825425bb815Sopenharmony_ci return ecma_op_general_object_define_own_property (obj_p, 1826425bb815Sopenharmony_ci property_name_p, 1827425bb815Sopenharmony_ci property_desc_p); 1828425bb815Sopenharmony_ci } 1829425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 1830425bb815Sopenharmony_ci uint32_t array_index = ecma_string_get_array_index (property_name_p); 1831425bb815Sopenharmony_ci 1832425bb815Sopenharmony_ci if (array_index != ECMA_STRING_NOT_ARRAY_INDEX) 1833425bb815Sopenharmony_ci { 1834425bb815Sopenharmony_ci bool define_status = ecma_op_typedarray_define_index_prop (obj_p, 1835425bb815Sopenharmony_ci array_index, 1836425bb815Sopenharmony_ci property_desc_p); 1837425bb815Sopenharmony_ci 1838425bb815Sopenharmony_ci if (define_status) 1839425bb815Sopenharmony_ci { 1840425bb815Sopenharmony_ci return ECMA_VALUE_TRUE; 1841425bb815Sopenharmony_ci } 1842425bb815Sopenharmony_ci 1843425bb815Sopenharmony_ci return ecma_reject (property_desc_p->flags & ECMA_PROP_IS_THROW); 1844425bb815Sopenharmony_ci } 1845425bb815Sopenharmony_ci 1846425bb815Sopenharmony_ci ecma_number_t num = ecma_string_to_number (property_name_p); 1847425bb815Sopenharmony_ci ecma_string_t *num_to_str = ecma_new_ecma_string_from_number (num); 1848425bb815Sopenharmony_ci 1849425bb815Sopenharmony_ci if (ecma_compare_ecma_strings (property_name_p, num_to_str)) 1850425bb815Sopenharmony_ci { 1851425bb815Sopenharmony_ci ecma_deref_ecma_string (num_to_str); 1852425bb815Sopenharmony_ci 1853425bb815Sopenharmony_ci return ecma_reject (property_desc_p->flags & ECMA_PROP_IS_THROW); 1854425bb815Sopenharmony_ci } 1855425bb815Sopenharmony_ci 1856425bb815Sopenharmony_ci ecma_deref_ecma_string (num_to_str); 1857425bb815Sopenharmony_ci } 1858425bb815Sopenharmony_ci 1859425bb815Sopenharmony_ci return ecma_op_general_object_define_own_property (obj_p, 1860425bb815Sopenharmony_ci property_name_p, 1861425bb815Sopenharmony_ci property_desc_p); 1862425bb815Sopenharmony_ci#else /* !ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) */ 1863425bb815Sopenharmony_ci break; 1864425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) */ 1865425bb815Sopenharmony_ci } 1866425bb815Sopenharmony_ci } 1867425bb815Sopenharmony_ci} /* ecma_op_object_define_own_property */ 1868425bb815Sopenharmony_ci 1869425bb815Sopenharmony_ci/** 1870425bb815Sopenharmony_ci * Get property descriptor from specified property 1871425bb815Sopenharmony_ci * 1872425bb815Sopenharmony_ci * depending on the property type the following fields are set: 1873425bb815Sopenharmony_ci * - for named data properties: { [Value], [Writable], [Enumerable], [Configurable] }; 1874425bb815Sopenharmony_ci * - for named accessor properties: { [Get] - if defined, 1875425bb815Sopenharmony_ci * [Set] - if defined, 1876425bb815Sopenharmony_ci * [Enumerable], [Configurable] 1877425bb815Sopenharmony_ci * }. 1878425bb815Sopenharmony_ci * 1879425bb815Sopenharmony_ci * The output property descriptor will always be initialized to an empty descriptor. 1880425bb815Sopenharmony_ci * 1881425bb815Sopenharmony_ci * @return true - if property found 1882425bb815Sopenharmony_ci * false - otherwise 1883425bb815Sopenharmony_ci */ 1884425bb815Sopenharmony_ciecma_value_t 1885425bb815Sopenharmony_ciecma_op_object_get_own_property_descriptor (ecma_object_t *object_p, /**< the object */ 1886425bb815Sopenharmony_ci ecma_string_t *property_name_p, /**< property name */ 1887425bb815Sopenharmony_ci ecma_property_descriptor_t *prop_desc_p) /**< property descriptor */ 1888425bb815Sopenharmony_ci{ 1889425bb815Sopenharmony_ci *prop_desc_p = ecma_make_empty_property_descriptor (); 1890425bb815Sopenharmony_ci 1891425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015_BUILTIN_PROXY) 1892425bb815Sopenharmony_ci if (ECMA_OBJECT_IS_PROXY (object_p)) 1893425bb815Sopenharmony_ci { 1894425bb815Sopenharmony_ci return ecma_proxy_object_get_own_property_descriptor (object_p, property_name_p, prop_desc_p); 1895425bb815Sopenharmony_ci } 1896425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */ 1897425bb815Sopenharmony_ci 1898425bb815Sopenharmony_ci ecma_property_ref_t property_ref; 1899425bb815Sopenharmony_ci 1900425bb815Sopenharmony_ci ecma_property_t property = ecma_op_object_get_own_property (object_p, 1901425bb815Sopenharmony_ci property_name_p, 1902425bb815Sopenharmony_ci &property_ref, 1903425bb815Sopenharmony_ci ECMA_PROPERTY_GET_VALUE); 1904425bb815Sopenharmony_ci 1905425bb815Sopenharmony_ci if (property == ECMA_PROPERTY_TYPE_NOT_FOUND || property == ECMA_PROPERTY_TYPE_NOT_FOUND_AND_STOP) 1906425bb815Sopenharmony_ci { 1907425bb815Sopenharmony_ci return ECMA_VALUE_FALSE; 1908425bb815Sopenharmony_ci } 1909425bb815Sopenharmony_ci 1910425bb815Sopenharmony_ci uint32_t flags = ecma_is_property_enumerable (property) ? ECMA_PROP_IS_ENUMERABLE : ECMA_PROP_NO_OPTS; 1911425bb815Sopenharmony_ci flags |= ecma_is_property_configurable (property) ? ECMA_PROP_IS_CONFIGURABLE: ECMA_PROP_NO_OPTS; 1912425bb815Sopenharmony_ci 1913425bb815Sopenharmony_ci prop_desc_p->flags = (uint16_t) (ECMA_PROP_IS_ENUMERABLE_DEFINED | ECMA_PROP_IS_CONFIGURABLE_DEFINED | flags); 1914425bb815Sopenharmony_ci 1915425bb815Sopenharmony_ci ecma_property_types_t type = ECMA_PROPERTY_GET_TYPE (property); 1916425bb815Sopenharmony_ci 1917425bb815Sopenharmony_ci if (type != ECMA_PROPERTY_TYPE_NAMEDACCESSOR) 1918425bb815Sopenharmony_ci { 1919425bb815Sopenharmony_ci if (type == ECMA_PROPERTY_TYPE_NAMEDDATA) 1920425bb815Sopenharmony_ci { 1921425bb815Sopenharmony_ci prop_desc_p->value = ecma_copy_value (property_ref.value_p->value); 1922425bb815Sopenharmony_ci } 1923425bb815Sopenharmony_ci else 1924425bb815Sopenharmony_ci { 1925425bb815Sopenharmony_ci JERRY_ASSERT (type == ECMA_PROPERTY_TYPE_VIRTUAL); 1926425bb815Sopenharmony_ci prop_desc_p->value = property_ref.virtual_value; 1927425bb815Sopenharmony_ci } 1928425bb815Sopenharmony_ci 1929425bb815Sopenharmony_ci prop_desc_p->flags |= (ECMA_PROP_IS_VALUE_DEFINED | ECMA_PROP_IS_WRITABLE_DEFINED); 1930425bb815Sopenharmony_ci prop_desc_p->flags = (uint16_t) (prop_desc_p->flags | (ecma_is_property_writable (property) ? ECMA_PROP_IS_WRITABLE 1931425bb815Sopenharmony_ci : ECMA_PROP_NO_OPTS)); 1932425bb815Sopenharmony_ci } 1933425bb815Sopenharmony_ci else 1934425bb815Sopenharmony_ci { 1935425bb815Sopenharmony_ci 1936425bb815Sopenharmony_ci ecma_getter_setter_pointers_t *get_set_pair_p = ecma_get_named_accessor_property (property_ref.value_p); 1937425bb815Sopenharmony_ci prop_desc_p->flags |= (ECMA_PROP_IS_GET_DEFINED | ECMA_PROP_IS_SET_DEFINED); 1938425bb815Sopenharmony_ci 1939425bb815Sopenharmony_ci if (get_set_pair_p->getter_cp == JMEM_CP_NULL) 1940425bb815Sopenharmony_ci { 1941425bb815Sopenharmony_ci prop_desc_p->get_p = NULL; 1942425bb815Sopenharmony_ci } 1943425bb815Sopenharmony_ci else 1944425bb815Sopenharmony_ci { 1945425bb815Sopenharmony_ci prop_desc_p->get_p = ECMA_GET_NON_NULL_POINTER (ecma_object_t, get_set_pair_p->getter_cp); 1946425bb815Sopenharmony_ci ecma_ref_object (prop_desc_p->get_p); 1947425bb815Sopenharmony_ci } 1948425bb815Sopenharmony_ci 1949425bb815Sopenharmony_ci if (get_set_pair_p->setter_cp == JMEM_CP_NULL) 1950425bb815Sopenharmony_ci { 1951425bb815Sopenharmony_ci prop_desc_p->set_p = NULL; 1952425bb815Sopenharmony_ci } 1953425bb815Sopenharmony_ci else 1954425bb815Sopenharmony_ci { 1955425bb815Sopenharmony_ci prop_desc_p->set_p = ECMA_GET_NON_NULL_POINTER (ecma_object_t, get_set_pair_p->setter_cp); 1956425bb815Sopenharmony_ci ecma_ref_object (prop_desc_p->set_p); 1957425bb815Sopenharmony_ci } 1958425bb815Sopenharmony_ci } 1959425bb815Sopenharmony_ci 1960425bb815Sopenharmony_ci return ECMA_VALUE_TRUE; 1961425bb815Sopenharmony_ci} /* ecma_op_object_get_own_property_descriptor */ 1962425bb815Sopenharmony_ci 1963425bb815Sopenharmony_ci/** 1964425bb815Sopenharmony_ci * [[HasInstance]] ecma object's operation 1965425bb815Sopenharmony_ci * 1966425bb815Sopenharmony_ci * See also: 1967425bb815Sopenharmony_ci * ECMA-262 v5, 8.6.2; ECMA-262 v5, Table 9 1968425bb815Sopenharmony_ci * 1969425bb815Sopenharmony_ci * @return ecma value containing a boolean value or an error 1970425bb815Sopenharmony_ci * Returned value must be freed with ecma_free_value 1971425bb815Sopenharmony_ci */ 1972425bb815Sopenharmony_ciecma_value_t 1973425bb815Sopenharmony_ciecma_op_object_has_instance (ecma_object_t *obj_p, /**< the object */ 1974425bb815Sopenharmony_ci ecma_value_t value) /**< argument 'V' */ 1975425bb815Sopenharmony_ci{ 1976425bb815Sopenharmony_ci JERRY_ASSERT (obj_p != NULL 1977425bb815Sopenharmony_ci && !ecma_is_lexical_environment (obj_p)); 1978425bb815Sopenharmony_ci 1979425bb815Sopenharmony_ci JERRY_ASSERT_OBJECT_TYPE_IS_VALID (ecma_get_object_type (obj_p)); 1980425bb815Sopenharmony_ci 1981425bb815Sopenharmony_ci if (ecma_op_object_is_callable (obj_p)) 1982425bb815Sopenharmony_ci { 1983425bb815Sopenharmony_ci return ecma_op_function_has_instance (obj_p, value); 1984425bb815Sopenharmony_ci } 1985425bb815Sopenharmony_ci 1986425bb815Sopenharmony_ci return ecma_raise_type_error (ECMA_ERR_MSG ("Expected a function object.")); 1987425bb815Sopenharmony_ci} /* ecma_op_object_has_instance */ 1988425bb815Sopenharmony_ci 1989425bb815Sopenharmony_ci/** 1990425bb815Sopenharmony_ci * Object's isPrototypeOf operation 1991425bb815Sopenharmony_ci * 1992425bb815Sopenharmony_ci * See also: 1993425bb815Sopenharmony_ci * ECMA-262 v5, 15.2.4.6; 3 1994425bb815Sopenharmony_ci * 1995425bb815Sopenharmony_ci * @return ECMA_VALUE_ERROR - if the operation fails 1996425bb815Sopenharmony_ci * ECMA_VALUE_TRUE - if the target object is prototype of the base object 1997425bb815Sopenharmony_ci * ECMA_VALUE_FALSE - if the target object is not prototype of the base object 1998425bb815Sopenharmony_ci */ 1999425bb815Sopenharmony_ciecma_value_t 2000425bb815Sopenharmony_ciecma_op_object_is_prototype_of (ecma_object_t *base_p, /**< base object */ 2001425bb815Sopenharmony_ci ecma_object_t *target_p) /**< target object */ 2002425bb815Sopenharmony_ci{ 2003425bb815Sopenharmony_ci do 2004425bb815Sopenharmony_ci { 2005425bb815Sopenharmony_ci jmem_cpointer_t target_cp; 2006425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015_BUILTIN_PROXY) 2007425bb815Sopenharmony_ci if (ECMA_OBJECT_IS_PROXY (target_p)) 2008425bb815Sopenharmony_ci { 2009425bb815Sopenharmony_ci ecma_value_t target_proto = ecma_proxy_object_get_prototype_of (target_p); 2010425bb815Sopenharmony_ci 2011425bb815Sopenharmony_ci if (ECMA_IS_VALUE_ERROR (target_proto)) 2012425bb815Sopenharmony_ci { 2013425bb815Sopenharmony_ci return target_proto; 2014425bb815Sopenharmony_ci } 2015425bb815Sopenharmony_ci target_cp = ecma_proxy_object_prototype_to_cp (target_proto); 2016425bb815Sopenharmony_ci } 2017425bb815Sopenharmony_ci else 2018425bb815Sopenharmony_ci { 2019425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */ 2020425bb815Sopenharmony_ci target_cp = ecma_op_ordinary_object_get_prototype_of (target_p); 2021425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015_BUILTIN_PROXY) 2022425bb815Sopenharmony_ci } 2023425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */ 2024425bb815Sopenharmony_ci 2025425bb815Sopenharmony_ci if (target_cp == JMEM_CP_NULL) 2026425bb815Sopenharmony_ci { 2027425bb815Sopenharmony_ci return ECMA_VALUE_FALSE; 2028425bb815Sopenharmony_ci } 2029425bb815Sopenharmony_ci 2030425bb815Sopenharmony_ci target_p = ECMA_GET_NON_NULL_POINTER (ecma_object_t, target_cp); 2031425bb815Sopenharmony_ci 2032425bb815Sopenharmony_ci if (target_p == base_p) 2033425bb815Sopenharmony_ci { 2034425bb815Sopenharmony_ci return ECMA_VALUE_TRUE; 2035425bb815Sopenharmony_ci } 2036425bb815Sopenharmony_ci } while (true); 2037425bb815Sopenharmony_ci} /* ecma_op_object_is_prototype_of */ 2038425bb815Sopenharmony_ci 2039425bb815Sopenharmony_ci/** 2040425bb815Sopenharmony_ci * Get collection of property names 2041425bb815Sopenharmony_ci * 2042425bb815Sopenharmony_ci * Order of names in the collection: 2043425bb815Sopenharmony_ci * - integer indices in ascending order 2044425bb815Sopenharmony_ci * - other indices in creation order (for built-ins: the order of the properties are listed in specification). 2045425bb815Sopenharmony_ci * 2046425bb815Sopenharmony_ci * Note: 2047425bb815Sopenharmony_ci * Implementation of the routine assumes that new properties are appended to beginning of corresponding object's 2048425bb815Sopenharmony_ci * property list, and the list is not reordered (in other words, properties are stored in order that is reversed 2049425bb815Sopenharmony_ci * to the properties' addition order). 2050425bb815Sopenharmony_ci * 2051425bb815Sopenharmony_ci * @return NULL - if the Proxy.[[OwnPropertyKeys]] operation raises error 2052425bb815Sopenharmony_ci * collection of property names - otherwise 2053425bb815Sopenharmony_ci */ 2054425bb815Sopenharmony_ciecma_collection_t * 2055425bb815Sopenharmony_ciecma_op_object_get_property_names (ecma_object_t *obj_p, /**< object */ 2056425bb815Sopenharmony_ci uint32_t opts) /**< any combination of ecma_list_properties_options_t values */ 2057425bb815Sopenharmony_ci{ 2058425bb815Sopenharmony_ci JERRY_ASSERT (obj_p != NULL 2059425bb815Sopenharmony_ci && !ecma_is_lexical_environment (obj_p)); 2060425bb815Sopenharmony_ci 2061425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015_BUILTIN_PROXY) 2062425bb815Sopenharmony_ci if (ECMA_OBJECT_IS_PROXY (obj_p)) 2063425bb815Sopenharmony_ci { 2064425bb815Sopenharmony_ci /* Integrated a part of ECMA 262 v6 7.3.21 EnumerableOwnNames operation. */ 2065425bb815Sopenharmony_ci ecma_collection_t *proxy_keys = ecma_proxy_object_own_property_keys (obj_p); 2066425bb815Sopenharmony_ci if (JERRY_UNLIKELY (proxy_keys == NULL)) 2067425bb815Sopenharmony_ci { 2068425bb815Sopenharmony_ci return proxy_keys; 2069425bb815Sopenharmony_ci } 2070425bb815Sopenharmony_ci ecma_collection_t *return_keys = ecma_new_collection (); 2071425bb815Sopenharmony_ci 2072425bb815Sopenharmony_ci /* Move valid elements to the output collection */ 2073425bb815Sopenharmony_ci for (uint32_t i = 0; i < proxy_keys->item_count; i++) 2074425bb815Sopenharmony_ci { 2075425bb815Sopenharmony_ci ecma_value_t entry = proxy_keys->buffer_p[i]; 2076425bb815Sopenharmony_ci ecma_string_t *prop_name_p = ecma_get_prop_name_from_value (entry); 2077425bb815Sopenharmony_ci bool prop_is_symbol = ecma_prop_name_is_symbol (prop_name_p); 2078425bb815Sopenharmony_ci 2079425bb815Sopenharmony_ci if (prop_is_symbol && ((opts & (ECMA_LIST_SYMBOLS | ECMA_LIST_SYMBOLS_ONLY)) != 0)) 2080425bb815Sopenharmony_ci { 2081425bb815Sopenharmony_ci ecma_collection_push_back (return_keys, entry); 2082425bb815Sopenharmony_ci } 2083425bb815Sopenharmony_ci else if (!prop_is_symbol && (opts & ECMA_LIST_SYMBOLS_ONLY) == 0) 2084425bb815Sopenharmony_ci { 2085425bb815Sopenharmony_ci ecma_collection_push_back (return_keys, entry); 2086425bb815Sopenharmony_ci } 2087425bb815Sopenharmony_ci else 2088425bb815Sopenharmony_ci { 2089425bb815Sopenharmony_ci ecma_free_value (entry); 2090425bb815Sopenharmony_ci } 2091425bb815Sopenharmony_ci } 2092425bb815Sopenharmony_ci 2093425bb815Sopenharmony_ci ecma_collection_destroy (proxy_keys); 2094425bb815Sopenharmony_ci return return_keys; 2095425bb815Sopenharmony_ci } 2096425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */ 2097425bb815Sopenharmony_ci 2098425bb815Sopenharmony_ci if (ecma_op_object_is_fast_array (obj_p)) 2099425bb815Sopenharmony_ci { 2100425bb815Sopenharmony_ci return ecma_fast_array_get_property_names (obj_p, opts); 2101425bb815Sopenharmony_ci } 2102425bb815Sopenharmony_ci 2103425bb815Sopenharmony_ci ecma_collection_t *ret_p = ecma_new_collection (); 2104425bb815Sopenharmony_ci ecma_collection_t *skipped_non_enumerable_p = ecma_new_collection (); 2105425bb815Sopenharmony_ci 2106425bb815Sopenharmony_ci const bool is_enumerable_only = (opts & ECMA_LIST_ENUMERABLE) != 0; 2107425bb815Sopenharmony_ci const bool is_array_indices_only = (opts & ECMA_LIST_ARRAY_INDICES) != 0; 2108425bb815Sopenharmony_ci const bool is_with_prototype_chain = (opts & ECMA_LIST_PROTOTYPE) != 0; 2109425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 2110425bb815Sopenharmony_ci const bool is_symbols = (opts & ECMA_LIST_SYMBOLS) != 0; 2111425bb815Sopenharmony_ci const bool is_symbols_only = (opts & ECMA_LIST_SYMBOLS_ONLY) != 0; 2112425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 2113425bb815Sopenharmony_ci 2114425bb815Sopenharmony_ci const size_t bitmap_row_size = sizeof (uint32_t) * JERRY_BITSINBYTE; 2115425bb815Sopenharmony_ci const size_t names_hashes_bitmap_size = ECMA_OBJECT_HASH_BITMAP_SIZE / bitmap_row_size; 2116425bb815Sopenharmony_ci JERRY_VLA (uint32_t, names_hashes_bitmap, names_hashes_bitmap_size); 2117425bb815Sopenharmony_ci 2118425bb815Sopenharmony_ci memset (names_hashes_bitmap, 0, names_hashes_bitmap_size * sizeof (names_hashes_bitmap[0])); 2119425bb815Sopenharmony_ci 2120425bb815Sopenharmony_ci while (true) 2121425bb815Sopenharmony_ci { 2122425bb815Sopenharmony_ci const ecma_object_type_t type = ecma_get_object_type (obj_p); 2123425bb815Sopenharmony_ci const bool obj_is_builtin = ecma_get_object_is_builtin (obj_p); 2124425bb815Sopenharmony_ci ecma_length_t string_named_properties_count = 0; 2125425bb815Sopenharmony_ci ecma_length_t array_index_named_properties_count = 0; 2126425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 2127425bb815Sopenharmony_ci ecma_length_t symbol_named_properties_count = 0; 2128425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 2129425bb815Sopenharmony_ci ecma_collection_t *prop_names_p = ecma_new_collection (); 2130425bb815Sopenharmony_ci 2131425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 2132425bb815Sopenharmony_ci if (JERRY_LIKELY (!is_symbols_only)) 2133425bb815Sopenharmony_ci { 2134425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 2135425bb815Sopenharmony_ci 2136425bb815Sopenharmony_ci if (obj_is_builtin) 2137425bb815Sopenharmony_ci { 2138425bb815Sopenharmony_ci if (type == ECMA_OBJECT_TYPE_FUNCTION && ecma_builtin_function_is_routine (obj_p)) 2139425bb815Sopenharmony_ci { 2140425bb815Sopenharmony_ci ecma_builtin_routine_list_lazy_property_names (obj_p, 2141425bb815Sopenharmony_ci opts, 2142425bb815Sopenharmony_ci prop_names_p, 2143425bb815Sopenharmony_ci skipped_non_enumerable_p); 2144425bb815Sopenharmony_ci } 2145425bb815Sopenharmony_ci else 2146425bb815Sopenharmony_ci { 2147425bb815Sopenharmony_ci ecma_builtin_list_lazy_property_names (obj_p, 2148425bb815Sopenharmony_ci opts, 2149425bb815Sopenharmony_ci prop_names_p, 2150425bb815Sopenharmony_ci skipped_non_enumerable_p); 2151425bb815Sopenharmony_ci } 2152425bb815Sopenharmony_ci } 2153425bb815Sopenharmony_ci else 2154425bb815Sopenharmony_ci { 2155425bb815Sopenharmony_ci switch (type) 2156425bb815Sopenharmony_ci { 2157425bb815Sopenharmony_ci case ECMA_OBJECT_TYPE_PSEUDO_ARRAY: 2158425bb815Sopenharmony_ci { 2159425bb815Sopenharmony_ci #if ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) 2160425bb815Sopenharmony_ci if (ecma_object_is_typedarray (obj_p)) 2161425bb815Sopenharmony_ci { 2162425bb815Sopenharmony_ci ecma_op_typedarray_list_lazy_property_names (obj_p, prop_names_p); 2163425bb815Sopenharmony_ci } 2164425bb815Sopenharmony_ci #endif /* ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) */ 2165425bb815Sopenharmony_ci break; 2166425bb815Sopenharmony_ci } 2167425bb815Sopenharmony_ci case ECMA_OBJECT_TYPE_FUNCTION: 2168425bb815Sopenharmony_ci { 2169425bb815Sopenharmony_ci if (!is_array_indices_only) 2170425bb815Sopenharmony_ci { 2171425bb815Sopenharmony_ci ecma_op_function_list_lazy_property_names (obj_p, 2172425bb815Sopenharmony_ci opts, 2173425bb815Sopenharmony_ci prop_names_p, 2174425bb815Sopenharmony_ci skipped_non_enumerable_p); 2175425bb815Sopenharmony_ci } 2176425bb815Sopenharmony_ci break; 2177425bb815Sopenharmony_ci } 2178425bb815Sopenharmony_ci case ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION: 2179425bb815Sopenharmony_ci { 2180425bb815Sopenharmony_ci if (!is_array_indices_only) 2181425bb815Sopenharmony_ci { 2182425bb815Sopenharmony_ci ecma_op_external_function_list_lazy_property_names (obj_p, 2183425bb815Sopenharmony_ci opts, 2184425bb815Sopenharmony_ci prop_names_p, 2185425bb815Sopenharmony_ci skipped_non_enumerable_p); 2186425bb815Sopenharmony_ci } 2187425bb815Sopenharmony_ci break; 2188425bb815Sopenharmony_ci } 2189425bb815Sopenharmony_ci case ECMA_OBJECT_TYPE_BOUND_FUNCTION: 2190425bb815Sopenharmony_ci { 2191425bb815Sopenharmony_ci if (!is_array_indices_only) 2192425bb815Sopenharmony_ci { 2193425bb815Sopenharmony_ci ecma_op_bound_function_list_lazy_property_names (obj_p, 2194425bb815Sopenharmony_ci opts, 2195425bb815Sopenharmony_ci prop_names_p, 2196425bb815Sopenharmony_ci skipped_non_enumerable_p); 2197425bb815Sopenharmony_ci } 2198425bb815Sopenharmony_ci break; 2199425bb815Sopenharmony_ci } 2200425bb815Sopenharmony_ci case ECMA_OBJECT_TYPE_CLASS: 2201425bb815Sopenharmony_ci { 2202425bb815Sopenharmony_ci ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) obj_p; 2203425bb815Sopenharmony_ci 2204425bb815Sopenharmony_ci if (ext_object_p->u.class_prop.class_id == LIT_MAGIC_STRING_STRING_UL) 2205425bb815Sopenharmony_ci { 2206425bb815Sopenharmony_ci ecma_op_string_list_lazy_property_names (obj_p, 2207425bb815Sopenharmony_ci opts, 2208425bb815Sopenharmony_ci prop_names_p, 2209425bb815Sopenharmony_ci skipped_non_enumerable_p); 2210425bb815Sopenharmony_ci } 2211425bb815Sopenharmony_ci 2212425bb815Sopenharmony_ci break; 2213425bb815Sopenharmony_ci } 2214425bb815Sopenharmony_ci case ECMA_OBJECT_TYPE_ARRAY: 2215425bb815Sopenharmony_ci { 2216425bb815Sopenharmony_ci ecma_op_array_list_lazy_property_names (obj_p, 2217425bb815Sopenharmony_ci opts, 2218425bb815Sopenharmony_ci prop_names_p, 2219425bb815Sopenharmony_ci skipped_non_enumerable_p); 2220425bb815Sopenharmony_ci break; 2221425bb815Sopenharmony_ci } 2222425bb815Sopenharmony_ci default: 2223425bb815Sopenharmony_ci { 2224425bb815Sopenharmony_ci JERRY_ASSERT (type == ECMA_OBJECT_TYPE_GENERAL); 2225425bb815Sopenharmony_ci 2226425bb815Sopenharmony_ci break; 2227425bb815Sopenharmony_ci } 2228425bb815Sopenharmony_ci } 2229425bb815Sopenharmony_ci } 2230425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 2231425bb815Sopenharmony_ci } 2232425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 2233425bb815Sopenharmony_ci 2234425bb815Sopenharmony_ci ecma_value_t *buffer_p = prop_names_p->buffer_p; 2235425bb815Sopenharmony_ci uint32_t lazy_prop_name_count = prop_names_p->item_count; 2236425bb815Sopenharmony_ci 2237425bb815Sopenharmony_ci const size_t own_names_hashes_bitmap_size = ECMA_OBJECT_HASH_BITMAP_SIZE / bitmap_row_size; 2238425bb815Sopenharmony_ci JERRY_VLA (uint32_t, own_names_hashes_bitmap, own_names_hashes_bitmap_size); 2239425bb815Sopenharmony_ci memset (own_names_hashes_bitmap, 0, own_names_hashes_bitmap_size * sizeof (own_names_hashes_bitmap[0])); 2240425bb815Sopenharmony_ci 2241425bb815Sopenharmony_ci for (uint32_t i = 0; i < prop_names_p->item_count; i++) 2242425bb815Sopenharmony_ci { 2243425bb815Sopenharmony_ci ecma_string_t *name_p = ecma_get_string_from_value (buffer_p[i]); 2244425bb815Sopenharmony_ci 2245425bb815Sopenharmony_ci if (ecma_string_get_array_index (name_p) != ECMA_STRING_NOT_ARRAY_INDEX) 2246425bb815Sopenharmony_ci { 2247425bb815Sopenharmony_ci array_index_named_properties_count++; 2248425bb815Sopenharmony_ci } 2249425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 2250425bb815Sopenharmony_ci else if (ecma_prop_name_is_symbol (name_p)) 2251425bb815Sopenharmony_ci { 2252425bb815Sopenharmony_ci symbol_named_properties_count++; 2253425bb815Sopenharmony_ci } 2254425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 2255425bb815Sopenharmony_ci else 2256425bb815Sopenharmony_ci { 2257425bb815Sopenharmony_ci string_named_properties_count++; 2258425bb815Sopenharmony_ci } 2259425bb815Sopenharmony_ci 2260425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 2261425bb815Sopenharmony_ci /* Symbols are never lazy listed */ 2262425bb815Sopenharmony_ci JERRY_ASSERT (!ecma_prop_name_is_symbol (name_p)); 2263425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 2264425bb815Sopenharmony_ci 2265425bb815Sopenharmony_ci uint8_t hash = (uint8_t) ecma_string_hash (name_p); 2266425bb815Sopenharmony_ci uint32_t bitmap_row = (uint32_t) (hash / bitmap_row_size); 2267425bb815Sopenharmony_ci uint32_t bitmap_column = (uint32_t) (hash % bitmap_row_size); 2268425bb815Sopenharmony_ci 2269425bb815Sopenharmony_ci if ((own_names_hashes_bitmap[bitmap_row] & (1u << bitmap_column)) == 0) 2270425bb815Sopenharmony_ci { 2271425bb815Sopenharmony_ci own_names_hashes_bitmap[bitmap_row] |= (1u << bitmap_column); 2272425bb815Sopenharmony_ci } 2273425bb815Sopenharmony_ci } 2274425bb815Sopenharmony_ci 2275425bb815Sopenharmony_ci jmem_cpointer_t prop_iter_cp = obj_p->u1.property_list_cp; 2276425bb815Sopenharmony_ci 2277425bb815Sopenharmony_ci if (ecma_op_object_is_fast_array (obj_p) && prop_iter_cp != JMEM_CP_NULL) 2278425bb815Sopenharmony_ci { 2279425bb815Sopenharmony_ci ecma_extended_object_t *ext_obj_p = (ecma_extended_object_t *) obj_p; 2280425bb815Sopenharmony_ci 2281425bb815Sopenharmony_ci uint32_t length = ext_obj_p->u.array.length; 2282425bb815Sopenharmony_ci array_index_named_properties_count = length - ecma_fast_array_get_hole_count (obj_p); 2283425bb815Sopenharmony_ci 2284425bb815Sopenharmony_ci ecma_value_t *values_p = ECMA_GET_NON_NULL_POINTER (ecma_value_t, prop_iter_cp); 2285425bb815Sopenharmony_ci 2286425bb815Sopenharmony_ci for (uint32_t i = 0; i < length; i++) 2287425bb815Sopenharmony_ci { 2288425bb815Sopenharmony_ci if (ecma_is_value_array_hole (values_p[i])) 2289425bb815Sopenharmony_ci { 2290425bb815Sopenharmony_ci continue; 2291425bb815Sopenharmony_ci } 2292425bb815Sopenharmony_ci 2293425bb815Sopenharmony_ci ecma_string_t *index_str_p = ecma_new_ecma_string_from_uint32 (i); 2294425bb815Sopenharmony_ci 2295425bb815Sopenharmony_ci uint8_t hash = (uint8_t) ecma_string_hash (index_str_p); 2296425bb815Sopenharmony_ci uint32_t bitmap_row = (uint32_t) (hash / bitmap_row_size); 2297425bb815Sopenharmony_ci uint32_t bitmap_column = (uint32_t) (hash % bitmap_row_size); 2298425bb815Sopenharmony_ci 2299425bb815Sopenharmony_ci bool is_add = true; 2300425bb815Sopenharmony_ci 2301425bb815Sopenharmony_ci if ((own_names_hashes_bitmap[bitmap_row] & (1u << bitmap_column)) != 0) 2302425bb815Sopenharmony_ci { 2303425bb815Sopenharmony_ci buffer_p = prop_names_p->buffer_p; 2304425bb815Sopenharmony_ci 2305425bb815Sopenharmony_ci for (uint32_t j = 0; j < prop_names_p->item_count; j++) 2306425bb815Sopenharmony_ci { 2307425bb815Sopenharmony_ci ecma_string_t *current_name_p = ecma_get_prop_name_from_value (buffer_p[j]); 2308425bb815Sopenharmony_ci 2309425bb815Sopenharmony_ci if (ecma_compare_ecma_strings (index_str_p, current_name_p)) 2310425bb815Sopenharmony_ci { 2311425bb815Sopenharmony_ci is_add = false; 2312425bb815Sopenharmony_ci break; 2313425bb815Sopenharmony_ci } 2314425bb815Sopenharmony_ci } 2315425bb815Sopenharmony_ci } 2316425bb815Sopenharmony_ci 2317425bb815Sopenharmony_ci if (is_add) 2318425bb815Sopenharmony_ci { 2319425bb815Sopenharmony_ci own_names_hashes_bitmap[bitmap_row] |= (1u << bitmap_column); 2320425bb815Sopenharmony_ci 2321425bb815Sopenharmony_ci ecma_collection_push_back (prop_names_p, ecma_make_string_value (index_str_p)); 2322425bb815Sopenharmony_ci } 2323425bb815Sopenharmony_ci } 2324425bb815Sopenharmony_ci } 2325425bb815Sopenharmony_ci else 2326425bb815Sopenharmony_ci { 2327425bb815Sopenharmony_ci#if ENABLED (JERRY_PROPRETY_HASHMAP) 2328425bb815Sopenharmony_ci if (prop_iter_cp != JMEM_CP_NULL) 2329425bb815Sopenharmony_ci { 2330425bb815Sopenharmony_ci ecma_property_header_t *prop_iter_p = ECMA_GET_NON_NULL_POINTER (ecma_property_header_t, prop_iter_cp); 2331425bb815Sopenharmony_ci 2332425bb815Sopenharmony_ci if (prop_iter_p->types[0] == ECMA_PROPERTY_TYPE_HASHMAP) 2333425bb815Sopenharmony_ci { 2334425bb815Sopenharmony_ci prop_iter_cp = prop_iter_p->next_property_cp; 2335425bb815Sopenharmony_ci } 2336425bb815Sopenharmony_ci } 2337425bb815Sopenharmony_ci #endif /* ENABLED (JERRY_PROPRETY_HASHMAP) */ 2338425bb815Sopenharmony_ci 2339425bb815Sopenharmony_ci while (prop_iter_cp != JMEM_CP_NULL) 2340425bb815Sopenharmony_ci { 2341425bb815Sopenharmony_ci ecma_property_header_t *prop_iter_p = ECMA_GET_NON_NULL_POINTER (ecma_property_header_t, prop_iter_cp); 2342425bb815Sopenharmony_ci JERRY_ASSERT (ECMA_PROPERTY_IS_PROPERTY_PAIR (prop_iter_p)); 2343425bb815Sopenharmony_ci 2344425bb815Sopenharmony_ci for (int i = 0; i < ECMA_PROPERTY_PAIR_ITEM_COUNT; i++) 2345425bb815Sopenharmony_ci { 2346425bb815Sopenharmony_ci ecma_property_t *property_p = prop_iter_p->types + i; 2347425bb815Sopenharmony_ci 2348425bb815Sopenharmony_ci if (ECMA_PROPERTY_GET_TYPE (*property_p) == ECMA_PROPERTY_TYPE_NAMEDDATA 2349425bb815Sopenharmony_ci || ECMA_PROPERTY_GET_TYPE (*property_p) == ECMA_PROPERTY_TYPE_NAMEDACCESSOR) 2350425bb815Sopenharmony_ci { 2351425bb815Sopenharmony_ci ecma_property_pair_t *prop_pair_p = (ecma_property_pair_t *) prop_iter_p; 2352425bb815Sopenharmony_ci 2353425bb815Sopenharmony_ci if (ECMA_PROPERTY_GET_NAME_TYPE (*property_p) == ECMA_DIRECT_STRING_MAGIC 2354425bb815Sopenharmony_ci && prop_pair_p->names_cp[i] >= LIT_NON_INTERNAL_MAGIC_STRING__COUNT 2355425bb815Sopenharmony_ci && prop_pair_p->names_cp[i] < LIT_MAGIC_STRING__COUNT) 2356425bb815Sopenharmony_ci { 2357425bb815Sopenharmony_ci /* Internal properties are never enumerated. */ 2358425bb815Sopenharmony_ci continue; 2359425bb815Sopenharmony_ci } 2360425bb815Sopenharmony_ci 2361425bb815Sopenharmony_ci ecma_string_t *name_p = ecma_string_from_property_name (*property_p, 2362425bb815Sopenharmony_ci prop_pair_p->names_cp[i]); 2363425bb815Sopenharmony_ci 2364425bb815Sopenharmony_ci if (!(is_enumerable_only && !ecma_is_property_enumerable (*property_p))) 2365425bb815Sopenharmony_ci { 2366425bb815Sopenharmony_ci #if ENABLED (JERRY_ES2015) 2367425bb815Sopenharmony_ci /* We skip the current property in the following cases: 2368425bb815Sopenharmony_ci 1. We don't want to list symbols (is_symbols and is_symbols_only are false) 2369425bb815Sopenharmony_ci and the current property is a symbol. 2370425bb815Sopenharmony_ci 2. We only want to list symbols (is_symbols_only is true) and the current 2371425bb815Sopenharmony_ci property is NOT a symbol. */ 2372425bb815Sopenharmony_ci bool is_symbol = ecma_prop_name_is_symbol (name_p); 2373425bb815Sopenharmony_ci if ((!(is_symbols || is_symbols_only) && is_symbol) || (is_symbols_only && !is_symbol)) 2374425bb815Sopenharmony_ci { 2375425bb815Sopenharmony_ci ecma_deref_ecma_string (name_p); 2376425bb815Sopenharmony_ci continue; 2377425bb815Sopenharmony_ci } 2378425bb815Sopenharmony_ci #endif /* ENABLED (JERRY_ES2015) */ 2379425bb815Sopenharmony_ci 2380425bb815Sopenharmony_ci uint8_t hash = (uint8_t) ecma_string_hash (name_p); 2381425bb815Sopenharmony_ci uint32_t bitmap_row = (uint32_t) (hash / bitmap_row_size); 2382425bb815Sopenharmony_ci uint32_t bitmap_column = (uint32_t) (hash % bitmap_row_size); 2383425bb815Sopenharmony_ci 2384425bb815Sopenharmony_ci bool is_add = true; 2385425bb815Sopenharmony_ci 2386425bb815Sopenharmony_ci if ((own_names_hashes_bitmap[bitmap_row] & (1u << bitmap_column)) != 0) 2387425bb815Sopenharmony_ci { 2388425bb815Sopenharmony_ci buffer_p = prop_names_p->buffer_p; 2389425bb815Sopenharmony_ci 2390425bb815Sopenharmony_ci for (uint32_t j = 0; j < prop_names_p->item_count; j++) 2391425bb815Sopenharmony_ci { 2392425bb815Sopenharmony_ci ecma_string_t *current_name_p = ecma_get_prop_name_from_value (buffer_p[j]); 2393425bb815Sopenharmony_ci 2394425bb815Sopenharmony_ci if (ecma_compare_ecma_strings (name_p, current_name_p)) 2395425bb815Sopenharmony_ci { 2396425bb815Sopenharmony_ci is_add = false; 2397425bb815Sopenharmony_ci break; 2398425bb815Sopenharmony_ci } 2399425bb815Sopenharmony_ci } 2400425bb815Sopenharmony_ci } 2401425bb815Sopenharmony_ci 2402425bb815Sopenharmony_ci if (is_add) 2403425bb815Sopenharmony_ci { 2404425bb815Sopenharmony_ci if (ecma_string_get_array_index (name_p) != ECMA_STRING_NOT_ARRAY_INDEX) 2405425bb815Sopenharmony_ci { 2406425bb815Sopenharmony_ci /* The name is a valid array index. */ 2407425bb815Sopenharmony_ci array_index_named_properties_count++; 2408425bb815Sopenharmony_ci } 2409425bb815Sopenharmony_ci else if (!is_array_indices_only) 2410425bb815Sopenharmony_ci { 2411425bb815Sopenharmony_ci #if ENABLED (JERRY_ES2015) 2412425bb815Sopenharmony_ci if (ecma_prop_name_is_symbol (name_p)) 2413425bb815Sopenharmony_ci { 2414425bb815Sopenharmony_ci symbol_named_properties_count++; 2415425bb815Sopenharmony_ci } 2416425bb815Sopenharmony_ci else 2417425bb815Sopenharmony_ci { 2418425bb815Sopenharmony_ci #endif /* ENABLED (JERRY_ES2015) */ 2419425bb815Sopenharmony_ci string_named_properties_count++; 2420425bb815Sopenharmony_ci #if ENABLED (JERRY_ES2015) 2421425bb815Sopenharmony_ci } 2422425bb815Sopenharmony_ci #endif /* ENABLED (JERRY_ES2015) */ 2423425bb815Sopenharmony_ci } 2424425bb815Sopenharmony_ci else 2425425bb815Sopenharmony_ci { 2426425bb815Sopenharmony_ci ecma_deref_ecma_string (name_p); 2427425bb815Sopenharmony_ci continue; 2428425bb815Sopenharmony_ci } 2429425bb815Sopenharmony_ci 2430425bb815Sopenharmony_ci own_names_hashes_bitmap[bitmap_row] |= (1u << bitmap_column); 2431425bb815Sopenharmony_ci 2432425bb815Sopenharmony_ci ecma_collection_push_back (prop_names_p, ecma_make_prop_name_value (name_p)); 2433425bb815Sopenharmony_ci } 2434425bb815Sopenharmony_ci else 2435425bb815Sopenharmony_ci { 2436425bb815Sopenharmony_ci ecma_deref_ecma_string (name_p); 2437425bb815Sopenharmony_ci } 2438425bb815Sopenharmony_ci } 2439425bb815Sopenharmony_ci else 2440425bb815Sopenharmony_ci { 2441425bb815Sopenharmony_ci JERRY_ASSERT (is_enumerable_only && !ecma_is_property_enumerable (*property_p)); 2442425bb815Sopenharmony_ci 2443425bb815Sopenharmony_ci ecma_collection_push_back (skipped_non_enumerable_p, ecma_make_prop_name_value (name_p)); 2444425bb815Sopenharmony_ci } 2445425bb815Sopenharmony_ci } 2446425bb815Sopenharmony_ci } 2447425bb815Sopenharmony_ci 2448425bb815Sopenharmony_ci prop_iter_cp = prop_iter_p->next_property_cp; 2449425bb815Sopenharmony_ci } 2450425bb815Sopenharmony_ci } 2451425bb815Sopenharmony_ci 2452425bb815Sopenharmony_ci ecma_length_t all_properties_count = array_index_named_properties_count + string_named_properties_count; 2453425bb815Sopenharmony_ci 2454425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 2455425bb815Sopenharmony_ci all_properties_count += symbol_named_properties_count; 2456425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 2457425bb815Sopenharmony_ci 2458425bb815Sopenharmony_ci /* Second pass: collecting property names into an array. */ 2459425bb815Sopenharmony_ci JMEM_DEFINE_LOCAL_ARRAY (names_p, all_properties_count, ecma_string_t *); 2460425bb815Sopenharmony_ci 2461425bb815Sopenharmony_ci ecma_string_t **string_names_p = names_p + array_index_named_properties_count; 2462425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 2463425bb815Sopenharmony_ci ecma_string_t **symbol_names_p = string_names_p + string_named_properties_count; 2464425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 2465425bb815Sopenharmony_ci 2466425bb815Sopenharmony_ci uint32_t array_index_name_pos = 0; 2467425bb815Sopenharmony_ci uint32_t string_name_pos = string_named_properties_count; 2468425bb815Sopenharmony_ci uint32_t lazy_string_name_pos = 0; 2469425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 2470425bb815Sopenharmony_ci uint32_t symbol_name_pos = symbol_named_properties_count; 2471425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 2472425bb815Sopenharmony_ci 2473425bb815Sopenharmony_ci buffer_p = prop_names_p->buffer_p; 2474425bb815Sopenharmony_ci 2475425bb815Sopenharmony_ci for (uint32_t i = 0; i < prop_names_p->item_count; i++) 2476425bb815Sopenharmony_ci { 2477425bb815Sopenharmony_ci ecma_string_t *name_p = ecma_get_prop_name_from_value (buffer_p[i]); 2478425bb815Sopenharmony_ci ecma_ref_ecma_string (name_p); 2479425bb815Sopenharmony_ci 2480425bb815Sopenharmony_ci uint32_t index = ecma_string_get_array_index (name_p); 2481425bb815Sopenharmony_ci 2482425bb815Sopenharmony_ci if (index != ECMA_STRING_NOT_ARRAY_INDEX) 2483425bb815Sopenharmony_ci { 2484425bb815Sopenharmony_ci JERRY_ASSERT (array_index_name_pos < array_index_named_properties_count); 2485425bb815Sopenharmony_ci 2486425bb815Sopenharmony_ci uint32_t insertion_pos = 0; 2487425bb815Sopenharmony_ci while (insertion_pos < array_index_name_pos 2488425bb815Sopenharmony_ci && index > ecma_string_get_array_index (names_p[insertion_pos])) 2489425bb815Sopenharmony_ci { 2490425bb815Sopenharmony_ci insertion_pos++; 2491425bb815Sopenharmony_ci } 2492425bb815Sopenharmony_ci 2493425bb815Sopenharmony_ci if (insertion_pos == array_index_name_pos) 2494425bb815Sopenharmony_ci { 2495425bb815Sopenharmony_ci names_p[array_index_name_pos++] = name_p; 2496425bb815Sopenharmony_ci } 2497425bb815Sopenharmony_ci else 2498425bb815Sopenharmony_ci { 2499425bb815Sopenharmony_ci JERRY_ASSERT (insertion_pos < array_index_name_pos); 2500425bb815Sopenharmony_ci JERRY_ASSERT (index <= ecma_string_get_array_index (names_p[insertion_pos])); 2501425bb815Sopenharmony_ci 2502425bb815Sopenharmony_ci uint32_t move_pos = array_index_name_pos++; 2503425bb815Sopenharmony_ci 2504425bb815Sopenharmony_ci while (move_pos > insertion_pos) 2505425bb815Sopenharmony_ci { 2506425bb815Sopenharmony_ci names_p[move_pos] = names_p[move_pos - 1u]; 2507425bb815Sopenharmony_ci 2508425bb815Sopenharmony_ci move_pos--; 2509425bb815Sopenharmony_ci } 2510425bb815Sopenharmony_ci 2511425bb815Sopenharmony_ci names_p[insertion_pos] = name_p; 2512425bb815Sopenharmony_ci } 2513425bb815Sopenharmony_ci } 2514425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 2515425bb815Sopenharmony_ci else if (ecma_prop_name_is_symbol (name_p)) 2516425bb815Sopenharmony_ci { 2517425bb815Sopenharmony_ci // Put in the symbols in reverse order. 2518425bb815Sopenharmony_ci JERRY_ASSERT (symbol_name_pos > 0); 2519425bb815Sopenharmony_ci JERRY_ASSERT (symbol_name_pos <= symbol_named_properties_count); 2520425bb815Sopenharmony_ci 2521425bb815Sopenharmony_ci symbol_names_p[--symbol_name_pos] = name_p; 2522425bb815Sopenharmony_ci } 2523425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 2524425bb815Sopenharmony_ci else 2525425bb815Sopenharmony_ci { 2526425bb815Sopenharmony_ci // Put in the strings in reverse order. 2527425bb815Sopenharmony_ci JERRY_ASSERT (string_name_pos > 0); 2528425bb815Sopenharmony_ci JERRY_ASSERT (string_name_pos <= string_named_properties_count); 2529425bb815Sopenharmony_ci 2530425bb815Sopenharmony_ci if (i < lazy_prop_name_count) 2531425bb815Sopenharmony_ci { 2532425bb815Sopenharmony_ci string_names_p[lazy_string_name_pos++] = name_p; 2533425bb815Sopenharmony_ci } 2534425bb815Sopenharmony_ci else 2535425bb815Sopenharmony_ci { 2536425bb815Sopenharmony_ci string_names_p[--string_name_pos] = name_p; 2537425bb815Sopenharmony_ci } 2538425bb815Sopenharmony_ci } 2539425bb815Sopenharmony_ci } 2540425bb815Sopenharmony_ci 2541425bb815Sopenharmony_ci JERRY_ASSERT (array_index_name_pos == array_index_named_properties_count); 2542425bb815Sopenharmony_ci JERRY_ASSERT (string_name_pos - lazy_string_name_pos == 0); 2543425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 2544425bb815Sopenharmony_ci JERRY_ASSERT (symbol_name_pos == 0); 2545425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 2546425bb815Sopenharmony_ci 2547425bb815Sopenharmony_ci ecma_collection_free (prop_names_p); 2548425bb815Sopenharmony_ci 2549425bb815Sopenharmony_ci /* Third pass: 2550425bb815Sopenharmony_ci * embedding own property names of current object of prototype chain to aggregate property names collection */ 2551425bb815Sopenharmony_ci for (uint32_t i = 0; i < all_properties_count; i++) 2552425bb815Sopenharmony_ci { 2553425bb815Sopenharmony_ci bool is_append = true; 2554425bb815Sopenharmony_ci 2555425bb815Sopenharmony_ci ecma_string_t *name_p = names_p[i]; 2556425bb815Sopenharmony_ci 2557425bb815Sopenharmony_ci uint8_t hash = (uint8_t) ecma_string_hash (name_p); 2558425bb815Sopenharmony_ci uint32_t bitmap_row = (uint32_t) (hash / bitmap_row_size); 2559425bb815Sopenharmony_ci uint32_t bitmap_column = (uint32_t) (hash % bitmap_row_size); 2560425bb815Sopenharmony_ci 2561425bb815Sopenharmony_ci if ((names_hashes_bitmap[bitmap_row] & (1u << bitmap_column)) == 0) 2562425bb815Sopenharmony_ci { 2563425bb815Sopenharmony_ci /* This hash has not been used before (for non-skipped). */ 2564425bb815Sopenharmony_ci names_hashes_bitmap[bitmap_row] |= (1u << bitmap_column); 2565425bb815Sopenharmony_ci } 2566425bb815Sopenharmony_ci else 2567425bb815Sopenharmony_ci { 2568425bb815Sopenharmony_ci /* Name with same hash has already occured. */ 2569425bb815Sopenharmony_ci buffer_p = ret_p->buffer_p; 2570425bb815Sopenharmony_ci 2571425bb815Sopenharmony_ci for (uint32_t j = 0; j < ret_p->item_count; j++) 2572425bb815Sopenharmony_ci { 2573425bb815Sopenharmony_ci ecma_string_t *current_name_p = ecma_get_prop_name_from_value (buffer_p[j]); 2574425bb815Sopenharmony_ci 2575425bb815Sopenharmony_ci if (ecma_compare_ecma_strings (name_p, current_name_p)) 2576425bb815Sopenharmony_ci { 2577425bb815Sopenharmony_ci is_append = false; 2578425bb815Sopenharmony_ci break; 2579425bb815Sopenharmony_ci } 2580425bb815Sopenharmony_ci } 2581425bb815Sopenharmony_ci } 2582425bb815Sopenharmony_ci 2583425bb815Sopenharmony_ci if (is_append) 2584425bb815Sopenharmony_ci { 2585425bb815Sopenharmony_ci buffer_p = skipped_non_enumerable_p->buffer_p; 2586425bb815Sopenharmony_ci 2587425bb815Sopenharmony_ci for (uint32_t j = 0; j < skipped_non_enumerable_p->item_count; j++) 2588425bb815Sopenharmony_ci { 2589425bb815Sopenharmony_ci ecma_string_t *current_name_p = ecma_get_prop_name_from_value (buffer_p[j]); 2590425bb815Sopenharmony_ci 2591425bb815Sopenharmony_ci if (ecma_compare_ecma_strings (name_p, current_name_p)) 2592425bb815Sopenharmony_ci { 2593425bb815Sopenharmony_ci is_append = false; 2594425bb815Sopenharmony_ci break; 2595425bb815Sopenharmony_ci } 2596425bb815Sopenharmony_ci } 2597425bb815Sopenharmony_ci } 2598425bb815Sopenharmony_ci 2599425bb815Sopenharmony_ci if (is_append) 2600425bb815Sopenharmony_ci { 2601425bb815Sopenharmony_ci JERRY_ASSERT ((names_hashes_bitmap[bitmap_row] & (1u << bitmap_column)) != 0); 2602425bb815Sopenharmony_ci 2603425bb815Sopenharmony_ci ecma_collection_push_back (ret_p, ecma_make_prop_name_value (name_p)); 2604425bb815Sopenharmony_ci } 2605425bb815Sopenharmony_ci else 2606425bb815Sopenharmony_ci { 2607425bb815Sopenharmony_ci ecma_deref_ecma_string (name_p); 2608425bb815Sopenharmony_ci } 2609425bb815Sopenharmony_ci 2610425bb815Sopenharmony_ci } 2611425bb815Sopenharmony_ci 2612425bb815Sopenharmony_ci JMEM_FINALIZE_LOCAL_ARRAY (names_p); 2613425bb815Sopenharmony_ci 2614425bb815Sopenharmony_ci if (!is_with_prototype_chain || obj_p->u2.prototype_cp == JMEM_CP_NULL) 2615425bb815Sopenharmony_ci { 2616425bb815Sopenharmony_ci break; 2617425bb815Sopenharmony_ci } 2618425bb815Sopenharmony_ci 2619425bb815Sopenharmony_ci obj_p = ECMA_GET_NON_NULL_POINTER (ecma_object_t, obj_p->u2.prototype_cp); 2620425bb815Sopenharmony_ci } 2621425bb815Sopenharmony_ci 2622425bb815Sopenharmony_ci ecma_collection_free (skipped_non_enumerable_p); 2623425bb815Sopenharmony_ci 2624425bb815Sopenharmony_ci return ret_p; 2625425bb815Sopenharmony_ci} /* ecma_op_object_get_property_names */ 2626425bb815Sopenharmony_ci 2627425bb815Sopenharmony_ci/** 2628425bb815Sopenharmony_ci * The function is used in the assert of ecma_object_get_class_name 2629425bb815Sopenharmony_ci * 2630425bb815Sopenharmony_ci * @return true - if class name is an object 2631425bb815Sopenharmony_ci * false - otherwise 2632425bb815Sopenharmony_ci */ 2633425bb815Sopenharmony_ciinline static bool 2634425bb815Sopenharmony_ciecma_object_check_class_name_is_object (ecma_object_t *obj_p) /**< object */ 2635425bb815Sopenharmony_ci{ 2636425bb815Sopenharmony_ci#ifndef JERRY_NDEBUG 2637425bb815Sopenharmony_ci return (ecma_builtin_is (obj_p, ECMA_BUILTIN_ID_GLOBAL) 2638425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015_BUILTIN_PROMISE) 2639425bb815Sopenharmony_ci || ecma_builtin_is (obj_p, ECMA_BUILTIN_ID_PROMISE_PROTOTYPE) 2640425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROMISE) */ 2641425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) 2642425bb815Sopenharmony_ci || ecma_builtin_is (obj_p, ECMA_BUILTIN_ID_ARRAYBUFFER_PROTOTYPE) 2643425bb815Sopenharmony_ci || ecma_builtin_is (obj_p, ECMA_BUILTIN_ID_TYPEDARRAY_PROTOTYPE) 2644425bb815Sopenharmony_ci || ecma_builtin_is (obj_p, ECMA_BUILTIN_ID_INT8ARRAY_PROTOTYPE) 2645425bb815Sopenharmony_ci || ecma_builtin_is (obj_p, ECMA_BUILTIN_ID_UINT8ARRAY_PROTOTYPE) 2646425bb815Sopenharmony_ci || ecma_builtin_is (obj_p, ECMA_BUILTIN_ID_INT16ARRAY_PROTOTYPE) 2647425bb815Sopenharmony_ci || ecma_builtin_is (obj_p, ECMA_BUILTIN_ID_UINT16ARRAY_PROTOTYPE) 2648425bb815Sopenharmony_ci || ecma_builtin_is (obj_p, ECMA_BUILTIN_ID_INT32ARRAY_PROTOTYPE) 2649425bb815Sopenharmony_ci || ecma_builtin_is (obj_p, ECMA_BUILTIN_ID_UINT32ARRAY_PROTOTYPE) 2650425bb815Sopenharmony_ci || ecma_builtin_is (obj_p, ECMA_BUILTIN_ID_FLOAT32ARRAY_PROTOTYPE) 2651425bb815Sopenharmony_ci || ecma_builtin_is (obj_p, ECMA_BUILTIN_ID_UINT8CLAMPEDARRAY_PROTOTYPE) 2652425bb815Sopenharmony_ci#if ENABLED (JERRY_NUMBER_TYPE_FLOAT64) 2653425bb815Sopenharmony_ci || ecma_builtin_is (obj_p, ECMA_BUILTIN_ID_FLOAT64ARRAY_PROTOTYPE) 2654425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_NUMBER_TYPE_FLOAT64) */ 2655425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) */ 2656425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 2657425bb815Sopenharmony_ci || ecma_builtin_is (obj_p, ECMA_BUILTIN_ID_ARRAY_PROTOTYPE_UNSCOPABLES) 2658425bb815Sopenharmony_ci || ecma_builtin_is (obj_p, ECMA_BUILTIN_ID_ARRAY_ITERATOR_PROTOTYPE) 2659425bb815Sopenharmony_ci || ecma_builtin_is (obj_p, ECMA_BUILTIN_ID_ITERATOR_PROTOTYPE) 2660425bb815Sopenharmony_ci || ecma_builtin_is (obj_p, ECMA_BUILTIN_ID_STRING_ITERATOR_PROTOTYPE) 2661425bb815Sopenharmony_ci || ecma_builtin_is (obj_p, ECMA_BUILTIN_ID_EVAL_ERROR_PROTOTYPE) 2662425bb815Sopenharmony_ci || ecma_builtin_is (obj_p, ECMA_BUILTIN_ID_RANGE_ERROR_PROTOTYPE) 2663425bb815Sopenharmony_ci || ecma_builtin_is (obj_p, ECMA_BUILTIN_ID_REFERENCE_ERROR_PROTOTYPE) 2664425bb815Sopenharmony_ci || ecma_builtin_is (obj_p, ECMA_BUILTIN_ID_SYNTAX_ERROR_PROTOTYPE) 2665425bb815Sopenharmony_ci || ecma_builtin_is (obj_p, ECMA_BUILTIN_ID_GENERATOR_PROTOTYPE) 2666425bb815Sopenharmony_ci || ecma_builtin_is (obj_p, ECMA_BUILTIN_ID_TYPE_ERROR_PROTOTYPE) 2667425bb815Sopenharmony_ci || ecma_builtin_is (obj_p, ECMA_BUILTIN_ID_URI_ERROR_PROTOTYPE) 2668425bb815Sopenharmony_ci || ecma_builtin_is (obj_p, ECMA_BUILTIN_ID_ERROR_PROTOTYPE) 2669425bb815Sopenharmony_ci || ecma_builtin_is (obj_p, ECMA_BUILTIN_ID_STRING_PROTOTYPE) 2670425bb815Sopenharmony_ci || ecma_builtin_is (obj_p, ECMA_BUILTIN_ID_BOOLEAN_PROTOTYPE) 2671425bb815Sopenharmony_ci || ecma_builtin_is (obj_p, ECMA_BUILTIN_ID_NUMBER_PROTOTYPE) 2672425bb815Sopenharmony_ci || ecma_builtin_is (obj_p, ECMA_BUILTIN_ID_DATE_PROTOTYPE) 2673425bb815Sopenharmony_ci || ecma_builtin_is (obj_p, ECMA_BUILTIN_ID_REGEXP_PROTOTYPE) 2674425bb815Sopenharmony_ci || ecma_builtin_is (obj_p, ECMA_BUILTIN_ID_SYMBOL_PROTOTYPE) 2675425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 2676425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015_BUILTIN_MAP) 2677425bb815Sopenharmony_ci || ecma_builtin_is (obj_p, ECMA_BUILTIN_ID_MAP_PROTOTYPE) 2678425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 2679425bb815Sopenharmony_ci || ecma_builtin_is (obj_p, ECMA_BUILTIN_ID_MAP_ITERATOR_PROTOTYPE) 2680425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 2681425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015_BUILTIN_MAP) */ 2682425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015_BUILTIN_SET) 2683425bb815Sopenharmony_ci || ecma_builtin_is (obj_p, ECMA_BUILTIN_ID_SET_PROTOTYPE) 2684425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 2685425bb815Sopenharmony_ci || ecma_builtin_is (obj_p, ECMA_BUILTIN_ID_SET_ITERATOR_PROTOTYPE) 2686425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 2687425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015_BUILTIN_SET) */ 2688425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015_BUILTIN_WEAKMAP) 2689425bb815Sopenharmony_ci || ecma_builtin_is (obj_p, ECMA_BUILTIN_ID_WEAKMAP_PROTOTYPE) 2690425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015_BUILTIN_WEAKMAP) */ 2691425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015_BUILTIN_WEAKSET) 2692425bb815Sopenharmony_ci || ecma_builtin_is (obj_p, ECMA_BUILTIN_ID_WEAKSET_PROTOTYPE) 2693425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015_BUILTIN_WEAKSET) */ 2694425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015_BUILTIN_DATAVIEW) 2695425bb815Sopenharmony_ci || ecma_builtin_is (obj_p, ECMA_BUILTIN_ID_DATAVIEW_PROTOTYPE) 2696425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015_BUILTIN_DATAVIEW) */ 2697425bb815Sopenharmony_ci || ecma_builtin_is (obj_p, ECMA_BUILTIN_ID_OBJECT_PROTOTYPE)); 2698425bb815Sopenharmony_ci#else /* JERRY_NDEBUG */ 2699425bb815Sopenharmony_ci JERRY_UNUSED (obj_p); 2700425bb815Sopenharmony_ci return true; 2701425bb815Sopenharmony_ci#endif /* !JERRY_NDEBUG */ 2702425bb815Sopenharmony_ci} /* ecma_object_check_class_name_is_object */ 2703425bb815Sopenharmony_ci 2704425bb815Sopenharmony_ci/** 2705425bb815Sopenharmony_ci * Get [[Class]] string of specified object 2706425bb815Sopenharmony_ci * 2707425bb815Sopenharmony_ci * @return class name magic string 2708425bb815Sopenharmony_ci */ 2709425bb815Sopenharmony_cilit_magic_string_id_t 2710425bb815Sopenharmony_ciecma_object_get_class_name (ecma_object_t *obj_p) /**< object */ 2711425bb815Sopenharmony_ci{ 2712425bb815Sopenharmony_ci ecma_object_type_t type = ecma_get_object_type (obj_p); 2713425bb815Sopenharmony_ci 2714425bb815Sopenharmony_ci switch (type) 2715425bb815Sopenharmony_ci { 2716425bb815Sopenharmony_ci case ECMA_OBJECT_TYPE_ARRAY: 2717425bb815Sopenharmony_ci { 2718425bb815Sopenharmony_ci return LIT_MAGIC_STRING_ARRAY_UL; 2719425bb815Sopenharmony_ci } 2720425bb815Sopenharmony_ci case ECMA_OBJECT_TYPE_CLASS: 2721425bb815Sopenharmony_ci { 2722425bb815Sopenharmony_ci ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) obj_p; 2723425bb815Sopenharmony_ci 2724425bb815Sopenharmony_ci return (lit_magic_string_id_t) ext_object_p->u.class_prop.class_id; 2725425bb815Sopenharmony_ci } 2726425bb815Sopenharmony_ci case ECMA_OBJECT_TYPE_PSEUDO_ARRAY: 2727425bb815Sopenharmony_ci { 2728425bb815Sopenharmony_ci ecma_extended_object_t *ext_obj_p = (ecma_extended_object_t *) obj_p; 2729425bb815Sopenharmony_ci 2730425bb815Sopenharmony_ci switch (ext_obj_p->u.pseudo_array.type) 2731425bb815Sopenharmony_ci { 2732425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) 2733425bb815Sopenharmony_ci case ECMA_PSEUDO_ARRAY_TYPEDARRAY: 2734425bb815Sopenharmony_ci case ECMA_PSEUDO_ARRAY_TYPEDARRAY_WITH_INFO: 2735425bb815Sopenharmony_ci { 2736425bb815Sopenharmony_ci return (lit_magic_string_id_t) ext_obj_p->u.pseudo_array.u1.class_id; 2737425bb815Sopenharmony_ci } 2738425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY) */ 2739425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 2740425bb815Sopenharmony_ci case ECMA_PSEUDO_ARRAY_ITERATOR: 2741425bb815Sopenharmony_ci { 2742425bb815Sopenharmony_ci return LIT_MAGIC_STRING_ARRAY_ITERATOR_UL; 2743425bb815Sopenharmony_ci } 2744425bb815Sopenharmony_ci case ECMA_PSEUDO_SET_ITERATOR: 2745425bb815Sopenharmony_ci { 2746425bb815Sopenharmony_ci return LIT_MAGIC_STRING_SET_ITERATOR_UL; 2747425bb815Sopenharmony_ci } 2748425bb815Sopenharmony_ci case ECMA_PSEUDO_MAP_ITERATOR: 2749425bb815Sopenharmony_ci { 2750425bb815Sopenharmony_ci return LIT_MAGIC_STRING_MAP_ITERATOR_UL; 2751425bb815Sopenharmony_ci } 2752425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 2753425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 2754425bb815Sopenharmony_ci case ECMA_PSEUDO_STRING_ITERATOR: 2755425bb815Sopenharmony_ci { 2756425bb815Sopenharmony_ci return LIT_MAGIC_STRING_STRING_ITERATOR_UL; 2757425bb815Sopenharmony_ci } 2758425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 2759425bb815Sopenharmony_ci default: 2760425bb815Sopenharmony_ci { 2761425bb815Sopenharmony_ci JERRY_ASSERT (ext_obj_p->u.pseudo_array.type == ECMA_PSEUDO_ARRAY_ARGUMENTS); 2762425bb815Sopenharmony_ci 2763425bb815Sopenharmony_ci return LIT_MAGIC_STRING_ARGUMENTS_UL; 2764425bb815Sopenharmony_ci } 2765425bb815Sopenharmony_ci } 2766425bb815Sopenharmony_ci 2767425bb815Sopenharmony_ci break; 2768425bb815Sopenharmony_ci } 2769425bb815Sopenharmony_ci case ECMA_OBJECT_TYPE_FUNCTION: 2770425bb815Sopenharmony_ci case ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION: 2771425bb815Sopenharmony_ci case ECMA_OBJECT_TYPE_BOUND_FUNCTION: 2772425bb815Sopenharmony_ci { 2773425bb815Sopenharmony_ci return LIT_MAGIC_STRING_FUNCTION_UL; 2774425bb815Sopenharmony_ci } 2775425bb815Sopenharmony_ci default: 2776425bb815Sopenharmony_ci { 2777425bb815Sopenharmony_ci JERRY_ASSERT (type == ECMA_OBJECT_TYPE_GENERAL || type == ECMA_OBJECT_TYPE_PROXY); 2778425bb815Sopenharmony_ci 2779425bb815Sopenharmony_ci if (ecma_get_object_is_builtin (obj_p)) 2780425bb815Sopenharmony_ci { 2781425bb815Sopenharmony_ci ecma_extended_object_t *ext_obj_p = (ecma_extended_object_t *) obj_p; 2782425bb815Sopenharmony_ci 2783425bb815Sopenharmony_ci switch (ext_obj_p->u.built_in.id) 2784425bb815Sopenharmony_ci { 2785425bb815Sopenharmony_ci#if ENABLED (JERRY_BUILTIN_MATH) 2786425bb815Sopenharmony_ci case ECMA_BUILTIN_ID_MATH: 2787425bb815Sopenharmony_ci { 2788425bb815Sopenharmony_ci return LIT_MAGIC_STRING_MATH_UL; 2789425bb815Sopenharmony_ci } 2790425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_BUILTIN_MATH) */ 2791425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015_BUILTIN_REFLECT) 2792425bb815Sopenharmony_ci case ECMA_BUILTIN_ID_REFLECT: 2793425bb815Sopenharmony_ci { 2794425bb815Sopenharmony_ci return LIT_MAGIC_STRING_REFLECT_UL; 2795425bb815Sopenharmony_ci } 2796425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015_BUILTIN_REFLECT) */ 2797425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 2798425bb815Sopenharmony_ci case ECMA_BUILTIN_ID_GENERATOR: 2799425bb815Sopenharmony_ci { 2800425bb815Sopenharmony_ci return LIT_MAGIC_STRING_GENERATOR_UL; 2801425bb815Sopenharmony_ci } 2802425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 2803425bb815Sopenharmony_ci#if ENABLED (JERRY_BUILTIN_JSON) 2804425bb815Sopenharmony_ci case ECMA_BUILTIN_ID_JSON: 2805425bb815Sopenharmony_ci { 2806425bb815Sopenharmony_ci return LIT_MAGIC_STRING_JSON_U; 2807425bb815Sopenharmony_ci } 2808425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_BUILTIN_JSON) */ 2809425bb815Sopenharmony_ci#if !ENABLED (JERRY_ES2015) 2810425bb815Sopenharmony_ci#if ENABLED (JERRY_BUILTIN_ERRORS) 2811425bb815Sopenharmony_ci case ECMA_BUILTIN_ID_EVAL_ERROR_PROTOTYPE: 2812425bb815Sopenharmony_ci case ECMA_BUILTIN_ID_RANGE_ERROR_PROTOTYPE: 2813425bb815Sopenharmony_ci case ECMA_BUILTIN_ID_REFERENCE_ERROR_PROTOTYPE: 2814425bb815Sopenharmony_ci case ECMA_BUILTIN_ID_SYNTAX_ERROR_PROTOTYPE: 2815425bb815Sopenharmony_ci case ECMA_BUILTIN_ID_TYPE_ERROR_PROTOTYPE: 2816425bb815Sopenharmony_ci case ECMA_BUILTIN_ID_URI_ERROR_PROTOTYPE: 2817425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_BUILTIN_ERRORS) */ 2818425bb815Sopenharmony_ci case ECMA_BUILTIN_ID_ERROR_PROTOTYPE: 2819425bb815Sopenharmony_ci { 2820425bb815Sopenharmony_ci return LIT_MAGIC_STRING_ERROR_UL; 2821425bb815Sopenharmony_ci } 2822425bb815Sopenharmony_ci#endif /* !ENABLED (JERRY_ES2015) */ 2823425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015_BUILTIN_PROXY) 2824425bb815Sopenharmony_ci case ECMA_BUILTIN_ID_PROXY: 2825425bb815Sopenharmony_ci { 2826425bb815Sopenharmony_ci return LIT_MAGIC_STRING_FUNCTION_UL; 2827425bb815Sopenharmony_ci } 2828425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */ 2829425bb815Sopenharmony_ci default: 2830425bb815Sopenharmony_ci { 2831425bb815Sopenharmony_ci JERRY_ASSERT (ecma_object_check_class_name_is_object (obj_p)); 2832425bb815Sopenharmony_ci 2833425bb815Sopenharmony_ci return LIT_MAGIC_STRING_OBJECT_UL; 2834425bb815Sopenharmony_ci } 2835425bb815Sopenharmony_ci } 2836425bb815Sopenharmony_ci } 2837425bb815Sopenharmony_ci else 2838425bb815Sopenharmony_ci { 2839425bb815Sopenharmony_ci return LIT_MAGIC_STRING_OBJECT_UL; 2840425bb815Sopenharmony_ci } 2841425bb815Sopenharmony_ci } 2842425bb815Sopenharmony_ci } 2843425bb815Sopenharmony_ci} /* ecma_object_get_class_name */ 2844425bb815Sopenharmony_ci 2845425bb815Sopenharmony_ci/** 2846425bb815Sopenharmony_ci * Get value of an object if the class matches 2847425bb815Sopenharmony_ci * 2848425bb815Sopenharmony_ci * @return value of the object if the class matches 2849425bb815Sopenharmony_ci * ECMA_VALUE_NOT_FOUND otherwise 2850425bb815Sopenharmony_ci */ 2851425bb815Sopenharmony_ciinline bool JERRY_ATTR_ALWAYS_INLINE 2852425bb815Sopenharmony_ciecma_object_class_is (ecma_object_t *object_p, /**< object */ 2853425bb815Sopenharmony_ci uint32_t class_id) /**< class id */ 2854425bb815Sopenharmony_ci{ 2855425bb815Sopenharmony_ci if (ecma_get_object_type (object_p) == ECMA_OBJECT_TYPE_CLASS) 2856425bb815Sopenharmony_ci { 2857425bb815Sopenharmony_ci ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) object_p; 2858425bb815Sopenharmony_ci 2859425bb815Sopenharmony_ci if (ext_object_p->u.class_prop.class_id == class_id) 2860425bb815Sopenharmony_ci { 2861425bb815Sopenharmony_ci return true; 2862425bb815Sopenharmony_ci } 2863425bb815Sopenharmony_ci } 2864425bb815Sopenharmony_ci 2865425bb815Sopenharmony_ci return false; 2866425bb815Sopenharmony_ci} /* ecma_object_class_is */ 2867425bb815Sopenharmony_ci 2868425bb815Sopenharmony_ci/** 2869425bb815Sopenharmony_ci * Checks if the given argument has [[RegExpMatcher]] internal slot 2870425bb815Sopenharmony_ci * 2871425bb815Sopenharmony_ci * @return true - if the given argument is a regexp 2872425bb815Sopenharmony_ci * false - otherwise 2873425bb815Sopenharmony_ci */ 2874425bb815Sopenharmony_ciinline bool JERRY_ATTR_ALWAYS_INLINE 2875425bb815Sopenharmony_ciecma_object_is_regexp_object (ecma_value_t arg) /**< argument */ 2876425bb815Sopenharmony_ci{ 2877425bb815Sopenharmony_ci return (ecma_is_value_object (arg) 2878425bb815Sopenharmony_ci && ecma_object_class_is (ecma_get_object_from_value (arg), LIT_MAGIC_STRING_REGEXP_UL)); 2879425bb815Sopenharmony_ci} /* ecma_object_is_regexp_object */ 2880425bb815Sopenharmony_ci 2881425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 2882425bb815Sopenharmony_ci/** 2883425bb815Sopenharmony_ci * Object's IsConcatSpreadable operation, used for Array.prototype.concat 2884425bb815Sopenharmony_ci * It checks the argument's [Symbol.isConcatSpreadable] property value 2885425bb815Sopenharmony_ci * 2886425bb815Sopenharmony_ci * See also: 2887425bb815Sopenharmony_ci * ECMA-262 v6, 22.1.3.1.1; 2888425bb815Sopenharmony_ci * 2889425bb815Sopenharmony_ci * @return ECMA_VALUE_ERROR - if the operation fails 2890425bb815Sopenharmony_ci * ECMA_VALUE_TRUE - if the argument is concatSpreadable 2891425bb815Sopenharmony_ci * ECMA_VALUE_FALSE - otherwise 2892425bb815Sopenharmony_ci */ 2893425bb815Sopenharmony_ciecma_value_t 2894425bb815Sopenharmony_ciecma_op_is_concat_spreadable (ecma_value_t arg) /**< argument */ 2895425bb815Sopenharmony_ci{ 2896425bb815Sopenharmony_ci if (!ecma_is_value_object (arg)) 2897425bb815Sopenharmony_ci { 2898425bb815Sopenharmony_ci return ECMA_VALUE_FALSE; 2899425bb815Sopenharmony_ci } 2900425bb815Sopenharmony_ci 2901425bb815Sopenharmony_ci ecma_value_t spreadable = ecma_op_object_get_by_symbol_id (ecma_get_object_from_value (arg), 2902425bb815Sopenharmony_ci LIT_GLOBAL_SYMBOL_IS_CONCAT_SPREADABLE); 2903425bb815Sopenharmony_ci 2904425bb815Sopenharmony_ci if (ECMA_IS_VALUE_ERROR (spreadable)) 2905425bb815Sopenharmony_ci { 2906425bb815Sopenharmony_ci return spreadable; 2907425bb815Sopenharmony_ci } 2908425bb815Sopenharmony_ci 2909425bb815Sopenharmony_ci if (!ecma_is_value_undefined (spreadable)) 2910425bb815Sopenharmony_ci { 2911425bb815Sopenharmony_ci const bool to_bool = ecma_op_to_boolean (spreadable); 2912425bb815Sopenharmony_ci ecma_free_value (spreadable); 2913425bb815Sopenharmony_ci return ecma_make_boolean_value (to_bool); 2914425bb815Sopenharmony_ci } 2915425bb815Sopenharmony_ci 2916425bb815Sopenharmony_ci return ecma_is_value_array (arg); 2917425bb815Sopenharmony_ci} /* ecma_op_is_concat_spreadable */ 2918425bb815Sopenharmony_ci 2919425bb815Sopenharmony_ci/** 2920425bb815Sopenharmony_ci * IsRegExp operation 2921425bb815Sopenharmony_ci * 2922425bb815Sopenharmony_ci * See also: 2923425bb815Sopenharmony_ci * ECMA-262 v6, 22.1.3.1.1; 2924425bb815Sopenharmony_ci * 2925425bb815Sopenharmony_ci * @return ECMA_VALUE_ERROR - if the operation fails 2926425bb815Sopenharmony_ci * ECMA_VALUE_TRUE - if the argument is regexp 2927425bb815Sopenharmony_ci * ECMA_VALUE_FALSE - otherwise 2928425bb815Sopenharmony_ci */ 2929425bb815Sopenharmony_ciecma_value_t 2930425bb815Sopenharmony_ciecma_op_is_regexp (ecma_value_t arg) /**< argument */ 2931425bb815Sopenharmony_ci{ 2932425bb815Sopenharmony_ci if (!ecma_is_value_object (arg)) 2933425bb815Sopenharmony_ci { 2934425bb815Sopenharmony_ci return ECMA_VALUE_FALSE; 2935425bb815Sopenharmony_ci } 2936425bb815Sopenharmony_ci 2937425bb815Sopenharmony_ci ecma_value_t is_regexp = ecma_op_object_get_by_symbol_id (ecma_get_object_from_value (arg), 2938425bb815Sopenharmony_ci LIT_GLOBAL_SYMBOL_MATCH); 2939425bb815Sopenharmony_ci 2940425bb815Sopenharmony_ci if (ECMA_IS_VALUE_ERROR (is_regexp)) 2941425bb815Sopenharmony_ci { 2942425bb815Sopenharmony_ci return is_regexp; 2943425bb815Sopenharmony_ci } 2944425bb815Sopenharmony_ci 2945425bb815Sopenharmony_ci if (!ecma_is_value_undefined (is_regexp)) 2946425bb815Sopenharmony_ci { 2947425bb815Sopenharmony_ci const bool to_bool = ecma_op_to_boolean (is_regexp); 2948425bb815Sopenharmony_ci ecma_free_value (is_regexp); 2949425bb815Sopenharmony_ci return ecma_make_boolean_value (to_bool); 2950425bb815Sopenharmony_ci } 2951425bb815Sopenharmony_ci 2952425bb815Sopenharmony_ci return ecma_make_boolean_value (ecma_object_is_regexp_object (arg)); 2953425bb815Sopenharmony_ci} /* ecma_op_is_regexp */ 2954425bb815Sopenharmony_ci 2955425bb815Sopenharmony_ci/** 2956425bb815Sopenharmony_ci * SpeciesConstructor operation 2957425bb815Sopenharmony_ci * See also: 2958425bb815Sopenharmony_ci * ECMA-262 v6, 7.3.20; 2959425bb815Sopenharmony_ci * 2960425bb815Sopenharmony_ci * @return ecma_value 2961425bb815Sopenharmony_ci * returned value must be freed with ecma_free_value 2962425bb815Sopenharmony_ci */ 2963425bb815Sopenharmony_ciecma_value_t 2964425bb815Sopenharmony_ciecma_op_species_constructor (ecma_object_t *this_value, /**< This Value */ 2965425bb815Sopenharmony_ci ecma_builtin_id_t default_constructor_id) /**< Builtin ID of default constructor */ 2966425bb815Sopenharmony_ci{ 2967425bb815Sopenharmony_ci ecma_object_t *default_constructor_p = ecma_builtin_get (default_constructor_id); 2968425bb815Sopenharmony_ci ecma_value_t constructor = ecma_op_object_get_by_magic_id (this_value, LIT_MAGIC_STRING_CONSTRUCTOR); 2969425bb815Sopenharmony_ci if (ECMA_IS_VALUE_ERROR (constructor)) 2970425bb815Sopenharmony_ci { 2971425bb815Sopenharmony_ci return constructor; 2972425bb815Sopenharmony_ci } 2973425bb815Sopenharmony_ci 2974425bb815Sopenharmony_ci if (ecma_is_value_undefined (constructor)) 2975425bb815Sopenharmony_ci { 2976425bb815Sopenharmony_ci ecma_ref_object (default_constructor_p); 2977425bb815Sopenharmony_ci return ecma_make_object_value (default_constructor_p); 2978425bb815Sopenharmony_ci } 2979425bb815Sopenharmony_ci 2980425bb815Sopenharmony_ci if (!ecma_is_value_object (constructor)) 2981425bb815Sopenharmony_ci { 2982425bb815Sopenharmony_ci ecma_free_value (constructor); 2983425bb815Sopenharmony_ci return ecma_raise_type_error (ECMA_ERR_MSG ("Constructor must be an Object")); 2984425bb815Sopenharmony_ci } 2985425bb815Sopenharmony_ci 2986425bb815Sopenharmony_ci ecma_object_t *ctor_object_p = ecma_get_object_from_value (constructor); 2987425bb815Sopenharmony_ci ecma_value_t species = ecma_op_object_get_by_symbol_id (ctor_object_p, LIT_GLOBAL_SYMBOL_SPECIES); 2988425bb815Sopenharmony_ci ecma_deref_object (ctor_object_p); 2989425bb815Sopenharmony_ci 2990425bb815Sopenharmony_ci if (ECMA_IS_VALUE_ERROR (species)) 2991425bb815Sopenharmony_ci { 2992425bb815Sopenharmony_ci return species; 2993425bb815Sopenharmony_ci } 2994425bb815Sopenharmony_ci 2995425bb815Sopenharmony_ci if (ecma_is_value_undefined (species) || ecma_is_value_null (species)) 2996425bb815Sopenharmony_ci { 2997425bb815Sopenharmony_ci ecma_ref_object (default_constructor_p); 2998425bb815Sopenharmony_ci return ecma_make_object_value (default_constructor_p); 2999425bb815Sopenharmony_ci } 3000425bb815Sopenharmony_ci 3001425bb815Sopenharmony_ci if (!ecma_is_constructor (species)) 3002425bb815Sopenharmony_ci { 3003425bb815Sopenharmony_ci ecma_free_value (species); 3004425bb815Sopenharmony_ci return ecma_raise_type_error (ECMA_ERR_MSG ("Species must be a Constructor")); 3005425bb815Sopenharmony_ci } 3006425bb815Sopenharmony_ci 3007425bb815Sopenharmony_ci return species; 3008425bb815Sopenharmony_ci} /* ecma_op_species_constructor */ 3009425bb815Sopenharmony_ci 3010425bb815Sopenharmony_ci/** 3011425bb815Sopenharmony_ci * 7.3.18 Abstract operation Invoke when property name is a magic string 3012425bb815Sopenharmony_ci * 3013425bb815Sopenharmony_ci * @return ecma_value result of the invoked function or raised error 3014425bb815Sopenharmony_ci * note: returned value must be freed with ecma_free_value 3015425bb815Sopenharmony_ci */ 3016425bb815Sopenharmony_ciinline ecma_value_t JERRY_ATTR_ALWAYS_INLINE 3017425bb815Sopenharmony_ciecma_op_invoke_by_symbol_id (ecma_value_t object, /**< Object value */ 3018425bb815Sopenharmony_ci lit_magic_string_id_t symbol_id, /**< Symbol ID */ 3019425bb815Sopenharmony_ci ecma_value_t *args_p, /**< Argument list */ 3020425bb815Sopenharmony_ci ecma_length_t args_len) /**< Argument list length */ 3021425bb815Sopenharmony_ci{ 3022425bb815Sopenharmony_ci ecma_string_t *symbol_p = ecma_op_get_global_symbol (symbol_id); 3023425bb815Sopenharmony_ci ecma_value_t ret_value = ecma_op_invoke (object, symbol_p, args_p, args_len); 3024425bb815Sopenharmony_ci ecma_deref_ecma_string (symbol_p); 3025425bb815Sopenharmony_ci 3026425bb815Sopenharmony_ci return ret_value; 3027425bb815Sopenharmony_ci} /* ecma_op_invoke_by_symbol_id */ 3028425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 3029425bb815Sopenharmony_ci 3030425bb815Sopenharmony_ci/** 3031425bb815Sopenharmony_ci * 7.3.18 Abstract operation Invoke when property name is a magic string 3032425bb815Sopenharmony_ci * 3033425bb815Sopenharmony_ci * @return ecma_value result of the invoked function or raised error 3034425bb815Sopenharmony_ci * note: returned value must be freed with ecma_free_value 3035425bb815Sopenharmony_ci */ 3036425bb815Sopenharmony_ciinline ecma_value_t JERRY_ATTR_ALWAYS_INLINE 3037425bb815Sopenharmony_ciecma_op_invoke_by_magic_id (ecma_value_t object, /**< Object value */ 3038425bb815Sopenharmony_ci lit_magic_string_id_t magic_string_id, /**< Magic string ID */ 3039425bb815Sopenharmony_ci ecma_value_t *args_p, /**< Argument list */ 3040425bb815Sopenharmony_ci ecma_length_t args_len) /**< Argument list length */ 3041425bb815Sopenharmony_ci{ 3042425bb815Sopenharmony_ci return ecma_op_invoke (object, ecma_get_magic_string (magic_string_id), args_p, args_len); 3043425bb815Sopenharmony_ci} /* ecma_op_invoke_by_magic_id */ 3044425bb815Sopenharmony_ci 3045425bb815Sopenharmony_ci/** 3046425bb815Sopenharmony_ci * 7.3.18 Abstract operation Invoke 3047425bb815Sopenharmony_ci * 3048425bb815Sopenharmony_ci * @return ecma_value result of the invoked function or raised error 3049425bb815Sopenharmony_ci * note: returned value must be freed with ecma_free_value 3050425bb815Sopenharmony_ci */ 3051425bb815Sopenharmony_ciecma_value_t 3052425bb815Sopenharmony_ciecma_op_invoke (ecma_value_t object, /**< Object value */ 3053425bb815Sopenharmony_ci ecma_string_t *property_name_p, /**< Property name */ 3054425bb815Sopenharmony_ci ecma_value_t *args_p, /**< Argument list */ 3055425bb815Sopenharmony_ci ecma_length_t args_len) /**< Argument list length */ 3056425bb815Sopenharmony_ci{ 3057425bb815Sopenharmony_ci /* 3. */ 3058425bb815Sopenharmony_ci ecma_value_t object_value = ecma_op_to_object (object); 3059425bb815Sopenharmony_ci if (ECMA_IS_VALUE_ERROR (object_value)) 3060425bb815Sopenharmony_ci { 3061425bb815Sopenharmony_ci return object_value; 3062425bb815Sopenharmony_ci } 3063425bb815Sopenharmony_ci 3064425bb815Sopenharmony_ci ecma_object_t *object_p = ecma_get_object_from_value (object_value); 3065425bb815Sopenharmony_ci ecma_value_t func = ecma_op_object_get (object_p, property_name_p); 3066425bb815Sopenharmony_ci 3067425bb815Sopenharmony_ci if (ECMA_IS_VALUE_ERROR (func)) 3068425bb815Sopenharmony_ci { 3069425bb815Sopenharmony_ci ecma_deref_object (object_p); 3070425bb815Sopenharmony_ci return func; 3071425bb815Sopenharmony_ci } 3072425bb815Sopenharmony_ci 3073425bb815Sopenharmony_ci /* 4. */ 3074425bb815Sopenharmony_ci if (!ecma_op_is_callable (func)) 3075425bb815Sopenharmony_ci { 3076425bb815Sopenharmony_ci ecma_free_value (func); 3077425bb815Sopenharmony_ci ecma_deref_object (object_p); 3078425bb815Sopenharmony_ci return ecma_raise_type_error (ECMA_ERR_MSG ("Argument is not callable")); 3079425bb815Sopenharmony_ci } 3080425bb815Sopenharmony_ci 3081425bb815Sopenharmony_ci ecma_object_t *func_obj_p = ecma_get_object_from_value (func); 3082425bb815Sopenharmony_ci ecma_value_t call_result = ecma_op_function_call (func_obj_p, object, args_p, args_len); 3083425bb815Sopenharmony_ci ecma_deref_object (object_p); 3084425bb815Sopenharmony_ci ecma_deref_object (func_obj_p); 3085425bb815Sopenharmony_ci 3086425bb815Sopenharmony_ci return call_result; 3087425bb815Sopenharmony_ci} /* ecma_op_invoke */ 3088425bb815Sopenharmony_ci 3089425bb815Sopenharmony_ci/** 3090425bb815Sopenharmony_ci * Ordinary object [[GetPrototypeOf]] operation 3091425bb815Sopenharmony_ci * 3092425bb815Sopenharmony_ci * See also: 3093425bb815Sopenharmony_ci * ECMAScript v6, 9.1.1 3094425bb815Sopenharmony_ci * 3095425bb815Sopenharmony_ci * @return the value of the [[Prototype]] internal slot of the given object. 3096425bb815Sopenharmony_ci */ 3097425bb815Sopenharmony_ciinline jmem_cpointer_t JERRY_ATTR_ALWAYS_INLINE 3098425bb815Sopenharmony_ciecma_op_ordinary_object_get_prototype_of (ecma_object_t *obj_p) /**< object */ 3099425bb815Sopenharmony_ci{ 3100425bb815Sopenharmony_ci JERRY_ASSERT (!ecma_is_lexical_environment (obj_p)); 3101425bb815Sopenharmony_ci JERRY_ASSERT (!ECMA_OBJECT_IS_PROXY (obj_p)); 3102425bb815Sopenharmony_ci 3103425bb815Sopenharmony_ci return obj_p->u2.prototype_cp; 3104425bb815Sopenharmony_ci} /* ecma_op_ordinary_object_get_prototype_of */ 3105425bb815Sopenharmony_ci 3106425bb815Sopenharmony_ci/** 3107425bb815Sopenharmony_ci * Ordinary object [[SetPrototypeOf]] operation 3108425bb815Sopenharmony_ci * 3109425bb815Sopenharmony_ci * See also: 3110425bb815Sopenharmony_ci * ECMAScript v6, 9.1.2 3111425bb815Sopenharmony_ci * 3112425bb815Sopenharmony_ci * @return ECMA_VALUE_FALSE - if the operation fails 3113425bb815Sopenharmony_ci * ECMA_VALUE_TRUE - otherwise 3114425bb815Sopenharmony_ci */ 3115425bb815Sopenharmony_ciinline ecma_value_t JERRY_ATTR_ALWAYS_INLINE 3116425bb815Sopenharmony_ciecma_op_ordinary_object_set_prototype_of (ecma_object_t *obj_p, /**< base object */ 3117425bb815Sopenharmony_ci ecma_value_t proto) /**< prototype object */ 3118425bb815Sopenharmony_ci{ 3119425bb815Sopenharmony_ci JERRY_ASSERT (!ecma_is_lexical_environment (obj_p)); 3120425bb815Sopenharmony_ci JERRY_ASSERT (!ECMA_OBJECT_IS_PROXY (obj_p)); 3121425bb815Sopenharmony_ci 3122425bb815Sopenharmony_ci /* 1. */ 3123425bb815Sopenharmony_ci JERRY_ASSERT (ecma_is_value_object (proto) || ecma_is_value_null (proto)); 3124425bb815Sopenharmony_ci 3125425bb815Sopenharmony_ci /* 3. */ 3126425bb815Sopenharmony_ci ecma_object_t *current_proto_p = ECMA_GET_POINTER (ecma_object_t, ecma_op_ordinary_object_get_prototype_of (obj_p)); 3127425bb815Sopenharmony_ci ecma_object_t *new_proto_p = ecma_is_value_null (proto) ? NULL : ecma_get_object_from_value (proto); 3128425bb815Sopenharmony_ci 3129425bb815Sopenharmony_ci /* 4. */ 3130425bb815Sopenharmony_ci if (new_proto_p == current_proto_p) 3131425bb815Sopenharmony_ci { 3132425bb815Sopenharmony_ci return ECMA_VALUE_TRUE; 3133425bb815Sopenharmony_ci } 3134425bb815Sopenharmony_ci 3135425bb815Sopenharmony_ci /* 2 - 5. */ 3136425bb815Sopenharmony_ci if (!ecma_op_ordinary_object_is_extensible (obj_p)) 3137425bb815Sopenharmony_ci { 3138425bb815Sopenharmony_ci return ECMA_VALUE_FALSE; 3139425bb815Sopenharmony_ci } 3140425bb815Sopenharmony_ci 3141425bb815Sopenharmony_ci /* 6. */ 3142425bb815Sopenharmony_ci ecma_object_t *iter_p = new_proto_p; 3143425bb815Sopenharmony_ci 3144425bb815Sopenharmony_ci /* 7 - 8. */ 3145425bb815Sopenharmony_ci while (true) 3146425bb815Sopenharmony_ci { 3147425bb815Sopenharmony_ci /* 8.a */ 3148425bb815Sopenharmony_ci if (iter_p == NULL) 3149425bb815Sopenharmony_ci { 3150425bb815Sopenharmony_ci break; 3151425bb815Sopenharmony_ci } 3152425bb815Sopenharmony_ci 3153425bb815Sopenharmony_ci /* 8.b */ 3154425bb815Sopenharmony_ci if (obj_p == iter_p) 3155425bb815Sopenharmony_ci { 3156425bb815Sopenharmony_ci return ECMA_VALUE_FALSE; 3157425bb815Sopenharmony_ci } 3158425bb815Sopenharmony_ci 3159425bb815Sopenharmony_ci /* 8.c.i */ 3160425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015_BUILTIN_PROXY) 3161425bb815Sopenharmony_ci if (ECMA_OBJECT_IS_PROXY (iter_p)) 3162425bb815Sopenharmony_ci { 3163425bb815Sopenharmony_ci break; 3164425bb815Sopenharmony_ci } 3165425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */ 3166425bb815Sopenharmony_ci 3167425bb815Sopenharmony_ci /* 8.c.ii */ 3168425bb815Sopenharmony_ci iter_p = ECMA_GET_POINTER (ecma_object_t, ecma_op_ordinary_object_get_prototype_of (iter_p)); 3169425bb815Sopenharmony_ci } 3170425bb815Sopenharmony_ci 3171425bb815Sopenharmony_ci /* 9. */ 3172425bb815Sopenharmony_ci ECMA_SET_POINTER (obj_p->u2.prototype_cp, new_proto_p); 3173425bb815Sopenharmony_ci 3174425bb815Sopenharmony_ci /* 10. */ 3175425bb815Sopenharmony_ci return ECMA_VALUE_TRUE; 3176425bb815Sopenharmony_ci} /* ecma_op_ordinary_object_set_prototype_of */ 3177425bb815Sopenharmony_ci 3178425bb815Sopenharmony_ci/** 3179425bb815Sopenharmony_ci * [[IsExtensible]] operation for Ordinary object. 3180425bb815Sopenharmony_ci * 3181425bb815Sopenharmony_ci * See also: 3182425bb815Sopenharmony_ci * ECMAScript v6, 9.1.2 3183425bb815Sopenharmony_ci * 3184425bb815Sopenharmony_ci * @return true - if object is extensible 3185425bb815Sopenharmony_ci * false - otherwise 3186425bb815Sopenharmony_ci */ 3187425bb815Sopenharmony_ciinline bool JERRY_ATTR_PURE 3188425bb815Sopenharmony_ciecma_op_ordinary_object_is_extensible (ecma_object_t *object_p) /**< object */ 3189425bb815Sopenharmony_ci{ 3190425bb815Sopenharmony_ci JERRY_ASSERT (!ECMA_OBJECT_IS_PROXY (object_p)); 3191425bb815Sopenharmony_ci 3192425bb815Sopenharmony_ci return (object_p->type_flags_refs & ECMA_OBJECT_FLAG_EXTENSIBLE) != 0; 3193425bb815Sopenharmony_ci} /* ecma_op_ordinary_object_is_extensible */ 3194425bb815Sopenharmony_ci 3195425bb815Sopenharmony_ci/** 3196425bb815Sopenharmony_ci * Set value of [[Extensible]] object's internal property. 3197425bb815Sopenharmony_ci */ 3198425bb815Sopenharmony_civoid JERRY_ATTR_NOINLINE 3199425bb815Sopenharmony_ciecma_op_ordinary_object_prevent_extensions (ecma_object_t *object_p) /**< object */ 3200425bb815Sopenharmony_ci{ 3201425bb815Sopenharmony_ci JERRY_ASSERT (!ECMA_OBJECT_IS_PROXY (object_p)); 3202425bb815Sopenharmony_ci object_p->type_flags_refs = (uint16_t) (object_p->type_flags_refs & ~ECMA_OBJECT_FLAG_EXTENSIBLE); 3203425bb815Sopenharmony_ci} /* ecma_op_ordinary_object_prevent_extensions */ 3204425bb815Sopenharmony_ci 3205425bb815Sopenharmony_ci/** 3206425bb815Sopenharmony_ci * Checks whether an object (excluding prototypes) has a named property 3207425bb815Sopenharmony_ci * 3208425bb815Sopenharmony_ci * @return true - if property is found 3209425bb815Sopenharmony_ci * false - otherwise 3210425bb815Sopenharmony_ci */ 3211425bb815Sopenharmony_ciinline bool JERRY_ATTR_ALWAYS_INLINE 3212425bb815Sopenharmony_ciecma_op_ordinary_object_has_own_property (ecma_object_t *object_p, /**< the object */ 3213425bb815Sopenharmony_ci ecma_string_t *property_name_p) /**< property name */ 3214425bb815Sopenharmony_ci{ 3215425bb815Sopenharmony_ci JERRY_ASSERT (!ECMA_OBJECT_IS_PROXY (object_p)); 3216425bb815Sopenharmony_ci 3217425bb815Sopenharmony_ci ecma_property_t property = ecma_op_object_get_own_property (object_p, 3218425bb815Sopenharmony_ci property_name_p, 3219425bb815Sopenharmony_ci NULL, 3220425bb815Sopenharmony_ci ECMA_PROPERTY_GET_HAS_OWN_PROP); 3221425bb815Sopenharmony_ci 3222425bb815Sopenharmony_ci return property != ECMA_PROPERTY_TYPE_NOT_FOUND && property != ECMA_PROPERTY_TYPE_NOT_FOUND_AND_STOP; 3223425bb815Sopenharmony_ci} /* ecma_op_ordinary_object_has_own_property */ 3224425bb815Sopenharmony_ci 3225425bb815Sopenharmony_ci/** 3226425bb815Sopenharmony_ci * @} 3227425bb815Sopenharmony_ci * @} 3228425bb815Sopenharmony_ci */ 3229