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-alloc.h" 17425bb815Sopenharmony_ci#include "ecma-array-object.h" 18425bb815Sopenharmony_ci#include "ecma-gc.h" 19425bb815Sopenharmony_ci#include "ecma-globals.h" 20425bb815Sopenharmony_ci#include "ecma-helpers.h" 21425bb815Sopenharmony_ci#include "ecma-lcache.h" 22425bb815Sopenharmony_ci#include "ecma-property-hashmap.h" 23425bb815Sopenharmony_ci#include "jcontext.h" 24425bb815Sopenharmony_ci#include "jrt-bit-fields.h" 25425bb815Sopenharmony_ci#include "byte-code.h" 26425bb815Sopenharmony_ci#include "re-compiler.h" 27425bb815Sopenharmony_ci#include "ecma-builtins.h" 28425bb815Sopenharmony_ci 29425bb815Sopenharmony_ci#if ENABLED (JERRY_DEBUGGER) 30425bb815Sopenharmony_ci#include "debugger.h" 31425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_DEBUGGER) */ 32425bb815Sopenharmony_ci 33425bb815Sopenharmony_ci/** \addtogroup ecma ECMA 34425bb815Sopenharmony_ci * @{ 35425bb815Sopenharmony_ci * 36425bb815Sopenharmony_ci * \addtogroup ecmahelpers Helpers for operations with ECMA data types 37425bb815Sopenharmony_ci * @{ 38425bb815Sopenharmony_ci */ 39425bb815Sopenharmony_ci 40425bb815Sopenharmony_ciJERRY_STATIC_ASSERT (ECMA_PROPERTY_TYPE_MASK >= ECMA_PROPERTY_TYPE__MAX, 41425bb815Sopenharmony_ci ecma_property_types_must_be_lower_than_the_container_mask); 42425bb815Sopenharmony_ci 43425bb815Sopenharmony_ciJERRY_STATIC_ASSERT (ECMA_OBJECT_TYPE_MASK >= ECMA_OBJECT_TYPE__MAX - 1, 44425bb815Sopenharmony_ci ecma_object_types_must_be_lower_than_the_container_mask); 45425bb815Sopenharmony_ci 46425bb815Sopenharmony_ciJERRY_STATIC_ASSERT (ECMA_OBJECT_TYPE_MASK >= ECMA_LEXICAL_ENVIRONMENT_TYPE__MAX, 47425bb815Sopenharmony_ci ecma_lexical_environment_types_must_be_lower_than_the_container_mask); 48425bb815Sopenharmony_ci 49425bb815Sopenharmony_ciJERRY_STATIC_ASSERT (ECMA_OBJECT_TYPE_MASK + 1 == ECMA_OBJECT_FLAG_BUILT_IN_OR_LEXICAL_ENV, 50425bb815Sopenharmony_ci ecma_built_in_flag_must_follow_the_object_type); 51425bb815Sopenharmony_ci 52425bb815Sopenharmony_ciJERRY_STATIC_ASSERT (ECMA_OBJECT_FLAG_EXTENSIBLE == (ECMA_OBJECT_FLAG_BUILT_IN_OR_LEXICAL_ENV << 1), 53425bb815Sopenharmony_ci ecma_extensible_flag_must_follow_the_built_in_flag); 54425bb815Sopenharmony_ci 55425bb815Sopenharmony_ciJERRY_STATIC_ASSERT (ECMA_OBJECT_REF_ONE == (ECMA_OBJECT_FLAG_EXTENSIBLE << 1), 56425bb815Sopenharmony_ci ecma_object_ref_one_must_follow_the_extensible_flag); 57425bb815Sopenharmony_ci 58425bb815Sopenharmony_ciJERRY_STATIC_ASSERT (((ECMA_OBJECT_MAX_REF + ECMA_OBJECT_REF_ONE) | (ECMA_OBJECT_REF_ONE - 1)) == UINT16_MAX, 59425bb815Sopenharmony_ci ecma_object_max_ref_does_not_fill_the_remaining_bits); 60425bb815Sopenharmony_ci 61425bb815Sopenharmony_ciJERRY_STATIC_ASSERT (ECMA_PROPERTY_TYPE_DELETED == (ECMA_DIRECT_STRING_MAGIC << ECMA_PROPERTY_NAME_TYPE_SHIFT), 62425bb815Sopenharmony_ci ecma_property_type_deleted_must_have_magic_string_name_type); 63425bb815Sopenharmony_ci 64425bb815Sopenharmony_ci/** 65425bb815Sopenharmony_ci * Create an object with specified prototype object 66425bb815Sopenharmony_ci * (or NULL prototype if there is not prototype for the object) 67425bb815Sopenharmony_ci * and value of 'Extensible' attribute. 68425bb815Sopenharmony_ci * 69425bb815Sopenharmony_ci * Reference counter's value will be set to one. 70425bb815Sopenharmony_ci * 71425bb815Sopenharmony_ci * @return pointer to the object's descriptor 72425bb815Sopenharmony_ci */ 73425bb815Sopenharmony_ciecma_object_t * 74425bb815Sopenharmony_ciecma_create_object (ecma_object_t *prototype_object_p, /**< pointer to prototybe of the object (or NULL) */ 75425bb815Sopenharmony_ci size_t ext_object_size, /**< size of extended objects */ 76425bb815Sopenharmony_ci ecma_object_type_t type) /**< object type */ 77425bb815Sopenharmony_ci{ 78425bb815Sopenharmony_ci ecma_object_t *new_object_p; 79425bb815Sopenharmony_ci 80425bb815Sopenharmony_ci if (ext_object_size > 0) 81425bb815Sopenharmony_ci { 82425bb815Sopenharmony_ci new_object_p = (ecma_object_t *) ecma_alloc_extended_object (ext_object_size); 83425bb815Sopenharmony_ci } 84425bb815Sopenharmony_ci else 85425bb815Sopenharmony_ci { 86425bb815Sopenharmony_ci new_object_p = ecma_alloc_object (); 87425bb815Sopenharmony_ci } 88425bb815Sopenharmony_ci 89425bb815Sopenharmony_ci new_object_p->type_flags_refs = (uint16_t) (type | ECMA_OBJECT_FLAG_EXTENSIBLE); 90425bb815Sopenharmony_ci 91425bb815Sopenharmony_ci ecma_init_gc_info (new_object_p); 92425bb815Sopenharmony_ci 93425bb815Sopenharmony_ci new_object_p->u1.property_list_cp = JMEM_CP_NULL; 94425bb815Sopenharmony_ci 95425bb815Sopenharmony_ci ECMA_SET_POINTER (new_object_p->u2.prototype_cp, prototype_object_p); 96425bb815Sopenharmony_ci 97425bb815Sopenharmony_ci return new_object_p; 98425bb815Sopenharmony_ci} /* ecma_create_object */ 99425bb815Sopenharmony_ci 100425bb815Sopenharmony_ci/** 101425bb815Sopenharmony_ci * Create a declarative lexical environment with specified outer lexical environment 102425bb815Sopenharmony_ci * (or NULL if the environment is not nested). 103425bb815Sopenharmony_ci * 104425bb815Sopenharmony_ci * See also: ECMA-262 v5, 10.2.1.1 105425bb815Sopenharmony_ci * 106425bb815Sopenharmony_ci * Reference counter's value will be set to one. 107425bb815Sopenharmony_ci * 108425bb815Sopenharmony_ci * @return pointer to the descriptor of lexical environment 109425bb815Sopenharmony_ci */ 110425bb815Sopenharmony_ciecma_object_t * 111425bb815Sopenharmony_ciecma_create_decl_lex_env (ecma_object_t *outer_lexical_environment_p) /**< outer lexical environment */ 112425bb815Sopenharmony_ci{ 113425bb815Sopenharmony_ci ecma_object_t *new_lexical_environment_p = ecma_alloc_object (); 114425bb815Sopenharmony_ci 115425bb815Sopenharmony_ci uint16_t type = ECMA_OBJECT_FLAG_BUILT_IN_OR_LEXICAL_ENV | ECMA_LEXICAL_ENVIRONMENT_DECLARATIVE; 116425bb815Sopenharmony_ci new_lexical_environment_p->type_flags_refs = type; 117425bb815Sopenharmony_ci 118425bb815Sopenharmony_ci ecma_init_gc_info (new_lexical_environment_p); 119425bb815Sopenharmony_ci 120425bb815Sopenharmony_ci new_lexical_environment_p->u1.property_list_cp = JMEM_CP_NULL; 121425bb815Sopenharmony_ci 122425bb815Sopenharmony_ci ECMA_SET_POINTER (new_lexical_environment_p->u2.outer_reference_cp, outer_lexical_environment_p); 123425bb815Sopenharmony_ci 124425bb815Sopenharmony_ci return new_lexical_environment_p; 125425bb815Sopenharmony_ci} /* ecma_create_decl_lex_env */ 126425bb815Sopenharmony_ci 127425bb815Sopenharmony_ci/** 128425bb815Sopenharmony_ci * Create a object lexical environment with specified outer lexical environment 129425bb815Sopenharmony_ci * (or NULL if the environment is not nested), binding object and provided type flag. 130425bb815Sopenharmony_ci * 131425bb815Sopenharmony_ci * See also: ECMA-262 v5, 10.2.1.2 132425bb815Sopenharmony_ci * 133425bb815Sopenharmony_ci * Reference counter's value will be set to one. 134425bb815Sopenharmony_ci * 135425bb815Sopenharmony_ci * @return pointer to the descriptor of lexical environment 136425bb815Sopenharmony_ci */ 137425bb815Sopenharmony_ciecma_object_t * 138425bb815Sopenharmony_ciecma_create_object_lex_env (ecma_object_t *outer_lexical_environment_p, /**< outer lexical environment */ 139425bb815Sopenharmony_ci ecma_object_t *binding_obj_p, /**< binding object */ 140425bb815Sopenharmony_ci ecma_lexical_environment_type_t type) /**< type of the new lexical environment */ 141425bb815Sopenharmony_ci{ 142425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 143425bb815Sopenharmony_ci JERRY_ASSERT (type == ECMA_LEXICAL_ENVIRONMENT_THIS_OBJECT_BOUND 144425bb815Sopenharmony_ci || type == ECMA_LEXICAL_ENVIRONMENT_HOME_OBJECT_BOUND); 145425bb815Sopenharmony_ci#else /* !ENABLED (JERRY_ES2015) */ 146425bb815Sopenharmony_ci JERRY_ASSERT (type == ECMA_LEXICAL_ENVIRONMENT_THIS_OBJECT_BOUND); 147425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 148425bb815Sopenharmony_ci 149425bb815Sopenharmony_ci JERRY_ASSERT (binding_obj_p != NULL 150425bb815Sopenharmony_ci && !ecma_is_lexical_environment (binding_obj_p)); 151425bb815Sopenharmony_ci 152425bb815Sopenharmony_ci ecma_object_t *new_lexical_environment_p = ecma_alloc_object (); 153425bb815Sopenharmony_ci 154425bb815Sopenharmony_ci new_lexical_environment_p->type_flags_refs = (uint16_t) (ECMA_OBJECT_FLAG_BUILT_IN_OR_LEXICAL_ENV | type); 155425bb815Sopenharmony_ci 156425bb815Sopenharmony_ci ecma_init_gc_info (new_lexical_environment_p); 157425bb815Sopenharmony_ci 158425bb815Sopenharmony_ci ECMA_SET_NON_NULL_POINTER (new_lexical_environment_p->u1.bound_object_cp, 159425bb815Sopenharmony_ci binding_obj_p); 160425bb815Sopenharmony_ci 161425bb815Sopenharmony_ci ECMA_SET_POINTER (new_lexical_environment_p->u2.outer_reference_cp, outer_lexical_environment_p); 162425bb815Sopenharmony_ci 163425bb815Sopenharmony_ci return new_lexical_environment_p; 164425bb815Sopenharmony_ci} /* ecma_create_object_lex_env */ 165425bb815Sopenharmony_ci 166425bb815Sopenharmony_ci/** 167425bb815Sopenharmony_ci * Check if the object is lexical environment. 168425bb815Sopenharmony_ci * 169425bb815Sopenharmony_ci * @return true - if object is a lexical environment 170425bb815Sopenharmony_ci * false - otherwise 171425bb815Sopenharmony_ci */ 172425bb815Sopenharmony_ciinline bool JERRY_ATTR_PURE 173425bb815Sopenharmony_ciecma_is_lexical_environment (const ecma_object_t *object_p) /**< object or lexical environment */ 174425bb815Sopenharmony_ci{ 175425bb815Sopenharmony_ci JERRY_ASSERT (object_p != NULL); 176425bb815Sopenharmony_ci 177425bb815Sopenharmony_ci uint32_t full_type = object_p->type_flags_refs & (ECMA_OBJECT_FLAG_BUILT_IN_OR_LEXICAL_ENV | ECMA_OBJECT_TYPE_MASK); 178425bb815Sopenharmony_ci 179425bb815Sopenharmony_ci return full_type >= (ECMA_OBJECT_FLAG_BUILT_IN_OR_LEXICAL_ENV | ECMA_LEXICAL_ENVIRONMENT_TYPE_START); 180425bb815Sopenharmony_ci} /* ecma_is_lexical_environment */ 181425bb815Sopenharmony_ci 182425bb815Sopenharmony_ci/** 183425bb815Sopenharmony_ci * Set value of [[Extensible]] object's internal property. 184425bb815Sopenharmony_ci */ 185425bb815Sopenharmony_ciinline void 186425bb815Sopenharmony_ciecma_op_ordinary_object_set_extensible (ecma_object_t *object_p) /**< object */ 187425bb815Sopenharmony_ci{ 188425bb815Sopenharmony_ci JERRY_ASSERT (object_p != NULL); 189425bb815Sopenharmony_ci JERRY_ASSERT (!ecma_is_lexical_environment (object_p)); 190425bb815Sopenharmony_ci 191425bb815Sopenharmony_ci object_p->type_flags_refs = (uint16_t) (object_p->type_flags_refs | ECMA_OBJECT_FLAG_EXTENSIBLE); 192425bb815Sopenharmony_ci} /* ecma_op_ordinary_object_set_extensible */ 193425bb815Sopenharmony_ci 194425bb815Sopenharmony_ci/** 195425bb815Sopenharmony_ci * Get object's internal implementation-defined type. 196425bb815Sopenharmony_ci * 197425bb815Sopenharmony_ci * @return type of the object (ecma_object_type_t) 198425bb815Sopenharmony_ci */ 199425bb815Sopenharmony_ciinline ecma_object_type_t JERRY_ATTR_PURE 200425bb815Sopenharmony_ciecma_get_object_type (const ecma_object_t *object_p) /**< object */ 201425bb815Sopenharmony_ci{ 202425bb815Sopenharmony_ci JERRY_ASSERT (object_p != NULL); 203425bb815Sopenharmony_ci JERRY_ASSERT (!ecma_is_lexical_environment (object_p)); 204425bb815Sopenharmony_ci 205425bb815Sopenharmony_ci return (ecma_object_type_t) (object_p->type_flags_refs & ECMA_OBJECT_TYPE_MASK); 206425bb815Sopenharmony_ci} /* ecma_get_object_type */ 207425bb815Sopenharmony_ci 208425bb815Sopenharmony_ci/** 209425bb815Sopenharmony_ci * Check if the object is a built-in object 210425bb815Sopenharmony_ci * 211425bb815Sopenharmony_ci * @return true - if object is a built-in object 212425bb815Sopenharmony_ci * false - otherwise 213425bb815Sopenharmony_ci */ 214425bb815Sopenharmony_ciinline bool JERRY_ATTR_PURE 215425bb815Sopenharmony_ciecma_get_object_is_builtin (const ecma_object_t *object_p) /**< object */ 216425bb815Sopenharmony_ci{ 217425bb815Sopenharmony_ci JERRY_ASSERT (object_p != NULL); 218425bb815Sopenharmony_ci JERRY_ASSERT (!ecma_is_lexical_environment (object_p)); 219425bb815Sopenharmony_ci 220425bb815Sopenharmony_ci return (object_p->type_flags_refs & ECMA_OBJECT_FLAG_BUILT_IN_OR_LEXICAL_ENV) != 0; 221425bb815Sopenharmony_ci} /* ecma_get_object_is_builtin */ 222425bb815Sopenharmony_ci 223425bb815Sopenharmony_ci/** 224425bb815Sopenharmony_ci * Set flag indicating whether the object is a built-in object 225425bb815Sopenharmony_ci */ 226425bb815Sopenharmony_ciinline void 227425bb815Sopenharmony_ciecma_set_object_is_builtin (ecma_object_t *object_p) /**< object */ 228425bb815Sopenharmony_ci{ 229425bb815Sopenharmony_ci JERRY_ASSERT (object_p != NULL); 230425bb815Sopenharmony_ci JERRY_ASSERT (!(object_p->type_flags_refs & ECMA_OBJECT_FLAG_BUILT_IN_OR_LEXICAL_ENV)); 231425bb815Sopenharmony_ci JERRY_ASSERT ((object_p->type_flags_refs & ECMA_OBJECT_TYPE_MASK) < ECMA_LEXICAL_ENVIRONMENT_TYPE_START); 232425bb815Sopenharmony_ci 233425bb815Sopenharmony_ci object_p->type_flags_refs = (uint16_t) (object_p->type_flags_refs | ECMA_OBJECT_FLAG_BUILT_IN_OR_LEXICAL_ENV); 234425bb815Sopenharmony_ci} /* ecma_set_object_is_builtin */ 235425bb815Sopenharmony_ci 236425bb815Sopenharmony_ci/** 237425bb815Sopenharmony_ci * Get the built-in ID of the object. 238425bb815Sopenharmony_ci * If the object is not builtin, return ECMA_BUILTIN_ID__COUNT 239425bb815Sopenharmony_ci * 240425bb815Sopenharmony_ci * @return the ID of the built-in 241425bb815Sopenharmony_ci */ 242425bb815Sopenharmony_ciinline uint8_t 243425bb815Sopenharmony_ciecma_get_object_builtin_id (ecma_object_t *object_p) /**< object */ 244425bb815Sopenharmony_ci{ 245425bb815Sopenharmony_ci if (!ecma_get_object_is_builtin (object_p)) 246425bb815Sopenharmony_ci { 247425bb815Sopenharmony_ci return ECMA_BUILTIN_ID__COUNT; 248425bb815Sopenharmony_ci } 249425bb815Sopenharmony_ci 250425bb815Sopenharmony_ci ecma_built_in_props_t *built_in_props_p; 251425bb815Sopenharmony_ci ecma_object_type_t object_type = ecma_get_object_type (object_p); 252425bb815Sopenharmony_ci 253425bb815Sopenharmony_ci if (object_type == ECMA_OBJECT_TYPE_CLASS || object_type == ECMA_OBJECT_TYPE_ARRAY) 254425bb815Sopenharmony_ci { 255425bb815Sopenharmony_ci built_in_props_p = &((ecma_extended_built_in_object_t *) object_p)->built_in; 256425bb815Sopenharmony_ci } 257425bb815Sopenharmony_ci else 258425bb815Sopenharmony_ci { 259425bb815Sopenharmony_ci built_in_props_p = &((ecma_extended_object_t *) object_p)->u.built_in; 260425bb815Sopenharmony_ci } 261425bb815Sopenharmony_ci 262425bb815Sopenharmony_ci return built_in_props_p->id; 263425bb815Sopenharmony_ci} /* ecma_get_object_builtin_id */ 264425bb815Sopenharmony_ci 265425bb815Sopenharmony_ci/** 266425bb815Sopenharmony_ci * Get type of lexical environment. 267425bb815Sopenharmony_ci * 268425bb815Sopenharmony_ci * @return type of the lexical environment (ecma_lexical_environment_type_t) 269425bb815Sopenharmony_ci */ 270425bb815Sopenharmony_ciinline ecma_lexical_environment_type_t JERRY_ATTR_PURE 271425bb815Sopenharmony_ciecma_get_lex_env_type (const ecma_object_t *object_p) /**< lexical environment */ 272425bb815Sopenharmony_ci{ 273425bb815Sopenharmony_ci JERRY_ASSERT (object_p != NULL); 274425bb815Sopenharmony_ci JERRY_ASSERT (ecma_is_lexical_environment (object_p)); 275425bb815Sopenharmony_ci 276425bb815Sopenharmony_ci if (object_p == NULL) 277425bb815Sopenharmony_ci { 278425bb815Sopenharmony_ci jerry_fatal(ERR_FAILED_INTERNAL_ASSERTION); 279425bb815Sopenharmony_ci } 280425bb815Sopenharmony_ci 281425bb815Sopenharmony_ci return (ecma_lexical_environment_type_t) (object_p->type_flags_refs & ECMA_OBJECT_TYPE_MASK); 282425bb815Sopenharmony_ci} /* ecma_get_lex_env_type */ 283425bb815Sopenharmony_ci 284425bb815Sopenharmony_ci/** 285425bb815Sopenharmony_ci * Get lexical environment's bound object. 286425bb815Sopenharmony_ci * 287425bb815Sopenharmony_ci * @return pointer to ecma object 288425bb815Sopenharmony_ci */ 289425bb815Sopenharmony_ciinline ecma_object_t *JERRY_ATTR_PURE 290425bb815Sopenharmony_ciecma_get_lex_env_binding_object (const ecma_object_t *object_p) /**< object-bound lexical environment */ 291425bb815Sopenharmony_ci{ 292425bb815Sopenharmony_ci JERRY_ASSERT (object_p != NULL); 293425bb815Sopenharmony_ci JERRY_ASSERT (ecma_is_lexical_environment (object_p)); 294425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 295425bb815Sopenharmony_ci JERRY_ASSERT (ecma_get_lex_env_type (object_p) == ECMA_LEXICAL_ENVIRONMENT_THIS_OBJECT_BOUND 296425bb815Sopenharmony_ci || ecma_get_lex_env_type (object_p) == ECMA_LEXICAL_ENVIRONMENT_HOME_OBJECT_BOUND); 297425bb815Sopenharmony_ci#else /* !ENABLED (JERRY_ES2015) */ 298425bb815Sopenharmony_ci JERRY_ASSERT (ecma_get_lex_env_type (object_p) == ECMA_LEXICAL_ENVIRONMENT_THIS_OBJECT_BOUND); 299425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 300425bb815Sopenharmony_ci 301425bb815Sopenharmony_ci return ECMA_GET_NON_NULL_POINTER (ecma_object_t, object_p->u1.bound_object_cp); 302425bb815Sopenharmony_ci} /* ecma_get_lex_env_binding_object */ 303425bb815Sopenharmony_ci 304425bb815Sopenharmony_ci/** 305425bb815Sopenharmony_ci * Create a new lexical environment with the same property list as the passed lexical environment 306425bb815Sopenharmony_ci * 307425bb815Sopenharmony_ci * @return pointer to the newly created lexical environment 308425bb815Sopenharmony_ci */ 309425bb815Sopenharmony_ciecma_object_t * 310425bb815Sopenharmony_ciecma_clone_decl_lexical_environment (ecma_object_t *lex_env_p, /**< declarative lexical environment */ 311425bb815Sopenharmony_ci bool copy_values) /**< copy property values as well */ 312425bb815Sopenharmony_ci{ 313425bb815Sopenharmony_ci JERRY_ASSERT (ecma_get_lex_env_type (lex_env_p) == ECMA_LEXICAL_ENVIRONMENT_DECLARATIVE); 314425bb815Sopenharmony_ci JERRY_ASSERT (lex_env_p->u2.outer_reference_cp != JMEM_CP_NULL); 315425bb815Sopenharmony_ci 316425bb815Sopenharmony_ci ecma_object_t *outer_lex_env_p = ECMA_GET_NON_NULL_POINTER (ecma_object_t, lex_env_p->u2.outer_reference_cp); 317425bb815Sopenharmony_ci ecma_object_t *new_lex_env_p = ecma_create_decl_lex_env (outer_lex_env_p); 318425bb815Sopenharmony_ci 319425bb815Sopenharmony_ci jmem_cpointer_t prop_iter_cp = lex_env_p->u1.property_list_cp; 320425bb815Sopenharmony_ci JERRY_ASSERT (prop_iter_cp != JMEM_CP_NULL); 321425bb815Sopenharmony_ci 322425bb815Sopenharmony_ci ecma_property_header_t *prop_iter_p = ECMA_GET_NON_NULL_POINTER (ecma_property_header_t, 323425bb815Sopenharmony_ci prop_iter_cp); 324425bb815Sopenharmony_ci if (prop_iter_p->types[0] == ECMA_PROPERTY_TYPE_HASHMAP) 325425bb815Sopenharmony_ci { 326425bb815Sopenharmony_ci prop_iter_cp = prop_iter_p->next_property_cp; 327425bb815Sopenharmony_ci } 328425bb815Sopenharmony_ci 329425bb815Sopenharmony_ci JERRY_ASSERT (prop_iter_cp != JMEM_CP_NULL); 330425bb815Sopenharmony_ci 331425bb815Sopenharmony_ci do 332425bb815Sopenharmony_ci { 333425bb815Sopenharmony_ci prop_iter_p = ECMA_GET_NON_NULL_POINTER (ecma_property_header_t, prop_iter_cp); 334425bb815Sopenharmony_ci 335425bb815Sopenharmony_ci JERRY_ASSERT (ECMA_PROPERTY_IS_PROPERTY_PAIR (prop_iter_p)); 336425bb815Sopenharmony_ci 337425bb815Sopenharmony_ci ecma_property_pair_t *prop_pair_p = (ecma_property_pair_t *) prop_iter_p; 338425bb815Sopenharmony_ci 339425bb815Sopenharmony_ci for (int i = 0; i < ECMA_PROPERTY_PAIR_ITEM_COUNT; i++) 340425bb815Sopenharmony_ci { 341425bb815Sopenharmony_ci if (prop_iter_p->types[i] != ECMA_PROPERTY_TYPE_DELETED) 342425bb815Sopenharmony_ci { 343425bb815Sopenharmony_ci JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (prop_iter_p->types[i]) == ECMA_PROPERTY_TYPE_NAMEDDATA); 344425bb815Sopenharmony_ci 345425bb815Sopenharmony_ci uint8_t prop_attributes = (uint8_t) (prop_iter_p->types[i] & ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE); 346425bb815Sopenharmony_ci ecma_string_t *name_p = ecma_string_from_property_name (prop_iter_p->types[i], prop_pair_p->names_cp[i]); 347425bb815Sopenharmony_ci 348425bb815Sopenharmony_ci ecma_property_value_t *property_value_p; 349425bb815Sopenharmony_ci property_value_p = ecma_create_named_data_property (new_lex_env_p, name_p, prop_attributes, NULL); 350425bb815Sopenharmony_ci 351425bb815Sopenharmony_ci ecma_deref_ecma_string (name_p); 352425bb815Sopenharmony_ci 353425bb815Sopenharmony_ci JERRY_ASSERT (property_value_p->value == ECMA_VALUE_UNDEFINED); 354425bb815Sopenharmony_ci 355425bb815Sopenharmony_ci if (copy_values) 356425bb815Sopenharmony_ci { 357425bb815Sopenharmony_ci property_value_p->value = ecma_copy_value_if_not_object (prop_pair_p->values[i].value); 358425bb815Sopenharmony_ci } 359425bb815Sopenharmony_ci else 360425bb815Sopenharmony_ci { 361425bb815Sopenharmony_ci property_value_p->value = ECMA_VALUE_UNINITIALIZED; 362425bb815Sopenharmony_ci } 363425bb815Sopenharmony_ci } 364425bb815Sopenharmony_ci } 365425bb815Sopenharmony_ci 366425bb815Sopenharmony_ci prop_iter_cp = prop_iter_p->next_property_cp; 367425bb815Sopenharmony_ci } 368425bb815Sopenharmony_ci while (prop_iter_cp != JMEM_CP_NULL); 369425bb815Sopenharmony_ci 370425bb815Sopenharmony_ci ecma_deref_object (lex_env_p); 371425bb815Sopenharmony_ci return new_lex_env_p; 372425bb815Sopenharmony_ci} /* ecma_clone_decl_lexical_environment */ 373425bb815Sopenharmony_ci 374425bb815Sopenharmony_ci/** 375425bb815Sopenharmony_ci * Create a property in an object and link it into 376425bb815Sopenharmony_ci * the object's properties' linked-list (at start of the list). 377425bb815Sopenharmony_ci * 378425bb815Sopenharmony_ci * @return pointer to the newly created property value 379425bb815Sopenharmony_ci */ 380425bb815Sopenharmony_cistatic ecma_property_value_t * 381425bb815Sopenharmony_ciecma_create_property (ecma_object_t *object_p, /**< the object */ 382425bb815Sopenharmony_ci ecma_string_t *name_p, /**< property name */ 383425bb815Sopenharmony_ci uint8_t type_and_flags, /**< type and flags, see ecma_property_info_t */ 384425bb815Sopenharmony_ci ecma_property_value_t value, /**< property value */ 385425bb815Sopenharmony_ci ecma_property_t **out_prop_p) /**< [out] the property is also returned 386425bb815Sopenharmony_ci * if this field is non-NULL */ 387425bb815Sopenharmony_ci{ 388425bb815Sopenharmony_ci JERRY_ASSERT (ECMA_PROPERTY_PAIR_ITEM_COUNT == 2); 389425bb815Sopenharmony_ci JERRY_ASSERT (name_p != NULL); 390425bb815Sopenharmony_ci JERRY_ASSERT (object_p != NULL); 391425bb815Sopenharmony_ci 392425bb815Sopenharmony_ci jmem_cpointer_t *property_list_head_p = &object_p->u1.property_list_cp; 393425bb815Sopenharmony_ci 394425bb815Sopenharmony_ci if (*property_list_head_p != ECMA_NULL_POINTER) 395425bb815Sopenharmony_ci { 396425bb815Sopenharmony_ci /* If the first entry is free (deleted), it is reused. */ 397425bb815Sopenharmony_ci ecma_property_header_t *first_property_p = ECMA_GET_NON_NULL_POINTER (ecma_property_header_t, 398425bb815Sopenharmony_ci *property_list_head_p); 399425bb815Sopenharmony_ci 400425bb815Sopenharmony_ci#if ENABLED (JERRY_PROPRETY_HASHMAP) 401425bb815Sopenharmony_ci bool has_hashmap = false; 402425bb815Sopenharmony_ci 403425bb815Sopenharmony_ci if (first_property_p->types[0] == ECMA_PROPERTY_TYPE_HASHMAP) 404425bb815Sopenharmony_ci { 405425bb815Sopenharmony_ci property_list_head_p = &first_property_p->next_property_cp; 406425bb815Sopenharmony_ci first_property_p = ECMA_GET_NON_NULL_POINTER (ecma_property_header_t, 407425bb815Sopenharmony_ci *property_list_head_p); 408425bb815Sopenharmony_ci has_hashmap = true; 409425bb815Sopenharmony_ci } 410425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_PROPRETY_HASHMAP) */ 411425bb815Sopenharmony_ci 412425bb815Sopenharmony_ci JERRY_ASSERT (ECMA_PROPERTY_IS_PROPERTY_PAIR (first_property_p)); 413425bb815Sopenharmony_ci 414425bb815Sopenharmony_ci if (first_property_p->types[0] == ECMA_PROPERTY_TYPE_DELETED) 415425bb815Sopenharmony_ci { 416425bb815Sopenharmony_ci ecma_property_pair_t *first_property_pair_p = (ecma_property_pair_t *) first_property_p; 417425bb815Sopenharmony_ci 418425bb815Sopenharmony_ci ecma_property_t name_type; 419425bb815Sopenharmony_ci first_property_pair_p->names_cp[0] = ecma_string_to_property_name (name_p, 420425bb815Sopenharmony_ci &name_type); 421425bb815Sopenharmony_ci first_property_p->types[0] = (ecma_property_t) (type_and_flags | name_type); 422425bb815Sopenharmony_ci 423425bb815Sopenharmony_ci ecma_property_t *property_p = first_property_p->types + 0; 424425bb815Sopenharmony_ci 425425bb815Sopenharmony_ci JERRY_ASSERT (ECMA_PROPERTY_VALUE_PTR (property_p) == first_property_pair_p->values + 0); 426425bb815Sopenharmony_ci 427425bb815Sopenharmony_ci if (out_prop_p != NULL) 428425bb815Sopenharmony_ci { 429425bb815Sopenharmony_ci *out_prop_p = property_p; 430425bb815Sopenharmony_ci } 431425bb815Sopenharmony_ci 432425bb815Sopenharmony_ci first_property_pair_p->values[0] = value; 433425bb815Sopenharmony_ci 434425bb815Sopenharmony_ci#if ENABLED (JERRY_PROPRETY_HASHMAP) 435425bb815Sopenharmony_ci /* The property must be fully initialized before ecma_property_hashmap_insert 436425bb815Sopenharmony_ci * is called, because the insert operation may reallocate the hashmap, and 437425bb815Sopenharmony_ci * that triggers garbage collection which scans all properties of all objects. 438425bb815Sopenharmony_ci * A not fully initialized but queued property may cause a crash. */ 439425bb815Sopenharmony_ci 440425bb815Sopenharmony_ci if (has_hashmap) 441425bb815Sopenharmony_ci { 442425bb815Sopenharmony_ci ecma_property_hashmap_insert (object_p, 443425bb815Sopenharmony_ci name_p, 444425bb815Sopenharmony_ci first_property_pair_p, 445425bb815Sopenharmony_ci 0); 446425bb815Sopenharmony_ci } 447425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_PROPRETY_HASHMAP) */ 448425bb815Sopenharmony_ci 449425bb815Sopenharmony_ci return first_property_pair_p->values + 0; 450425bb815Sopenharmony_ci } 451425bb815Sopenharmony_ci } 452425bb815Sopenharmony_ci 453425bb815Sopenharmony_ci /* Otherwise we create a new property pair and use its second value. */ 454425bb815Sopenharmony_ci ecma_property_pair_t *first_property_pair_p = ecma_alloc_property_pair (); 455425bb815Sopenharmony_ci 456425bb815Sopenharmony_ci /* Need to query property_list_head_p again and recheck the existennce 457425bb815Sopenharmony_ci * of property hasmap, because ecma_alloc_property_pair may delete them. */ 458425bb815Sopenharmony_ci property_list_head_p = &object_p->u1.property_list_cp; 459425bb815Sopenharmony_ci#if ENABLED (JERRY_PROPRETY_HASHMAP) 460425bb815Sopenharmony_ci bool has_hashmap = false; 461425bb815Sopenharmony_ci 462425bb815Sopenharmony_ci if (*property_list_head_p != ECMA_NULL_POINTER) 463425bb815Sopenharmony_ci { 464425bb815Sopenharmony_ci ecma_property_header_t *first_property_p = ECMA_GET_NON_NULL_POINTER (ecma_property_header_t, 465425bb815Sopenharmony_ci *property_list_head_p); 466425bb815Sopenharmony_ci 467425bb815Sopenharmony_ci if (first_property_p->types[0] == ECMA_PROPERTY_TYPE_HASHMAP) 468425bb815Sopenharmony_ci { 469425bb815Sopenharmony_ci property_list_head_p = &first_property_p->next_property_cp; 470425bb815Sopenharmony_ci has_hashmap = true; 471425bb815Sopenharmony_ci } 472425bb815Sopenharmony_ci } 473425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_PROPRETY_HASHMAP) */ 474425bb815Sopenharmony_ci 475425bb815Sopenharmony_ci /* Just copy the previous value (no need to decompress, compress). */ 476425bb815Sopenharmony_ci first_property_pair_p->header.next_property_cp = *property_list_head_p; 477425bb815Sopenharmony_ci first_property_pair_p->header.types[0] = ECMA_PROPERTY_TYPE_DELETED; 478425bb815Sopenharmony_ci first_property_pair_p->names_cp[0] = LIT_INTERNAL_MAGIC_STRING_DELETED; 479425bb815Sopenharmony_ci 480425bb815Sopenharmony_ci ecma_property_t name_type; 481425bb815Sopenharmony_ci first_property_pair_p->names_cp[1] = ecma_string_to_property_name (name_p, 482425bb815Sopenharmony_ci &name_type); 483425bb815Sopenharmony_ci 484425bb815Sopenharmony_ci first_property_pair_p->header.types[1] = (ecma_property_t) (type_and_flags | name_type); 485425bb815Sopenharmony_ci 486425bb815Sopenharmony_ci ECMA_SET_NON_NULL_POINTER (*property_list_head_p, &first_property_pair_p->header); 487425bb815Sopenharmony_ci 488425bb815Sopenharmony_ci ecma_property_t *property_p = first_property_pair_p->header.types + 1; 489425bb815Sopenharmony_ci 490425bb815Sopenharmony_ci JERRY_ASSERT (ECMA_PROPERTY_VALUE_PTR (property_p) == first_property_pair_p->values + 1); 491425bb815Sopenharmony_ci 492425bb815Sopenharmony_ci if (out_prop_p != NULL) 493425bb815Sopenharmony_ci { 494425bb815Sopenharmony_ci *out_prop_p = property_p; 495425bb815Sopenharmony_ci } 496425bb815Sopenharmony_ci 497425bb815Sopenharmony_ci first_property_pair_p->values[1] = value; 498425bb815Sopenharmony_ci 499425bb815Sopenharmony_ci#if ENABLED (JERRY_PROPRETY_HASHMAP) 500425bb815Sopenharmony_ci /* See the comment before the other ecma_property_hashmap_insert above. */ 501425bb815Sopenharmony_ci 502425bb815Sopenharmony_ci if (has_hashmap) 503425bb815Sopenharmony_ci { 504425bb815Sopenharmony_ci ecma_property_hashmap_insert (object_p, 505425bb815Sopenharmony_ci name_p, 506425bb815Sopenharmony_ci first_property_pair_p, 507425bb815Sopenharmony_ci 1); 508425bb815Sopenharmony_ci } 509425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_PROPRETY_HASHMAP) */ 510425bb815Sopenharmony_ci 511425bb815Sopenharmony_ci return first_property_pair_p->values + 1; 512425bb815Sopenharmony_ci} /* ecma_create_property */ 513425bb815Sopenharmony_ci 514425bb815Sopenharmony_ci/** 515425bb815Sopenharmony_ci * Create named data property with given name, attributes and undefined value 516425bb815Sopenharmony_ci * in the specified object. 517425bb815Sopenharmony_ci * 518425bb815Sopenharmony_ci * @return pointer to the newly created property value 519425bb815Sopenharmony_ci */ 520425bb815Sopenharmony_ciecma_property_value_t * 521425bb815Sopenharmony_ciecma_create_named_data_property (ecma_object_t *object_p, /**< object */ 522425bb815Sopenharmony_ci ecma_string_t *name_p, /**< property name */ 523425bb815Sopenharmony_ci uint8_t prop_attributes, /**< property attributes (See: ecma_property_flags_t) */ 524425bb815Sopenharmony_ci ecma_property_t **out_prop_p) /**< [out] the property is also returned 525425bb815Sopenharmony_ci * if this field is non-NULL */ 526425bb815Sopenharmony_ci{ 527425bb815Sopenharmony_ci JERRY_ASSERT (object_p != NULL && name_p != NULL); 528425bb815Sopenharmony_ci JERRY_ASSERT (ecma_is_lexical_environment (object_p) 529425bb815Sopenharmony_ci || !ecma_op_object_is_fast_array (object_p)); 530425bb815Sopenharmony_ci JERRY_ASSERT (ecma_find_named_property (object_p, name_p) == NULL); 531425bb815Sopenharmony_ci JERRY_ASSERT ((prop_attributes & ~ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE) == 0); 532425bb815Sopenharmony_ci 533425bb815Sopenharmony_ci uint8_t type_and_flags = ECMA_PROPERTY_TYPE_NAMEDDATA | prop_attributes; 534425bb815Sopenharmony_ci 535425bb815Sopenharmony_ci ecma_property_value_t value; 536425bb815Sopenharmony_ci value.value = ECMA_VALUE_UNDEFINED; 537425bb815Sopenharmony_ci 538425bb815Sopenharmony_ci return ecma_create_property (object_p, name_p, type_and_flags, value, out_prop_p); 539425bb815Sopenharmony_ci} /* ecma_create_named_data_property */ 540425bb815Sopenharmony_ci 541425bb815Sopenharmony_ci/** 542425bb815Sopenharmony_ci * Create named accessor property with given name, attributes, getter and setter. 543425bb815Sopenharmony_ci * 544425bb815Sopenharmony_ci * @return pointer to the newly created property value 545425bb815Sopenharmony_ci */ 546425bb815Sopenharmony_ciecma_property_value_t * 547425bb815Sopenharmony_ciecma_create_named_accessor_property (ecma_object_t *object_p, /**< object */ 548425bb815Sopenharmony_ci ecma_string_t *name_p, /**< property name */ 549425bb815Sopenharmony_ci ecma_object_t *get_p, /**< getter */ 550425bb815Sopenharmony_ci ecma_object_t *set_p, /**< setter */ 551425bb815Sopenharmony_ci uint8_t prop_attributes, /**< property attributes */ 552425bb815Sopenharmony_ci ecma_property_t **out_prop_p) /**< [out] the property is also returned 553425bb815Sopenharmony_ci * if this field is non-NULL */ 554425bb815Sopenharmony_ci{ 555425bb815Sopenharmony_ci JERRY_ASSERT (object_p != NULL && name_p != NULL); 556425bb815Sopenharmony_ci JERRY_ASSERT (ecma_is_lexical_environment (object_p) 557425bb815Sopenharmony_ci || !ecma_op_object_is_fast_array (object_p)); 558425bb815Sopenharmony_ci JERRY_ASSERT (ecma_find_named_property (object_p, name_p) == NULL); 559425bb815Sopenharmony_ci JERRY_ASSERT ((prop_attributes & ~ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE) == 0); 560425bb815Sopenharmony_ci 561425bb815Sopenharmony_ci uint8_t type_and_flags = ECMA_PROPERTY_TYPE_NAMEDACCESSOR | prop_attributes; 562425bb815Sopenharmony_ci 563425bb815Sopenharmony_ci ecma_property_value_t value; 564425bb815Sopenharmony_ci#if ENABLED (JERRY_CPOINTER_32_BIT) 565425bb815Sopenharmony_ci ecma_getter_setter_pointers_t *getter_setter_pair_p; 566425bb815Sopenharmony_ci getter_setter_pair_p = jmem_pools_alloc (sizeof (ecma_getter_setter_pointers_t)); 567425bb815Sopenharmony_ci ECMA_SET_POINTER (getter_setter_pair_p->getter_cp, get_p); 568425bb815Sopenharmony_ci ECMA_SET_POINTER (getter_setter_pair_p->setter_cp, set_p); 569425bb815Sopenharmony_ci ECMA_SET_NON_NULL_POINTER (value.getter_setter_pair_cp, getter_setter_pair_p); 570425bb815Sopenharmony_ci#else /* !ENABLED (JERRY_CPOINTER_32_BIT) */ 571425bb815Sopenharmony_ci ECMA_SET_POINTER (value.getter_setter_pair.getter_cp, get_p); 572425bb815Sopenharmony_ci ECMA_SET_POINTER (value.getter_setter_pair.setter_cp, set_p); 573425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_CPOINTER_32_BIT) */ 574425bb815Sopenharmony_ci 575425bb815Sopenharmony_ci return ecma_create_property (object_p, name_p, type_and_flags, value, out_prop_p); 576425bb815Sopenharmony_ci} /* ecma_create_named_accessor_property */ 577425bb815Sopenharmony_ci 578425bb815Sopenharmony_ci/** 579425bb815Sopenharmony_ci * Find named data property or named access property in specified object. 580425bb815Sopenharmony_ci * 581425bb815Sopenharmony_ci * @return pointer to the property, if it is found, 582425bb815Sopenharmony_ci * NULL - otherwise. 583425bb815Sopenharmony_ci */ 584425bb815Sopenharmony_ciecma_property_t * 585425bb815Sopenharmony_ciecma_find_named_property (ecma_object_t *obj_p, /**< object to find property in */ 586425bb815Sopenharmony_ci ecma_string_t *name_p) /**< property's name */ 587425bb815Sopenharmony_ci{ 588425bb815Sopenharmony_ci JERRY_ASSERT (obj_p != NULL); 589425bb815Sopenharmony_ci JERRY_ASSERT (name_p != NULL); 590425bb815Sopenharmony_ci JERRY_ASSERT (ecma_is_lexical_environment (obj_p) 591425bb815Sopenharmony_ci || !ecma_op_object_is_fast_array (obj_p)); 592425bb815Sopenharmony_ci 593425bb815Sopenharmony_ci ecma_property_t *property_p = NULL; 594425bb815Sopenharmony_ci 595425bb815Sopenharmony_ci#if ENABLED (JERRY_LCACHE) 596425bb815Sopenharmony_ci property_p = ecma_lcache_lookup (obj_p, name_p); 597425bb815Sopenharmony_ci if (property_p != NULL) 598425bb815Sopenharmony_ci { 599425bb815Sopenharmony_ci return property_p; 600425bb815Sopenharmony_ci } 601425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_LCACHE) */ 602425bb815Sopenharmony_ci 603425bb815Sopenharmony_ci jmem_cpointer_t prop_iter_cp = obj_p->u1.property_list_cp; 604425bb815Sopenharmony_ci 605425bb815Sopenharmony_ci#if ENABLED (JERRY_PROPRETY_HASHMAP) 606425bb815Sopenharmony_ci if (prop_iter_cp != JMEM_CP_NULL) 607425bb815Sopenharmony_ci { 608425bb815Sopenharmony_ci ecma_property_header_t *prop_iter_p = ECMA_GET_NON_NULL_POINTER (ecma_property_header_t, 609425bb815Sopenharmony_ci prop_iter_cp); 610425bb815Sopenharmony_ci if (prop_iter_p->types[0] == ECMA_PROPERTY_TYPE_HASHMAP) 611425bb815Sopenharmony_ci { 612425bb815Sopenharmony_ci jmem_cpointer_t property_real_name_cp; 613425bb815Sopenharmony_ci property_p = ecma_property_hashmap_find ((ecma_property_hashmap_t *) prop_iter_p, 614425bb815Sopenharmony_ci name_p, 615425bb815Sopenharmony_ci &property_real_name_cp); 616425bb815Sopenharmony_ci#if ENABLED (JERRY_LCACHE) 617425bb815Sopenharmony_ci if (property_p != NULL 618425bb815Sopenharmony_ci && !ecma_is_property_lcached (property_p)) 619425bb815Sopenharmony_ci { 620425bb815Sopenharmony_ci ecma_lcache_insert (obj_p, property_real_name_cp, property_p); 621425bb815Sopenharmony_ci } 622425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_LCACHE) */ 623425bb815Sopenharmony_ci return property_p; 624425bb815Sopenharmony_ci } 625425bb815Sopenharmony_ci } 626425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_PROPRETY_HASHMAP) */ 627425bb815Sopenharmony_ci 628425bb815Sopenharmony_ci#if ENABLED (JERRY_PROPRETY_HASHMAP) 629425bb815Sopenharmony_ci uint32_t steps = 0; 630425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_PROPRETY_HASHMAP) */ 631425bb815Sopenharmony_ci jmem_cpointer_t property_name_cp = ECMA_NULL_POINTER; 632425bb815Sopenharmony_ci 633425bb815Sopenharmony_ci if (ECMA_IS_DIRECT_STRING (name_p)) 634425bb815Sopenharmony_ci { 635425bb815Sopenharmony_ci ecma_property_t prop_name_type = (ecma_property_t) ECMA_GET_DIRECT_STRING_TYPE (name_p); 636425bb815Sopenharmony_ci property_name_cp = (jmem_cpointer_t) ECMA_GET_DIRECT_STRING_VALUE (name_p); 637425bb815Sopenharmony_ci 638425bb815Sopenharmony_ci JERRY_ASSERT (prop_name_type > 0); 639425bb815Sopenharmony_ci 640425bb815Sopenharmony_ci while (prop_iter_cp != JMEM_CP_NULL) 641425bb815Sopenharmony_ci { 642425bb815Sopenharmony_ci ecma_property_header_t *prop_iter_p = ECMA_GET_NON_NULL_POINTER (ecma_property_header_t, 643425bb815Sopenharmony_ci prop_iter_cp); 644425bb815Sopenharmony_ci 645425bb815Sopenharmony_ci JERRY_ASSERT (ECMA_PROPERTY_IS_PROPERTY_PAIR (prop_iter_p)); 646425bb815Sopenharmony_ci 647425bb815Sopenharmony_ci ecma_property_pair_t *prop_pair_p = (ecma_property_pair_t *) prop_iter_p; 648425bb815Sopenharmony_ci 649425bb815Sopenharmony_ci if (prop_pair_p->names_cp[0] == property_name_cp 650425bb815Sopenharmony_ci && ECMA_PROPERTY_GET_NAME_TYPE (prop_iter_p->types[0]) == prop_name_type) 651425bb815Sopenharmony_ci { 652425bb815Sopenharmony_ci JERRY_ASSERT (ECMA_PROPERTY_IS_NAMED_PROPERTY (prop_iter_p->types[0])); 653425bb815Sopenharmony_ci 654425bb815Sopenharmony_ci property_p = prop_iter_p->types + 0; 655425bb815Sopenharmony_ci break; 656425bb815Sopenharmony_ci } 657425bb815Sopenharmony_ci 658425bb815Sopenharmony_ci if (prop_pair_p->names_cp[1] == property_name_cp 659425bb815Sopenharmony_ci && ECMA_PROPERTY_GET_NAME_TYPE (prop_iter_p->types[1]) == prop_name_type) 660425bb815Sopenharmony_ci { 661425bb815Sopenharmony_ci JERRY_ASSERT (ECMA_PROPERTY_IS_NAMED_PROPERTY (prop_iter_p->types[1])); 662425bb815Sopenharmony_ci 663425bb815Sopenharmony_ci property_p = prop_iter_p->types + 1; 664425bb815Sopenharmony_ci break; 665425bb815Sopenharmony_ci } 666425bb815Sopenharmony_ci 667425bb815Sopenharmony_ci#if ENABLED (JERRY_PROPRETY_HASHMAP) 668425bb815Sopenharmony_ci steps++; 669425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_PROPRETY_HASHMAP) */ 670425bb815Sopenharmony_ci prop_iter_cp = prop_iter_p->next_property_cp; 671425bb815Sopenharmony_ci } 672425bb815Sopenharmony_ci } 673425bb815Sopenharmony_ci else 674425bb815Sopenharmony_ci { 675425bb815Sopenharmony_ci while (prop_iter_cp != JMEM_CP_NULL) 676425bb815Sopenharmony_ci { 677425bb815Sopenharmony_ci ecma_property_header_t *prop_iter_p = ECMA_GET_NON_NULL_POINTER (ecma_property_header_t, 678425bb815Sopenharmony_ci prop_iter_cp); 679425bb815Sopenharmony_ci 680425bb815Sopenharmony_ci JERRY_ASSERT (ECMA_PROPERTY_IS_PROPERTY_PAIR (prop_iter_p)); 681425bb815Sopenharmony_ci 682425bb815Sopenharmony_ci ecma_property_pair_t *prop_pair_p = (ecma_property_pair_t *) prop_iter_p; 683425bb815Sopenharmony_ci 684425bb815Sopenharmony_ci if (ECMA_PROPERTY_GET_NAME_TYPE (prop_iter_p->types[0]) == ECMA_DIRECT_STRING_PTR) 685425bb815Sopenharmony_ci { 686425bb815Sopenharmony_ci property_name_cp = prop_pair_p->names_cp[0]; 687425bb815Sopenharmony_ci ecma_string_t *prop_name_p = ECMA_GET_NON_NULL_POINTER (ecma_string_t, property_name_cp); 688425bb815Sopenharmony_ci 689425bb815Sopenharmony_ci if (ecma_compare_ecma_non_direct_strings (name_p, prop_name_p)) 690425bb815Sopenharmony_ci { 691425bb815Sopenharmony_ci property_p = prop_iter_p->types + 0; 692425bb815Sopenharmony_ci break; 693425bb815Sopenharmony_ci } 694425bb815Sopenharmony_ci } 695425bb815Sopenharmony_ci 696425bb815Sopenharmony_ci if (ECMA_PROPERTY_GET_NAME_TYPE (prop_iter_p->types[1]) == ECMA_DIRECT_STRING_PTR) 697425bb815Sopenharmony_ci { 698425bb815Sopenharmony_ci property_name_cp = prop_pair_p->names_cp[1]; 699425bb815Sopenharmony_ci ecma_string_t *prop_name_p = ECMA_GET_NON_NULL_POINTER (ecma_string_t, property_name_cp); 700425bb815Sopenharmony_ci 701425bb815Sopenharmony_ci if (ecma_compare_ecma_non_direct_strings (name_p, prop_name_p)) 702425bb815Sopenharmony_ci { 703425bb815Sopenharmony_ci property_p = prop_iter_p->types + 1; 704425bb815Sopenharmony_ci break; 705425bb815Sopenharmony_ci } 706425bb815Sopenharmony_ci } 707425bb815Sopenharmony_ci 708425bb815Sopenharmony_ci#if ENABLED (JERRY_PROPRETY_HASHMAP) 709425bb815Sopenharmony_ci steps++; 710425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_PROPRETY_HASHMAP) */ 711425bb815Sopenharmony_ci prop_iter_cp = prop_iter_p->next_property_cp; 712425bb815Sopenharmony_ci } 713425bb815Sopenharmony_ci } 714425bb815Sopenharmony_ci 715425bb815Sopenharmony_ci#if ENABLED (JERRY_PROPRETY_HASHMAP) 716425bb815Sopenharmony_ci if (steps >= (ECMA_PROPERTY_HASMAP_MINIMUM_SIZE / 2)) 717425bb815Sopenharmony_ci { 718425bb815Sopenharmony_ci ecma_property_hashmap_create (obj_p); 719425bb815Sopenharmony_ci } 720425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_PROPRETY_HASHMAP) */ 721425bb815Sopenharmony_ci 722425bb815Sopenharmony_ci#if ENABLED (JERRY_LCACHE) 723425bb815Sopenharmony_ci if (property_p != NULL 724425bb815Sopenharmony_ci && !ecma_is_property_lcached (property_p)) 725425bb815Sopenharmony_ci { 726425bb815Sopenharmony_ci ecma_lcache_insert (obj_p, property_name_cp, property_p); 727425bb815Sopenharmony_ci } 728425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_LCACHE) */ 729425bb815Sopenharmony_ci 730425bb815Sopenharmony_ci return property_p; 731425bb815Sopenharmony_ci} /* ecma_find_named_property */ 732425bb815Sopenharmony_ci 733425bb815Sopenharmony_ci/** 734425bb815Sopenharmony_ci * Get named data property or named access property in specified object. 735425bb815Sopenharmony_ci * 736425bb815Sopenharmony_ci * Warning: 737425bb815Sopenharmony_ci * the property must exist 738425bb815Sopenharmony_ci * 739425bb815Sopenharmony_ci * @return pointer to the property, if it is found, 740425bb815Sopenharmony_ci * NULL - otherwise. 741425bb815Sopenharmony_ci */ 742425bb815Sopenharmony_ciecma_property_value_t * 743425bb815Sopenharmony_ciecma_get_named_data_property (ecma_object_t *obj_p, /**< object to find property in */ 744425bb815Sopenharmony_ci ecma_string_t *name_p) /**< property's name */ 745425bb815Sopenharmony_ci{ 746425bb815Sopenharmony_ci JERRY_ASSERT (obj_p != NULL); 747425bb815Sopenharmony_ci JERRY_ASSERT (name_p != NULL); 748425bb815Sopenharmony_ci JERRY_ASSERT (ecma_is_lexical_environment (obj_p) 749425bb815Sopenharmony_ci || !ecma_op_object_is_fast_array (obj_p)); 750425bb815Sopenharmony_ci 751425bb815Sopenharmony_ci ecma_property_t *property_p = ecma_find_named_property (obj_p, name_p); 752425bb815Sopenharmony_ci 753425bb815Sopenharmony_ci JERRY_ASSERT (property_p != NULL 754425bb815Sopenharmony_ci && ECMA_PROPERTY_GET_TYPE (*property_p) == ECMA_PROPERTY_TYPE_NAMEDDATA); 755425bb815Sopenharmony_ci 756425bb815Sopenharmony_ci return ECMA_PROPERTY_VALUE_PTR (property_p); 757425bb815Sopenharmony_ci} /* ecma_get_named_data_property */ 758425bb815Sopenharmony_ci 759425bb815Sopenharmony_ci/** 760425bb815Sopenharmony_ci * Free property values and change their type to deleted. 761425bb815Sopenharmony_ci */ 762425bb815Sopenharmony_civoid 763425bb815Sopenharmony_ciecma_free_property (ecma_object_t *object_p, /**< object the property belongs to */ 764425bb815Sopenharmony_ci jmem_cpointer_t name_cp, /**< name of the property or ECMA_NULL_POINTER */ 765425bb815Sopenharmony_ci ecma_property_t *property_p) /**< property */ 766425bb815Sopenharmony_ci{ 767425bb815Sopenharmony_ci JERRY_ASSERT (object_p != NULL && property_p != NULL); 768425bb815Sopenharmony_ci 769425bb815Sopenharmony_ci switch (ECMA_PROPERTY_GET_TYPE (*property_p)) 770425bb815Sopenharmony_ci { 771425bb815Sopenharmony_ci case ECMA_PROPERTY_TYPE_NAMEDDATA: 772425bb815Sopenharmony_ci { 773425bb815Sopenharmony_ci ecma_free_value_if_not_object (ECMA_PROPERTY_VALUE_PTR (property_p)->value); 774425bb815Sopenharmony_ci break; 775425bb815Sopenharmony_ci } 776425bb815Sopenharmony_ci case ECMA_PROPERTY_TYPE_NAMEDACCESSOR: 777425bb815Sopenharmony_ci { 778425bb815Sopenharmony_ci#if ENABLED (JERRY_CPOINTER_32_BIT) 779425bb815Sopenharmony_ci ecma_getter_setter_pointers_t *getter_setter_pair_p; 780425bb815Sopenharmony_ci getter_setter_pair_p = ECMA_GET_NON_NULL_POINTER (ecma_getter_setter_pointers_t, 781425bb815Sopenharmony_ci ECMA_PROPERTY_VALUE_PTR (property_p)->getter_setter_pair_cp); 782425bb815Sopenharmony_ci jmem_pools_free (getter_setter_pair_p, sizeof (ecma_getter_setter_pointers_t)); 783425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_CPOINTER_32_BIT) */ 784425bb815Sopenharmony_ci break; 785425bb815Sopenharmony_ci } 786425bb815Sopenharmony_ci default: 787425bb815Sopenharmony_ci { 788425bb815Sopenharmony_ci JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (*property_p) == ECMA_PROPERTY_TYPE_INTERNAL); 789425bb815Sopenharmony_ci 790425bb815Sopenharmony_ci /* Must be a native pointer. */ 791425bb815Sopenharmony_ci JERRY_ASSERT (ECMA_PROPERTY_GET_NAME_TYPE (*property_p) == ECMA_DIRECT_STRING_MAGIC 792425bb815Sopenharmony_ci && name_cp >= LIT_FIRST_INTERNAL_MAGIC_STRING); 793425bb815Sopenharmony_ci break; 794425bb815Sopenharmony_ci } 795425bb815Sopenharmony_ci } 796425bb815Sopenharmony_ci 797425bb815Sopenharmony_ci#if ENABLED (JERRY_LCACHE) 798425bb815Sopenharmony_ci if (ecma_is_property_lcached (property_p)) 799425bb815Sopenharmony_ci { 800425bb815Sopenharmony_ci ecma_lcache_invalidate (object_p, name_cp, property_p); 801425bb815Sopenharmony_ci } 802425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_LCACHE) */ 803425bb815Sopenharmony_ci 804425bb815Sopenharmony_ci if (ECMA_PROPERTY_GET_NAME_TYPE (*property_p) == ECMA_DIRECT_STRING_PTR) 805425bb815Sopenharmony_ci { 806425bb815Sopenharmony_ci ecma_string_t *prop_name_p = ECMA_GET_NON_NULL_POINTER (ecma_string_t, name_cp); 807425bb815Sopenharmony_ci ecma_deref_ecma_string (prop_name_p); 808425bb815Sopenharmony_ci } 809425bb815Sopenharmony_ci} /* ecma_free_property */ 810425bb815Sopenharmony_ci 811425bb815Sopenharmony_ci/** 812425bb815Sopenharmony_ci * Delete the object's property referenced by its value pointer. 813425bb815Sopenharmony_ci * 814425bb815Sopenharmony_ci * Note: specified property must be owned by specified object. 815425bb815Sopenharmony_ci */ 816425bb815Sopenharmony_civoid 817425bb815Sopenharmony_ciecma_delete_property (ecma_object_t *object_p, /**< object */ 818425bb815Sopenharmony_ci ecma_property_value_t *prop_value_p) /**< property value reference */ 819425bb815Sopenharmony_ci{ 820425bb815Sopenharmony_ci jmem_cpointer_t cur_prop_cp = object_p->u1.property_list_cp; 821425bb815Sopenharmony_ci 822425bb815Sopenharmony_ci ecma_property_header_t *prev_prop_p = NULL; 823425bb815Sopenharmony_ci 824425bb815Sopenharmony_ci#if ENABLED (JERRY_PROPRETY_HASHMAP) 825425bb815Sopenharmony_ci ecma_property_hashmap_delete_status hashmap_status = ECMA_PROPERTY_HASHMAP_DELETE_NO_HASHMAP; 826425bb815Sopenharmony_ci 827425bb815Sopenharmony_ci if (cur_prop_cp != JMEM_CP_NULL) 828425bb815Sopenharmony_ci { 829425bb815Sopenharmony_ci ecma_property_header_t *cur_prop_p = ECMA_GET_NON_NULL_POINTER (ecma_property_header_t, 830425bb815Sopenharmony_ci cur_prop_cp); 831425bb815Sopenharmony_ci 832425bb815Sopenharmony_ci if (cur_prop_p->types[0] == ECMA_PROPERTY_TYPE_HASHMAP) 833425bb815Sopenharmony_ci { 834425bb815Sopenharmony_ci prev_prop_p = cur_prop_p; 835425bb815Sopenharmony_ci cur_prop_cp = cur_prop_p->next_property_cp; 836425bb815Sopenharmony_ci hashmap_status = ECMA_PROPERTY_HASHMAP_DELETE_HAS_HASHMAP; 837425bb815Sopenharmony_ci } 838425bb815Sopenharmony_ci } 839425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_PROPRETY_HASHMAP) */ 840425bb815Sopenharmony_ci 841425bb815Sopenharmony_ci while (cur_prop_cp != JMEM_CP_NULL) 842425bb815Sopenharmony_ci { 843425bb815Sopenharmony_ci ecma_property_header_t *cur_prop_p = ECMA_GET_NON_NULL_POINTER (ecma_property_header_t, 844425bb815Sopenharmony_ci cur_prop_cp); 845425bb815Sopenharmony_ci 846425bb815Sopenharmony_ci JERRY_ASSERT (ECMA_PROPERTY_IS_PROPERTY_PAIR (cur_prop_p)); 847425bb815Sopenharmony_ci 848425bb815Sopenharmony_ci ecma_property_pair_t *prop_pair_p = (ecma_property_pair_t *) cur_prop_p; 849425bb815Sopenharmony_ci 850425bb815Sopenharmony_ci for (int i = 0; i < ECMA_PROPERTY_PAIR_ITEM_COUNT; i++) 851425bb815Sopenharmony_ci { 852425bb815Sopenharmony_ci if ((prop_pair_p->values + i) == prop_value_p) 853425bb815Sopenharmony_ci { 854425bb815Sopenharmony_ci JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (cur_prop_p->types[i]) != ECMA_PROPERTY_TYPE_SPECIAL); 855425bb815Sopenharmony_ci 856425bb815Sopenharmony_ci#if ENABLED (JERRY_PROPRETY_HASHMAP) 857425bb815Sopenharmony_ci if (hashmap_status == ECMA_PROPERTY_HASHMAP_DELETE_HAS_HASHMAP) 858425bb815Sopenharmony_ci { 859425bb815Sopenharmony_ci hashmap_status = ecma_property_hashmap_delete (object_p, 860425bb815Sopenharmony_ci prop_pair_p->names_cp[i], 861425bb815Sopenharmony_ci cur_prop_p->types + i); 862425bb815Sopenharmony_ci } 863425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_PROPRETY_HASHMAP) */ 864425bb815Sopenharmony_ci 865425bb815Sopenharmony_ci ecma_free_property (object_p, prop_pair_p->names_cp[i], cur_prop_p->types + i); 866425bb815Sopenharmony_ci cur_prop_p->types[i] = ECMA_PROPERTY_TYPE_DELETED; 867425bb815Sopenharmony_ci prop_pair_p->names_cp[i] = LIT_INTERNAL_MAGIC_STRING_DELETED; 868425bb815Sopenharmony_ci 869425bb815Sopenharmony_ci JERRY_ASSERT (ECMA_PROPERTY_PAIR_ITEM_COUNT == 2); 870425bb815Sopenharmony_ci 871425bb815Sopenharmony_ci if (cur_prop_p->types[1 - i] != ECMA_PROPERTY_TYPE_DELETED) 872425bb815Sopenharmony_ci { 873425bb815Sopenharmony_ci#if ENABLED (JERRY_PROPRETY_HASHMAP) 874425bb815Sopenharmony_ci /* The other property is still valid. */ 875425bb815Sopenharmony_ci if (hashmap_status == ECMA_PROPERTY_HASHMAP_DELETE_RECREATE_HASHMAP) 876425bb815Sopenharmony_ci { 877425bb815Sopenharmony_ci ecma_property_hashmap_free (object_p); 878425bb815Sopenharmony_ci ecma_property_hashmap_create (object_p); 879425bb815Sopenharmony_ci } 880425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_PROPRETY_HASHMAP) */ 881425bb815Sopenharmony_ci return; 882425bb815Sopenharmony_ci } 883425bb815Sopenharmony_ci 884425bb815Sopenharmony_ci JERRY_ASSERT (cur_prop_p->types[i] == ECMA_PROPERTY_TYPE_DELETED); 885425bb815Sopenharmony_ci 886425bb815Sopenharmony_ci if (prev_prop_p == NULL) 887425bb815Sopenharmony_ci { 888425bb815Sopenharmony_ci object_p->u1.property_list_cp = cur_prop_p->next_property_cp; 889425bb815Sopenharmony_ci } 890425bb815Sopenharmony_ci else 891425bb815Sopenharmony_ci { 892425bb815Sopenharmony_ci prev_prop_p->next_property_cp = cur_prop_p->next_property_cp; 893425bb815Sopenharmony_ci } 894425bb815Sopenharmony_ci 895425bb815Sopenharmony_ci ecma_dealloc_property_pair ((ecma_property_pair_t *) cur_prop_p); 896425bb815Sopenharmony_ci 897425bb815Sopenharmony_ci#if ENABLED (JERRY_PROPRETY_HASHMAP) 898425bb815Sopenharmony_ci if (hashmap_status == ECMA_PROPERTY_HASHMAP_DELETE_RECREATE_HASHMAP) 899425bb815Sopenharmony_ci { 900425bb815Sopenharmony_ci ecma_property_hashmap_free (object_p); 901425bb815Sopenharmony_ci ecma_property_hashmap_create (object_p); 902425bb815Sopenharmony_ci } 903425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_PROPRETY_HASHMAP) */ 904425bb815Sopenharmony_ci return; 905425bb815Sopenharmony_ci } 906425bb815Sopenharmony_ci } 907425bb815Sopenharmony_ci 908425bb815Sopenharmony_ci prev_prop_p = cur_prop_p; 909425bb815Sopenharmony_ci cur_prop_cp = cur_prop_p->next_property_cp; 910425bb815Sopenharmony_ci } 911425bb815Sopenharmony_ci} /* ecma_delete_property */ 912425bb815Sopenharmony_ci 913425bb815Sopenharmony_ci/** 914425bb815Sopenharmony_ci * Check whether the object contains a property 915425bb815Sopenharmony_ci */ 916425bb815Sopenharmony_cistatic void 917425bb815Sopenharmony_ciecma_assert_object_contains_the_property (const ecma_object_t *object_p, /**< ecma-object */ 918425bb815Sopenharmony_ci const ecma_property_value_t *prop_value_p, /**< property value */ 919425bb815Sopenharmony_ci ecma_property_types_t type) /**< expected property type */ 920425bb815Sopenharmony_ci{ 921425bb815Sopenharmony_ci#ifndef JERRY_NDEBUG 922425bb815Sopenharmony_ci jmem_cpointer_t prop_iter_cp = object_p->u1.property_list_cp; 923425bb815Sopenharmony_ci JERRY_ASSERT (prop_iter_cp != JMEM_CP_NULL); 924425bb815Sopenharmony_ci 925425bb815Sopenharmony_ci ecma_property_header_t *prop_iter_p = ECMA_GET_NON_NULL_POINTER (ecma_property_header_t, prop_iter_cp); 926425bb815Sopenharmony_ci 927425bb815Sopenharmony_ci if (prop_iter_p->types[0] == ECMA_PROPERTY_TYPE_HASHMAP) 928425bb815Sopenharmony_ci { 929425bb815Sopenharmony_ci prop_iter_cp = prop_iter_p->next_property_cp; 930425bb815Sopenharmony_ci } 931425bb815Sopenharmony_ci 932425bb815Sopenharmony_ci while (prop_iter_cp != JMEM_CP_NULL) 933425bb815Sopenharmony_ci { 934425bb815Sopenharmony_ci prop_iter_p = ECMA_GET_NON_NULL_POINTER (ecma_property_header_t, prop_iter_cp); 935425bb815Sopenharmony_ci 936425bb815Sopenharmony_ci JERRY_ASSERT (ECMA_PROPERTY_IS_PROPERTY_PAIR (prop_iter_p)); 937425bb815Sopenharmony_ci 938425bb815Sopenharmony_ci ecma_property_pair_t *prop_pair_p = (ecma_property_pair_t *) prop_iter_p; 939425bb815Sopenharmony_ci 940425bb815Sopenharmony_ci for (int i = 0; i < ECMA_PROPERTY_PAIR_ITEM_COUNT; i++) 941425bb815Sopenharmony_ci { 942425bb815Sopenharmony_ci if ((prop_pair_p->values + i) == prop_value_p) 943425bb815Sopenharmony_ci { 944425bb815Sopenharmony_ci JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (prop_pair_p->header.types[i]) == type); 945425bb815Sopenharmony_ci return; 946425bb815Sopenharmony_ci } 947425bb815Sopenharmony_ci } 948425bb815Sopenharmony_ci 949425bb815Sopenharmony_ci prop_iter_cp = prop_iter_p->next_property_cp; 950425bb815Sopenharmony_ci } 951425bb815Sopenharmony_ci#else /* JERRY_NDEBUG */ 952425bb815Sopenharmony_ci JERRY_UNUSED (object_p); 953425bb815Sopenharmony_ci JERRY_UNUSED (prop_value_p); 954425bb815Sopenharmony_ci JERRY_UNUSED (type); 955425bb815Sopenharmony_ci#endif /* !JERRY_NDEBUG */ 956425bb815Sopenharmony_ci} /* ecma_assert_object_contains_the_property */ 957425bb815Sopenharmony_ci 958425bb815Sopenharmony_ci/** 959425bb815Sopenharmony_ci * Assign value to named data property 960425bb815Sopenharmony_ci * 961425bb815Sopenharmony_ci * Note: 962425bb815Sopenharmony_ci * value previously stored in the property is freed 963425bb815Sopenharmony_ci */ 964425bb815Sopenharmony_ciinline void JERRY_ATTR_ALWAYS_INLINE 965425bb815Sopenharmony_ciecma_named_data_property_assign_value (ecma_object_t *obj_p, /**< object */ 966425bb815Sopenharmony_ci ecma_property_value_t *prop_value_p, /**< property value reference */ 967425bb815Sopenharmony_ci ecma_value_t value) /**< value to assign */ 968425bb815Sopenharmony_ci{ 969425bb815Sopenharmony_ci ecma_assert_object_contains_the_property (obj_p, prop_value_p, ECMA_PROPERTY_TYPE_NAMEDDATA); 970425bb815Sopenharmony_ci 971425bb815Sopenharmony_ci ecma_value_assign_value (&prop_value_p->value, value); 972425bb815Sopenharmony_ci} /* ecma_named_data_property_assign_value */ 973425bb815Sopenharmony_ci 974425bb815Sopenharmony_ci/** 975425bb815Sopenharmony_ci * Get named accessor property getter-setter-pair 976425bb815Sopenharmony_ci * 977425bb815Sopenharmony_ci * @return pointer to object's getter-setter pair 978425bb815Sopenharmony_ci */ 979425bb815Sopenharmony_ciecma_getter_setter_pointers_t * 980425bb815Sopenharmony_ciecma_get_named_accessor_property (const ecma_property_value_t *prop_value_p) /**< property value reference */ 981425bb815Sopenharmony_ci{ 982425bb815Sopenharmony_ci#if ENABLED (JERRY_CPOINTER_32_BIT) 983425bb815Sopenharmony_ci return ECMA_GET_NON_NULL_POINTER (ecma_getter_setter_pointers_t, prop_value_p->getter_setter_pair_cp); 984425bb815Sopenharmony_ci#else /* !ENABLED (JERRY_CPOINTER_32_BIT) */ 985425bb815Sopenharmony_ci return (ecma_getter_setter_pointers_t *) &prop_value_p->getter_setter_pair; 986425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_CPOINTER_32_BIT) */ 987425bb815Sopenharmony_ci} /* ecma_get_named_accessor_property */ 988425bb815Sopenharmony_ci 989425bb815Sopenharmony_ci/** 990425bb815Sopenharmony_ci * Set getter of named accessor property 991425bb815Sopenharmony_ci */ 992425bb815Sopenharmony_civoid 993425bb815Sopenharmony_ciecma_set_named_accessor_property_getter (ecma_object_t *object_p, /**< the property's container */ 994425bb815Sopenharmony_ci ecma_property_value_t *prop_value_p, /**< property value reference */ 995425bb815Sopenharmony_ci ecma_object_t *getter_p) /**< getter object */ 996425bb815Sopenharmony_ci{ 997425bb815Sopenharmony_ci ecma_assert_object_contains_the_property (object_p, prop_value_p, ECMA_PROPERTY_TYPE_NAMEDACCESSOR); 998425bb815Sopenharmony_ci 999425bb815Sopenharmony_ci#if ENABLED (JERRY_CPOINTER_32_BIT) 1000425bb815Sopenharmony_ci ecma_getter_setter_pointers_t *getter_setter_pair_p; 1001425bb815Sopenharmony_ci getter_setter_pair_p = ECMA_GET_NON_NULL_POINTER (ecma_getter_setter_pointers_t, 1002425bb815Sopenharmony_ci prop_value_p->getter_setter_pair_cp); 1003425bb815Sopenharmony_ci ECMA_SET_POINTER (getter_setter_pair_p->getter_cp, getter_p); 1004425bb815Sopenharmony_ci#else /* !ENABLED (JERRY_CPOINTER_32_BIT) */ 1005425bb815Sopenharmony_ci ECMA_SET_POINTER (prop_value_p->getter_setter_pair.getter_cp, getter_p); 1006425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_CPOINTER_32_BIT) */ 1007425bb815Sopenharmony_ci} /* ecma_set_named_accessor_property_getter */ 1008425bb815Sopenharmony_ci 1009425bb815Sopenharmony_ci/** 1010425bb815Sopenharmony_ci * Set setter of named accessor property 1011425bb815Sopenharmony_ci */ 1012425bb815Sopenharmony_civoid 1013425bb815Sopenharmony_ciecma_set_named_accessor_property_setter (ecma_object_t *object_p, /**< the property's container */ 1014425bb815Sopenharmony_ci ecma_property_value_t *prop_value_p, /**< property value reference */ 1015425bb815Sopenharmony_ci ecma_object_t *setter_p) /**< setter object */ 1016425bb815Sopenharmony_ci{ 1017425bb815Sopenharmony_ci ecma_assert_object_contains_the_property (object_p, prop_value_p, ECMA_PROPERTY_TYPE_NAMEDACCESSOR); 1018425bb815Sopenharmony_ci 1019425bb815Sopenharmony_ci#if ENABLED (JERRY_CPOINTER_32_BIT) 1020425bb815Sopenharmony_ci ecma_getter_setter_pointers_t *getter_setter_pair_p; 1021425bb815Sopenharmony_ci getter_setter_pair_p = ECMA_GET_NON_NULL_POINTER (ecma_getter_setter_pointers_t, 1022425bb815Sopenharmony_ci prop_value_p->getter_setter_pair_cp); 1023425bb815Sopenharmony_ci ECMA_SET_POINTER (getter_setter_pair_p->setter_cp, setter_p); 1024425bb815Sopenharmony_ci#else /* !ENABLED (JERRY_CPOINTER_32_BIT) */ 1025425bb815Sopenharmony_ci ECMA_SET_POINTER (prop_value_p->getter_setter_pair.setter_cp, setter_p); 1026425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_CPOINTER_32_BIT) */ 1027425bb815Sopenharmony_ci} /* ecma_set_named_accessor_property_setter */ 1028425bb815Sopenharmony_ci 1029425bb815Sopenharmony_ci/** 1030425bb815Sopenharmony_ci * Get property's 'Writable' attribute value 1031425bb815Sopenharmony_ci * 1032425bb815Sopenharmony_ci * @return true - property is writable, 1033425bb815Sopenharmony_ci * false - otherwise 1034425bb815Sopenharmony_ci */ 1035425bb815Sopenharmony_ciinline bool JERRY_ATTR_ALWAYS_INLINE 1036425bb815Sopenharmony_ciecma_is_property_writable (ecma_property_t property) /**< property */ 1037425bb815Sopenharmony_ci{ 1038425bb815Sopenharmony_ci JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (property) == ECMA_PROPERTY_TYPE_NAMEDDATA 1039425bb815Sopenharmony_ci || ECMA_PROPERTY_GET_TYPE (property) == ECMA_PROPERTY_TYPE_VIRTUAL); 1040425bb815Sopenharmony_ci 1041425bb815Sopenharmony_ci return (property & ECMA_PROPERTY_FLAG_WRITABLE) != 0; 1042425bb815Sopenharmony_ci} /* ecma_is_property_writable */ 1043425bb815Sopenharmony_ci 1044425bb815Sopenharmony_ci/** 1045425bb815Sopenharmony_ci * Set property's 'Writable' attribute value 1046425bb815Sopenharmony_ci */ 1047425bb815Sopenharmony_civoid 1048425bb815Sopenharmony_ciecma_set_property_writable_attr (ecma_property_t *property_p, /**< [in,out] property */ 1049425bb815Sopenharmony_ci bool is_writable) /**< new value for writable flag */ 1050425bb815Sopenharmony_ci{ 1051425bb815Sopenharmony_ci JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (*property_p) == ECMA_PROPERTY_TYPE_NAMEDDATA); 1052425bb815Sopenharmony_ci 1053425bb815Sopenharmony_ci if (is_writable) 1054425bb815Sopenharmony_ci { 1055425bb815Sopenharmony_ci *property_p = (uint8_t) (*property_p | ECMA_PROPERTY_FLAG_WRITABLE); 1056425bb815Sopenharmony_ci } 1057425bb815Sopenharmony_ci else 1058425bb815Sopenharmony_ci { 1059425bb815Sopenharmony_ci *property_p = (uint8_t) (*property_p & ~ECMA_PROPERTY_FLAG_WRITABLE); 1060425bb815Sopenharmony_ci } 1061425bb815Sopenharmony_ci} /* ecma_set_property_writable_attr */ 1062425bb815Sopenharmony_ci 1063425bb815Sopenharmony_ci/** 1064425bb815Sopenharmony_ci * Get property's 'Enumerable' attribute value 1065425bb815Sopenharmony_ci * 1066425bb815Sopenharmony_ci * @return true - property is enumerable, 1067425bb815Sopenharmony_ci * false - otherwise 1068425bb815Sopenharmony_ci */ 1069425bb815Sopenharmony_ciinline bool JERRY_ATTR_ALWAYS_INLINE 1070425bb815Sopenharmony_ciecma_is_property_enumerable (ecma_property_t property) /**< property */ 1071425bb815Sopenharmony_ci{ 1072425bb815Sopenharmony_ci JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (property) == ECMA_PROPERTY_TYPE_NAMEDDATA 1073425bb815Sopenharmony_ci || ECMA_PROPERTY_GET_TYPE (property) == ECMA_PROPERTY_TYPE_NAMEDACCESSOR 1074425bb815Sopenharmony_ci || ECMA_PROPERTY_GET_TYPE (property) == ECMA_PROPERTY_TYPE_VIRTUAL); 1075425bb815Sopenharmony_ci 1076425bb815Sopenharmony_ci return (property & ECMA_PROPERTY_FLAG_ENUMERABLE) != 0; 1077425bb815Sopenharmony_ci} /* ecma_is_property_enumerable */ 1078425bb815Sopenharmony_ci 1079425bb815Sopenharmony_ci/** 1080425bb815Sopenharmony_ci * Set property's 'Enumerable' attribute value 1081425bb815Sopenharmony_ci */ 1082425bb815Sopenharmony_civoid 1083425bb815Sopenharmony_ciecma_set_property_enumerable_attr (ecma_property_t *property_p, /**< [in,out] property */ 1084425bb815Sopenharmony_ci bool is_enumerable) /**< new value for enumerable flag */ 1085425bb815Sopenharmony_ci{ 1086425bb815Sopenharmony_ci JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (*property_p) == ECMA_PROPERTY_TYPE_NAMEDDATA 1087425bb815Sopenharmony_ci || ECMA_PROPERTY_GET_TYPE (*property_p) == ECMA_PROPERTY_TYPE_NAMEDACCESSOR); 1088425bb815Sopenharmony_ci 1089425bb815Sopenharmony_ci if (is_enumerable) 1090425bb815Sopenharmony_ci { 1091425bb815Sopenharmony_ci *property_p = (uint8_t) (*property_p | ECMA_PROPERTY_FLAG_ENUMERABLE); 1092425bb815Sopenharmony_ci } 1093425bb815Sopenharmony_ci else 1094425bb815Sopenharmony_ci { 1095425bb815Sopenharmony_ci *property_p = (uint8_t) (*property_p & ~ECMA_PROPERTY_FLAG_ENUMERABLE); 1096425bb815Sopenharmony_ci } 1097425bb815Sopenharmony_ci} /* ecma_set_property_enumerable_attr */ 1098425bb815Sopenharmony_ci 1099425bb815Sopenharmony_ci/** 1100425bb815Sopenharmony_ci * Get property's 'Configurable' attribute value 1101425bb815Sopenharmony_ci * 1102425bb815Sopenharmony_ci * @return true - property is configurable, 1103425bb815Sopenharmony_ci * false - otherwise 1104425bb815Sopenharmony_ci */ 1105425bb815Sopenharmony_ciinline bool JERRY_ATTR_ALWAYS_INLINE 1106425bb815Sopenharmony_ciecma_is_property_configurable (ecma_property_t property) /**< property */ 1107425bb815Sopenharmony_ci{ 1108425bb815Sopenharmony_ci JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (property) == ECMA_PROPERTY_TYPE_NAMEDDATA 1109425bb815Sopenharmony_ci || ECMA_PROPERTY_GET_TYPE (property) == ECMA_PROPERTY_TYPE_NAMEDACCESSOR 1110425bb815Sopenharmony_ci || ECMA_PROPERTY_GET_TYPE (property) == ECMA_PROPERTY_TYPE_VIRTUAL); 1111425bb815Sopenharmony_ci 1112425bb815Sopenharmony_ci return (property & ECMA_PROPERTY_FLAG_CONFIGURABLE) != 0; 1113425bb815Sopenharmony_ci} /* ecma_is_property_configurable */ 1114425bb815Sopenharmony_ci 1115425bb815Sopenharmony_ci/** 1116425bb815Sopenharmony_ci * Set property's 'Configurable' attribute value 1117425bb815Sopenharmony_ci */ 1118425bb815Sopenharmony_civoid 1119425bb815Sopenharmony_ciecma_set_property_configurable_attr (ecma_property_t *property_p, /**< [in,out] property */ 1120425bb815Sopenharmony_ci bool is_configurable) /**< new value for configurable flag */ 1121425bb815Sopenharmony_ci{ 1122425bb815Sopenharmony_ci JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (*property_p) == ECMA_PROPERTY_TYPE_NAMEDDATA 1123425bb815Sopenharmony_ci || ECMA_PROPERTY_GET_TYPE (*property_p) == ECMA_PROPERTY_TYPE_NAMEDACCESSOR); 1124425bb815Sopenharmony_ci 1125425bb815Sopenharmony_ci if (is_configurable) 1126425bb815Sopenharmony_ci { 1127425bb815Sopenharmony_ci *property_p = (uint8_t) (*property_p | ECMA_PROPERTY_FLAG_CONFIGURABLE); 1128425bb815Sopenharmony_ci } 1129425bb815Sopenharmony_ci else 1130425bb815Sopenharmony_ci { 1131425bb815Sopenharmony_ci *property_p = (uint8_t) (*property_p & ~ECMA_PROPERTY_FLAG_CONFIGURABLE); 1132425bb815Sopenharmony_ci } 1133425bb815Sopenharmony_ci} /* ecma_set_property_configurable_attr */ 1134425bb815Sopenharmony_ci 1135425bb815Sopenharmony_ci#if ENABLED (JERRY_LCACHE) 1136425bb815Sopenharmony_ci 1137425bb815Sopenharmony_ci/** 1138425bb815Sopenharmony_ci * Check whether the property is registered in LCache 1139425bb815Sopenharmony_ci * 1140425bb815Sopenharmony_ci * @return true / false 1141425bb815Sopenharmony_ci */ 1142425bb815Sopenharmony_ciinline bool JERRY_ATTR_ALWAYS_INLINE 1143425bb815Sopenharmony_ciecma_is_property_lcached (ecma_property_t *property_p) /**< property */ 1144425bb815Sopenharmony_ci{ 1145425bb815Sopenharmony_ci JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (*property_p) == ECMA_PROPERTY_TYPE_NAMEDDATA 1146425bb815Sopenharmony_ci || ECMA_PROPERTY_GET_TYPE (*property_p) == ECMA_PROPERTY_TYPE_NAMEDACCESSOR 1147425bb815Sopenharmony_ci || ECMA_PROPERTY_GET_TYPE (*property_p) == ECMA_PROPERTY_TYPE_INTERNAL); 1148425bb815Sopenharmony_ci 1149425bb815Sopenharmony_ci return (*property_p & ECMA_PROPERTY_FLAG_LCACHED) != 0; 1150425bb815Sopenharmony_ci} /* ecma_is_property_lcached */ 1151425bb815Sopenharmony_ci 1152425bb815Sopenharmony_ci/** 1153425bb815Sopenharmony_ci * Set value of flag indicating whether the property is registered in LCache 1154425bb815Sopenharmony_ci */ 1155425bb815Sopenharmony_ciinline void JERRY_ATTR_ALWAYS_INLINE 1156425bb815Sopenharmony_ciecma_set_property_lcached (ecma_property_t *property_p, /**< property */ 1157425bb815Sopenharmony_ci bool is_lcached) /**< new value for lcached flag */ 1158425bb815Sopenharmony_ci{ 1159425bb815Sopenharmony_ci JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (*property_p) == ECMA_PROPERTY_TYPE_NAMEDDATA 1160425bb815Sopenharmony_ci || ECMA_PROPERTY_GET_TYPE (*property_p) == ECMA_PROPERTY_TYPE_NAMEDACCESSOR 1161425bb815Sopenharmony_ci || ECMA_PROPERTY_GET_TYPE (*property_p) == ECMA_PROPERTY_TYPE_INTERNAL); 1162425bb815Sopenharmony_ci 1163425bb815Sopenharmony_ci if (is_lcached) 1164425bb815Sopenharmony_ci { 1165425bb815Sopenharmony_ci *property_p = (uint8_t) (*property_p | ECMA_PROPERTY_FLAG_LCACHED); 1166425bb815Sopenharmony_ci } 1167425bb815Sopenharmony_ci else 1168425bb815Sopenharmony_ci { 1169425bb815Sopenharmony_ci *property_p = (uint8_t) (*property_p & ~ECMA_PROPERTY_FLAG_LCACHED); 1170425bb815Sopenharmony_ci } 1171425bb815Sopenharmony_ci} /* ecma_set_property_lcached */ 1172425bb815Sopenharmony_ci 1173425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_LCACHE) */ 1174425bb815Sopenharmony_ci 1175425bb815Sopenharmony_ci/** 1176425bb815Sopenharmony_ci * Construct empty property descriptor, i.e.: 1177425bb815Sopenharmony_ci * property descriptor with all is_defined flags set to false and the rest - to default value. 1178425bb815Sopenharmony_ci * 1179425bb815Sopenharmony_ci * @return empty property descriptor 1180425bb815Sopenharmony_ci */ 1181425bb815Sopenharmony_ciecma_property_descriptor_t 1182425bb815Sopenharmony_ciecma_make_empty_property_descriptor (void) 1183425bb815Sopenharmony_ci{ 1184425bb815Sopenharmony_ci ecma_property_descriptor_t prop_desc; 1185425bb815Sopenharmony_ci 1186425bb815Sopenharmony_ci prop_desc.flags = 0; 1187425bb815Sopenharmony_ci prop_desc.value = ECMA_VALUE_UNDEFINED; 1188425bb815Sopenharmony_ci prop_desc.get_p = NULL; 1189425bb815Sopenharmony_ci prop_desc.set_p = NULL; 1190425bb815Sopenharmony_ci 1191425bb815Sopenharmony_ci return prop_desc; 1192425bb815Sopenharmony_ci} /* ecma_make_empty_property_descriptor */ 1193425bb815Sopenharmony_ci 1194425bb815Sopenharmony_ci/** 1195425bb815Sopenharmony_ci * Free values contained in the property descriptor 1196425bb815Sopenharmony_ci * and make it empty property descriptor 1197425bb815Sopenharmony_ci */ 1198425bb815Sopenharmony_civoid 1199425bb815Sopenharmony_ciecma_free_property_descriptor (ecma_property_descriptor_t *prop_desc_p) /**< property descriptor */ 1200425bb815Sopenharmony_ci{ 1201425bb815Sopenharmony_ci if (prop_desc_p->flags & ECMA_PROP_IS_VALUE_DEFINED) 1202425bb815Sopenharmony_ci { 1203425bb815Sopenharmony_ci ecma_free_value (prop_desc_p->value); 1204425bb815Sopenharmony_ci } 1205425bb815Sopenharmony_ci 1206425bb815Sopenharmony_ci if ((prop_desc_p->flags & ECMA_PROP_IS_GET_DEFINED) 1207425bb815Sopenharmony_ci && prop_desc_p->get_p != NULL) 1208425bb815Sopenharmony_ci { 1209425bb815Sopenharmony_ci ecma_deref_object (prop_desc_p->get_p); 1210425bb815Sopenharmony_ci } 1211425bb815Sopenharmony_ci 1212425bb815Sopenharmony_ci if ((prop_desc_p->flags & ECMA_PROP_IS_SET_DEFINED) 1213425bb815Sopenharmony_ci && prop_desc_p->set_p != NULL) 1214425bb815Sopenharmony_ci { 1215425bb815Sopenharmony_ci ecma_deref_object (prop_desc_p->set_p); 1216425bb815Sopenharmony_ci } 1217425bb815Sopenharmony_ci 1218425bb815Sopenharmony_ci *prop_desc_p = ecma_make_empty_property_descriptor (); 1219425bb815Sopenharmony_ci} /* ecma_free_property_descriptor */ 1220425bb815Sopenharmony_ci 1221425bb815Sopenharmony_ci/** 1222425bb815Sopenharmony_ci * The size of error reference must be 8 bytes to use jmem_pools_alloc(). 1223425bb815Sopenharmony_ci */ 1224425bb815Sopenharmony_ciJERRY_STATIC_ASSERT (sizeof (ecma_error_reference_t) == 8, 1225425bb815Sopenharmony_ci ecma_error_reference_size_must_be_8_bytes); 1226425bb815Sopenharmony_ci 1227425bb815Sopenharmony_ci/** 1228425bb815Sopenharmony_ci * Create an error reference from a given value. 1229425bb815Sopenharmony_ci * 1230425bb815Sopenharmony_ci * Note: 1231425bb815Sopenharmony_ci * Reference of the value is taken. 1232425bb815Sopenharmony_ci * 1233425bb815Sopenharmony_ci * @return error reference value 1234425bb815Sopenharmony_ci */ 1235425bb815Sopenharmony_ciecma_value_t 1236425bb815Sopenharmony_ciecma_create_error_reference (ecma_value_t value, /**< referenced value */ 1237425bb815Sopenharmony_ci bool is_exception) /**< error reference is an exception */ 1238425bb815Sopenharmony_ci{ 1239425bb815Sopenharmony_ci ecma_error_reference_t *error_ref_p = (ecma_error_reference_t *) jmem_pools_alloc (sizeof (ecma_error_reference_t)); 1240425bb815Sopenharmony_ci 1241425bb815Sopenharmony_ci error_ref_p->refs_and_flags = ECMA_ERROR_REF_ONE | (is_exception ? 0 : ECMA_ERROR_REF_ABORT); 1242425bb815Sopenharmony_ci error_ref_p->value = value; 1243425bb815Sopenharmony_ci return ecma_make_error_reference_value (error_ref_p); 1244425bb815Sopenharmony_ci} /* ecma_create_error_reference */ 1245425bb815Sopenharmony_ci 1246425bb815Sopenharmony_ci/** 1247425bb815Sopenharmony_ci * Create an error reference from the currently thrown error value. 1248425bb815Sopenharmony_ci * 1249425bb815Sopenharmony_ci * @return error reference value 1250425bb815Sopenharmony_ci */ 1251425bb815Sopenharmony_ciecma_value_t 1252425bb815Sopenharmony_ciecma_create_error_reference_from_context (void) 1253425bb815Sopenharmony_ci{ 1254425bb815Sopenharmony_ci bool is_abort = jcontext_has_pending_abort (); 1255425bb815Sopenharmony_ci 1256425bb815Sopenharmony_ci if (is_abort) 1257425bb815Sopenharmony_ci { 1258425bb815Sopenharmony_ci jcontext_set_abort_flag (false); 1259425bb815Sopenharmony_ci } 1260425bb815Sopenharmony_ci return ecma_create_error_reference (jcontext_take_exception (), !is_abort); 1261425bb815Sopenharmony_ci} /* ecma_create_error_reference_from_context */ 1262425bb815Sopenharmony_ci 1263425bb815Sopenharmony_ci/** 1264425bb815Sopenharmony_ci * Create an error reference from a given object. 1265425bb815Sopenharmony_ci * 1266425bb815Sopenharmony_ci * Note: 1267425bb815Sopenharmony_ci * Reference of the value is taken. 1268425bb815Sopenharmony_ci * 1269425bb815Sopenharmony_ci * @return error reference value 1270425bb815Sopenharmony_ci */ 1271425bb815Sopenharmony_ciinline ecma_value_t JERRY_ATTR_ALWAYS_INLINE 1272425bb815Sopenharmony_ciecma_create_error_object_reference (ecma_object_t *object_p) /**< referenced object */ 1273425bb815Sopenharmony_ci{ 1274425bb815Sopenharmony_ci return ecma_create_error_reference (ecma_make_object_value (object_p), true); 1275425bb815Sopenharmony_ci} /* ecma_create_error_object_reference */ 1276425bb815Sopenharmony_ci 1277425bb815Sopenharmony_ci/** 1278425bb815Sopenharmony_ci * Increase ref count of an error reference. 1279425bb815Sopenharmony_ci */ 1280425bb815Sopenharmony_civoid 1281425bb815Sopenharmony_ciecma_ref_error_reference (ecma_error_reference_t *error_ref_p) /**< error reference */ 1282425bb815Sopenharmony_ci{ 1283425bb815Sopenharmony_ci if (JERRY_LIKELY (error_ref_p->refs_and_flags < ECMA_ERROR_MAX_REF)) 1284425bb815Sopenharmony_ci { 1285425bb815Sopenharmony_ci error_ref_p->refs_and_flags += ECMA_ERROR_REF_ONE; 1286425bb815Sopenharmony_ci } 1287425bb815Sopenharmony_ci else 1288425bb815Sopenharmony_ci { 1289425bb815Sopenharmony_ci jerry_fatal (ERR_REF_COUNT_LIMIT); 1290425bb815Sopenharmony_ci } 1291425bb815Sopenharmony_ci} /* ecma_ref_error_reference */ 1292425bb815Sopenharmony_ci 1293425bb815Sopenharmony_ci/** 1294425bb815Sopenharmony_ci * Decrease ref count of an error reference. 1295425bb815Sopenharmony_ci */ 1296425bb815Sopenharmony_civoid 1297425bb815Sopenharmony_ciecma_deref_error_reference (ecma_error_reference_t *error_ref_p) /**< error reference */ 1298425bb815Sopenharmony_ci{ 1299425bb815Sopenharmony_ci JERRY_ASSERT (error_ref_p->refs_and_flags >= ECMA_ERROR_REF_ONE); 1300425bb815Sopenharmony_ci 1301425bb815Sopenharmony_ci error_ref_p->refs_and_flags -= ECMA_ERROR_REF_ONE; 1302425bb815Sopenharmony_ci 1303425bb815Sopenharmony_ci if (error_ref_p->refs_and_flags < ECMA_ERROR_REF_ONE) 1304425bb815Sopenharmony_ci { 1305425bb815Sopenharmony_ci ecma_free_value (error_ref_p->value); 1306425bb815Sopenharmony_ci jmem_pools_free (error_ref_p, sizeof (ecma_error_reference_t)); 1307425bb815Sopenharmony_ci } 1308425bb815Sopenharmony_ci} /* ecma_deref_error_reference */ 1309425bb815Sopenharmony_ci 1310425bb815Sopenharmony_ci/** 1311425bb815Sopenharmony_ci * Raise error from the given error reference. 1312425bb815Sopenharmony_ci * 1313425bb815Sopenharmony_ci * Note: the error reference's ref count is also decreased 1314425bb815Sopenharmony_ci */ 1315425bb815Sopenharmony_civoid 1316425bb815Sopenharmony_ciecma_raise_error_from_error_reference (ecma_value_t value) /**< error reference */ 1317425bb815Sopenharmony_ci{ 1318425bb815Sopenharmony_ci JERRY_ASSERT (!jcontext_has_pending_exception () && !jcontext_has_pending_abort ()); 1319425bb815Sopenharmony_ci ecma_error_reference_t *error_ref_p = ecma_get_error_reference_from_value (value); 1320425bb815Sopenharmony_ci 1321425bb815Sopenharmony_ci JERRY_ASSERT (error_ref_p->refs_and_flags >= ECMA_ERROR_REF_ONE); 1322425bb815Sopenharmony_ci 1323425bb815Sopenharmony_ci ecma_value_t referenced_value = error_ref_p->value; 1324425bb815Sopenharmony_ci 1325425bb815Sopenharmony_ci jcontext_set_exception_flag (true); 1326425bb815Sopenharmony_ci jcontext_set_abort_flag (error_ref_p->refs_and_flags & ECMA_ERROR_REF_ABORT); 1327425bb815Sopenharmony_ci 1328425bb815Sopenharmony_ci if (error_ref_p->refs_and_flags >= 2 * ECMA_ERROR_REF_ONE) 1329425bb815Sopenharmony_ci { 1330425bb815Sopenharmony_ci error_ref_p->refs_and_flags -= ECMA_ERROR_REF_ONE; 1331425bb815Sopenharmony_ci referenced_value = ecma_copy_value (referenced_value); 1332425bb815Sopenharmony_ci } 1333425bb815Sopenharmony_ci else 1334425bb815Sopenharmony_ci { 1335425bb815Sopenharmony_ci jmem_pools_free (error_ref_p, sizeof (ecma_error_reference_t)); 1336425bb815Sopenharmony_ci } 1337425bb815Sopenharmony_ci 1338425bb815Sopenharmony_ci JERRY_CONTEXT (error_value) = referenced_value; 1339425bb815Sopenharmony_ci} /* ecma_raise_error_from_error_reference */ 1340425bb815Sopenharmony_ci 1341425bb815Sopenharmony_ci/** 1342425bb815Sopenharmony_ci * Increase reference counter of Compact 1343425bb815Sopenharmony_ci * Byte Code or regexp byte code. 1344425bb815Sopenharmony_ci */ 1345425bb815Sopenharmony_civoid 1346425bb815Sopenharmony_ciecma_bytecode_ref (ecma_compiled_code_t *bytecode_p) /**< byte code pointer */ 1347425bb815Sopenharmony_ci{ 1348425bb815Sopenharmony_ci /* Abort program if maximum reference number is reached. */ 1349425bb815Sopenharmony_ci if (bytecode_p->refs >= UINT16_MAX) 1350425bb815Sopenharmony_ci { 1351425bb815Sopenharmony_ci jerry_fatal (ERR_REF_COUNT_LIMIT); 1352425bb815Sopenharmony_ci } 1353425bb815Sopenharmony_ci 1354425bb815Sopenharmony_ci bytecode_p->refs++; 1355425bb815Sopenharmony_ci} /* ecma_bytecode_ref */ 1356425bb815Sopenharmony_ci 1357425bb815Sopenharmony_ci/** 1358425bb815Sopenharmony_ci * Decrease reference counter of Compact 1359425bb815Sopenharmony_ci * Byte Code or regexp byte code. 1360425bb815Sopenharmony_ci */ 1361425bb815Sopenharmony_civoid 1362425bb815Sopenharmony_ciecma_bytecode_deref (ecma_compiled_code_t *bytecode_p) /**< byte code pointer */ 1363425bb815Sopenharmony_ci{ 1364425bb815Sopenharmony_ci JERRY_ASSERT (bytecode_p->refs > 0); 1365425bb815Sopenharmony_ci JERRY_ASSERT (!(bytecode_p->status_flags & CBC_CODE_FLAGS_STATIC_FUNCTION)); 1366425bb815Sopenharmony_ci 1367425bb815Sopenharmony_ci bytecode_p->refs--; 1368425bb815Sopenharmony_ci 1369425bb815Sopenharmony_ci if (bytecode_p->refs > 0) 1370425bb815Sopenharmony_ci { 1371425bb815Sopenharmony_ci /* Non-zero reference counter. */ 1372425bb815Sopenharmony_ci return; 1373425bb815Sopenharmony_ci } 1374425bb815Sopenharmony_ci 1375425bb815Sopenharmony_ci if (bytecode_p->status_flags & CBC_CODE_FLAGS_FUNCTION) 1376425bb815Sopenharmony_ci { 1377425bb815Sopenharmony_ci ecma_value_t *literal_start_p = NULL; 1378425bb815Sopenharmony_ci uint32_t literal_end; 1379425bb815Sopenharmony_ci uint32_t const_literal_end; 1380425bb815Sopenharmony_ci 1381425bb815Sopenharmony_ci if (bytecode_p->status_flags & CBC_CODE_FLAGS_UINT16_ARGUMENTS) 1382425bb815Sopenharmony_ci { 1383425bb815Sopenharmony_ci cbc_uint16_arguments_t *args_p = (cbc_uint16_arguments_t *) bytecode_p; 1384425bb815Sopenharmony_ci literal_end = args_p->literal_end; 1385425bb815Sopenharmony_ci const_literal_end = args_p->const_literal_end; 1386425bb815Sopenharmony_ci 1387425bb815Sopenharmony_ci literal_start_p = (ecma_value_t *) ((uint8_t *) bytecode_p + sizeof (cbc_uint16_arguments_t)); 1388425bb815Sopenharmony_ci literal_start_p -= args_p->register_end; 1389425bb815Sopenharmony_ci } 1390425bb815Sopenharmony_ci else 1391425bb815Sopenharmony_ci { 1392425bb815Sopenharmony_ci cbc_uint8_arguments_t *args_p = (cbc_uint8_arguments_t *) bytecode_p; 1393425bb815Sopenharmony_ci literal_end = args_p->literal_end; 1394425bb815Sopenharmony_ci const_literal_end = args_p->const_literal_end; 1395425bb815Sopenharmony_ci 1396425bb815Sopenharmony_ci literal_start_p = (ecma_value_t *) ((uint8_t *) bytecode_p + sizeof (cbc_uint8_arguments_t)); 1397425bb815Sopenharmony_ci literal_start_p -= args_p->register_end; 1398425bb815Sopenharmony_ci } 1399425bb815Sopenharmony_ci 1400425bb815Sopenharmony_ci for (uint32_t i = const_literal_end; i < literal_end; i++) 1401425bb815Sopenharmony_ci { 1402425bb815Sopenharmony_ci ecma_compiled_code_t *bytecode_literal_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_compiled_code_t, 1403425bb815Sopenharmony_ci literal_start_p[i]); 1404425bb815Sopenharmony_ci 1405425bb815Sopenharmony_ci /* Self references are ignored. */ 1406425bb815Sopenharmony_ci if (bytecode_literal_p != bytecode_p) 1407425bb815Sopenharmony_ci { 1408425bb815Sopenharmony_ci ecma_bytecode_deref (bytecode_literal_p); 1409425bb815Sopenharmony_ci } 1410425bb815Sopenharmony_ci } 1411425bb815Sopenharmony_ci 1412425bb815Sopenharmony_ci#if ENABLED (JERRY_DEBUGGER) 1413425bb815Sopenharmony_ci if ((JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CONNECTED) 1414425bb815Sopenharmony_ci && !(bytecode_p->status_flags & CBC_CODE_FLAGS_DEBUGGER_IGNORE) 1415425bb815Sopenharmony_ci && jerry_debugger_send_function_cp (JERRY_DEBUGGER_RELEASE_BYTE_CODE_CP, bytecode_p)) 1416425bb815Sopenharmony_ci { 1417425bb815Sopenharmony_ci /* Delay the byte code free until the debugger client is notified. 1418425bb815Sopenharmony_ci * If the connection is aborted the pointer is still freed by 1419425bb815Sopenharmony_ci * jerry_debugger_close_connection(). */ 1420425bb815Sopenharmony_ci jerry_debugger_byte_code_free_t *byte_code_free_p = (jerry_debugger_byte_code_free_t *) bytecode_p; 1421425bb815Sopenharmony_ci jmem_cpointer_t byte_code_free_head = JERRY_CONTEXT (debugger_byte_code_free_head); 1422425bb815Sopenharmony_ci 1423425bb815Sopenharmony_ci byte_code_free_p->prev_cp = ECMA_NULL_POINTER; 1424425bb815Sopenharmony_ci 1425425bb815Sopenharmony_ci jmem_cpointer_t byte_code_free_cp; 1426425bb815Sopenharmony_ci JMEM_CP_SET_NON_NULL_POINTER (byte_code_free_cp, byte_code_free_p); 1427425bb815Sopenharmony_ci 1428425bb815Sopenharmony_ci if (byte_code_free_head == ECMA_NULL_POINTER) 1429425bb815Sopenharmony_ci { 1430425bb815Sopenharmony_ci JERRY_CONTEXT (debugger_byte_code_free_tail) = byte_code_free_cp; 1431425bb815Sopenharmony_ci } 1432425bb815Sopenharmony_ci else 1433425bb815Sopenharmony_ci { 1434425bb815Sopenharmony_ci jerry_debugger_byte_code_free_t *first_byte_code_free_p; 1435425bb815Sopenharmony_ci 1436425bb815Sopenharmony_ci first_byte_code_free_p = JMEM_CP_GET_NON_NULL_POINTER (jerry_debugger_byte_code_free_t, 1437425bb815Sopenharmony_ci byte_code_free_head); 1438425bb815Sopenharmony_ci first_byte_code_free_p->prev_cp = byte_code_free_cp; 1439425bb815Sopenharmony_ci } 1440425bb815Sopenharmony_ci 1441425bb815Sopenharmony_ci JERRY_CONTEXT (debugger_byte_code_free_head) = byte_code_free_cp; 1442425bb815Sopenharmony_ci return; 1443425bb815Sopenharmony_ci } 1444425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_DEBUGGER) */ 1445425bb815Sopenharmony_ci 1446425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 1447425bb815Sopenharmony_ci if (bytecode_p->status_flags & CBC_CODE_FLAG_HAS_TAGGED_LITERALS) 1448425bb815Sopenharmony_ci { 1449425bb815Sopenharmony_ci ecma_collection_t *collection_p = ecma_compiled_code_get_tagged_template_collection (bytecode_p); 1450425bb815Sopenharmony_ci 1451425bb815Sopenharmony_ci /* Since the objects in the tagged template collection are not strong referenced anymore by the compiled code 1452425bb815Sopenharmony_ci we can treat them as 'new' objects. */ 1453425bb815Sopenharmony_ci JERRY_CONTEXT (ecma_gc_new_objects) += collection_p->item_count; 1454425bb815Sopenharmony_ci ecma_collection_free (collection_p); 1455425bb815Sopenharmony_ci } 1456425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 1457425bb815Sopenharmony_ci 1458425bb815Sopenharmony_ci#if ENABLED (JERRY_MEM_STATS) 1459425bb815Sopenharmony_ci jmem_stats_free_byte_code_bytes (((size_t) bytecode_p->size) << JMEM_ALIGNMENT_LOG); 1460425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_MEM_STATS) */ 1461425bb815Sopenharmony_ci } 1462425bb815Sopenharmony_ci else 1463425bb815Sopenharmony_ci { 1464425bb815Sopenharmony_ci#if ENABLED (JERRY_BUILTIN_REGEXP) 1465425bb815Sopenharmony_ci re_compiled_code_t *re_bytecode_p = (re_compiled_code_t *) bytecode_p; 1466425bb815Sopenharmony_ci 1467425bb815Sopenharmony_ci ecma_deref_ecma_string (ecma_get_string_from_value (re_bytecode_p->source)); 1468425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_BUILTIN_REGEXP) */ 1469425bb815Sopenharmony_ci } 1470425bb815Sopenharmony_ci 1471425bb815Sopenharmony_ci jmem_heap_free_block (bytecode_p, 1472425bb815Sopenharmony_ci ((size_t) bytecode_p->size) << JMEM_ALIGNMENT_LOG); 1473425bb815Sopenharmony_ci} /* ecma_bytecode_deref */ 1474425bb815Sopenharmony_ci 1475425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 1476425bb815Sopenharmony_ci/** 1477425bb815Sopenharmony_ci * Get the tagged template collection of the compiled code 1478425bb815Sopenharmony_ci * 1479425bb815Sopenharmony_ci * @return pointer to the tagged template collection 1480425bb815Sopenharmony_ci */ 1481425bb815Sopenharmony_ciecma_collection_t * 1482425bb815Sopenharmony_ciecma_compiled_code_get_tagged_template_collection (const ecma_compiled_code_t *bytecode_header_p) /**< compiled code */ 1483425bb815Sopenharmony_ci{ 1484425bb815Sopenharmony_ci JERRY_ASSERT (bytecode_header_p != NULL); 1485425bb815Sopenharmony_ci JERRY_ASSERT (bytecode_header_p->status_flags & CBC_CODE_FLAG_HAS_TAGGED_LITERALS); 1486425bb815Sopenharmony_ci 1487425bb815Sopenharmony_ci uint8_t *byte_p = (uint8_t *) bytecode_header_p; 1488425bb815Sopenharmony_ci byte_p += ((size_t) bytecode_header_p->size) << JMEM_ALIGNMENT_LOG; 1489425bb815Sopenharmony_ci 1490425bb815Sopenharmony_ci ecma_value_t *tagged_base_p = (ecma_value_t *) byte_p; 1491425bb815Sopenharmony_ci tagged_base_p -= ecma_compiled_code_get_formal_params (bytecode_header_p); 1492425bb815Sopenharmony_ci 1493425bb815Sopenharmony_ci return ECMA_GET_INTERNAL_VALUE_POINTER (ecma_collection_t, tagged_base_p[-1]); 1494425bb815Sopenharmony_ci} /* ecma_compiled_code_get_tagged_template_collection */ 1495425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 1496425bb815Sopenharmony_ci 1497425bb815Sopenharmony_ci#if ENABLED (JERRY_LINE_INFO) || ENABLED (JERRY_ES2015_MODULE_SYSTEM) || ENABLED (JERRY_ES2015) 1498425bb815Sopenharmony_ci/** 1499425bb815Sopenharmony_ci * Get the number of formal parameters of the compiled code 1500425bb815Sopenharmony_ci * 1501425bb815Sopenharmony_ci * @return number of formal parameters 1502425bb815Sopenharmony_ci */ 1503425bb815Sopenharmony_ciecma_length_t 1504425bb815Sopenharmony_ciecma_compiled_code_get_formal_params (const ecma_compiled_code_t *bytecode_header_p) /**< compiled code */ 1505425bb815Sopenharmony_ci{ 1506425bb815Sopenharmony_ci if (!(bytecode_header_p->status_flags & CBC_CODE_FLAGS_MAPPED_ARGUMENTS_NEEDED)) 1507425bb815Sopenharmony_ci { 1508425bb815Sopenharmony_ci return 0; 1509425bb815Sopenharmony_ci } 1510425bb815Sopenharmony_ci 1511425bb815Sopenharmony_ci if (bytecode_header_p->status_flags & CBC_CODE_FLAGS_UINT16_ARGUMENTS) 1512425bb815Sopenharmony_ci { 1513425bb815Sopenharmony_ci return ((cbc_uint16_arguments_t *) bytecode_header_p)->argument_end; 1514425bb815Sopenharmony_ci } 1515425bb815Sopenharmony_ci 1516425bb815Sopenharmony_ci return ((cbc_uint8_arguments_t *) bytecode_header_p)->argument_end; 1517425bb815Sopenharmony_ci} /* ecma_compiled_code_get_formal_params */ 1518425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_LINE_INFO) || ENABLED (JERRY_ES2015_MODULE_SYSTEM) || ENABLED (JERRY_ES2015) */ 1519425bb815Sopenharmony_ci 1520425bb815Sopenharmony_ci#if (JERRY_STACK_LIMIT != 0) 1521425bb815Sopenharmony_ci/** 1522425bb815Sopenharmony_ci * Check the current stack usage by calculating the difference from the initial stack base. 1523425bb815Sopenharmony_ci * 1524425bb815Sopenharmony_ci * @return current stack usage in bytes 1525425bb815Sopenharmony_ci */ 1526425bb815Sopenharmony_ciuintptr_t JERRY_ATTR_NOINLINE 1527425bb815Sopenharmony_ciecma_get_current_stack_usage (void) 1528425bb815Sopenharmony_ci{ 1529425bb815Sopenharmony_ci volatile int __sp; 1530425bb815Sopenharmony_ci return (uintptr_t) (JERRY_CONTEXT (stack_base) - (uintptr_t) &__sp); 1531425bb815Sopenharmony_ci} /* ecma_get_current_stack_usage */ 1532425bb815Sopenharmony_ci 1533425bb815Sopenharmony_ci#endif /* (JERRY_STACK_LIMIT != 0) */ 1534425bb815Sopenharmony_ci 1535425bb815Sopenharmony_ci/** 1536425bb815Sopenharmony_ci * @} 1537425bb815Sopenharmony_ci * @} 1538425bb815Sopenharmony_ci */ 1539