1425bb815Sopenharmony_ci/* Copyright JS Foundation and other contributors, http://js.foundation
2425bb815Sopenharmony_ci *
3425bb815Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4425bb815Sopenharmony_ci * you may not use this file except in compliance with the License.
5425bb815Sopenharmony_ci * You may obtain a copy of the License at
6425bb815Sopenharmony_ci *
7425bb815Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8425bb815Sopenharmony_ci *
9425bb815Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10425bb815Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS
11425bb815Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12425bb815Sopenharmony_ci * See the License for the specific language governing permissions and
13425bb815Sopenharmony_ci * limitations under the License.
14425bb815Sopenharmony_ci */
15425bb815Sopenharmony_ci
16425bb815Sopenharmony_ci#include "ecma-array-object.h"
17425bb815Sopenharmony_ci#include "ecma-builtins.h"
18425bb815Sopenharmony_ci#include "ecma-exceptions.h"
19425bb815Sopenharmony_ci#include "ecma-function-object.h"
20425bb815Sopenharmony_ci#include "ecma-gc.h"
21425bb815Sopenharmony_ci#include "ecma-globals.h"
22425bb815Sopenharmony_ci#include "ecma-helpers.h"
23425bb815Sopenharmony_ci#include "ecma-objects.h"
24425bb815Sopenharmony_ci#include "ecma-objects-general.h"
25425bb815Sopenharmony_ci#include "ecma-proxy-object.h"
26425bb815Sopenharmony_ci#include "ecma-try-catch-macro.h"
27425bb815Sopenharmony_ci
28425bb815Sopenharmony_ci/** \addtogroup ecma ECMA
29425bb815Sopenharmony_ci * @{
30425bb815Sopenharmony_ci *
31425bb815Sopenharmony_ci * \addtogroup ecmaobjectsinternalops ECMA objects' operations
32425bb815Sopenharmony_ci * @{
33425bb815Sopenharmony_ci */
34425bb815Sopenharmony_ci
35425bb815Sopenharmony_ci/**
36425bb815Sopenharmony_ci * Reject sequence
37425bb815Sopenharmony_ci *
38425bb815Sopenharmony_ci * @return ecma value
39425bb815Sopenharmony_ci *         Returned value must be freed with ecma_free_value
40425bb815Sopenharmony_ci */
41425bb815Sopenharmony_ciecma_value_t
42425bb815Sopenharmony_ciecma_reject (bool is_throw) /**< Throw flag */
43425bb815Sopenharmony_ci{
44425bb815Sopenharmony_ci  if (is_throw)
45425bb815Sopenharmony_ci  {
46425bb815Sopenharmony_ci    return ecma_raise_type_error (ECMA_ERR_MSG ("Invalid argument type."));
47425bb815Sopenharmony_ci  }
48425bb815Sopenharmony_ci  else
49425bb815Sopenharmony_ci  {
50425bb815Sopenharmony_ci    return ECMA_VALUE_FALSE;
51425bb815Sopenharmony_ci  }
52425bb815Sopenharmony_ci} /* ecma_reject */
53425bb815Sopenharmony_ci
54425bb815Sopenharmony_ci/**
55425bb815Sopenharmony_ci * 'Object' object creation operation with no arguments.
56425bb815Sopenharmony_ci *
57425bb815Sopenharmony_ci * See also: ECMA-262 v5, 15.2.2.1
58425bb815Sopenharmony_ci *
59425bb815Sopenharmony_ci * @return pointer to newly created 'Object' object
60425bb815Sopenharmony_ci */
61425bb815Sopenharmony_ciecma_object_t *
62425bb815Sopenharmony_ciecma_op_create_object_object_noarg (void)
63425bb815Sopenharmony_ci{
64425bb815Sopenharmony_ci  ecma_object_t *object_prototype_p = ecma_builtin_get (ECMA_BUILTIN_ID_OBJECT_PROTOTYPE);
65425bb815Sopenharmony_ci
66425bb815Sopenharmony_ci  /* 3., 4., 6., 7. */
67425bb815Sopenharmony_ci  return ecma_op_create_object_object_noarg_and_set_prototype (object_prototype_p);
68425bb815Sopenharmony_ci} /* ecma_op_create_object_object_noarg */
69425bb815Sopenharmony_ci
70425bb815Sopenharmony_ci/**
71425bb815Sopenharmony_ci * 'Object' object creation operation with one argument.
72425bb815Sopenharmony_ci *
73425bb815Sopenharmony_ci * See also: ECMA-262 v5, 15.2.2.1
74425bb815Sopenharmony_ci *
75425bb815Sopenharmony_ci * @return pointer to newly created 'Object' object
76425bb815Sopenharmony_ci */
77425bb815Sopenharmony_ciecma_value_t
78425bb815Sopenharmony_ciecma_op_create_object_object_arg (ecma_value_t value) /**< argument of constructor */
79425bb815Sopenharmony_ci{
80425bb815Sopenharmony_ci  ecma_check_value_type_is_spec_defined (value);
81425bb815Sopenharmony_ci
82425bb815Sopenharmony_ci  if (ecma_is_value_object (value)
83425bb815Sopenharmony_ci      || ecma_is_value_number (value)
84425bb815Sopenharmony_ci      || ecma_is_value_prop_name (value)
85425bb815Sopenharmony_ci      || ecma_is_value_boolean (value))
86425bb815Sopenharmony_ci  {
87425bb815Sopenharmony_ci    /* 1.b, 1.c, 1.d */
88425bb815Sopenharmony_ci    return ecma_op_to_object (value);
89425bb815Sopenharmony_ci  }
90425bb815Sopenharmony_ci  else
91425bb815Sopenharmony_ci  {
92425bb815Sopenharmony_ci    /* 2. */
93425bb815Sopenharmony_ci    JERRY_ASSERT (ecma_is_value_undefined (value)
94425bb815Sopenharmony_ci                  || ecma_is_value_null (value));
95425bb815Sopenharmony_ci
96425bb815Sopenharmony_ci    ecma_object_t *obj_p = ecma_op_create_object_object_noarg ();
97425bb815Sopenharmony_ci
98425bb815Sopenharmony_ci    return ecma_make_object_value (obj_p);
99425bb815Sopenharmony_ci  }
100425bb815Sopenharmony_ci} /* ecma_op_create_object_object_arg */
101425bb815Sopenharmony_ci
102425bb815Sopenharmony_ci/**
103425bb815Sopenharmony_ci * Object creation operation with no arguments.
104425bb815Sopenharmony_ci * It sets the given prototype to the newly created object.
105425bb815Sopenharmony_ci *
106425bb815Sopenharmony_ci * See also: ECMA-262 v5, 15.2.2.1, 15.2.3.5
107425bb815Sopenharmony_ci *
108425bb815Sopenharmony_ci * @return pointer to newly created object
109425bb815Sopenharmony_ci */
110425bb815Sopenharmony_ciecma_object_t *
111425bb815Sopenharmony_ciecma_op_create_object_object_noarg_and_set_prototype (ecma_object_t *object_prototype_p) /**< pointer to prototype of
112425bb815Sopenharmony_ci                                                                                              the object
113425bb815Sopenharmony_ci                                                                                              (can be NULL) */
114425bb815Sopenharmony_ci{
115425bb815Sopenharmony_ci  ecma_object_t *obj_p = ecma_create_object (object_prototype_p, 0, ECMA_OBJECT_TYPE_GENERAL);
116425bb815Sopenharmony_ci
117425bb815Sopenharmony_ci  /*
118425bb815Sopenharmony_ci   * [[Class]] property of ECMA_OBJECT_TYPE_GENERAL type objects
119425bb815Sopenharmony_ci   * without ECMA_INTERNAL_PROPERTY_CLASS internal property
120425bb815Sopenharmony_ci   * is "Object".
121425bb815Sopenharmony_ci   *
122425bb815Sopenharmony_ci   * See also: ecma_object_get_class_name
123425bb815Sopenharmony_ci   */
124425bb815Sopenharmony_ci
125425bb815Sopenharmony_ci  return obj_p;
126425bb815Sopenharmony_ci} /* ecma_op_create_object_object_noarg_and_set_prototype */
127425bb815Sopenharmony_ci
128425bb815Sopenharmony_ci/**
129425bb815Sopenharmony_ci * [[Delete]] ecma general object's operation
130425bb815Sopenharmony_ci *
131425bb815Sopenharmony_ci * See also:
132425bb815Sopenharmony_ci *          ECMA-262 v5, 8.6.2; ECMA-262 v5, Table 8
133425bb815Sopenharmony_ci *          ECMA-262 v5, 8.12.7
134425bb815Sopenharmony_ci *
135425bb815Sopenharmony_ci * @return ecma value
136425bb815Sopenharmony_ci *         Returned value must be freed with ecma_free_value
137425bb815Sopenharmony_ci */
138425bb815Sopenharmony_ciecma_value_t
139425bb815Sopenharmony_ciecma_op_general_object_delete (ecma_object_t *obj_p, /**< the object */
140425bb815Sopenharmony_ci                               ecma_string_t *property_name_p, /**< property name */
141425bb815Sopenharmony_ci                               bool is_throw) /**< flag that controls failure handling */
142425bb815Sopenharmony_ci{
143425bb815Sopenharmony_ci  JERRY_ASSERT (obj_p != NULL
144425bb815Sopenharmony_ci                && !ecma_is_lexical_environment (obj_p));
145425bb815Sopenharmony_ci  JERRY_ASSERT (property_name_p != NULL);
146425bb815Sopenharmony_ci
147425bb815Sopenharmony_ci  /* 1. */
148425bb815Sopenharmony_ci  ecma_property_ref_t property_ref;
149425bb815Sopenharmony_ci
150425bb815Sopenharmony_ci  ecma_property_t property = ecma_op_object_get_own_property (obj_p,
151425bb815Sopenharmony_ci                                                              property_name_p,
152425bb815Sopenharmony_ci                                                              &property_ref,
153425bb815Sopenharmony_ci                                                              ECMA_PROPERTY_GET_NO_OPTIONS);
154425bb815Sopenharmony_ci
155425bb815Sopenharmony_ci  /* 2. */
156425bb815Sopenharmony_ci  if (property == ECMA_PROPERTY_TYPE_NOT_FOUND || property == ECMA_PROPERTY_TYPE_NOT_FOUND_AND_STOP)
157425bb815Sopenharmony_ci  {
158425bb815Sopenharmony_ci    return ECMA_VALUE_TRUE;
159425bb815Sopenharmony_ci  }
160425bb815Sopenharmony_ci
161425bb815Sopenharmony_ci  /* 3. */
162425bb815Sopenharmony_ci  if (ecma_is_property_configurable (property))
163425bb815Sopenharmony_ci  {
164425bb815Sopenharmony_ci    if (ecma_get_object_type (obj_p) == ECMA_OBJECT_TYPE_ARRAY)
165425bb815Sopenharmony_ci    {
166425bb815Sopenharmony_ci      ecma_array_object_delete_property (obj_p, property_name_p, property_ref.value_p);
167425bb815Sopenharmony_ci    }
168425bb815Sopenharmony_ci    else
169425bb815Sopenharmony_ci    {
170425bb815Sopenharmony_ci      /* a. */
171425bb815Sopenharmony_ci      ecma_delete_property (obj_p, property_ref.value_p);
172425bb815Sopenharmony_ci    }
173425bb815Sopenharmony_ci
174425bb815Sopenharmony_ci    /* b. */
175425bb815Sopenharmony_ci    return ECMA_VALUE_TRUE;
176425bb815Sopenharmony_ci  }
177425bb815Sopenharmony_ci
178425bb815Sopenharmony_ci  /* 4. */
179425bb815Sopenharmony_ci  if (is_throw)
180425bb815Sopenharmony_ci  {
181425bb815Sopenharmony_ci    return ecma_raise_type_error (ECMA_ERR_MSG ("Expected a configurable property."));
182425bb815Sopenharmony_ci  }
183425bb815Sopenharmony_ci
184425bb815Sopenharmony_ci  /* 5. */
185425bb815Sopenharmony_ci  return ECMA_VALUE_FALSE;
186425bb815Sopenharmony_ci} /* ecma_op_general_object_delete */
187425bb815Sopenharmony_ci
188425bb815Sopenharmony_ci/**
189425bb815Sopenharmony_ci * Property invocation order during [[DefaultValue]] operation with string hint
190425bb815Sopenharmony_ci */
191425bb815Sopenharmony_cistatic const lit_magic_string_id_t to_primitive_string_hint_method_names[2] =
192425bb815Sopenharmony_ci{
193425bb815Sopenharmony_ci  LIT_MAGIC_STRING_TO_STRING_UL, /**< toString operation */
194425bb815Sopenharmony_ci  LIT_MAGIC_STRING_VALUE_OF_UL, /**< valueOf operation */
195425bb815Sopenharmony_ci};
196425bb815Sopenharmony_ci
197425bb815Sopenharmony_ci/**
198425bb815Sopenharmony_ci * Property invocation order during [[DefaultValue]] operation with non string hint
199425bb815Sopenharmony_ci */
200425bb815Sopenharmony_cistatic const lit_magic_string_id_t to_primitive_non_string_hint_method_names[2] =
201425bb815Sopenharmony_ci{
202425bb815Sopenharmony_ci  LIT_MAGIC_STRING_VALUE_OF_UL, /**< valueOf operation */
203425bb815Sopenharmony_ci  LIT_MAGIC_STRING_TO_STRING_UL, /**< toString operation */
204425bb815Sopenharmony_ci};
205425bb815Sopenharmony_ci
206425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015)
207425bb815Sopenharmony_ci/**
208425bb815Sopenharmony_ci * Hints for the ecma general object's toPrimitve operation
209425bb815Sopenharmony_ci */
210425bb815Sopenharmony_cistatic const lit_magic_string_id_t hints[3] =
211425bb815Sopenharmony_ci{
212425bb815Sopenharmony_ci  LIT_MAGIC_STRING_DEFAULT, /**< "default" hint */
213425bb815Sopenharmony_ci  LIT_MAGIC_STRING_NUMBER, /**< "number" hint */
214425bb815Sopenharmony_ci  LIT_MAGIC_STRING_STRING, /**< "string" hint */
215425bb815Sopenharmony_ci};
216425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */
217425bb815Sopenharmony_ci
218425bb815Sopenharmony_ci/**
219425bb815Sopenharmony_ci * [[DefaultValue]] ecma general object's operation
220425bb815Sopenharmony_ci *
221425bb815Sopenharmony_ci * See also:
222425bb815Sopenharmony_ci *          ECMA-262 v5, 8.6.2; ECMA-262 v5, Table 8
223425bb815Sopenharmony_ci *          ECMA-262 v5, 8.12.8
224425bb815Sopenharmony_ci *
225425bb815Sopenharmony_ci * @return ecma value
226425bb815Sopenharmony_ci *         Returned value must be freed with ecma_free_value
227425bb815Sopenharmony_ci */
228425bb815Sopenharmony_ciecma_value_t
229425bb815Sopenharmony_ciecma_op_general_object_default_value (ecma_object_t *obj_p, /**< the object */
230425bb815Sopenharmony_ci                                      ecma_preferred_type_hint_t hint) /**< hint on preferred result type */
231425bb815Sopenharmony_ci{
232425bb815Sopenharmony_ci  JERRY_ASSERT (obj_p != NULL
233425bb815Sopenharmony_ci                && !ecma_is_lexical_environment (obj_p));
234425bb815Sopenharmony_ci
235425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015)
236425bb815Sopenharmony_ci  ecma_value_t obj_value = ecma_make_object_value (obj_p);
237425bb815Sopenharmony_ci
238425bb815Sopenharmony_ci  ecma_value_t exotic_to_prim = ecma_op_get_method_by_symbol_id (obj_value,
239425bb815Sopenharmony_ci                                                                 LIT_GLOBAL_SYMBOL_TO_PRIMITIVE);
240425bb815Sopenharmony_ci
241425bb815Sopenharmony_ci  if (ECMA_IS_VALUE_ERROR (exotic_to_prim))
242425bb815Sopenharmony_ci  {
243425bb815Sopenharmony_ci    return exotic_to_prim;
244425bb815Sopenharmony_ci  }
245425bb815Sopenharmony_ci
246425bb815Sopenharmony_ci  if (!ecma_is_value_undefined (exotic_to_prim))
247425bb815Sopenharmony_ci  {
248425bb815Sopenharmony_ci    ecma_object_t *call_func_p = ecma_get_object_from_value (exotic_to_prim);
249425bb815Sopenharmony_ci    ecma_value_t argument = ecma_make_magic_string_value (hints[hint]);
250425bb815Sopenharmony_ci
251425bb815Sopenharmony_ci    ecma_value_t result = ecma_op_function_call (call_func_p,
252425bb815Sopenharmony_ci                                                 obj_value,
253425bb815Sopenharmony_ci                                                 &argument,
254425bb815Sopenharmony_ci                                                 1);
255425bb815Sopenharmony_ci
256425bb815Sopenharmony_ci    ecma_free_value (exotic_to_prim);
257425bb815Sopenharmony_ci
258425bb815Sopenharmony_ci    if (ECMA_IS_VALUE_ERROR (result)
259425bb815Sopenharmony_ci        || !ecma_is_value_object (result))
260425bb815Sopenharmony_ci    {
261425bb815Sopenharmony_ci      return result;
262425bb815Sopenharmony_ci    }
263425bb815Sopenharmony_ci
264425bb815Sopenharmony_ci    ecma_free_value (result);
265425bb815Sopenharmony_ci
266425bb815Sopenharmony_ci    return ecma_raise_type_error (ECMA_ERR_MSG ("Invalid argument type in [[DefaultValue]]."));
267425bb815Sopenharmony_ci  }
268425bb815Sopenharmony_ci
269425bb815Sopenharmony_ci  ecma_free_value (exotic_to_prim);
270425bb815Sopenharmony_ci
271425bb815Sopenharmony_ci  if (hint == ECMA_PREFERRED_TYPE_NO)
272425bb815Sopenharmony_ci  {
273425bb815Sopenharmony_ci    hint = ECMA_PREFERRED_TYPE_NUMBER;
274425bb815Sopenharmony_ci  }
275425bb815Sopenharmony_ci#else /* !ENABLED (JERRY_ES2015) */
276425bb815Sopenharmony_ci  if (hint == ECMA_PREFERRED_TYPE_NO)
277425bb815Sopenharmony_ci  {
278425bb815Sopenharmony_ci    if (ecma_object_class_is (obj_p, LIT_MAGIC_STRING_DATE_UL))
279425bb815Sopenharmony_ci    {
280425bb815Sopenharmony_ci      hint = ECMA_PREFERRED_TYPE_STRING;
281425bb815Sopenharmony_ci    }
282425bb815Sopenharmony_ci    else
283425bb815Sopenharmony_ci    {
284425bb815Sopenharmony_ci      hint = ECMA_PREFERRED_TYPE_NUMBER;
285425bb815Sopenharmony_ci    }
286425bb815Sopenharmony_ci  }
287425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */
288425bb815Sopenharmony_ci
289425bb815Sopenharmony_ci  return ecma_op_general_object_ordinary_value (obj_p, hint);
290425bb815Sopenharmony_ci} /* ecma_op_general_object_default_value */
291425bb815Sopenharmony_ci
292425bb815Sopenharmony_ci/**
293425bb815Sopenharmony_ci * Ecma general object's OrdinaryToPrimitive operation
294425bb815Sopenharmony_ci *
295425bb815Sopenharmony_ci * See also:
296425bb815Sopenharmony_ci *          ECMA-262 v6 7.1.1
297425bb815Sopenharmony_ci *
298425bb815Sopenharmony_ci * @return ecma value
299425bb815Sopenharmony_ci *         Returned value must be freed with ecma_free_value
300425bb815Sopenharmony_ci */
301425bb815Sopenharmony_ciecma_value_t
302425bb815Sopenharmony_ciecma_op_general_object_ordinary_value (ecma_object_t *obj_p, /**< the object */
303425bb815Sopenharmony_ci                                       ecma_preferred_type_hint_t hint) /**< hint on preferred result type */
304425bb815Sopenharmony_ci{
305425bb815Sopenharmony_ci  const lit_magic_string_id_t *function_name_ids_p = (hint == ECMA_PREFERRED_TYPE_STRING
306425bb815Sopenharmony_ci                                                      ? to_primitive_string_hint_method_names
307425bb815Sopenharmony_ci                                                      : to_primitive_non_string_hint_method_names);
308425bb815Sopenharmony_ci
309425bb815Sopenharmony_ci  for (uint32_t i = 0; i < 2; i++)
310425bb815Sopenharmony_ci  {
311425bb815Sopenharmony_ci    ecma_value_t function_value = ecma_op_object_get_by_magic_id (obj_p, function_name_ids_p[i]);
312425bb815Sopenharmony_ci
313425bb815Sopenharmony_ci    if (ECMA_IS_VALUE_ERROR (function_value))
314425bb815Sopenharmony_ci    {
315425bb815Sopenharmony_ci      return function_value;
316425bb815Sopenharmony_ci    }
317425bb815Sopenharmony_ci
318425bb815Sopenharmony_ci    ecma_value_t call_completion = ECMA_VALUE_EMPTY;
319425bb815Sopenharmony_ci
320425bb815Sopenharmony_ci    if (ecma_op_is_callable (function_value))
321425bb815Sopenharmony_ci    {
322425bb815Sopenharmony_ci      ecma_object_t *func_obj_p = ecma_get_object_from_value (function_value);
323425bb815Sopenharmony_ci
324425bb815Sopenharmony_ci      call_completion = ecma_op_function_call (func_obj_p,
325425bb815Sopenharmony_ci                                               ecma_make_object_value (obj_p),
326425bb815Sopenharmony_ci                                               NULL,
327425bb815Sopenharmony_ci                                               0);
328425bb815Sopenharmony_ci    }
329425bb815Sopenharmony_ci
330425bb815Sopenharmony_ci    ecma_free_value (function_value);
331425bb815Sopenharmony_ci
332425bb815Sopenharmony_ci    if (ECMA_IS_VALUE_ERROR (call_completion)
333425bb815Sopenharmony_ci        || (!ecma_is_value_empty (call_completion)
334425bb815Sopenharmony_ci           && !ecma_is_value_object (call_completion)))
335425bb815Sopenharmony_ci    {
336425bb815Sopenharmony_ci      return call_completion;
337425bb815Sopenharmony_ci    }
338425bb815Sopenharmony_ci
339425bb815Sopenharmony_ci    ecma_free_value (call_completion);
340425bb815Sopenharmony_ci  }
341425bb815Sopenharmony_ci
342425bb815Sopenharmony_ci  return ecma_raise_type_error (ECMA_ERR_MSG ("Invalid argument type in [[DefaultValue]]."));
343425bb815Sopenharmony_ci} /* ecma_op_general_object_ordinary_value */
344425bb815Sopenharmony_ci
345425bb815Sopenharmony_ci/**
346425bb815Sopenharmony_ci * Special type for ecma_op_general_object_define_own_property.
347425bb815Sopenharmony_ci */
348425bb815Sopenharmony_ci#define ECMA_PROPERTY_TYPE_GENERIC ECMA_PROPERTY_TYPE_SPECIAL
349425bb815Sopenharmony_ci
350425bb815Sopenharmony_ci/**
351425bb815Sopenharmony_ci * [[DefineOwnProperty]] ecma general object's operation
352425bb815Sopenharmony_ci *
353425bb815Sopenharmony_ci * See also:
354425bb815Sopenharmony_ci *          ECMA-262 v5, 8.6.2; ECMA-262 v5, Table 8
355425bb815Sopenharmony_ci *          ECMA-262 v5, 8.12.9
356425bb815Sopenharmony_ci *
357425bb815Sopenharmony_ci * @return ecma value
358425bb815Sopenharmony_ci *         Returned value must be freed with ecma_free_value
359425bb815Sopenharmony_ci */
360425bb815Sopenharmony_ciecma_value_t
361425bb815Sopenharmony_ciecma_op_general_object_define_own_property (ecma_object_t *object_p, /**< the object */
362425bb815Sopenharmony_ci                                            ecma_string_t *property_name_p, /**< property name */
363425bb815Sopenharmony_ci                                            const ecma_property_descriptor_t *property_desc_p) /**< property
364425bb815Sopenharmony_ci                                                                                                *   descriptor */
365425bb815Sopenharmony_ci{
366425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015_BUILTIN_PROXY)
367425bb815Sopenharmony_ci  if (ECMA_OBJECT_IS_PROXY (object_p))
368425bb815Sopenharmony_ci  {
369425bb815Sopenharmony_ci    return ecma_proxy_object_define_own_property (object_p, property_name_p, property_desc_p);
370425bb815Sopenharmony_ci  }
371425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */
372425bb815Sopenharmony_ci
373425bb815Sopenharmony_ci  JERRY_ASSERT (object_p != NULL
374425bb815Sopenharmony_ci                && !ecma_is_lexical_environment (object_p));
375425bb815Sopenharmony_ci  JERRY_ASSERT (!ecma_op_object_is_fast_array (object_p));
376425bb815Sopenharmony_ci  JERRY_ASSERT (property_name_p != NULL);
377425bb815Sopenharmony_ci
378425bb815Sopenharmony_ci  ecma_property_types_t property_desc_type = ECMA_PROPERTY_TYPE_GENERIC;
379425bb815Sopenharmony_ci
380425bb815Sopenharmony_ci  if (property_desc_p->flags & (ECMA_PROP_IS_VALUE_DEFINED | ECMA_PROP_IS_WRITABLE_DEFINED))
381425bb815Sopenharmony_ci  {
382425bb815Sopenharmony_ci    /* A property descriptor cannot be both named data and named accessor. */
383425bb815Sopenharmony_ci    JERRY_ASSERT ((property_desc_p->flags & (ECMA_PROP_IS_GET_DEFINED | ECMA_PROP_IS_SET_DEFINED))
384425bb815Sopenharmony_ci                   != (ECMA_PROP_IS_GET_DEFINED | ECMA_PROP_IS_SET_DEFINED));
385425bb815Sopenharmony_ci    property_desc_type = ECMA_PROPERTY_TYPE_NAMEDDATA;
386425bb815Sopenharmony_ci  }
387425bb815Sopenharmony_ci  else if (property_desc_p->flags & (ECMA_PROP_IS_GET_DEFINED | ECMA_PROP_IS_SET_DEFINED))
388425bb815Sopenharmony_ci  {
389425bb815Sopenharmony_ci    JERRY_ASSERT (!(property_desc_p->flags & ECMA_PROP_IS_WRITABLE_DEFINED));
390425bb815Sopenharmony_ci    property_desc_type = ECMA_PROPERTY_TYPE_NAMEDACCESSOR;
391425bb815Sopenharmony_ci  }
392425bb815Sopenharmony_ci
393425bb815Sopenharmony_ci  /* These three asserts ensures that a new property is created with the appropriate default flags.
394425bb815Sopenharmony_ci   * E.g. if ECMA_PROP_IS_CONFIGURABLE_DEFINED is false, the newly created property must be non-configurable. */
395425bb815Sopenharmony_ci  JERRY_ASSERT ((property_desc_p->flags & ECMA_PROP_IS_CONFIGURABLE_DEFINED)
396425bb815Sopenharmony_ci                || !(property_desc_p->flags & ECMA_PROP_IS_CONFIGURABLE));
397425bb815Sopenharmony_ci  JERRY_ASSERT ((property_desc_p->flags & ECMA_PROP_IS_ENUMERABLE_DEFINED)
398425bb815Sopenharmony_ci                || !(property_desc_p->flags & ECMA_PROP_IS_ENUMERABLE));
399425bb815Sopenharmony_ci  JERRY_ASSERT ((property_desc_p->flags & ECMA_PROP_IS_WRITABLE_DEFINED)
400425bb815Sopenharmony_ci                || !(property_desc_p->flags & ECMA_PROP_IS_WRITABLE));
401425bb815Sopenharmony_ci
402425bb815Sopenharmony_ci  /* 1. */
403425bb815Sopenharmony_ci  ecma_extended_property_ref_t ext_property_ref = { .property_ref.value_p = NULL, .property_p = NULL };
404425bb815Sopenharmony_ci  ecma_property_t current_prop;
405425bb815Sopenharmony_ci
406425bb815Sopenharmony_ci  current_prop = ecma_op_object_get_own_property (object_p,
407425bb815Sopenharmony_ci                                                  property_name_p,
408425bb815Sopenharmony_ci                                                  &ext_property_ref.property_ref,
409425bb815Sopenharmony_ci                                                  ECMA_PROPERTY_GET_VALUE | ECMA_PROPERTY_GET_EXT_REFERENCE);
410425bb815Sopenharmony_ci
411425bb815Sopenharmony_ci  if (current_prop == ECMA_PROPERTY_TYPE_NOT_FOUND || current_prop == ECMA_PROPERTY_TYPE_NOT_FOUND_AND_STOP)
412425bb815Sopenharmony_ci  {
413425bb815Sopenharmony_ci    /* 3. */
414425bb815Sopenharmony_ci    if (!ecma_op_ordinary_object_is_extensible (object_p))
415425bb815Sopenharmony_ci    {
416425bb815Sopenharmony_ci      /* 2. */
417425bb815Sopenharmony_ci      return ecma_reject (property_desc_p->flags & ECMA_PROP_IS_THROW);
418425bb815Sopenharmony_ci    }
419425bb815Sopenharmony_ci
420425bb815Sopenharmony_ci    /* 4. */
421425bb815Sopenharmony_ci    uint8_t prop_attributes = (uint8_t) (property_desc_p->flags & ECMA_PROPERTY_FLAGS_MASK);
422425bb815Sopenharmony_ci
423425bb815Sopenharmony_ci    if (property_desc_type != ECMA_PROPERTY_TYPE_NAMEDACCESSOR)
424425bb815Sopenharmony_ci    {
425425bb815Sopenharmony_ci      /* a. */
426425bb815Sopenharmony_ci      JERRY_ASSERT (property_desc_type == ECMA_PROPERTY_TYPE_GENERIC
427425bb815Sopenharmony_ci                    || property_desc_type == ECMA_PROPERTY_TYPE_NAMEDDATA);
428425bb815Sopenharmony_ci
429425bb815Sopenharmony_ci      ecma_property_value_t *new_prop_value_p = ecma_create_named_data_property (object_p,
430425bb815Sopenharmony_ci                                                                                 property_name_p,
431425bb815Sopenharmony_ci                                                                                 prop_attributes,
432425bb815Sopenharmony_ci                                                                                 NULL);
433425bb815Sopenharmony_ci
434425bb815Sopenharmony_ci      JERRY_ASSERT ((property_desc_p->flags & ECMA_PROP_IS_VALUE_DEFINED)
435425bb815Sopenharmony_ci                    || ecma_is_value_undefined (property_desc_p->value));
436425bb815Sopenharmony_ci
437425bb815Sopenharmony_ci      new_prop_value_p->value = ecma_copy_value_if_not_object (property_desc_p->value);
438425bb815Sopenharmony_ci    }
439425bb815Sopenharmony_ci    else
440425bb815Sopenharmony_ci    {
441425bb815Sopenharmony_ci      /* b. */
442425bb815Sopenharmony_ci
443425bb815Sopenharmony_ci      ecma_create_named_accessor_property (object_p,
444425bb815Sopenharmony_ci                                           property_name_p,
445425bb815Sopenharmony_ci                                           property_desc_p->get_p,
446425bb815Sopenharmony_ci                                           property_desc_p->set_p,
447425bb815Sopenharmony_ci                                           prop_attributes,
448425bb815Sopenharmony_ci                                           NULL);
449425bb815Sopenharmony_ci    }
450425bb815Sopenharmony_ci
451425bb815Sopenharmony_ci    return ECMA_VALUE_TRUE;
452425bb815Sopenharmony_ci  }
453425bb815Sopenharmony_ci
454425bb815Sopenharmony_ci  /* 6. */
455425bb815Sopenharmony_ci  ecma_property_types_t current_property_type = ECMA_PROPERTY_GET_TYPE (current_prop);
456425bb815Sopenharmony_ci  const bool is_current_configurable = ecma_is_property_configurable (current_prop);
457425bb815Sopenharmony_ci
458425bb815Sopenharmony_ci  JERRY_ASSERT (current_property_type == ECMA_PROPERTY_TYPE_NAMEDDATA
459425bb815Sopenharmony_ci                || current_property_type == ECMA_PROPERTY_TYPE_NAMEDACCESSOR
460425bb815Sopenharmony_ci                || current_property_type == ECMA_PROPERTY_TYPE_VIRTUAL);
461425bb815Sopenharmony_ci
462425bb815Sopenharmony_ci  /* 7. a., b. */
463425bb815Sopenharmony_ci  bool is_enumerable = (property_desc_p->flags & ECMA_PROP_IS_ENUMERABLE) != 0;
464425bb815Sopenharmony_ci  if (!is_current_configurable
465425bb815Sopenharmony_ci      && ((property_desc_p->flags & ECMA_PROP_IS_CONFIGURABLE)
466425bb815Sopenharmony_ci          || ((property_desc_p->flags & ECMA_PROP_IS_ENUMERABLE_DEFINED)
467425bb815Sopenharmony_ci              && (is_enumerable != ecma_is_property_enumerable (current_prop)))))
468425bb815Sopenharmony_ci  {
469425bb815Sopenharmony_ci    if (current_property_type == ECMA_PROPERTY_TYPE_VIRTUAL)
470425bb815Sopenharmony_ci    {
471425bb815Sopenharmony_ci      ecma_free_value (ext_property_ref.property_ref.virtual_value);
472425bb815Sopenharmony_ci    }
473425bb815Sopenharmony_ci    return ecma_reject (property_desc_p->flags & ECMA_PROP_IS_THROW);
474425bb815Sopenharmony_ci  }
475425bb815Sopenharmony_ci
476425bb815Sopenharmony_ci  if (current_property_type == ECMA_PROPERTY_TYPE_VIRTUAL)
477425bb815Sopenharmony_ci  {
478425bb815Sopenharmony_ci    JERRY_ASSERT (!is_current_configurable && !ecma_is_property_writable (current_prop));
479425bb815Sopenharmony_ci
480425bb815Sopenharmony_ci    ecma_value_t result = ECMA_VALUE_TRUE;
481425bb815Sopenharmony_ci
482425bb815Sopenharmony_ci    if (property_desc_type == ECMA_PROPERTY_TYPE_NAMEDACCESSOR
483425bb815Sopenharmony_ci        || (property_desc_p->flags & ECMA_PROP_IS_WRITABLE)
484425bb815Sopenharmony_ci        || ((property_desc_p->flags & ECMA_PROP_IS_VALUE_DEFINED)
485425bb815Sopenharmony_ci            && !ecma_op_same_value (property_desc_p->value,
486425bb815Sopenharmony_ci                                    ext_property_ref.property_ref.virtual_value)))
487425bb815Sopenharmony_ci    {
488425bb815Sopenharmony_ci      result = ecma_reject (property_desc_p->flags & ECMA_PROP_IS_THROW);
489425bb815Sopenharmony_ci    }
490425bb815Sopenharmony_ci
491425bb815Sopenharmony_ci    ecma_free_value (ext_property_ref.property_ref.virtual_value);
492425bb815Sopenharmony_ci    return result;
493425bb815Sopenharmony_ci  }
494425bb815Sopenharmony_ci
495425bb815Sopenharmony_ci  /* 8. */
496425bb815Sopenharmony_ci  if (property_desc_type == ECMA_PROPERTY_TYPE_GENERIC)
497425bb815Sopenharmony_ci  {
498425bb815Sopenharmony_ci    /* No action required. */
499425bb815Sopenharmony_ci  }
500425bb815Sopenharmony_ci  else if (JERRY_LIKELY (property_desc_type == current_property_type))
501425bb815Sopenharmony_ci  {
502425bb815Sopenharmony_ci    /* If property is configurable, there is no need for checks. */
503425bb815Sopenharmony_ci    if (JERRY_UNLIKELY (!is_current_configurable))
504425bb815Sopenharmony_ci    {
505425bb815Sopenharmony_ci      if (property_desc_type == ECMA_PROPERTY_TYPE_NAMEDDATA)
506425bb815Sopenharmony_ci      {
507425bb815Sopenharmony_ci        /* 10. a. i. & ii. */
508425bb815Sopenharmony_ci        if (!ecma_is_property_writable (current_prop)
509425bb815Sopenharmony_ci            && ((property_desc_p->flags & ECMA_PROP_IS_WRITABLE)
510425bb815Sopenharmony_ci                || ((property_desc_p->flags & ECMA_PROP_IS_VALUE_DEFINED)
511425bb815Sopenharmony_ci                    && !ecma_op_same_value (property_desc_p->value,
512425bb815Sopenharmony_ci                                            ext_property_ref.property_ref.value_p->value))))
513425bb815Sopenharmony_ci        {
514425bb815Sopenharmony_ci          return ecma_reject (property_desc_p->flags & ECMA_PROP_IS_THROW);
515425bb815Sopenharmony_ci        }
516425bb815Sopenharmony_ci      }
517425bb815Sopenharmony_ci      else
518425bb815Sopenharmony_ci      {
519425bb815Sopenharmony_ci        /* 11. */
520425bb815Sopenharmony_ci
521425bb815Sopenharmony_ci        /* a. */
522425bb815Sopenharmony_ci        ecma_property_value_t *value_p = ext_property_ref.property_ref.value_p;
523425bb815Sopenharmony_ci
524425bb815Sopenharmony_ci        ecma_getter_setter_pointers_t *get_set_pair_p = ecma_get_named_accessor_property (value_p);
525425bb815Sopenharmony_ci        jmem_cpointer_t prop_desc_getter_cp, prop_desc_setter_cp;
526425bb815Sopenharmony_ci        ECMA_SET_POINTER (prop_desc_getter_cp, property_desc_p->get_p);
527425bb815Sopenharmony_ci        ECMA_SET_POINTER (prop_desc_setter_cp, property_desc_p->set_p);
528425bb815Sopenharmony_ci
529425bb815Sopenharmony_ci        if (((property_desc_p->flags & ECMA_PROP_IS_GET_DEFINED)
530425bb815Sopenharmony_ci             && prop_desc_getter_cp != get_set_pair_p->getter_cp)
531425bb815Sopenharmony_ci            || ((property_desc_p->flags & ECMA_PROP_IS_SET_DEFINED)
532425bb815Sopenharmony_ci                && prop_desc_setter_cp != get_set_pair_p->setter_cp))
533425bb815Sopenharmony_ci        {
534425bb815Sopenharmony_ci          /* i., ii. */
535425bb815Sopenharmony_ci          return ecma_reject (property_desc_p->flags & ECMA_PROP_IS_THROW);
536425bb815Sopenharmony_ci        }
537425bb815Sopenharmony_ci      }
538425bb815Sopenharmony_ci    }
539425bb815Sopenharmony_ci  }
540425bb815Sopenharmony_ci  else
541425bb815Sopenharmony_ci  {
542425bb815Sopenharmony_ci    /* 9. */
543425bb815Sopenharmony_ci    if (!is_current_configurable)
544425bb815Sopenharmony_ci    {
545425bb815Sopenharmony_ci      /* a. */
546425bb815Sopenharmony_ci      return ecma_reject (property_desc_p->flags & ECMA_PROP_IS_THROW);
547425bb815Sopenharmony_ci    }
548425bb815Sopenharmony_ci
549425bb815Sopenharmony_ci    ecma_property_value_t *value_p = ext_property_ref.property_ref.value_p;
550425bb815Sopenharmony_ci
551425bb815Sopenharmony_ci    if (property_desc_type == ECMA_PROPERTY_TYPE_NAMEDACCESSOR)
552425bb815Sopenharmony_ci    {
553425bb815Sopenharmony_ci      JERRY_ASSERT (current_property_type == ECMA_PROPERTY_TYPE_NAMEDDATA);
554425bb815Sopenharmony_ci      ecma_free_value_if_not_object (value_p->value);
555425bb815Sopenharmony_ci
556425bb815Sopenharmony_ci#if ENABLED (JERRY_CPOINTER_32_BIT)
557425bb815Sopenharmony_ci      ecma_getter_setter_pointers_t *getter_setter_pair_p;
558425bb815Sopenharmony_ci      getter_setter_pair_p = jmem_pools_alloc (sizeof (ecma_getter_setter_pointers_t));
559425bb815Sopenharmony_ci      getter_setter_pair_p->getter_cp = JMEM_CP_NULL;
560425bb815Sopenharmony_ci      getter_setter_pair_p->setter_cp = JMEM_CP_NULL;
561425bb815Sopenharmony_ci      ECMA_SET_NON_NULL_POINTER (value_p->getter_setter_pair_cp, getter_setter_pair_p);
562425bb815Sopenharmony_ci#else /* !ENABLED (JERRY_CPOINTER_32_BIT) */
563425bb815Sopenharmony_ci      value_p->getter_setter_pair.getter_cp = JMEM_CP_NULL;
564425bb815Sopenharmony_ci      value_p->getter_setter_pair.setter_cp = JMEM_CP_NULL;
565425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_CPOINTER_32_BIT) */
566425bb815Sopenharmony_ci    }
567425bb815Sopenharmony_ci    else
568425bb815Sopenharmony_ci    {
569425bb815Sopenharmony_ci      JERRY_ASSERT (current_property_type == ECMA_PROPERTY_TYPE_NAMEDACCESSOR);
570425bb815Sopenharmony_ci#if ENABLED (JERRY_CPOINTER_32_BIT)
571425bb815Sopenharmony_ci      ecma_getter_setter_pointers_t *getter_setter_pair_p;
572425bb815Sopenharmony_ci      getter_setter_pair_p = ECMA_GET_NON_NULL_POINTER (ecma_getter_setter_pointers_t,
573425bb815Sopenharmony_ci                                                        value_p->getter_setter_pair_cp);
574425bb815Sopenharmony_ci      jmem_pools_free (getter_setter_pair_p, sizeof (ecma_getter_setter_pointers_t));
575425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_CPOINTER_32_BIT) */
576425bb815Sopenharmony_ci      value_p->value = ECMA_VALUE_UNDEFINED;
577425bb815Sopenharmony_ci    }
578425bb815Sopenharmony_ci
579425bb815Sopenharmony_ci    /* Update flags */
580425bb815Sopenharmony_ci    ecma_property_t prop_flags = *(ext_property_ref.property_p);
581425bb815Sopenharmony_ci    prop_flags = (ecma_property_t) (prop_flags & ~(ECMA_PROPERTY_TYPE_MASK | ECMA_PROPERTY_FLAG_WRITABLE));
582425bb815Sopenharmony_ci    prop_flags = (ecma_property_t) (prop_flags | property_desc_type);
583425bb815Sopenharmony_ci    *(ext_property_ref.property_p) = prop_flags;
584425bb815Sopenharmony_ci  }
585425bb815Sopenharmony_ci
586425bb815Sopenharmony_ci  /* 12. */
587425bb815Sopenharmony_ci  if (property_desc_type == ECMA_PROPERTY_TYPE_NAMEDDATA)
588425bb815Sopenharmony_ci  {
589425bb815Sopenharmony_ci    JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (*ext_property_ref.property_p) == ECMA_PROPERTY_TYPE_NAMEDDATA);
590425bb815Sopenharmony_ci
591425bb815Sopenharmony_ci    if (property_desc_p->flags & ECMA_PROP_IS_VALUE_DEFINED)
592425bb815Sopenharmony_ci    {
593425bb815Sopenharmony_ci      ecma_named_data_property_assign_value (object_p,
594425bb815Sopenharmony_ci                                             ext_property_ref.property_ref.value_p,
595425bb815Sopenharmony_ci                                             property_desc_p->value);
596425bb815Sopenharmony_ci    }
597425bb815Sopenharmony_ci
598425bb815Sopenharmony_ci    if (property_desc_p->flags & ECMA_PROP_IS_WRITABLE_DEFINED)
599425bb815Sopenharmony_ci    {
600425bb815Sopenharmony_ci      ecma_set_property_writable_attr (ext_property_ref.property_p, (property_desc_p->flags & ECMA_PROP_IS_WRITABLE));
601425bb815Sopenharmony_ci    }
602425bb815Sopenharmony_ci  }
603425bb815Sopenharmony_ci  else if (property_desc_type == ECMA_PROPERTY_TYPE_NAMEDACCESSOR)
604425bb815Sopenharmony_ci  {
605425bb815Sopenharmony_ci    JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (*ext_property_ref.property_p) == ECMA_PROPERTY_TYPE_NAMEDACCESSOR);
606425bb815Sopenharmony_ci
607425bb815Sopenharmony_ci    if (property_desc_p->flags & ECMA_PROP_IS_GET_DEFINED)
608425bb815Sopenharmony_ci    {
609425bb815Sopenharmony_ci      ecma_set_named_accessor_property_getter (object_p,
610425bb815Sopenharmony_ci                                               ext_property_ref.property_ref.value_p,
611425bb815Sopenharmony_ci                                               property_desc_p->get_p);
612425bb815Sopenharmony_ci    }
613425bb815Sopenharmony_ci
614425bb815Sopenharmony_ci    if (property_desc_p->flags & ECMA_PROP_IS_SET_DEFINED)
615425bb815Sopenharmony_ci    {
616425bb815Sopenharmony_ci      ecma_set_named_accessor_property_setter (object_p,
617425bb815Sopenharmony_ci                                               ext_property_ref.property_ref.value_p,
618425bb815Sopenharmony_ci                                               property_desc_p->set_p);
619425bb815Sopenharmony_ci    }
620425bb815Sopenharmony_ci  }
621425bb815Sopenharmony_ci
622425bb815Sopenharmony_ci  if (property_desc_p->flags & ECMA_PROP_IS_ENUMERABLE_DEFINED)
623425bb815Sopenharmony_ci  {
624425bb815Sopenharmony_ci    ecma_set_property_enumerable_attr (ext_property_ref.property_p,
625425bb815Sopenharmony_ci                                       (property_desc_p->flags & ECMA_PROP_IS_ENUMERABLE));
626425bb815Sopenharmony_ci  }
627425bb815Sopenharmony_ci
628425bb815Sopenharmony_ci  if (property_desc_p->flags & ECMA_PROP_IS_CONFIGURABLE_DEFINED)
629425bb815Sopenharmony_ci  {
630425bb815Sopenharmony_ci    ecma_set_property_configurable_attr (ext_property_ref.property_p,
631425bb815Sopenharmony_ci                                         (property_desc_p->flags & ECMA_PROP_IS_CONFIGURABLE));
632425bb815Sopenharmony_ci  }
633425bb815Sopenharmony_ci
634425bb815Sopenharmony_ci  return ECMA_VALUE_TRUE;
635425bb815Sopenharmony_ci} /* ecma_op_general_object_define_own_property */
636425bb815Sopenharmony_ci
637425bb815Sopenharmony_ci#undef ECMA_PROPERTY_TYPE_GENERIC
638425bb815Sopenharmony_ci
639425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015)
640425bb815Sopenharmony_ci/**
641425bb815Sopenharmony_ci * The IsCompatiblePropertyDescriptor method for Proxy object internal methods
642425bb815Sopenharmony_ci *
643425bb815Sopenharmony_ci * See also:
644425bb815Sopenharmony_ci *          ECMAScript v6, 9.1.6.2
645425bb815Sopenharmony_ci *
646425bb815Sopenharmony_ci * @return bool
647425bb815Sopenharmony_ci */
648425bb815Sopenharmony_cibool
649425bb815Sopenharmony_ciecma_op_is_compatible_property_descriptor (const ecma_property_descriptor_t *desc_p, /**< target descriptor */
650425bb815Sopenharmony_ci                                           const ecma_property_descriptor_t *current_p, /**< current descriptor */
651425bb815Sopenharmony_ci                                           bool is_extensible) /**< true - if target object is extensible
652425bb815Sopenharmony_ci                                                                    false - otherwise */
653425bb815Sopenharmony_ci{
654425bb815Sopenharmony_ci  JERRY_ASSERT (desc_p != NULL);
655425bb815Sopenharmony_ci
656425bb815Sopenharmony_ci  /* 2. */
657425bb815Sopenharmony_ci  if (current_p == NULL)
658425bb815Sopenharmony_ci  {
659425bb815Sopenharmony_ci    return is_extensible;
660425bb815Sopenharmony_ci  }
661425bb815Sopenharmony_ci
662425bb815Sopenharmony_ci  /* 3. */
663425bb815Sopenharmony_ci  if (desc_p->flags == 0)
664425bb815Sopenharmony_ci  {
665425bb815Sopenharmony_ci    return true;
666425bb815Sopenharmony_ci  }
667425bb815Sopenharmony_ci
668425bb815Sopenharmony_ci  /* 4. */
669425bb815Sopenharmony_ci  if ((current_p->flags & desc_p->flags) == desc_p->flags)
670425bb815Sopenharmony_ci  {
671425bb815Sopenharmony_ci    if ((current_p->flags & ECMA_PROP_IS_VALUE_DEFINED)
672425bb815Sopenharmony_ci         && ecma_op_same_value (current_p->value, desc_p->value))
673425bb815Sopenharmony_ci    {
674425bb815Sopenharmony_ci      return true;
675425bb815Sopenharmony_ci    }
676425bb815Sopenharmony_ci
677425bb815Sopenharmony_ci    if ((current_p->flags & (ECMA_PROP_IS_GET_DEFINED | ECMA_PROP_IS_SET_DEFINED)
678425bb815Sopenharmony_ci         && current_p->get_p == desc_p->get_p
679425bb815Sopenharmony_ci         && current_p->set_p == desc_p->set_p))
680425bb815Sopenharmony_ci    {
681425bb815Sopenharmony_ci      return true;
682425bb815Sopenharmony_ci    }
683425bb815Sopenharmony_ci  }
684425bb815Sopenharmony_ci
685425bb815Sopenharmony_ci  /* 5. */
686425bb815Sopenharmony_ci  if (!(current_p->flags & ECMA_PROP_IS_CONFIGURABLE))
687425bb815Sopenharmony_ci  {
688425bb815Sopenharmony_ci    if (desc_p->flags & ECMA_PROP_IS_CONFIGURABLE)
689425bb815Sopenharmony_ci    {
690425bb815Sopenharmony_ci      return false;
691425bb815Sopenharmony_ci    }
692425bb815Sopenharmony_ci    if ((desc_p->flags & ECMA_PROP_IS_ENUMERABLE_DEFINED)
693425bb815Sopenharmony_ci        && ((current_p->flags & ECMA_PROP_IS_ENUMERABLE) != (desc_p->flags & ECMA_PROP_IS_ENUMERABLE)))
694425bb815Sopenharmony_ci    {
695425bb815Sopenharmony_ci      return false;
696425bb815Sopenharmony_ci    }
697425bb815Sopenharmony_ci  }
698425bb815Sopenharmony_ci
699425bb815Sopenharmony_ci  const uint32_t accessor_desc_flags = (ECMA_PROP_IS_SET_DEFINED | ECMA_PROP_IS_GET_DEFINED);
700425bb815Sopenharmony_ci  const uint32_t data_desc_flags = (ECMA_PROP_IS_VALUE_DEFINED | ECMA_PROP_IS_WRITABLE_DEFINED);
701425bb815Sopenharmony_ci
702425bb815Sopenharmony_ci  bool desc_is_accessor = (desc_p->flags & accessor_desc_flags) != 0;
703425bb815Sopenharmony_ci  bool desc_is_data = (desc_p->flags & data_desc_flags) != 0;
704425bb815Sopenharmony_ci  bool current_is_data = (current_p->flags & data_desc_flags) != 0;
705425bb815Sopenharmony_ci
706425bb815Sopenharmony_ci  /* 6. */
707425bb815Sopenharmony_ci  if (!desc_is_accessor && !desc_is_data)
708425bb815Sopenharmony_ci  {
709425bb815Sopenharmony_ci    return true;
710425bb815Sopenharmony_ci  }
711425bb815Sopenharmony_ci
712425bb815Sopenharmony_ci  /* 7. */
713425bb815Sopenharmony_ci  if (current_is_data != desc_is_data)
714425bb815Sopenharmony_ci  {
715425bb815Sopenharmony_ci    return (current_p->flags & ECMA_PROP_IS_CONFIGURABLE) != 0;
716425bb815Sopenharmony_ci  }
717425bb815Sopenharmony_ci
718425bb815Sopenharmony_ci  /* 8. */
719425bb815Sopenharmony_ci  if (current_is_data)
720425bb815Sopenharmony_ci  {
721425bb815Sopenharmony_ci    if (!(current_p->flags & ECMA_PROP_IS_CONFIGURABLE))
722425bb815Sopenharmony_ci    {
723425bb815Sopenharmony_ci      if (!(current_p->flags & ECMA_PROP_IS_WRITABLE)
724425bb815Sopenharmony_ci           && (desc_p->flags & ECMA_PROP_IS_WRITABLE))
725425bb815Sopenharmony_ci      {
726425bb815Sopenharmony_ci        return false;
727425bb815Sopenharmony_ci      }
728425bb815Sopenharmony_ci
729425bb815Sopenharmony_ci      if (!(current_p->flags & ECMA_PROP_IS_WRITABLE)
730425bb815Sopenharmony_ci           && (desc_p->flags & ECMA_PROP_IS_VALUE_DEFINED)
731425bb815Sopenharmony_ci           && !ecma_op_same_value (desc_p->value, current_p->value))
732425bb815Sopenharmony_ci      {
733425bb815Sopenharmony_ci        return false;
734425bb815Sopenharmony_ci      }
735425bb815Sopenharmony_ci    }
736425bb815Sopenharmony_ci
737425bb815Sopenharmony_ci    return true;
738425bb815Sopenharmony_ci  }
739425bb815Sopenharmony_ci
740425bb815Sopenharmony_ci  JERRY_ASSERT ((current_p->flags & (ECMA_PROP_IS_GET_DEFINED | ECMA_PROP_IS_SET_DEFINED)) != 0);
741425bb815Sopenharmony_ci  JERRY_ASSERT ((desc_p->flags & (ECMA_PROP_IS_GET_DEFINED | ECMA_PROP_IS_SET_DEFINED)) != 0);
742425bb815Sopenharmony_ci
743425bb815Sopenharmony_ci  /* 9. */
744425bb815Sopenharmony_ci  if (!(current_p->flags & ECMA_PROP_IS_CONFIGURABLE))
745425bb815Sopenharmony_ci  {
746425bb815Sopenharmony_ci    if ((desc_p->flags & ECMA_PROP_IS_SET_DEFINED)
747425bb815Sopenharmony_ci         && desc_p->set_p != current_p->set_p)
748425bb815Sopenharmony_ci    {
749425bb815Sopenharmony_ci      return false;
750425bb815Sopenharmony_ci    }
751425bb815Sopenharmony_ci
752425bb815Sopenharmony_ci    if ((desc_p->flags & ECMA_PROP_IS_GET_DEFINED)
753425bb815Sopenharmony_ci         && desc_p->get_p != current_p->get_p)
754425bb815Sopenharmony_ci    {
755425bb815Sopenharmony_ci      return false;
756425bb815Sopenharmony_ci    }
757425bb815Sopenharmony_ci  }
758425bb815Sopenharmony_ci
759425bb815Sopenharmony_ci  return true;
760425bb815Sopenharmony_ci} /* ecma_op_is_compatible_property_descriptor */
761425bb815Sopenharmony_ci
762425bb815Sopenharmony_ci/**
763425bb815Sopenharmony_ci * CompletePropertyDescriptor method for proxy internal method
764425bb815Sopenharmony_ci *
765425bb815Sopenharmony_ci * See also:
766425bb815Sopenharmony_ci *          ECMA-262 v6, 6.2.4.5
767425bb815Sopenharmony_ci */
768425bb815Sopenharmony_civoid
769425bb815Sopenharmony_ciecma_op_to_complete_property_descriptor (ecma_property_descriptor_t *desc_p) /**< target descriptor */
770425bb815Sopenharmony_ci{
771425bb815Sopenharmony_ci  /* 4. */
772425bb815Sopenharmony_ci  if (!(desc_p->flags & (ECMA_PROP_IS_GET_DEFINED | ECMA_PROP_IS_SET_DEFINED)))
773425bb815Sopenharmony_ci  {
774425bb815Sopenharmony_ci    /* a. */
775425bb815Sopenharmony_ci    desc_p->flags |= ECMA_PROP_IS_VALUE_DEFINED;
776425bb815Sopenharmony_ci  }
777425bb815Sopenharmony_ci  /* 5. */
778425bb815Sopenharmony_ci  else
779425bb815Sopenharmony_ci  {
780425bb815Sopenharmony_ci    desc_p->flags |= (ECMA_PROP_IS_GET_DEFINED | ECMA_PROP_IS_SET_DEFINED);
781425bb815Sopenharmony_ci  }
782425bb815Sopenharmony_ci} /* ecma_op_to_complete_property_descriptor */
783425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */
784425bb815Sopenharmony_ci
785425bb815Sopenharmony_ci/**
786425bb815Sopenharmony_ci * @}
787425bb815Sopenharmony_ci * @}
788425bb815Sopenharmony_ci */
789