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