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-builtins.h"
19425bb815Sopenharmony_ci#include "ecma-builtin-object.h"
20425bb815Sopenharmony_ci#include "ecma-exceptions.h"
21425bb815Sopenharmony_ci#include "ecma-function-object.h"
22425bb815Sopenharmony_ci#include "ecma-gc.h"
23425bb815Sopenharmony_ci#include "ecma-globals.h"
24425bb815Sopenharmony_ci#include "ecma-helpers.h"
25425bb815Sopenharmony_ci#include "ecma-objects.h"
26425bb815Sopenharmony_ci#include "ecma-objects-general.h"
27425bb815Sopenharmony_ci#include "ecma-proxy-object.h"
28425bb815Sopenharmony_ci#include "jcontext.h"
29425bb815Sopenharmony_ci
30425bb815Sopenharmony_ci/** \addtogroup ecma ECMA
31425bb815Sopenharmony_ci * @{
32425bb815Sopenharmony_ci *
33425bb815Sopenharmony_ci * \addtogroup ecmaproxyobject ECMA Proxy object related routines
34425bb815Sopenharmony_ci * @{
35425bb815Sopenharmony_ci */
36425bb815Sopenharmony_ci
37425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015_BUILTIN_PROXY)
38425bb815Sopenharmony_ci/**
39425bb815Sopenharmony_ci * Check whether the argument satifies the requrements of [[ProxyTarget]] or [[ProxyHandler]]
40425bb815Sopenharmony_ci *
41425bb815Sopenharmony_ci * See also:
42425bb815Sopenharmony_ci *          ES2015 9.5.15.1-2
43425bb815Sopenharmony_ci *          ES2015 9.5.15.3-4
44425bb815Sopenharmony_ci *
45425bb815Sopenharmony_ci * @return true - if the arguments can be a valid [[ProxyTarget]] or [[ProxyHandler]]
46425bb815Sopenharmony_ci *         false - otherwise
47425bb815Sopenharmony_ci */
48425bb815Sopenharmony_cistatic bool
49425bb815Sopenharmony_ciecma_proxy_validate (ecma_value_t argument) /**< argument to validate */
50425bb815Sopenharmony_ci{
51425bb815Sopenharmony_ci  if (ecma_is_value_object (argument))
52425bb815Sopenharmony_ci  {
53425bb815Sopenharmony_ci    ecma_object_t *obj_p = ecma_get_object_from_value (argument);
54425bb815Sopenharmony_ci
55425bb815Sopenharmony_ci    return (!ECMA_OBJECT_IS_PROXY (obj_p)
56425bb815Sopenharmony_ci            || !ecma_is_value_null (((ecma_proxy_object_t *) obj_p)->handler));
57425bb815Sopenharmony_ci  }
58425bb815Sopenharmony_ci
59425bb815Sopenharmony_ci  return false;
60425bb815Sopenharmony_ci} /* ecma_proxy_validate */
61425bb815Sopenharmony_ci
62425bb815Sopenharmony_ci/**
63425bb815Sopenharmony_ci * ProxyCreate operation for create a new proxy object
64425bb815Sopenharmony_ci *
65425bb815Sopenharmony_ci * See also:
66425bb815Sopenharmony_ci *         ES2015 9.5.15
67425bb815Sopenharmony_ci *
68425bb815Sopenharmony_ci * @return created Proxy object as an ecma-value - if success
69425bb815Sopenharmony_ci *         raised error - otherwise
70425bb815Sopenharmony_ci */
71425bb815Sopenharmony_ciecma_object_t *
72425bb815Sopenharmony_ciecma_proxy_create (ecma_value_t target, /**< proxy target */
73425bb815Sopenharmony_ci                   ecma_value_t handler) /**< proxy handler */
74425bb815Sopenharmony_ci{
75425bb815Sopenharmony_ci  /* 1 - 4. */
76425bb815Sopenharmony_ci  if (!ecma_proxy_validate (target) || !ecma_proxy_validate (handler))
77425bb815Sopenharmony_ci  {
78425bb815Sopenharmony_ci    ecma_raise_type_error (ECMA_ERR_MSG ("Cannot create proxy with a non-object target or handler"));
79425bb815Sopenharmony_ci    return NULL;
80425bb815Sopenharmony_ci  }
81425bb815Sopenharmony_ci
82425bb815Sopenharmony_ci  /* 5 - 6. */
83425bb815Sopenharmony_ci  ecma_object_t *obj_p = ecma_create_object (ecma_builtin_get (ECMA_BUILTIN_ID_OBJECT_PROTOTYPE),
84425bb815Sopenharmony_ci                                             sizeof (ecma_proxy_object_t),
85425bb815Sopenharmony_ci                                             ECMA_OBJECT_TYPE_PROXY);
86425bb815Sopenharmony_ci
87425bb815Sopenharmony_ci  ecma_proxy_object_t *proxy_obj_p = (ecma_proxy_object_t *) obj_p;
88425bb815Sopenharmony_ci
89425bb815Sopenharmony_ci  /* 8. */
90425bb815Sopenharmony_ci  proxy_obj_p->target = target;
91425bb815Sopenharmony_ci  /* 9. */
92425bb815Sopenharmony_ci  proxy_obj_p->handler = handler;
93425bb815Sopenharmony_ci
94425bb815Sopenharmony_ci  /* 10. */
95425bb815Sopenharmony_ci  return obj_p;
96425bb815Sopenharmony_ci} /* ecma_proxy_create */
97425bb815Sopenharmony_ci
98425bb815Sopenharmony_ci/**
99425bb815Sopenharmony_ci * Definition of Proxy Revocation Function
100425bb815Sopenharmony_ci *
101425bb815Sopenharmony_ci * See also:
102425bb815Sopenharmony_ci *         ES2015 26.2.2.1.1
103425bb815Sopenharmony_ci *
104425bb815Sopenharmony_ci * @return ECMA_VALUE_UNDEFINED
105425bb815Sopenharmony_ci */
106425bb815Sopenharmony_ciecma_value_t
107425bb815Sopenharmony_ciecma_proxy_revoke_cb (const ecma_value_t function_obj, /**< the function itself */
108425bb815Sopenharmony_ci                      const ecma_value_t this_val, /**< this_arg of the function */
109425bb815Sopenharmony_ci                      const ecma_value_t args_p[], /**< argument list */
110425bb815Sopenharmony_ci                      const ecma_length_t args_count) /**< argument number */
111425bb815Sopenharmony_ci{
112425bb815Sopenharmony_ci  JERRY_UNUSED_3 (this_val, args_p, args_count);
113425bb815Sopenharmony_ci
114425bb815Sopenharmony_ci  ecma_object_t *func_obj_p = ecma_get_object_from_value (function_obj);
115425bb815Sopenharmony_ci
116425bb815Sopenharmony_ci  /* 1. */
117425bb815Sopenharmony_ci  ecma_revocable_proxy_object_t *rev_proxy_p = (ecma_revocable_proxy_object_t *) func_obj_p;
118425bb815Sopenharmony_ci
119425bb815Sopenharmony_ci  /* 2. */
120425bb815Sopenharmony_ci  if (ecma_is_value_null (rev_proxy_p->proxy))
121425bb815Sopenharmony_ci  {
122425bb815Sopenharmony_ci    return ECMA_VALUE_UNDEFINED;
123425bb815Sopenharmony_ci  }
124425bb815Sopenharmony_ci
125425bb815Sopenharmony_ci  /* 4. */
126425bb815Sopenharmony_ci  ecma_proxy_object_t *proxy_p = (ecma_proxy_object_t *) ecma_get_object_from_value (rev_proxy_p->proxy);
127425bb815Sopenharmony_ci  JERRY_ASSERT (ECMA_OBJECT_IS_PROXY ((ecma_object_t *) proxy_p));
128425bb815Sopenharmony_ci
129425bb815Sopenharmony_ci  /* 3. */
130425bb815Sopenharmony_ci  rev_proxy_p->proxy = ECMA_VALUE_NULL;
131425bb815Sopenharmony_ci
132425bb815Sopenharmony_ci  /* 5. */
133425bb815Sopenharmony_ci  proxy_p->target = ECMA_VALUE_NULL;
134425bb815Sopenharmony_ci
135425bb815Sopenharmony_ci  /* 6. */
136425bb815Sopenharmony_ci  proxy_p->handler = ECMA_VALUE_NULL;
137425bb815Sopenharmony_ci
138425bb815Sopenharmony_ci  /* 7. */
139425bb815Sopenharmony_ci  return ECMA_VALUE_UNDEFINED;
140425bb815Sopenharmony_ci} /* ecma_proxy_revoke_cb */
141425bb815Sopenharmony_ci
142425bb815Sopenharmony_ci/**
143425bb815Sopenharmony_ci * Proxy.revocable operation for create a new revocable proxy object
144425bb815Sopenharmony_ci *
145425bb815Sopenharmony_ci * See also:
146425bb815Sopenharmony_ci *         ES2015 26.2.2.1
147425bb815Sopenharmony_ci *
148425bb815Sopenharmony_ci * @return NULL - if the operation fails
149425bb815Sopenharmony_ci *         pointer to the newly created revocable proxy object - otherwise
150425bb815Sopenharmony_ci */
151425bb815Sopenharmony_ciecma_object_t *
152425bb815Sopenharmony_ciecma_proxy_create_revocable (ecma_value_t target, /**< target argument */
153425bb815Sopenharmony_ci                             ecma_value_t handler) /**< handler argument */
154425bb815Sopenharmony_ci{
155425bb815Sopenharmony_ci  /* 1. */
156425bb815Sopenharmony_ci  ecma_object_t *proxy_p = ecma_proxy_create (target, handler);
157425bb815Sopenharmony_ci
158425bb815Sopenharmony_ci  /* 2. */
159425bb815Sopenharmony_ci  if (proxy_p == NULL)
160425bb815Sopenharmony_ci  {
161425bb815Sopenharmony_ci    return proxy_p;
162425bb815Sopenharmony_ci  }
163425bb815Sopenharmony_ci
164425bb815Sopenharmony_ci  ecma_value_t proxy_value = ecma_make_object_value (proxy_p);
165425bb815Sopenharmony_ci
166425bb815Sopenharmony_ci  /* 3. */
167425bb815Sopenharmony_ci  ecma_object_t *func_obj_p;
168425bb815Sopenharmony_ci  func_obj_p = ecma_create_object (ecma_builtin_get (ECMA_BUILTIN_ID_FUNCTION_PROTOTYPE),
169425bb815Sopenharmony_ci                                   sizeof (ecma_revocable_proxy_object_t),
170425bb815Sopenharmony_ci                                   ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION);
171425bb815Sopenharmony_ci
172425bb815Sopenharmony_ci  ecma_revocable_proxy_object_t *rev_proxy_p = (ecma_revocable_proxy_object_t *) func_obj_p;
173425bb815Sopenharmony_ci  rev_proxy_p->header.u.external_handler_cb = ecma_proxy_revoke_cb;
174425bb815Sopenharmony_ci  /* 4. */
175425bb815Sopenharmony_ci  rev_proxy_p->proxy = proxy_value;
176425bb815Sopenharmony_ci
177425bb815Sopenharmony_ci  ecma_property_value_t *prop_value_p;
178425bb815Sopenharmony_ci  ecma_value_t revoker = ecma_make_object_value (func_obj_p);
179425bb815Sopenharmony_ci
180425bb815Sopenharmony_ci  /* 5. */
181425bb815Sopenharmony_ci  ecma_object_t *obj_p = ecma_create_object (ecma_builtin_get (ECMA_BUILTIN_ID_OBJECT_PROTOTYPE),
182425bb815Sopenharmony_ci                                             0,
183425bb815Sopenharmony_ci                                             ECMA_OBJECT_TYPE_GENERAL);
184425bb815Sopenharmony_ci
185425bb815Sopenharmony_ci  /* 6. */
186425bb815Sopenharmony_ci  prop_value_p = ecma_create_named_data_property (obj_p,
187425bb815Sopenharmony_ci                                                  ecma_get_magic_string (LIT_MAGIC_STRING_PROXY),
188425bb815Sopenharmony_ci                                                  ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE,
189425bb815Sopenharmony_ci                                                  NULL);
190425bb815Sopenharmony_ci  prop_value_p->value = proxy_value;
191425bb815Sopenharmony_ci
192425bb815Sopenharmony_ci  /* 7. */
193425bb815Sopenharmony_ci  prop_value_p = ecma_create_named_data_property (obj_p,
194425bb815Sopenharmony_ci                                                  ecma_get_magic_string (LIT_MAGIC_STRING_REVOKE),
195425bb815Sopenharmony_ci                                                  ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE,
196425bb815Sopenharmony_ci                                                  NULL);
197425bb815Sopenharmony_ci  prop_value_p->value = revoker;
198425bb815Sopenharmony_ci
199425bb815Sopenharmony_ci  ecma_deref_object (proxy_p);
200425bb815Sopenharmony_ci  ecma_deref_object (func_obj_p);
201425bb815Sopenharmony_ci
202425bb815Sopenharmony_ci  /* 8. */
203425bb815Sopenharmony_ci  return obj_p;
204425bb815Sopenharmony_ci} /* ecma_proxy_create_revocable */
205425bb815Sopenharmony_ci
206425bb815Sopenharmony_ci/**
207425bb815Sopenharmony_ci * Internal find property operation for Proxy object
208425bb815Sopenharmony_ci *
209425bb815Sopenharmony_ci * Note: Returned value must be freed with ecma_free_value.
210425bb815Sopenharmony_ci *
211425bb815Sopenharmony_ci * @return ECMA_VALUE_ERROR - if the operation fails
212425bb815Sopenharmony_ci *         ECMA_VALUE_NOT_FOUND - if the property is not found
213425bb815Sopenharmony_ci *         value of the property - otherwise
214425bb815Sopenharmony_ci */
215425bb815Sopenharmony_ciecma_value_t
216425bb815Sopenharmony_ciecma_proxy_object_find (ecma_object_t *obj_p, /**< proxy object */
217425bb815Sopenharmony_ci                        ecma_string_t *prop_name_p) /**< property name */
218425bb815Sopenharmony_ci{
219425bb815Sopenharmony_ci  JERRY_ASSERT (ECMA_OBJECT_IS_PROXY (obj_p));
220425bb815Sopenharmony_ci
221425bb815Sopenharmony_ci  ecma_value_t has_result = ecma_proxy_object_has (obj_p, prop_name_p);
222425bb815Sopenharmony_ci
223425bb815Sopenharmony_ci  if (ECMA_IS_VALUE_ERROR (has_result))
224425bb815Sopenharmony_ci  {
225425bb815Sopenharmony_ci    return has_result;
226425bb815Sopenharmony_ci  }
227425bb815Sopenharmony_ci
228425bb815Sopenharmony_ci  if (ecma_is_value_false (has_result))
229425bb815Sopenharmony_ci  {
230425bb815Sopenharmony_ci    return ECMA_VALUE_NOT_FOUND;
231425bb815Sopenharmony_ci  }
232425bb815Sopenharmony_ci
233425bb815Sopenharmony_ci  return ecma_proxy_object_get (obj_p, prop_name_p, ecma_make_object_value (obj_p));
234425bb815Sopenharmony_ci} /* ecma_proxy_object_find */
235425bb815Sopenharmony_ci
236425bb815Sopenharmony_ci/**
237425bb815Sopenharmony_ci * Convert the result of the ecma_proxy_object_get_prototype_of to compressed pointer
238425bb815Sopenharmony_ci *
239425bb815Sopenharmony_ci * Note: if `proto` is non-null, the reference from the object is released
240425bb815Sopenharmony_ci *
241425bb815Sopenharmony_ci * @return compressed pointer to the `proto` value
242425bb815Sopenharmony_ci */
243425bb815Sopenharmony_cijmem_cpointer_t
244425bb815Sopenharmony_ciecma_proxy_object_prototype_to_cp (ecma_value_t proto) /**< ECMA_VALUE_NULL or object */
245425bb815Sopenharmony_ci{
246425bb815Sopenharmony_ci  JERRY_ASSERT (ecma_is_value_null (proto) || ecma_is_value_object (proto));
247425bb815Sopenharmony_ci
248425bb815Sopenharmony_ci  if (ecma_is_value_null (proto))
249425bb815Sopenharmony_ci  {
250425bb815Sopenharmony_ci    return JMEM_CP_NULL;
251425bb815Sopenharmony_ci  }
252425bb815Sopenharmony_ci
253425bb815Sopenharmony_ci  jmem_cpointer_t proto_cp;
254425bb815Sopenharmony_ci  ecma_object_t *proto_obj_p = ecma_get_object_from_value (proto);
255425bb815Sopenharmony_ci  ECMA_SET_POINTER (proto_cp, proto_obj_p);
256425bb815Sopenharmony_ci  ecma_deref_object (proto_obj_p);
257425bb815Sopenharmony_ci
258425bb815Sopenharmony_ci  return proto_cp;
259425bb815Sopenharmony_ci} /* ecma_proxy_object_prototype_to_cp */
260425bb815Sopenharmony_ci
261425bb815Sopenharmony_ci/**
262425bb815Sopenharmony_ci * Helper method for validate the proxy object
263425bb815Sopenharmony_ci *
264425bb815Sopenharmony_ci * @return proxy trap - if the validation is successful
265425bb815Sopenharmony_ci *         ECMA_VALUE_ERROR - otherwise
266425bb815Sopenharmony_ci */
267425bb815Sopenharmony_cistatic ecma_value_t
268425bb815Sopenharmony_ciecma_validate_proxy_object (ecma_value_t handler, /**< proxy handler */
269425bb815Sopenharmony_ci                            lit_magic_string_id_t magic_id) /**< routine magic id */
270425bb815Sopenharmony_ci{
271425bb815Sopenharmony_ci  if (ecma_is_value_null (handler))
272425bb815Sopenharmony_ci  {
273425bb815Sopenharmony_ci    return ecma_raise_type_error (ECMA_ERR_MSG ("Handler can not be null"));
274425bb815Sopenharmony_ci  }
275425bb815Sopenharmony_ci
276425bb815Sopenharmony_ci  JERRY_ASSERT (ecma_is_value_object (handler));
277425bb815Sopenharmony_ci
278425bb815Sopenharmony_ci  return ecma_op_get_method_by_magic_id (handler, magic_id);
279425bb815Sopenharmony_ci} /* ecma_validate_proxy_object */
280425bb815Sopenharmony_ci
281425bb815Sopenharmony_ci/* Interal operations */
282425bb815Sopenharmony_ci
283425bb815Sopenharmony_ci/**
284425bb815Sopenharmony_ci * The Proxy object [[GetPrototypeOf]] internal routine
285425bb815Sopenharmony_ci *
286425bb815Sopenharmony_ci * See also:
287425bb815Sopenharmony_ci *          ECMAScript v6, 9.5.1
288425bb815Sopenharmony_ci *
289425bb815Sopenharmony_ci * @return ECMA_VALUE_ERROR - if the operation fails
290425bb815Sopenharmony_ci *         ECMA_VALUE_NULL or valid object (prototype) otherwise
291425bb815Sopenharmony_ci */
292425bb815Sopenharmony_ciecma_value_t
293425bb815Sopenharmony_ciecma_proxy_object_get_prototype_of (ecma_object_t *obj_p) /**< proxy object */
294425bb815Sopenharmony_ci{
295425bb815Sopenharmony_ci  JERRY_ASSERT (ECMA_OBJECT_IS_PROXY (obj_p));
296425bb815Sopenharmony_ci
297425bb815Sopenharmony_ci  ecma_proxy_object_t *proxy_obj_p = (ecma_proxy_object_t *) obj_p;
298425bb815Sopenharmony_ci
299425bb815Sopenharmony_ci  /* 1. */
300425bb815Sopenharmony_ci  ecma_value_t handler = proxy_obj_p->handler;
301425bb815Sopenharmony_ci
302425bb815Sopenharmony_ci  /* 2-5. */
303425bb815Sopenharmony_ci  ecma_value_t trap = ecma_validate_proxy_object (handler, LIT_MAGIC_STRING_GET_PROTOTYPE_OF_UL);
304425bb815Sopenharmony_ci
305425bb815Sopenharmony_ci  /* 6. */
306425bb815Sopenharmony_ci  if (ECMA_IS_VALUE_ERROR (trap))
307425bb815Sopenharmony_ci  {
308425bb815Sopenharmony_ci    return trap;
309425bb815Sopenharmony_ci  }
310425bb815Sopenharmony_ci
311425bb815Sopenharmony_ci  ecma_value_t target = proxy_obj_p->target;
312425bb815Sopenharmony_ci  ecma_object_t *target_obj_p = ecma_get_object_from_value (target);
313425bb815Sopenharmony_ci
314425bb815Sopenharmony_ci  /* 7. */
315425bb815Sopenharmony_ci  if (ecma_is_value_undefined (trap))
316425bb815Sopenharmony_ci  {
317425bb815Sopenharmony_ci    return ecma_builtin_object_object_get_prototype_of (target_obj_p);
318425bb815Sopenharmony_ci  }
319425bb815Sopenharmony_ci
320425bb815Sopenharmony_ci  ecma_object_t *func_obj_p = ecma_get_object_from_value (trap);
321425bb815Sopenharmony_ci
322425bb815Sopenharmony_ci  /* 8. */
323425bb815Sopenharmony_ci  ecma_value_t handler_proto = ecma_op_function_call (func_obj_p, handler, &target, 1);
324425bb815Sopenharmony_ci
325425bb815Sopenharmony_ci  ecma_deref_object (func_obj_p);
326425bb815Sopenharmony_ci
327425bb815Sopenharmony_ci  /* 9. */
328425bb815Sopenharmony_ci  if (ECMA_IS_VALUE_ERROR (handler_proto))
329425bb815Sopenharmony_ci  {
330425bb815Sopenharmony_ci    return handler_proto;
331425bb815Sopenharmony_ci  }
332425bb815Sopenharmony_ci
333425bb815Sopenharmony_ci  /* 10. */
334425bb815Sopenharmony_ci  if (!ecma_is_value_object (handler_proto) && !ecma_is_value_null (handler_proto))
335425bb815Sopenharmony_ci  {
336425bb815Sopenharmony_ci    ecma_free_value (handler_proto);
337425bb815Sopenharmony_ci
338425bb815Sopenharmony_ci    return ecma_raise_type_error (ECMA_ERR_MSG ("Trap returned neither object nor null."));
339425bb815Sopenharmony_ci  }
340425bb815Sopenharmony_ci
341425bb815Sopenharmony_ci  /* 11. */
342425bb815Sopenharmony_ci  ecma_value_t extensible_target = ecma_builtin_object_object_is_extensible (target_obj_p);
343425bb815Sopenharmony_ci
344425bb815Sopenharmony_ci  /* 12. */
345425bb815Sopenharmony_ci  if (ECMA_IS_VALUE_ERROR (extensible_target))
346425bb815Sopenharmony_ci  {
347425bb815Sopenharmony_ci    ecma_free_value (handler_proto);
348425bb815Sopenharmony_ci
349425bb815Sopenharmony_ci    return extensible_target;
350425bb815Sopenharmony_ci  }
351425bb815Sopenharmony_ci
352425bb815Sopenharmony_ci  /* 13. */
353425bb815Sopenharmony_ci  if (ecma_is_value_true (extensible_target))
354425bb815Sopenharmony_ci  {
355425bb815Sopenharmony_ci    return handler_proto;
356425bb815Sopenharmony_ci  }
357425bb815Sopenharmony_ci
358425bb815Sopenharmony_ci  /* 14. */
359425bb815Sopenharmony_ci  ecma_value_t target_proto = ecma_builtin_object_object_get_prototype_of (target_obj_p);
360425bb815Sopenharmony_ci
361425bb815Sopenharmony_ci  /* 15. */
362425bb815Sopenharmony_ci  if (ECMA_IS_VALUE_ERROR (target_proto))
363425bb815Sopenharmony_ci  {
364425bb815Sopenharmony_ci    return target_proto;
365425bb815Sopenharmony_ci  }
366425bb815Sopenharmony_ci
367425bb815Sopenharmony_ci  ecma_value_t ret_value = handler_proto;
368425bb815Sopenharmony_ci
369425bb815Sopenharmony_ci  /* 16. */
370425bb815Sopenharmony_ci  if (handler_proto != target_proto)
371425bb815Sopenharmony_ci  {
372425bb815Sopenharmony_ci    ecma_free_value (handler_proto);
373425bb815Sopenharmony_ci
374425bb815Sopenharmony_ci    ret_value = ecma_raise_type_error (ECMA_ERR_MSG ("Proxy target is non-extensible, but the trap did not "
375425bb815Sopenharmony_ci                                                     "return its actual prototype."));
376425bb815Sopenharmony_ci  }
377425bb815Sopenharmony_ci
378425bb815Sopenharmony_ci  ecma_free_value (target_proto);
379425bb815Sopenharmony_ci
380425bb815Sopenharmony_ci  /* 17. */
381425bb815Sopenharmony_ci  return ret_value;
382425bb815Sopenharmony_ci} /* ecma_proxy_object_get_prototype_of */
383425bb815Sopenharmony_ci
384425bb815Sopenharmony_ci/**
385425bb815Sopenharmony_ci * The Proxy object [[SetPrototypeOf]] internal routine
386425bb815Sopenharmony_ci *
387425bb815Sopenharmony_ci * See also:
388425bb815Sopenharmony_ci *          ECMAScript v6, 9.5.2
389425bb815Sopenharmony_ci *
390425bb815Sopenharmony_ci * Note: Returned value is always a simple value so freeing it is unnecessary.
391425bb815Sopenharmony_ci *
392425bb815Sopenharmony_ci * @return ECMA_VALUE_ERROR - if the operation fails
393425bb815Sopenharmony_ci *         ECMA_VALUE_{TRUE/FALSE} - depends on whether the new prototype can be set for the given object
394425bb815Sopenharmony_ci */
395425bb815Sopenharmony_ciecma_value_t
396425bb815Sopenharmony_ciecma_proxy_object_set_prototype_of (ecma_object_t *obj_p, /**< proxy object */
397425bb815Sopenharmony_ci                                    ecma_value_t proto) /**< new prototype object */
398425bb815Sopenharmony_ci{
399425bb815Sopenharmony_ci  JERRY_ASSERT (ECMA_OBJECT_IS_PROXY (obj_p));
400425bb815Sopenharmony_ci
401425bb815Sopenharmony_ci  /* 1. */
402425bb815Sopenharmony_ci  JERRY_ASSERT (ecma_is_value_object (proto) || ecma_is_value_null (proto));
403425bb815Sopenharmony_ci
404425bb815Sopenharmony_ci  ecma_proxy_object_t *proxy_obj_p = (ecma_proxy_object_t *) obj_p;
405425bb815Sopenharmony_ci
406425bb815Sopenharmony_ci  /* 2. */
407425bb815Sopenharmony_ci  ecma_value_t handler = proxy_obj_p->handler;
408425bb815Sopenharmony_ci
409425bb815Sopenharmony_ci  /* 3-6. */
410425bb815Sopenharmony_ci  ecma_value_t trap = ecma_validate_proxy_object (handler, LIT_MAGIC_STRING_SET_PROTOTYPE_OF_UL);
411425bb815Sopenharmony_ci
412425bb815Sopenharmony_ci  /* 7.*/
413425bb815Sopenharmony_ci  if (ECMA_IS_VALUE_ERROR (trap))
414425bb815Sopenharmony_ci  {
415425bb815Sopenharmony_ci    return trap;
416425bb815Sopenharmony_ci  }
417425bb815Sopenharmony_ci
418425bb815Sopenharmony_ci  ecma_value_t target = proxy_obj_p->target;
419425bb815Sopenharmony_ci  ecma_object_t *target_obj_p = ecma_get_object_from_value (target);
420425bb815Sopenharmony_ci
421425bb815Sopenharmony_ci  /* 8. */
422425bb815Sopenharmony_ci  if (ecma_is_value_undefined (trap))
423425bb815Sopenharmony_ci  {
424425bb815Sopenharmony_ci    if (ECMA_OBJECT_IS_PROXY (target_obj_p))
425425bb815Sopenharmony_ci    {
426425bb815Sopenharmony_ci      return ecma_proxy_object_set_prototype_of (target_obj_p, proto);
427425bb815Sopenharmony_ci    }
428425bb815Sopenharmony_ci
429425bb815Sopenharmony_ci    return ecma_op_ordinary_object_set_prototype_of (target_obj_p, proto);
430425bb815Sopenharmony_ci  }
431425bb815Sopenharmony_ci
432425bb815Sopenharmony_ci  ecma_object_t *func_obj_p = ecma_get_object_from_value (trap);
433425bb815Sopenharmony_ci  ecma_value_t args[] = { target, proto };
434425bb815Sopenharmony_ci
435425bb815Sopenharmony_ci  /* 9. */
436425bb815Sopenharmony_ci  ecma_value_t trap_result = ecma_op_function_call (func_obj_p, handler, args, 2);
437425bb815Sopenharmony_ci
438425bb815Sopenharmony_ci  ecma_deref_object (func_obj_p);
439425bb815Sopenharmony_ci
440425bb815Sopenharmony_ci  /* 10. */
441425bb815Sopenharmony_ci  if (ECMA_IS_VALUE_ERROR (trap_result))
442425bb815Sopenharmony_ci  {
443425bb815Sopenharmony_ci    return trap_result;
444425bb815Sopenharmony_ci  }
445425bb815Sopenharmony_ci
446425bb815Sopenharmony_ci  bool boolean_trap_result = ecma_op_to_boolean (trap_result);
447425bb815Sopenharmony_ci
448425bb815Sopenharmony_ci  ecma_free_value (trap_result);
449425bb815Sopenharmony_ci
450425bb815Sopenharmony_ci  /* 11. */
451425bb815Sopenharmony_ci  ecma_value_t extensible_target = ecma_builtin_object_object_is_extensible (target_obj_p);
452425bb815Sopenharmony_ci
453425bb815Sopenharmony_ci  /* 12. */
454425bb815Sopenharmony_ci  if (ECMA_IS_VALUE_ERROR (extensible_target))
455425bb815Sopenharmony_ci  {
456425bb815Sopenharmony_ci    return extensible_target;
457425bb815Sopenharmony_ci  }
458425bb815Sopenharmony_ci
459425bb815Sopenharmony_ci  /* 13. */
460425bb815Sopenharmony_ci  if (ecma_is_value_true (extensible_target))
461425bb815Sopenharmony_ci  {
462425bb815Sopenharmony_ci    return ecma_make_boolean_value (boolean_trap_result);
463425bb815Sopenharmony_ci  }
464425bb815Sopenharmony_ci
465425bb815Sopenharmony_ci  /* 14. */
466425bb815Sopenharmony_ci  ecma_value_t target_proto = ecma_builtin_object_object_get_prototype_of (target_obj_p);
467425bb815Sopenharmony_ci
468425bb815Sopenharmony_ci  /* 15. */
469425bb815Sopenharmony_ci  if (ECMA_IS_VALUE_ERROR (target_proto))
470425bb815Sopenharmony_ci  {
471425bb815Sopenharmony_ci    return target_proto;
472425bb815Sopenharmony_ci  }
473425bb815Sopenharmony_ci
474425bb815Sopenharmony_ci  ecma_value_t ret_value = ecma_make_boolean_value (boolean_trap_result);
475425bb815Sopenharmony_ci
476425bb815Sopenharmony_ci  /* 16. */
477425bb815Sopenharmony_ci  if (boolean_trap_result && (target_proto != proto))
478425bb815Sopenharmony_ci  {
479425bb815Sopenharmony_ci    ret_value = ecma_raise_type_error (ECMA_ERR_MSG ("Target object is non-extensible and trap "
480425bb815Sopenharmony_ci                                                     "returned different prototype."));
481425bb815Sopenharmony_ci  }
482425bb815Sopenharmony_ci
483425bb815Sopenharmony_ci  ecma_free_value (target_proto);
484425bb815Sopenharmony_ci
485425bb815Sopenharmony_ci  /* 17. */
486425bb815Sopenharmony_ci  return ret_value;
487425bb815Sopenharmony_ci} /* ecma_proxy_object_set_prototype_of */
488425bb815Sopenharmony_ci
489425bb815Sopenharmony_ci/**
490425bb815Sopenharmony_ci * The Proxy object [[isExtensible]] internal routine
491425bb815Sopenharmony_ci *
492425bb815Sopenharmony_ci * See also:
493425bb815Sopenharmony_ci *          ECMAScript v6, 9.5.3
494425bb815Sopenharmony_ci *
495425bb815Sopenharmony_ci * Note: Returned value is always a simple value so freeing it is unnecessary.
496425bb815Sopenharmony_ci *
497425bb815Sopenharmony_ci * @return ECMA_VALUE_ERROR - if the operation fails
498425bb815Sopenharmony_ci *         ECMA_VALUE_{TRUE/FALSE} - depends on whether the object is extensible
499425bb815Sopenharmony_ci */
500425bb815Sopenharmony_ciecma_value_t
501425bb815Sopenharmony_ciecma_proxy_object_is_extensible (ecma_object_t *obj_p) /**< proxy object */
502425bb815Sopenharmony_ci{
503425bb815Sopenharmony_ci  JERRY_ASSERT (ECMA_OBJECT_IS_PROXY (obj_p));
504425bb815Sopenharmony_ci
505425bb815Sopenharmony_ci  ecma_proxy_object_t *proxy_obj_p = (ecma_proxy_object_t *) obj_p;
506425bb815Sopenharmony_ci
507425bb815Sopenharmony_ci  /* 1. */
508425bb815Sopenharmony_ci  ecma_value_t handler = proxy_obj_p->handler;
509425bb815Sopenharmony_ci
510425bb815Sopenharmony_ci  /* 2-5. */
511425bb815Sopenharmony_ci  ecma_value_t trap = ecma_validate_proxy_object (handler, LIT_MAGIC_STRING_IS_EXTENSIBLE);
512425bb815Sopenharmony_ci
513425bb815Sopenharmony_ci  /* 6. */
514425bb815Sopenharmony_ci  if (ECMA_IS_VALUE_ERROR (trap))
515425bb815Sopenharmony_ci  {
516425bb815Sopenharmony_ci    return trap;
517425bb815Sopenharmony_ci  }
518425bb815Sopenharmony_ci
519425bb815Sopenharmony_ci  ecma_value_t target = proxy_obj_p->target;
520425bb815Sopenharmony_ci  ecma_object_t *target_obj_p = ecma_get_object_from_value (target);
521425bb815Sopenharmony_ci
522425bb815Sopenharmony_ci  /* 7. */
523425bb815Sopenharmony_ci  if (ecma_is_value_undefined (trap))
524425bb815Sopenharmony_ci  {
525425bb815Sopenharmony_ci    return ecma_builtin_object_object_is_extensible (target_obj_p);
526425bb815Sopenharmony_ci  }
527425bb815Sopenharmony_ci
528425bb815Sopenharmony_ci  ecma_object_t *func_obj_p = ecma_get_object_from_value (trap);
529425bb815Sopenharmony_ci
530425bb815Sopenharmony_ci  /* 8. */
531425bb815Sopenharmony_ci  ecma_value_t trap_result = ecma_op_function_call (func_obj_p, handler, &target, 1);
532425bb815Sopenharmony_ci
533425bb815Sopenharmony_ci  ecma_deref_object (func_obj_p);
534425bb815Sopenharmony_ci
535425bb815Sopenharmony_ci  /* 9. */
536425bb815Sopenharmony_ci  if (ECMA_IS_VALUE_ERROR (trap_result))
537425bb815Sopenharmony_ci  {
538425bb815Sopenharmony_ci    return trap_result;
539425bb815Sopenharmony_ci  }
540425bb815Sopenharmony_ci
541425bb815Sopenharmony_ci  bool boolean_trap_result = ecma_op_to_boolean (trap_result);
542425bb815Sopenharmony_ci
543425bb815Sopenharmony_ci  ecma_free_value (trap_result);
544425bb815Sopenharmony_ci
545425bb815Sopenharmony_ci  bool target_result;
546425bb815Sopenharmony_ci
547425bb815Sopenharmony_ci  /* 10. */
548425bb815Sopenharmony_ci  if (ECMA_OBJECT_IS_PROXY (target_obj_p))
549425bb815Sopenharmony_ci  {
550425bb815Sopenharmony_ci    ecma_value_t proxy_is_ext = ecma_proxy_object_is_extensible (target_obj_p);
551425bb815Sopenharmony_ci
552425bb815Sopenharmony_ci    if (ECMA_IS_VALUE_ERROR (proxy_is_ext))
553425bb815Sopenharmony_ci    {
554425bb815Sopenharmony_ci      return proxy_is_ext;
555425bb815Sopenharmony_ci    }
556425bb815Sopenharmony_ci
557425bb815Sopenharmony_ci    target_result = ecma_is_value_true (proxy_is_ext);
558425bb815Sopenharmony_ci  }
559425bb815Sopenharmony_ci  else
560425bb815Sopenharmony_ci  {
561425bb815Sopenharmony_ci    target_result = ecma_op_ordinary_object_is_extensible (target_obj_p);
562425bb815Sopenharmony_ci  }
563425bb815Sopenharmony_ci
564425bb815Sopenharmony_ci  /* 12. */
565425bb815Sopenharmony_ci  if (boolean_trap_result != target_result)
566425bb815Sopenharmony_ci  {
567425bb815Sopenharmony_ci    return ecma_raise_type_error (ECMA_ERR_MSG ("Trap result does not reflect extensibility of proxy target"));
568425bb815Sopenharmony_ci  }
569425bb815Sopenharmony_ci
570425bb815Sopenharmony_ci  return ecma_make_boolean_value (boolean_trap_result);
571425bb815Sopenharmony_ci} /* ecma_proxy_object_is_extensible */
572425bb815Sopenharmony_ci
573425bb815Sopenharmony_ci/**
574425bb815Sopenharmony_ci * The Proxy object [[PreventExtensions]] internal routine
575425bb815Sopenharmony_ci *
576425bb815Sopenharmony_ci * See also:
577425bb815Sopenharmony_ci *          ECMAScript v6, 9.5.4
578425bb815Sopenharmony_ci *
579425bb815Sopenharmony_ci * Note: Returned value is always a simple value so freeing it is unnecessary.
580425bb815Sopenharmony_ci *
581425bb815Sopenharmony_ci * @return ECMA_VALUE_ERROR - if the operation fails
582425bb815Sopenharmony_ci *         ECMA_VALUE_{TRUE/FALSE} - depends on whether the object can be set as inextensible
583425bb815Sopenharmony_ci */
584425bb815Sopenharmony_ciecma_value_t
585425bb815Sopenharmony_ciecma_proxy_object_prevent_extensions (ecma_object_t *obj_p) /**< proxy object */
586425bb815Sopenharmony_ci{
587425bb815Sopenharmony_ci  JERRY_ASSERT (ECMA_OBJECT_IS_PROXY (obj_p));
588425bb815Sopenharmony_ci
589425bb815Sopenharmony_ci  ecma_proxy_object_t *proxy_obj_p = (ecma_proxy_object_t *) obj_p;
590425bb815Sopenharmony_ci
591425bb815Sopenharmony_ci  /* 1. */
592425bb815Sopenharmony_ci  ecma_value_t handler = proxy_obj_p->handler;
593425bb815Sopenharmony_ci
594425bb815Sopenharmony_ci  /* 2-5. */
595425bb815Sopenharmony_ci  ecma_value_t trap = ecma_validate_proxy_object (handler, LIT_MAGIC_STRING_PREVENT_EXTENSIONS_UL);
596425bb815Sopenharmony_ci
597425bb815Sopenharmony_ci  /* 6. */
598425bb815Sopenharmony_ci  if (ECMA_IS_VALUE_ERROR (trap))
599425bb815Sopenharmony_ci  {
600425bb815Sopenharmony_ci    return trap;
601425bb815Sopenharmony_ci  }
602425bb815Sopenharmony_ci
603425bb815Sopenharmony_ci  ecma_value_t target = proxy_obj_p->target;
604425bb815Sopenharmony_ci  ecma_object_t *target_obj_p = ecma_get_object_from_value (target);
605425bb815Sopenharmony_ci
606425bb815Sopenharmony_ci  /* 7. */
607425bb815Sopenharmony_ci  if (ecma_is_value_undefined (trap))
608425bb815Sopenharmony_ci  {
609425bb815Sopenharmony_ci    ecma_value_t ret_value = ecma_builtin_object_object_prevent_extensions (target_obj_p);
610425bb815Sopenharmony_ci
611425bb815Sopenharmony_ci    if (ECMA_IS_VALUE_ERROR (ret_value))
612425bb815Sopenharmony_ci    {
613425bb815Sopenharmony_ci      return ret_value;
614425bb815Sopenharmony_ci    }
615425bb815Sopenharmony_ci
616425bb815Sopenharmony_ci    ecma_deref_object (target_obj_p);
617425bb815Sopenharmony_ci
618425bb815Sopenharmony_ci    return ECMA_VALUE_TRUE;
619425bb815Sopenharmony_ci  }
620425bb815Sopenharmony_ci
621425bb815Sopenharmony_ci  ecma_object_t *func_obj_p = ecma_get_object_from_value (trap);
622425bb815Sopenharmony_ci
623425bb815Sopenharmony_ci  /* 8. */
624425bb815Sopenharmony_ci  ecma_value_t trap_result = ecma_op_function_call (func_obj_p, handler, &target, 1);
625425bb815Sopenharmony_ci
626425bb815Sopenharmony_ci  ecma_deref_object (func_obj_p);
627425bb815Sopenharmony_ci
628425bb815Sopenharmony_ci  /* 9. */
629425bb815Sopenharmony_ci  if (ECMA_IS_VALUE_ERROR (trap_result))
630425bb815Sopenharmony_ci  {
631425bb815Sopenharmony_ci    return trap_result;
632425bb815Sopenharmony_ci  }
633425bb815Sopenharmony_ci
634425bb815Sopenharmony_ci  bool boolean_trap_result = ecma_op_to_boolean (trap_result);
635425bb815Sopenharmony_ci
636425bb815Sopenharmony_ci  ecma_free_value (trap_result);
637425bb815Sopenharmony_ci
638425bb815Sopenharmony_ci  /* 10. */
639425bb815Sopenharmony_ci  if (boolean_trap_result)
640425bb815Sopenharmony_ci  {
641425bb815Sopenharmony_ci    ecma_value_t target_is_ext = ecma_builtin_object_object_is_extensible (target_obj_p);
642425bb815Sopenharmony_ci
643425bb815Sopenharmony_ci    if (ECMA_IS_VALUE_ERROR (target_is_ext))
644425bb815Sopenharmony_ci    {
645425bb815Sopenharmony_ci      return target_is_ext;
646425bb815Sopenharmony_ci    }
647425bb815Sopenharmony_ci
648425bb815Sopenharmony_ci    if (ecma_is_value_true (target_is_ext))
649425bb815Sopenharmony_ci    {
650425bb815Sopenharmony_ci      return ecma_raise_type_error (ECMA_ERR_MSG ("Trap result does not reflect inextensibility of proxy target"));
651425bb815Sopenharmony_ci    }
652425bb815Sopenharmony_ci  }
653425bb815Sopenharmony_ci
654425bb815Sopenharmony_ci  /* 11. */
655425bb815Sopenharmony_ci  return ecma_make_boolean_value (boolean_trap_result);
656425bb815Sopenharmony_ci} /* ecma_proxy_object_prevent_extensions */
657425bb815Sopenharmony_ci
658425bb815Sopenharmony_ci/**
659425bb815Sopenharmony_ci * The Proxy object [[GetOwnProperty]] internal routine
660425bb815Sopenharmony_ci *
661425bb815Sopenharmony_ci * See also:
662425bb815Sopenharmony_ci *          ECMAScript v6, 9.5.5
663425bb815Sopenharmony_ci *
664425bb815Sopenharmony_ci * Note: - Returned value is always a simple value so freeing it is unnecessary.
665425bb815Sopenharmony_ci *       - If the operation does not fail, freeing the filled property descriptor is the caller's responsibility
666425bb815Sopenharmony_ci *
667425bb815Sopenharmony_ci * @return ECMA_VALUE_ERROR - if the operation fails
668425bb815Sopenharmony_ci *         ECMA_VALUE_{TRUE_FALSE} - depends on whether object has property with the given name
669425bb815Sopenharmony_ci */
670425bb815Sopenharmony_ciecma_value_t
671425bb815Sopenharmony_ciecma_proxy_object_get_own_property_descriptor (ecma_object_t *obj_p, /**< proxy object */
672425bb815Sopenharmony_ci                                               ecma_string_t *prop_name_p, /**< property name */
673425bb815Sopenharmony_ci                                               ecma_property_descriptor_t *prop_desc_p) /**< [out] property
674425bb815Sopenharmony_ci                                                                                         *   descriptor */
675425bb815Sopenharmony_ci{
676425bb815Sopenharmony_ci  ecma_proxy_object_t *proxy_obj_p = (ecma_proxy_object_t *) obj_p;
677425bb815Sopenharmony_ci
678425bb815Sopenharmony_ci  /* 2. */
679425bb815Sopenharmony_ci  ecma_value_t handler = proxy_obj_p->handler;
680425bb815Sopenharmony_ci
681425bb815Sopenharmony_ci  /* 3-6. */
682425bb815Sopenharmony_ci  ecma_value_t trap = ecma_validate_proxy_object (handler, LIT_MAGIC_STRING_GET_OWN_PROPERTY_DESCRIPTOR_UL);
683425bb815Sopenharmony_ci
684425bb815Sopenharmony_ci  ecma_value_t target = proxy_obj_p->target;
685425bb815Sopenharmony_ci
686425bb815Sopenharmony_ci  /* 7. */
687425bb815Sopenharmony_ci  if (ECMA_IS_VALUE_ERROR (trap))
688425bb815Sopenharmony_ci  {
689425bb815Sopenharmony_ci    return trap;
690425bb815Sopenharmony_ci  }
691425bb815Sopenharmony_ci
692425bb815Sopenharmony_ci  ecma_object_t *target_obj_p = ecma_get_object_from_value (target);
693425bb815Sopenharmony_ci
694425bb815Sopenharmony_ci  /* 8. */
695425bb815Sopenharmony_ci  if (ecma_is_value_undefined (trap))
696425bb815Sopenharmony_ci  {
697425bb815Sopenharmony_ci    return ecma_op_object_get_own_property_descriptor (target_obj_p, prop_name_p, prop_desc_p);
698425bb815Sopenharmony_ci  }
699425bb815Sopenharmony_ci
700425bb815Sopenharmony_ci  ecma_object_t *func_obj_p = ecma_get_object_from_value (trap);
701425bb815Sopenharmony_ci  ecma_value_t prop_value = ecma_make_prop_name_value (prop_name_p);
702425bb815Sopenharmony_ci  ecma_value_t args[] = { target, prop_value };
703425bb815Sopenharmony_ci
704425bb815Sopenharmony_ci  /* 9. */
705425bb815Sopenharmony_ci  ecma_value_t trap_result = ecma_op_function_call (func_obj_p, handler, args, 2);
706425bb815Sopenharmony_ci  ecma_deref_object (func_obj_p);
707425bb815Sopenharmony_ci
708425bb815Sopenharmony_ci  /* 10. */
709425bb815Sopenharmony_ci  if (ECMA_IS_VALUE_ERROR (trap_result))
710425bb815Sopenharmony_ci  {
711425bb815Sopenharmony_ci    return trap_result;
712425bb815Sopenharmony_ci  }
713425bb815Sopenharmony_ci
714425bb815Sopenharmony_ci  /* 11. */
715425bb815Sopenharmony_ci  if (!ecma_is_value_object (trap_result) && !ecma_is_value_undefined (trap_result))
716425bb815Sopenharmony_ci  {
717425bb815Sopenharmony_ci    ecma_free_value (trap_result);
718425bb815Sopenharmony_ci    return ecma_raise_type_error (ECMA_ERR_MSG ("Trap is not object nor undefined."));
719425bb815Sopenharmony_ci  }
720425bb815Sopenharmony_ci
721425bb815Sopenharmony_ci  /* 12. */
722425bb815Sopenharmony_ci  ecma_property_descriptor_t target_desc;
723425bb815Sopenharmony_ci  ecma_value_t target_status = ecma_op_object_get_own_property_descriptor (target_obj_p, prop_name_p, &target_desc);
724425bb815Sopenharmony_ci
725425bb815Sopenharmony_ci  /* 13. */
726425bb815Sopenharmony_ci  if (ECMA_IS_VALUE_ERROR (target_status))
727425bb815Sopenharmony_ci  {
728425bb815Sopenharmony_ci    ecma_free_value (trap_result);
729425bb815Sopenharmony_ci    return target_status;
730425bb815Sopenharmony_ci  }
731425bb815Sopenharmony_ci
732425bb815Sopenharmony_ci  /* 14. */
733425bb815Sopenharmony_ci  if (ecma_is_value_undefined (trap_result))
734425bb815Sopenharmony_ci  {
735425bb815Sopenharmony_ci    /* .a */
736425bb815Sopenharmony_ci    if (ecma_is_value_false (target_status))
737425bb815Sopenharmony_ci    {
738425bb815Sopenharmony_ci      return ECMA_VALUE_FALSE;
739425bb815Sopenharmony_ci    }
740425bb815Sopenharmony_ci    /* .b */
741425bb815Sopenharmony_ci    if (!(target_desc.flags & ECMA_PROP_IS_CONFIGURABLE))
742425bb815Sopenharmony_ci    {
743425bb815Sopenharmony_ci      ecma_free_property_descriptor (&target_desc);
744425bb815Sopenharmony_ci      return ecma_raise_type_error (ECMA_ERR_MSG ("Given property is a non-configurable"
745425bb815Sopenharmony_ci                                                  " data property on the proxy target"));
746425bb815Sopenharmony_ci    }
747425bb815Sopenharmony_ci
748425bb815Sopenharmony_ci    /* .c */
749425bb815Sopenharmony_ci    ecma_free_property_descriptor (&target_desc);
750425bb815Sopenharmony_ci    ecma_value_t extensible_target = ecma_builtin_object_object_is_extensible (target_obj_p);
751425bb815Sopenharmony_ci
752425bb815Sopenharmony_ci    /* .d */
753425bb815Sopenharmony_ci    if (ECMA_IS_VALUE_ERROR (extensible_target))
754425bb815Sopenharmony_ci    {
755425bb815Sopenharmony_ci      return extensible_target;
756425bb815Sopenharmony_ci    }
757425bb815Sopenharmony_ci
758425bb815Sopenharmony_ci    /* .e */
759425bb815Sopenharmony_ci    JERRY_ASSERT (ecma_is_value_boolean (extensible_target));
760425bb815Sopenharmony_ci
761425bb815Sopenharmony_ci    /* .f */
762425bb815Sopenharmony_ci    if (ecma_is_value_false (extensible_target))
763425bb815Sopenharmony_ci    {
764425bb815Sopenharmony_ci      return ecma_raise_type_error (ECMA_ERR_MSG ("Target not extensible."));
765425bb815Sopenharmony_ci    }
766425bb815Sopenharmony_ci
767425bb815Sopenharmony_ci    /* .g */
768425bb815Sopenharmony_ci    return ECMA_VALUE_FALSE;
769425bb815Sopenharmony_ci  }
770425bb815Sopenharmony_ci
771425bb815Sopenharmony_ci  /* 15. */
772425bb815Sopenharmony_ci  ecma_value_t extensible_target = ecma_builtin_object_object_is_extensible (target_obj_p);
773425bb815Sopenharmony_ci
774425bb815Sopenharmony_ci  /* 16. */
775425bb815Sopenharmony_ci  if (ECMA_IS_VALUE_ERROR (extensible_target))
776425bb815Sopenharmony_ci  {
777425bb815Sopenharmony_ci    if (ecma_is_value_true (target_status))
778425bb815Sopenharmony_ci    {
779425bb815Sopenharmony_ci      ecma_free_property_descriptor (&target_desc);
780425bb815Sopenharmony_ci    }
781425bb815Sopenharmony_ci    ecma_free_value (trap_result);
782425bb815Sopenharmony_ci    return extensible_target;
783425bb815Sopenharmony_ci  }
784425bb815Sopenharmony_ci
785425bb815Sopenharmony_ci  /* 17, 19 */
786425bb815Sopenharmony_ci  ecma_value_t result_val = ecma_op_to_property_descriptor (trap_result, prop_desc_p);
787425bb815Sopenharmony_ci
788425bb815Sopenharmony_ci  ecma_op_to_complete_property_descriptor (prop_desc_p);
789425bb815Sopenharmony_ci  ecma_free_value (trap_result);
790425bb815Sopenharmony_ci
791425bb815Sopenharmony_ci  /* 18. */
792425bb815Sopenharmony_ci  if (ECMA_IS_VALUE_ERROR (result_val))
793425bb815Sopenharmony_ci  {
794425bb815Sopenharmony_ci    if (ecma_is_value_true (target_status))
795425bb815Sopenharmony_ci    {
796425bb815Sopenharmony_ci      ecma_free_property_descriptor (&target_desc);
797425bb815Sopenharmony_ci    }
798425bb815Sopenharmony_ci    return result_val;
799425bb815Sopenharmony_ci  }
800425bb815Sopenharmony_ci
801425bb815Sopenharmony_ci  /* 20. */
802425bb815Sopenharmony_ci  bool is_extensible = ecma_is_value_true (extensible_target);
803425bb815Sopenharmony_ci
804425bb815Sopenharmony_ci  bool is_valid = ecma_op_is_compatible_property_descriptor (prop_desc_p,
805425bb815Sopenharmony_ci                                                             (ecma_is_value_true (target_status) ? &target_desc : NULL),
806425bb815Sopenharmony_ci                                                             is_extensible);
807425bb815Sopenharmony_ci
808425bb815Sopenharmony_ci  bool target_has_desc = ecma_is_value_true (target_status);
809425bb815Sopenharmony_ci  bool target_is_configurable = false;
810425bb815Sopenharmony_ci
811425bb815Sopenharmony_ci  if (target_has_desc)
812425bb815Sopenharmony_ci  {
813425bb815Sopenharmony_ci    target_is_configurable = ((target_desc.flags & ECMA_PROP_IS_CONFIGURABLE) != 0);
814425bb815Sopenharmony_ci    ecma_free_property_descriptor (&target_desc);
815425bb815Sopenharmony_ci  }
816425bb815Sopenharmony_ci
817425bb815Sopenharmony_ci  /* 21. */
818425bb815Sopenharmony_ci  if (!is_valid)
819425bb815Sopenharmony_ci  {
820425bb815Sopenharmony_ci    ecma_free_property_descriptor (prop_desc_p);
821425bb815Sopenharmony_ci    return ecma_raise_type_error (ECMA_ERR_MSG ("The two descriptors are not compatible."));
822425bb815Sopenharmony_ci  }
823425bb815Sopenharmony_ci
824425bb815Sopenharmony_ci  /* 22. */
825425bb815Sopenharmony_ci  else if (!(prop_desc_p->flags & ECMA_PROP_IS_CONFIGURABLE))
826425bb815Sopenharmony_ci  {
827425bb815Sopenharmony_ci    if (!target_has_desc || target_is_configurable)
828425bb815Sopenharmony_ci    {
829425bb815Sopenharmony_ci      ecma_free_property_descriptor (prop_desc_p);
830425bb815Sopenharmony_ci      return ecma_raise_type_error (ECMA_ERR_MSG ("Not compatible."));
831425bb815Sopenharmony_ci    }
832425bb815Sopenharmony_ci  }
833425bb815Sopenharmony_ci  return ECMA_VALUE_TRUE;
834425bb815Sopenharmony_ci} /* ecma_proxy_object_get_own_property_descriptor */
835425bb815Sopenharmony_ci
836425bb815Sopenharmony_ci/**
837425bb815Sopenharmony_ci * The Proxy object [[DefineOwnProperty]] internal routine
838425bb815Sopenharmony_ci *
839425bb815Sopenharmony_ci * See also:
840425bb815Sopenharmony_ci *          ECMAScript v6, 9.5.6
841425bb815Sopenharmony_ci *
842425bb815Sopenharmony_ci * Note: Returned value is always a simple value so freeing it is unnecessary.
843425bb815Sopenharmony_ci *
844425bb815Sopenharmony_ci * @return ECMA_VALUE_ERROR - if the operation fails
845425bb815Sopenharmony_ci *         ECMA_VALUE_{TRUE_FALSE} - depends on whether the property can be defined for the given object
846425bb815Sopenharmony_ci */
847425bb815Sopenharmony_ciecma_value_t
848425bb815Sopenharmony_ciecma_proxy_object_define_own_property (ecma_object_t *obj_p, /**< proxy object */
849425bb815Sopenharmony_ci                                       ecma_string_t *prop_name_p, /**< property name */
850425bb815Sopenharmony_ci                                       const ecma_property_descriptor_t *prop_desc_p) /**< property descriptor */
851425bb815Sopenharmony_ci{
852425bb815Sopenharmony_ci  JERRY_ASSERT (ECMA_OBJECT_IS_PROXY (obj_p));
853425bb815Sopenharmony_ci
854425bb815Sopenharmony_ci  ecma_proxy_object_t *proxy_obj_p = (ecma_proxy_object_t *) obj_p;
855425bb815Sopenharmony_ci
856425bb815Sopenharmony_ci  /* 2. */
857425bb815Sopenharmony_ci  ecma_value_t handler = proxy_obj_p->handler;
858425bb815Sopenharmony_ci
859425bb815Sopenharmony_ci  /* 3-6. */
860425bb815Sopenharmony_ci  ecma_value_t trap = ecma_validate_proxy_object (handler, LIT_MAGIC_STRING_DEFINE_PROPERTY_UL);
861425bb815Sopenharmony_ci
862425bb815Sopenharmony_ci  /* 7. */
863425bb815Sopenharmony_ci  if (ECMA_IS_VALUE_ERROR (trap))
864425bb815Sopenharmony_ci  {
865425bb815Sopenharmony_ci    return trap;
866425bb815Sopenharmony_ci  }
867425bb815Sopenharmony_ci
868425bb815Sopenharmony_ci  ecma_value_t target = proxy_obj_p->target;
869425bb815Sopenharmony_ci  ecma_object_t *target_obj_p = ecma_get_object_from_value (target);
870425bb815Sopenharmony_ci
871425bb815Sopenharmony_ci  /* 8. */
872425bb815Sopenharmony_ci  if (ecma_is_value_undefined (trap))
873425bb815Sopenharmony_ci  {
874425bb815Sopenharmony_ci    return ecma_op_object_define_own_property (target_obj_p, prop_name_p, prop_desc_p);
875425bb815Sopenharmony_ci  }
876425bb815Sopenharmony_ci
877425bb815Sopenharmony_ci  /* 9. */
878425bb815Sopenharmony_ci  ecma_object_t *desc_obj = ecma_op_from_property_descriptor (prop_desc_p);
879425bb815Sopenharmony_ci
880425bb815Sopenharmony_ci  ecma_object_t *func_obj_p = ecma_get_object_from_value (trap);
881425bb815Sopenharmony_ci  ecma_value_t prop_value = ecma_make_prop_name_value (prop_name_p);
882425bb815Sopenharmony_ci  ecma_value_t desc_obj_value = ecma_make_object_value (desc_obj);
883425bb815Sopenharmony_ci  ecma_value_t args[] = {target, prop_value, desc_obj_value};
884425bb815Sopenharmony_ci
885425bb815Sopenharmony_ci  /* 10. */
886425bb815Sopenharmony_ci  ecma_value_t trap_result = ecma_op_function_call (func_obj_p, handler, args, 3);
887425bb815Sopenharmony_ci
888425bb815Sopenharmony_ci  ecma_deref_object (func_obj_p);
889425bb815Sopenharmony_ci  ecma_deref_object (desc_obj);
890425bb815Sopenharmony_ci
891425bb815Sopenharmony_ci  /* 11. */
892425bb815Sopenharmony_ci  if (ECMA_IS_VALUE_ERROR (trap_result))
893425bb815Sopenharmony_ci  {
894425bb815Sopenharmony_ci    return trap_result;
895425bb815Sopenharmony_ci  }
896425bb815Sopenharmony_ci
897425bb815Sopenharmony_ci  bool boolean_trap_result = ecma_op_to_boolean (trap_result);
898425bb815Sopenharmony_ci
899425bb815Sopenharmony_ci  ecma_free_value (trap_result);
900425bb815Sopenharmony_ci
901425bb815Sopenharmony_ci  /* 12. */
902425bb815Sopenharmony_ci  if (!boolean_trap_result)
903425bb815Sopenharmony_ci  {
904425bb815Sopenharmony_ci    return ECMA_VALUE_FALSE;
905425bb815Sopenharmony_ci  }
906425bb815Sopenharmony_ci
907425bb815Sopenharmony_ci  /* 13. */
908425bb815Sopenharmony_ci  ecma_property_descriptor_t target_desc;
909425bb815Sopenharmony_ci
910425bb815Sopenharmony_ci  ecma_value_t status = ecma_op_object_get_own_property_descriptor (target_obj_p, prop_name_p, &target_desc);
911425bb815Sopenharmony_ci
912425bb815Sopenharmony_ci  /* 14. */
913425bb815Sopenharmony_ci  if (ECMA_IS_VALUE_ERROR (status))
914425bb815Sopenharmony_ci  {
915425bb815Sopenharmony_ci    return status;
916425bb815Sopenharmony_ci  }
917425bb815Sopenharmony_ci
918425bb815Sopenharmony_ci  bool target_prop_found = ecma_is_value_true (status);
919425bb815Sopenharmony_ci
920425bb815Sopenharmony_ci  /* 15. */
921425bb815Sopenharmony_ci  ecma_value_t extensible_target = ecma_builtin_object_object_is_extensible (target_obj_p);
922425bb815Sopenharmony_ci
923425bb815Sopenharmony_ci  bool is_target_ext = ecma_is_value_true (extensible_target);
924425bb815Sopenharmony_ci
925425bb815Sopenharmony_ci  /* 16. */
926425bb815Sopenharmony_ci  if (ECMA_IS_VALUE_ERROR (extensible_target))
927425bb815Sopenharmony_ci  {
928425bb815Sopenharmony_ci    if (target_prop_found)
929425bb815Sopenharmony_ci    {
930425bb815Sopenharmony_ci      ecma_free_property_descriptor (&target_desc);
931425bb815Sopenharmony_ci    }
932425bb815Sopenharmony_ci
933425bb815Sopenharmony_ci    return extensible_target;
934425bb815Sopenharmony_ci  }
935425bb815Sopenharmony_ci
936425bb815Sopenharmony_ci  /* 17. */
937425bb815Sopenharmony_ci  bool setting_config_false = ((prop_desc_p->flags & ECMA_PROP_IS_CONFIGURABLE_DEFINED)
938425bb815Sopenharmony_ci                                && !(prop_desc_p->flags & ECMA_PROP_IS_CONFIGURABLE));
939425bb815Sopenharmony_ci
940425bb815Sopenharmony_ci  /* 19. */
941425bb815Sopenharmony_ci  if (!target_prop_found)
942425bb815Sopenharmony_ci  {
943425bb815Sopenharmony_ci    if (!is_target_ext)
944425bb815Sopenharmony_ci    {
945425bb815Sopenharmony_ci      return ecma_raise_type_error (ECMA_ERR_MSG ("Trap returned truish for adding property "
946425bb815Sopenharmony_ci                                                  "to the non-extensible target"));
947425bb815Sopenharmony_ci    }
948425bb815Sopenharmony_ci
949425bb815Sopenharmony_ci    if (setting_config_false)
950425bb815Sopenharmony_ci    {
951425bb815Sopenharmony_ci      return ecma_raise_type_error (ECMA_ERR_MSG ("Trap returned truish for defining non-configurable property "
952425bb815Sopenharmony_ci                                                  "which is non-existent in the target"));
953425bb815Sopenharmony_ci    }
954425bb815Sopenharmony_ci  }
955425bb815Sopenharmony_ci  /* 20. */
956425bb815Sopenharmony_ci  else
957425bb815Sopenharmony_ci  {
958425bb815Sopenharmony_ci    ecma_value_t ret_value = ECMA_VALUE_EMPTY;
959425bb815Sopenharmony_ci
960425bb815Sopenharmony_ci    if (!ecma_op_is_compatible_property_descriptor (prop_desc_p, &target_desc, is_target_ext))
961425bb815Sopenharmony_ci    {
962425bb815Sopenharmony_ci      ret_value = ecma_raise_type_error (ECMA_ERR_MSG ("Trap returned truish for adding property that is "
963425bb815Sopenharmony_ci                                                       "incompatible with the existing property in the target"));
964425bb815Sopenharmony_ci    }
965425bb815Sopenharmony_ci    else if (setting_config_false && (target_desc.flags & ECMA_PROP_IS_CONFIGURABLE))
966425bb815Sopenharmony_ci    {
967425bb815Sopenharmony_ci      ret_value = ecma_raise_type_error (ECMA_ERR_MSG ("Trap returned truish for defining non-configurable property "
968425bb815Sopenharmony_ci                                                       "which is configurable in the target"));
969425bb815Sopenharmony_ci    }
970425bb815Sopenharmony_ci
971425bb815Sopenharmony_ci    ecma_free_property_descriptor (&target_desc);
972425bb815Sopenharmony_ci
973425bb815Sopenharmony_ci    if (ECMA_IS_VALUE_ERROR (ret_value))
974425bb815Sopenharmony_ci    {
975425bb815Sopenharmony_ci      return ret_value;
976425bb815Sopenharmony_ci    }
977425bb815Sopenharmony_ci  }
978425bb815Sopenharmony_ci
979425bb815Sopenharmony_ci  return ECMA_VALUE_TRUE;
980425bb815Sopenharmony_ci} /* ecma_proxy_object_define_own_property */
981425bb815Sopenharmony_ci
982425bb815Sopenharmony_ci/**
983425bb815Sopenharmony_ci * The Proxy object [[HasProperty]] internal routine
984425bb815Sopenharmony_ci *
985425bb815Sopenharmony_ci * See also:
986425bb815Sopenharmony_ci *          ECMAScript v6, 9.5.7
987425bb815Sopenharmony_ci *
988425bb815Sopenharmony_ci * Note: Returned value is always a simple value so freeing it is unnecessary.
989425bb815Sopenharmony_ci *
990425bb815Sopenharmony_ci * @return ECMA_VALUE_ERROR - if the operation fails
991425bb815Sopenharmony_ci *         ECMA_VALUE_{TRUE_FALSE} - depends on whether the property is found
992425bb815Sopenharmony_ci */
993425bb815Sopenharmony_ciecma_value_t
994425bb815Sopenharmony_ciecma_proxy_object_has (ecma_object_t *obj_p, /**< proxy object */
995425bb815Sopenharmony_ci                       ecma_string_t *prop_name_p) /**< property name */
996425bb815Sopenharmony_ci{
997425bb815Sopenharmony_ci  JERRY_ASSERT (ECMA_OBJECT_IS_PROXY (obj_p));
998425bb815Sopenharmony_ci  ECMA_CHECK_STACK_USAGE ();
999425bb815Sopenharmony_ci
1000425bb815Sopenharmony_ci  ecma_proxy_object_t *proxy_obj_p = (ecma_proxy_object_t *) obj_p;
1001425bb815Sopenharmony_ci
1002425bb815Sopenharmony_ci  /* 2. */
1003425bb815Sopenharmony_ci  ecma_value_t handler = proxy_obj_p->handler;
1004425bb815Sopenharmony_ci
1005425bb815Sopenharmony_ci  /* 3-6. */
1006425bb815Sopenharmony_ci  ecma_value_t trap = ecma_validate_proxy_object (handler, LIT_MAGIC_STRING_HAS);
1007425bb815Sopenharmony_ci
1008425bb815Sopenharmony_ci  /* 7. */
1009425bb815Sopenharmony_ci  if (ECMA_IS_VALUE_ERROR (trap))
1010425bb815Sopenharmony_ci  {
1011425bb815Sopenharmony_ci    return trap;
1012425bb815Sopenharmony_ci  }
1013425bb815Sopenharmony_ci
1014425bb815Sopenharmony_ci  ecma_value_t target = proxy_obj_p->target;
1015425bb815Sopenharmony_ci  ecma_object_t *target_obj_p = ecma_get_object_from_value (target);
1016425bb815Sopenharmony_ci
1017425bb815Sopenharmony_ci  /* 8. */
1018425bb815Sopenharmony_ci  if (ecma_is_value_undefined (trap))
1019425bb815Sopenharmony_ci  {
1020425bb815Sopenharmony_ci    return ecma_op_object_has_property (target_obj_p, prop_name_p);
1021425bb815Sopenharmony_ci  }
1022425bb815Sopenharmony_ci
1023425bb815Sopenharmony_ci  ecma_object_t *func_obj_p = ecma_get_object_from_value (trap);
1024425bb815Sopenharmony_ci  ecma_value_t prop_value = ecma_make_prop_name_value (prop_name_p);
1025425bb815Sopenharmony_ci  ecma_value_t args[] = {target, prop_value};
1026425bb815Sopenharmony_ci
1027425bb815Sopenharmony_ci  /* 9. */
1028425bb815Sopenharmony_ci  ecma_value_t trap_result = ecma_op_function_call (func_obj_p, handler, args, 2);
1029425bb815Sopenharmony_ci
1030425bb815Sopenharmony_ci  ecma_deref_object (func_obj_p);
1031425bb815Sopenharmony_ci
1032425bb815Sopenharmony_ci  /* 10. */
1033425bb815Sopenharmony_ci  if (ECMA_IS_VALUE_ERROR (trap_result))
1034425bb815Sopenharmony_ci  {
1035425bb815Sopenharmony_ci    return trap_result;
1036425bb815Sopenharmony_ci  }
1037425bb815Sopenharmony_ci
1038425bb815Sopenharmony_ci  bool boolean_trap_result = ecma_op_to_boolean (trap_result);
1039425bb815Sopenharmony_ci
1040425bb815Sopenharmony_ci  ecma_free_value (trap_result);
1041425bb815Sopenharmony_ci
1042425bb815Sopenharmony_ci  /* 11. */
1043425bb815Sopenharmony_ci  if (!boolean_trap_result)
1044425bb815Sopenharmony_ci  {
1045425bb815Sopenharmony_ci    ecma_property_descriptor_t target_desc;
1046425bb815Sopenharmony_ci
1047425bb815Sopenharmony_ci    ecma_value_t status = ecma_op_object_get_own_property_descriptor (target_obj_p, prop_name_p, &target_desc);
1048425bb815Sopenharmony_ci
1049425bb815Sopenharmony_ci    if (ECMA_IS_VALUE_ERROR (status))
1050425bb815Sopenharmony_ci    {
1051425bb815Sopenharmony_ci      return status;
1052425bb815Sopenharmony_ci    }
1053425bb815Sopenharmony_ci
1054425bb815Sopenharmony_ci    if (ecma_is_value_true (status))
1055425bb815Sopenharmony_ci    {
1056425bb815Sopenharmony_ci      bool prop_is_configurable = target_desc.flags & ECMA_PROP_IS_CONFIGURABLE;
1057425bb815Sopenharmony_ci
1058425bb815Sopenharmony_ci      ecma_free_property_descriptor (&target_desc);
1059425bb815Sopenharmony_ci
1060425bb815Sopenharmony_ci      if (!prop_is_configurable)
1061425bb815Sopenharmony_ci      {
1062425bb815Sopenharmony_ci        return ecma_raise_type_error (ECMA_ERR_MSG ("Trap returned falsish for property which exists "
1063425bb815Sopenharmony_ci                                                    "in the proxy target as non-configurable"));
1064425bb815Sopenharmony_ci      }
1065425bb815Sopenharmony_ci
1066425bb815Sopenharmony_ci      ecma_value_t extensible_target = ecma_builtin_object_object_is_extensible (target_obj_p);
1067425bb815Sopenharmony_ci
1068425bb815Sopenharmony_ci      if (ECMA_IS_VALUE_ERROR (extensible_target))
1069425bb815Sopenharmony_ci      {
1070425bb815Sopenharmony_ci        return extensible_target;
1071425bb815Sopenharmony_ci      }
1072425bb815Sopenharmony_ci
1073425bb815Sopenharmony_ci      if (ecma_is_value_false (extensible_target))
1074425bb815Sopenharmony_ci      {
1075425bb815Sopenharmony_ci        return ecma_raise_type_error (ECMA_ERR_MSG ("Trap returned falsish for property but "
1076425bb815Sopenharmony_ci                                                    "the proxy target is not extensible"));
1077425bb815Sopenharmony_ci      }
1078425bb815Sopenharmony_ci    }
1079425bb815Sopenharmony_ci  }
1080425bb815Sopenharmony_ci
1081425bb815Sopenharmony_ci  /* 12. */
1082425bb815Sopenharmony_ci  return ecma_make_boolean_value (boolean_trap_result);
1083425bb815Sopenharmony_ci} /* ecma_proxy_object_has */
1084425bb815Sopenharmony_ci
1085425bb815Sopenharmony_ci/**
1086425bb815Sopenharmony_ci * The Proxy object [[Get]] internal routine
1087425bb815Sopenharmony_ci *
1088425bb815Sopenharmony_ci * See also:
1089425bb815Sopenharmony_ci *          ECMAScript v6, 9.5.8
1090425bb815Sopenharmony_ci *
1091425bb815Sopenharmony_ci * Note: Returned value is always a simple value so freeing it is unnecessary.
1092425bb815Sopenharmony_ci *
1093425bb815Sopenharmony_ci * @return ECMA_VALUE_ERROR - if the operation fails
1094425bb815Sopenharmony_ci *         value of the given nameddata property or the result of the getter function call - otherwise
1095425bb815Sopenharmony_ci */
1096425bb815Sopenharmony_ciecma_value_t
1097425bb815Sopenharmony_ciecma_proxy_object_get (ecma_object_t *obj_p, /**< proxy object */
1098425bb815Sopenharmony_ci                       ecma_string_t *prop_name_p, /**< property name */
1099425bb815Sopenharmony_ci                       ecma_value_t receiver) /**< receiver to invoke getter function */
1100425bb815Sopenharmony_ci{
1101425bb815Sopenharmony_ci  JERRY_ASSERT (ECMA_OBJECT_IS_PROXY (obj_p));
1102425bb815Sopenharmony_ci  ECMA_CHECK_STACK_USAGE ();
1103425bb815Sopenharmony_ci
1104425bb815Sopenharmony_ci  ecma_proxy_object_t *proxy_obj_p = (ecma_proxy_object_t *) obj_p;
1105425bb815Sopenharmony_ci
1106425bb815Sopenharmony_ci  /* 2. */
1107425bb815Sopenharmony_ci  ecma_value_t handler = proxy_obj_p->handler;
1108425bb815Sopenharmony_ci
1109425bb815Sopenharmony_ci  /* 3-6. */
1110425bb815Sopenharmony_ci  ecma_value_t trap = ecma_validate_proxy_object (handler, LIT_MAGIC_STRING_GET);
1111425bb815Sopenharmony_ci
1112425bb815Sopenharmony_ci  /* 7. */
1113425bb815Sopenharmony_ci  if (ECMA_IS_VALUE_ERROR (trap))
1114425bb815Sopenharmony_ci  {
1115425bb815Sopenharmony_ci    return trap;
1116425bb815Sopenharmony_ci  }
1117425bb815Sopenharmony_ci
1118425bb815Sopenharmony_ci  ecma_value_t target = proxy_obj_p->target;
1119425bb815Sopenharmony_ci  ecma_object_t *target_obj_p = ecma_get_object_from_value (target);
1120425bb815Sopenharmony_ci
1121425bb815Sopenharmony_ci  /* 8. */
1122425bb815Sopenharmony_ci  if (ecma_is_value_undefined (trap))
1123425bb815Sopenharmony_ci  {
1124425bb815Sopenharmony_ci    return ecma_op_object_get_with_receiver (target_obj_p, prop_name_p, receiver);
1125425bb815Sopenharmony_ci  }
1126425bb815Sopenharmony_ci
1127425bb815Sopenharmony_ci  ecma_object_t *func_obj_p = ecma_get_object_from_value (trap);
1128425bb815Sopenharmony_ci  ecma_value_t prop_value = ecma_make_prop_name_value (prop_name_p);
1129425bb815Sopenharmony_ci  ecma_value_t args[] = { target, prop_value, receiver };
1130425bb815Sopenharmony_ci
1131425bb815Sopenharmony_ci  /* 9. */
1132425bb815Sopenharmony_ci  ecma_value_t trap_result = ecma_op_function_call (func_obj_p, handler, args, 3);
1133425bb815Sopenharmony_ci
1134425bb815Sopenharmony_ci  ecma_deref_object (func_obj_p);
1135425bb815Sopenharmony_ci
1136425bb815Sopenharmony_ci  /* 10. */
1137425bb815Sopenharmony_ci  if (ECMA_IS_VALUE_ERROR (trap_result))
1138425bb815Sopenharmony_ci  {
1139425bb815Sopenharmony_ci    return trap_result;
1140425bb815Sopenharmony_ci  }
1141425bb815Sopenharmony_ci
1142425bb815Sopenharmony_ci  /* 11. */
1143425bb815Sopenharmony_ci  ecma_property_descriptor_t target_desc;
1144425bb815Sopenharmony_ci
1145425bb815Sopenharmony_ci  ecma_value_t status = ecma_op_object_get_own_property_descriptor (target_obj_p, prop_name_p, &target_desc);
1146425bb815Sopenharmony_ci
1147425bb815Sopenharmony_ci  /* 12. */
1148425bb815Sopenharmony_ci  if (ECMA_IS_VALUE_ERROR (status))
1149425bb815Sopenharmony_ci  {
1150425bb815Sopenharmony_ci    return status;
1151425bb815Sopenharmony_ci  }
1152425bb815Sopenharmony_ci
1153425bb815Sopenharmony_ci  /* 13. */
1154425bb815Sopenharmony_ci  if (ecma_is_value_true (status))
1155425bb815Sopenharmony_ci  {
1156425bb815Sopenharmony_ci    ecma_value_t ret_value = ECMA_VALUE_EMPTY;
1157425bb815Sopenharmony_ci
1158425bb815Sopenharmony_ci    if ((target_desc.flags & ECMA_PROP_IS_VALUE_DEFINED)
1159425bb815Sopenharmony_ci        && !(target_desc.flags & ECMA_PROP_IS_CONFIGURABLE)
1160425bb815Sopenharmony_ci        && !(target_desc.flags & ECMA_PROP_IS_WRITABLE)
1161425bb815Sopenharmony_ci        && !ecma_op_same_value (trap_result, target_desc.value))
1162425bb815Sopenharmony_ci    {
1163425bb815Sopenharmony_ci      ret_value = ecma_raise_type_error (ECMA_ERR_MSG ("given property is a read-only and non-configurable"
1164425bb815Sopenharmony_ci                                                       " data property on the proxy target"));
1165425bb815Sopenharmony_ci    }
1166425bb815Sopenharmony_ci    else if (!(target_desc.flags & ECMA_PROP_IS_CONFIGURABLE)
1167425bb815Sopenharmony_ci            && (target_desc.flags & (ECMA_PROP_IS_GET_DEFINED | ECMA_PROP_IS_SET_DEFINED))
1168425bb815Sopenharmony_ci            && target_desc.get_p == NULL
1169425bb815Sopenharmony_ci            && !ecma_is_value_undefined (trap_result))
1170425bb815Sopenharmony_ci    {
1171425bb815Sopenharmony_ci      ret_value = ecma_raise_type_error (ECMA_ERR_MSG ("given property is a non-configurable property and"
1172425bb815Sopenharmony_ci                                                       " does not have a getter function"));
1173425bb815Sopenharmony_ci    }
1174425bb815Sopenharmony_ci
1175425bb815Sopenharmony_ci    ecma_free_property_descriptor (&target_desc);
1176425bb815Sopenharmony_ci
1177425bb815Sopenharmony_ci    if (ECMA_IS_VALUE_ERROR (ret_value))
1178425bb815Sopenharmony_ci    {
1179425bb815Sopenharmony_ci      ecma_free_value (trap_result);
1180425bb815Sopenharmony_ci
1181425bb815Sopenharmony_ci      return ret_value;
1182425bb815Sopenharmony_ci    }
1183425bb815Sopenharmony_ci  }
1184425bb815Sopenharmony_ci
1185425bb815Sopenharmony_ci  /* 14. */
1186425bb815Sopenharmony_ci  return trap_result;
1187425bb815Sopenharmony_ci} /* ecma_proxy_object_get */
1188425bb815Sopenharmony_ci
1189425bb815Sopenharmony_ci/**
1190425bb815Sopenharmony_ci * The Proxy object [[Set]] internal routine
1191425bb815Sopenharmony_ci *
1192425bb815Sopenharmony_ci * See also:
1193425bb815Sopenharmony_ci *          ECMAScript v6, 9.5.9
1194425bb815Sopenharmony_ci *
1195425bb815Sopenharmony_ci * Note: Returned value is always a simple value so freeing it is unnecessary.
1196425bb815Sopenharmony_ci *
1197425bb815Sopenharmony_ci * @return ECMA_VALUE_ERROR - if the operation fails
1198425bb815Sopenharmony_ci *         ECMA_VALUE_{TRUE/FALSE} - depends on whether the propety can be set to the given object
1199425bb815Sopenharmony_ci */
1200425bb815Sopenharmony_ciecma_value_t
1201425bb815Sopenharmony_ciecma_proxy_object_set (ecma_object_t *obj_p, /**< proxy object */
1202425bb815Sopenharmony_ci                       ecma_string_t *prop_name_p, /**< property name */
1203425bb815Sopenharmony_ci                       ecma_value_t value, /**< value to set */
1204425bb815Sopenharmony_ci                       ecma_value_t receiver) /**< receiver to invoke setter function */
1205425bb815Sopenharmony_ci{
1206425bb815Sopenharmony_ci  JERRY_ASSERT (ECMA_OBJECT_IS_PROXY (obj_p));
1207425bb815Sopenharmony_ci  ECMA_CHECK_STACK_USAGE ();
1208425bb815Sopenharmony_ci
1209425bb815Sopenharmony_ci  ecma_proxy_object_t *proxy_obj_p = (ecma_proxy_object_t *) obj_p;
1210425bb815Sopenharmony_ci
1211425bb815Sopenharmony_ci  /* 2. */
1212425bb815Sopenharmony_ci  ecma_value_t handler = proxy_obj_p->handler;
1213425bb815Sopenharmony_ci
1214425bb815Sopenharmony_ci  /* 3-6. */
1215425bb815Sopenharmony_ci  ecma_value_t trap = ecma_validate_proxy_object (handler, LIT_MAGIC_STRING_SET);
1216425bb815Sopenharmony_ci
1217425bb815Sopenharmony_ci  /* 7. */
1218425bb815Sopenharmony_ci  if (ECMA_IS_VALUE_ERROR (trap))
1219425bb815Sopenharmony_ci  {
1220425bb815Sopenharmony_ci    return trap;
1221425bb815Sopenharmony_ci  }
1222425bb815Sopenharmony_ci
1223425bb815Sopenharmony_ci  ecma_value_t target = proxy_obj_p->target;
1224425bb815Sopenharmony_ci  ecma_object_t *target_obj_p = ecma_get_object_from_value (target);
1225425bb815Sopenharmony_ci
1226425bb815Sopenharmony_ci  /* 8. */
1227425bb815Sopenharmony_ci  if (ecma_is_value_undefined (trap))
1228425bb815Sopenharmony_ci  {
1229425bb815Sopenharmony_ci    return ecma_op_object_put_with_receiver (target_obj_p, prop_name_p, value, receiver, false);
1230425bb815Sopenharmony_ci  }
1231425bb815Sopenharmony_ci
1232425bb815Sopenharmony_ci  ecma_object_t *func_obj_p = ecma_get_object_from_value (trap);
1233425bb815Sopenharmony_ci  ecma_value_t prop_name_value = ecma_make_prop_name_value (prop_name_p);
1234425bb815Sopenharmony_ci  ecma_value_t args[] = { target, prop_name_value, value, receiver };
1235425bb815Sopenharmony_ci
1236425bb815Sopenharmony_ci  /* 9. */
1237425bb815Sopenharmony_ci  ecma_value_t trap_result = ecma_op_function_call (func_obj_p, handler, args, 4);
1238425bb815Sopenharmony_ci
1239425bb815Sopenharmony_ci  ecma_deref_object (func_obj_p);
1240425bb815Sopenharmony_ci
1241425bb815Sopenharmony_ci  /* 10. */
1242425bb815Sopenharmony_ci  if (ECMA_IS_VALUE_ERROR (trap_result))
1243425bb815Sopenharmony_ci  {
1244425bb815Sopenharmony_ci    return trap_result;
1245425bb815Sopenharmony_ci  }
1246425bb815Sopenharmony_ci
1247425bb815Sopenharmony_ci  bool boolean_trap_result = ecma_op_to_boolean (trap_result);
1248425bb815Sopenharmony_ci
1249425bb815Sopenharmony_ci  ecma_free_value (trap_result);
1250425bb815Sopenharmony_ci
1251425bb815Sopenharmony_ci  /* 11. */
1252425bb815Sopenharmony_ci  if (!boolean_trap_result)
1253425bb815Sopenharmony_ci  {
1254425bb815Sopenharmony_ci    return ECMA_VALUE_FALSE;
1255425bb815Sopenharmony_ci  }
1256425bb815Sopenharmony_ci
1257425bb815Sopenharmony_ci  /* 12. */
1258425bb815Sopenharmony_ci  ecma_property_descriptor_t target_desc;
1259425bb815Sopenharmony_ci
1260425bb815Sopenharmony_ci  ecma_value_t status = ecma_op_object_get_own_property_descriptor (target_obj_p, prop_name_p, &target_desc);
1261425bb815Sopenharmony_ci
1262425bb815Sopenharmony_ci  /* 13. */
1263425bb815Sopenharmony_ci  if (ECMA_IS_VALUE_ERROR (status))
1264425bb815Sopenharmony_ci  {
1265425bb815Sopenharmony_ci    return status;
1266425bb815Sopenharmony_ci  }
1267425bb815Sopenharmony_ci
1268425bb815Sopenharmony_ci  /* 14. */
1269425bb815Sopenharmony_ci  if (ecma_is_value_true (status))
1270425bb815Sopenharmony_ci  {
1271425bb815Sopenharmony_ci    ecma_value_t ret_value = ECMA_VALUE_EMPTY;
1272425bb815Sopenharmony_ci
1273425bb815Sopenharmony_ci    if ((target_desc.flags & ECMA_PROP_IS_VALUE_DEFINED)
1274425bb815Sopenharmony_ci        && !(target_desc.flags & ECMA_PROP_IS_CONFIGURABLE)
1275425bb815Sopenharmony_ci        && !(target_desc.flags & ECMA_PROP_IS_WRITABLE)
1276425bb815Sopenharmony_ci        && !ecma_op_same_value (value, target_desc.value))
1277425bb815Sopenharmony_ci    {
1278425bb815Sopenharmony_ci      ret_value = ecma_raise_type_error (ECMA_ERR_MSG ("The property exists in the proxy target as a"
1279425bb815Sopenharmony_ci                                                       " non-configurable and non-writable data property"
1280425bb815Sopenharmony_ci                                                       " with a different value."));
1281425bb815Sopenharmony_ci    }
1282425bb815Sopenharmony_ci    else if (!(target_desc.flags & ECMA_PROP_IS_CONFIGURABLE)
1283425bb815Sopenharmony_ci            && (target_desc.flags & (ECMA_PROP_IS_GET_DEFINED | ECMA_PROP_IS_SET_DEFINED))
1284425bb815Sopenharmony_ci            && target_desc.set_p == NULL)
1285425bb815Sopenharmony_ci    {
1286425bb815Sopenharmony_ci      ret_value = ecma_raise_type_error (ECMA_ERR_MSG ("The property exists in the proxy target as a"
1287425bb815Sopenharmony_ci                                                       " non-configurable accessor property whitout a setter."));
1288425bb815Sopenharmony_ci    }
1289425bb815Sopenharmony_ci
1290425bb815Sopenharmony_ci    ecma_free_property_descriptor (&target_desc);
1291425bb815Sopenharmony_ci
1292425bb815Sopenharmony_ci    if (ECMA_IS_VALUE_ERROR (ret_value))
1293425bb815Sopenharmony_ci    {
1294425bb815Sopenharmony_ci      return ret_value;
1295425bb815Sopenharmony_ci    }
1296425bb815Sopenharmony_ci  }
1297425bb815Sopenharmony_ci
1298425bb815Sopenharmony_ci  /* 15. */
1299425bb815Sopenharmony_ci  return ECMA_VALUE_TRUE;
1300425bb815Sopenharmony_ci} /* ecma_proxy_object_set */
1301425bb815Sopenharmony_ci
1302425bb815Sopenharmony_ci/**
1303425bb815Sopenharmony_ci * The Proxy object [[Delete]] internal routine
1304425bb815Sopenharmony_ci *
1305425bb815Sopenharmony_ci * See also:
1306425bb815Sopenharmony_ci *          ECMAScript v6, 9.5.10
1307425bb815Sopenharmony_ci *
1308425bb815Sopenharmony_ci * Note: Returned value is always a simple value so freeing it is unnecessary.
1309425bb815Sopenharmony_ci *
1310425bb815Sopenharmony_ci * @return ECMA_VALUE_ERROR - if the operation fails
1311425bb815Sopenharmony_ci *         ECMA_VALUE_{TRUE/FALSE} - depends on whether the propety can be deleted
1312425bb815Sopenharmony_ci */
1313425bb815Sopenharmony_ciecma_value_t
1314425bb815Sopenharmony_ciecma_proxy_object_delete_property (ecma_object_t *obj_p, /**< proxy object */
1315425bb815Sopenharmony_ci                                   ecma_string_t *prop_name_p) /**< property name */
1316425bb815Sopenharmony_ci{
1317425bb815Sopenharmony_ci  JERRY_ASSERT (ECMA_OBJECT_IS_PROXY (obj_p));
1318425bb815Sopenharmony_ci
1319425bb815Sopenharmony_ci  ecma_proxy_object_t *proxy_obj_p = (ecma_proxy_object_t *) obj_p;
1320425bb815Sopenharmony_ci
1321425bb815Sopenharmony_ci  /* 2. */
1322425bb815Sopenharmony_ci  ecma_value_t handler = proxy_obj_p->handler;
1323425bb815Sopenharmony_ci
1324425bb815Sopenharmony_ci  /* 3-6.*/
1325425bb815Sopenharmony_ci  ecma_value_t trap = ecma_validate_proxy_object (handler, LIT_MAGIC_STRING_DELETE_PROPERTY_UL);
1326425bb815Sopenharmony_ci
1327425bb815Sopenharmony_ci  /* 7. */
1328425bb815Sopenharmony_ci  if (ECMA_IS_VALUE_ERROR (trap))
1329425bb815Sopenharmony_ci  {
1330425bb815Sopenharmony_ci    return trap;
1331425bb815Sopenharmony_ci  }
1332425bb815Sopenharmony_ci
1333425bb815Sopenharmony_ci  ecma_value_t target = proxy_obj_p->target;
1334425bb815Sopenharmony_ci  ecma_object_t *target_obj_p = ecma_get_object_from_value (target);
1335425bb815Sopenharmony_ci
1336425bb815Sopenharmony_ci  /* 8. */
1337425bb815Sopenharmony_ci  if (ecma_is_value_undefined (trap))
1338425bb815Sopenharmony_ci  {
1339425bb815Sopenharmony_ci    return ecma_op_object_delete (target_obj_p, prop_name_p, false);
1340425bb815Sopenharmony_ci  }
1341425bb815Sopenharmony_ci
1342425bb815Sopenharmony_ci  ecma_object_t *func_obj_p = ecma_get_object_from_value (trap);
1343425bb815Sopenharmony_ci  ecma_value_t prop_name_value = ecma_make_prop_name_value (prop_name_p);
1344425bb815Sopenharmony_ci  ecma_value_t args[] = { target, prop_name_value };
1345425bb815Sopenharmony_ci
1346425bb815Sopenharmony_ci  /* 9. */
1347425bb815Sopenharmony_ci  ecma_value_t trap_result = ecma_op_function_call (func_obj_p, handler, args, 2);
1348425bb815Sopenharmony_ci
1349425bb815Sopenharmony_ci  ecma_deref_object (func_obj_p);
1350425bb815Sopenharmony_ci
1351425bb815Sopenharmony_ci  /* 10. */
1352425bb815Sopenharmony_ci  if (ECMA_IS_VALUE_ERROR (trap_result))
1353425bb815Sopenharmony_ci  {
1354425bb815Sopenharmony_ci    return trap_result;
1355425bb815Sopenharmony_ci  }
1356425bb815Sopenharmony_ci
1357425bb815Sopenharmony_ci  bool boolean_trap_result = ecma_op_to_boolean (trap_result);
1358425bb815Sopenharmony_ci
1359425bb815Sopenharmony_ci  ecma_free_value (trap_result);
1360425bb815Sopenharmony_ci
1361425bb815Sopenharmony_ci  /* 11. */
1362425bb815Sopenharmony_ci  if (!boolean_trap_result)
1363425bb815Sopenharmony_ci  {
1364425bb815Sopenharmony_ci    return ECMA_VALUE_FALSE;
1365425bb815Sopenharmony_ci  }
1366425bb815Sopenharmony_ci
1367425bb815Sopenharmony_ci  /* 12. */
1368425bb815Sopenharmony_ci  ecma_property_descriptor_t target_desc;
1369425bb815Sopenharmony_ci
1370425bb815Sopenharmony_ci  ecma_value_t status = ecma_op_object_get_own_property_descriptor (target_obj_p, prop_name_p, &target_desc);
1371425bb815Sopenharmony_ci
1372425bb815Sopenharmony_ci  /* 13. */
1373425bb815Sopenharmony_ci  if (ECMA_IS_VALUE_ERROR (status))
1374425bb815Sopenharmony_ci  {
1375425bb815Sopenharmony_ci    return status;
1376425bb815Sopenharmony_ci  }
1377425bb815Sopenharmony_ci
1378425bb815Sopenharmony_ci  /* 14. */
1379425bb815Sopenharmony_ci  if (ecma_is_value_false (status))
1380425bb815Sopenharmony_ci  {
1381425bb815Sopenharmony_ci    return ECMA_VALUE_TRUE;
1382425bb815Sopenharmony_ci  }
1383425bb815Sopenharmony_ci
1384425bb815Sopenharmony_ci  ecma_value_t ret_value = ECMA_VALUE_TRUE;
1385425bb815Sopenharmony_ci
1386425bb815Sopenharmony_ci  /* 15. */
1387425bb815Sopenharmony_ci  if (!(target_desc.flags & ECMA_PROP_IS_CONFIGURABLE))
1388425bb815Sopenharmony_ci  {
1389425bb815Sopenharmony_ci    ret_value = ecma_raise_type_error (ECMA_ERR_MSG ("Trap returned truish for property which is "
1390425bb815Sopenharmony_ci                                                     "non-configurable in the proxy target."));
1391425bb815Sopenharmony_ci  }
1392425bb815Sopenharmony_ci
1393425bb815Sopenharmony_ci  ecma_free_property_descriptor (&target_desc);
1394425bb815Sopenharmony_ci
1395425bb815Sopenharmony_ci  /* 16. */
1396425bb815Sopenharmony_ci  return ret_value;
1397425bb815Sopenharmony_ci} /* ecma_proxy_object_delete_property */
1398425bb815Sopenharmony_ci
1399425bb815Sopenharmony_ci/**
1400425bb815Sopenharmony_ci * The Proxy object [[Enumerate]] internal routine
1401425bb815Sopenharmony_ci *
1402425bb815Sopenharmony_ci * See also:
1403425bb815Sopenharmony_ci *          ECMAScript v6, 9.5.11
1404425bb815Sopenharmony_ci *
1405425bb815Sopenharmony_ci * Note: Returned value must be freed with ecma_free_value.
1406425bb815Sopenharmony_ci *
1407425bb815Sopenharmony_ci * @return ECMA_VALUE_ERROR - if the operation fails
1408425bb815Sopenharmony_ci *         ecma-object - otherwise
1409425bb815Sopenharmony_ci */
1410425bb815Sopenharmony_ciecma_value_t
1411425bb815Sopenharmony_ciecma_proxy_object_enumerate (ecma_object_t *obj_p) /**< proxy object */
1412425bb815Sopenharmony_ci{
1413425bb815Sopenharmony_ci  JERRY_ASSERT (ECMA_OBJECT_IS_PROXY (obj_p));
1414425bb815Sopenharmony_ci  JERRY_UNUSED (obj_p);
1415425bb815Sopenharmony_ci  return ecma_raise_type_error (ECMA_ERR_MSG ("UNIMPLEMENTED: Proxy.[[Enumerate]]"));
1416425bb815Sopenharmony_ci} /* ecma_proxy_object_enumerate */
1417425bb815Sopenharmony_ci
1418425bb815Sopenharmony_ci/**
1419425bb815Sopenharmony_ci * Helper method for the Proxy object [[OwnPropertyKeys]] operation
1420425bb815Sopenharmony_ci *
1421425bb815Sopenharmony_ci * See also:
1422425bb815Sopenharmony_ci *          ECMAScript v6, 9.5.12 steps 21. 23.
1423425bb815Sopenharmony_ci *
1424425bb815Sopenharmony_ci * @return ECMA_VALUE_ERROR - if a target key is not in the unchecked_result_keys collection
1425425bb815Sopenharmony_ci *         ECMA_VALUE_EMPTY - otherwise
1426425bb815Sopenharmony_ci */
1427425bb815Sopenharmony_cistatic ecma_value_t
1428425bb815Sopenharmony_ciecma_proxy_object_own_property_keys_helper (ecma_collection_t *target_collection, /**< target keys */
1429425bb815Sopenharmony_ci                                            ecma_collection_t *unchecked_result_keys, /**< unchecked keys */
1430425bb815Sopenharmony_ci                                            uint32_t *counter) /**< unchecked property counter */
1431425bb815Sopenharmony_ci{
1432425bb815Sopenharmony_ci  ecma_value_t ret_value = ECMA_VALUE_EMPTY;
1433425bb815Sopenharmony_ci
1434425bb815Sopenharmony_ci  for (uint32_t i = 0; i < target_collection->item_count; i++)
1435425bb815Sopenharmony_ci  {
1436425bb815Sopenharmony_ci    ecma_string_t *current_prop_name = ecma_get_prop_name_from_value (target_collection->buffer_p[i]);
1437425bb815Sopenharmony_ci
1438425bb815Sopenharmony_ci    ret_value = ECMA_VALUE_ERROR;
1439425bb815Sopenharmony_ci
1440425bb815Sopenharmony_ci    for (uint32_t j = 0; j < unchecked_result_keys->item_count; j++)
1441425bb815Sopenharmony_ci    {
1442425bb815Sopenharmony_ci      if (ecma_is_value_empty (unchecked_result_keys->buffer_p[j]))
1443425bb815Sopenharmony_ci      {
1444425bb815Sopenharmony_ci        continue;
1445425bb815Sopenharmony_ci      }
1446425bb815Sopenharmony_ci
1447425bb815Sopenharmony_ci      ecma_string_t *unchecked_prop_name = ecma_get_prop_name_from_value (unchecked_result_keys->buffer_p[j]);
1448425bb815Sopenharmony_ci
1449425bb815Sopenharmony_ci      if (ecma_compare_ecma_strings (current_prop_name, unchecked_prop_name))
1450425bb815Sopenharmony_ci      {
1451425bb815Sopenharmony_ci        ecma_deref_ecma_string (unchecked_prop_name);
1452425bb815Sopenharmony_ci        ret_value = ECMA_VALUE_EMPTY;
1453425bb815Sopenharmony_ci        unchecked_result_keys->buffer_p[j] = ECMA_VALUE_EMPTY;
1454425bb815Sopenharmony_ci        (*counter)++;
1455425bb815Sopenharmony_ci      }
1456425bb815Sopenharmony_ci    }
1457425bb815Sopenharmony_ci
1458425bb815Sopenharmony_ci    if (ECMA_IS_VALUE_ERROR (ret_value))
1459425bb815Sopenharmony_ci    {
1460425bb815Sopenharmony_ci      break;
1461425bb815Sopenharmony_ci    }
1462425bb815Sopenharmony_ci  }
1463425bb815Sopenharmony_ci
1464425bb815Sopenharmony_ci  return ret_value;
1465425bb815Sopenharmony_ci} /* ecma_proxy_object_own_property_keys_helper */
1466425bb815Sopenharmony_ci
1467425bb815Sopenharmony_ci/**
1468425bb815Sopenharmony_ci * Helper method for checking the invariants in the Proxy object [[OwnPropertyKeys]] operation
1469425bb815Sopenharmony_ci *
1470425bb815Sopenharmony_ci * See also:
1471425bb815Sopenharmony_ci *          ECMAScript v6, 9.5.12 steps 20-25.
1472425bb815Sopenharmony_ci *
1473425bb815Sopenharmony_ci * @return true - if none of the invariants got violated
1474425bb815Sopenharmony_ci *         false - otherwise
1475425bb815Sopenharmony_ci */
1476425bb815Sopenharmony_cistatic bool
1477425bb815Sopenharmony_ciecma_proxy_check_invariants_for_own_prop_keys (ecma_collection_t *trap_result,
1478425bb815Sopenharmony_ci                                               ecma_collection_t *target_non_configurable_keys,
1479425bb815Sopenharmony_ci                                               ecma_collection_t *target_configurable_keys,
1480425bb815Sopenharmony_ci                                               ecma_value_t extensible_target)
1481425bb815Sopenharmony_ci{
1482425bb815Sopenharmony_ci  /* 20. */
1483425bb815Sopenharmony_ci  ecma_collection_t *unchecked_result_keys = ecma_new_collection ();
1484425bb815Sopenharmony_ci
1485425bb815Sopenharmony_ci  ecma_collection_append (unchecked_result_keys, trap_result->buffer_p, trap_result->item_count);
1486425bb815Sopenharmony_ci
1487425bb815Sopenharmony_ci  for (uint32_t i = 0; i < unchecked_result_keys->item_count; i++)
1488425bb815Sopenharmony_ci  {
1489425bb815Sopenharmony_ci    ecma_string_t *unchecked_prop_name = ecma_get_prop_name_from_value (unchecked_result_keys->buffer_p[i]);
1490425bb815Sopenharmony_ci    ecma_ref_ecma_string (unchecked_prop_name);
1491425bb815Sopenharmony_ci  }
1492425bb815Sopenharmony_ci
1493425bb815Sopenharmony_ci  bool check_ok = false;
1494425bb815Sopenharmony_ci  uint32_t unchecked_prop_name_counter = 0;
1495425bb815Sopenharmony_ci
1496425bb815Sopenharmony_ci  /* 21. */
1497425bb815Sopenharmony_ci  if (ECMA_IS_VALUE_ERROR (ecma_proxy_object_own_property_keys_helper (target_non_configurable_keys,
1498425bb815Sopenharmony_ci                                                                       unchecked_result_keys,
1499425bb815Sopenharmony_ci                                                                       &unchecked_prop_name_counter)))
1500425bb815Sopenharmony_ci  {
1501425bb815Sopenharmony_ci    ecma_raise_type_error (ECMA_ERR_MSG ("Trap result did not include all non-configurable keys."));
1502425bb815Sopenharmony_ci  }
1503425bb815Sopenharmony_ci  /* 22. */
1504425bb815Sopenharmony_ci  else if (ecma_is_value_true (extensible_target))
1505425bb815Sopenharmony_ci  {
1506425bb815Sopenharmony_ci    check_ok = true;
1507425bb815Sopenharmony_ci  }
1508425bb815Sopenharmony_ci  /* 23. */
1509425bb815Sopenharmony_ci  else if (ECMA_IS_VALUE_ERROR (ecma_proxy_object_own_property_keys_helper (target_configurable_keys,
1510425bb815Sopenharmony_ci                                                                            unchecked_result_keys,
1511425bb815Sopenharmony_ci                                                                            &unchecked_prop_name_counter)))
1512425bb815Sopenharmony_ci  {
1513425bb815Sopenharmony_ci    ecma_raise_type_error (ECMA_ERR_MSG ("Trap result did not include all configurable keys."));
1514425bb815Sopenharmony_ci  }
1515425bb815Sopenharmony_ci  /* 24. */
1516425bb815Sopenharmony_ci  else if (unchecked_result_keys->item_count != unchecked_prop_name_counter)
1517425bb815Sopenharmony_ci  {
1518425bb815Sopenharmony_ci    ecma_raise_type_error (ECMA_ERR_MSG ("Trap returned extra keys but proxy target is non-extensible"));
1519425bb815Sopenharmony_ci  }
1520425bb815Sopenharmony_ci  /* 25. */
1521425bb815Sopenharmony_ci  else
1522425bb815Sopenharmony_ci  {
1523425bb815Sopenharmony_ci    check_ok = true;
1524425bb815Sopenharmony_ci  }
1525425bb815Sopenharmony_ci
1526425bb815Sopenharmony_ci  ecma_collection_free (unchecked_result_keys);
1527425bb815Sopenharmony_ci
1528425bb815Sopenharmony_ci  return check_ok;
1529425bb815Sopenharmony_ci} /* ecma_proxy_check_invariants_for_own_prop_keys */
1530425bb815Sopenharmony_ci
1531425bb815Sopenharmony_ci/**
1532425bb815Sopenharmony_ci * The Proxy object [[OwnPropertyKeys]] internal routine
1533425bb815Sopenharmony_ci *
1534425bb815Sopenharmony_ci * See also:
1535425bb815Sopenharmony_ci *          ECMAScript v6, 9.5.12
1536425bb815Sopenharmony_ci *
1537425bb815Sopenharmony_ci * Note: If the returned collection is not NULL, it must be freed with
1538425bb815Sopenharmony_ci *       ecma_collection_free if it is no longer needed
1539425bb815Sopenharmony_ci *
1540425bb815Sopenharmony_ci * @return NULL - if the operation fails
1541425bb815Sopenharmony_ci *         pointer to a newly allocated list of property names - otherwise
1542425bb815Sopenharmony_ci */
1543425bb815Sopenharmony_ciecma_collection_t *
1544425bb815Sopenharmony_ciecma_proxy_object_own_property_keys (ecma_object_t *obj_p) /**< proxy object */
1545425bb815Sopenharmony_ci{
1546425bb815Sopenharmony_ci  JERRY_ASSERT (ECMA_OBJECT_IS_PROXY (obj_p));
1547425bb815Sopenharmony_ci
1548425bb815Sopenharmony_ci  ecma_proxy_object_t *proxy_obj_p = (ecma_proxy_object_t *) obj_p;
1549425bb815Sopenharmony_ci
1550425bb815Sopenharmony_ci  /* 1. */
1551425bb815Sopenharmony_ci  ecma_value_t handler = proxy_obj_p->handler;
1552425bb815Sopenharmony_ci
1553425bb815Sopenharmony_ci  /* 2-5. */
1554425bb815Sopenharmony_ci  ecma_value_t trap = ecma_validate_proxy_object (handler, LIT_MAGIC_STRING_OWN_KEYS_UL);
1555425bb815Sopenharmony_ci
1556425bb815Sopenharmony_ci  /* 6. */
1557425bb815Sopenharmony_ci  if (ECMA_IS_VALUE_ERROR (trap))
1558425bb815Sopenharmony_ci  {
1559425bb815Sopenharmony_ci    return NULL;
1560425bb815Sopenharmony_ci  }
1561425bb815Sopenharmony_ci
1562425bb815Sopenharmony_ci  ecma_value_t target = proxy_obj_p->target;
1563425bb815Sopenharmony_ci  ecma_object_t *target_obj_p = ecma_get_object_from_value (target);
1564425bb815Sopenharmony_ci
1565425bb815Sopenharmony_ci  /* 7. */
1566425bb815Sopenharmony_ci  if (ecma_is_value_undefined (trap))
1567425bb815Sopenharmony_ci  {
1568425bb815Sopenharmony_ci    return ecma_op_object_get_property_names (target_obj_p, ECMA_LIST_SYMBOLS);
1569425bb815Sopenharmony_ci  }
1570425bb815Sopenharmony_ci
1571425bb815Sopenharmony_ci  ecma_object_t *func_obj_p = ecma_get_object_from_value (trap);
1572425bb815Sopenharmony_ci
1573425bb815Sopenharmony_ci  /* 8. */
1574425bb815Sopenharmony_ci  ecma_value_t trap_result_array = ecma_op_function_call (func_obj_p, handler, &target, 1);
1575425bb815Sopenharmony_ci
1576425bb815Sopenharmony_ci  ecma_deref_object (func_obj_p);
1577425bb815Sopenharmony_ci
1578425bb815Sopenharmony_ci  if (ECMA_IS_VALUE_ERROR (trap_result_array))
1579425bb815Sopenharmony_ci  {
1580425bb815Sopenharmony_ci    return NULL;
1581425bb815Sopenharmony_ci  }
1582425bb815Sopenharmony_ci
1583425bb815Sopenharmony_ci  /* 9. */
1584425bb815Sopenharmony_ci  ecma_collection_t *trap_result = ecma_op_create_list_from_array_like (trap_result_array, true);
1585425bb815Sopenharmony_ci
1586425bb815Sopenharmony_ci  ecma_free_value (trap_result_array);
1587425bb815Sopenharmony_ci
1588425bb815Sopenharmony_ci  /* 10. */
1589425bb815Sopenharmony_ci  if (trap_result == NULL)
1590425bb815Sopenharmony_ci  {
1591425bb815Sopenharmony_ci    return trap_result;
1592425bb815Sopenharmony_ci  }
1593425bb815Sopenharmony_ci
1594425bb815Sopenharmony_ci  /* 11. */
1595425bb815Sopenharmony_ci  ecma_value_t extensible_target = ecma_builtin_object_object_is_extensible (target_obj_p);
1596425bb815Sopenharmony_ci
1597425bb815Sopenharmony_ci  /* 12. */
1598425bb815Sopenharmony_ci  if (ECMA_IS_VALUE_ERROR (extensible_target))
1599425bb815Sopenharmony_ci  {
1600425bb815Sopenharmony_ci    ecma_collection_free (trap_result);
1601425bb815Sopenharmony_ci    return NULL;
1602425bb815Sopenharmony_ci  }
1603425bb815Sopenharmony_ci
1604425bb815Sopenharmony_ci  /* 13. */
1605425bb815Sopenharmony_ci  ecma_collection_t *target_keys = ecma_op_object_get_property_names (target_obj_p, ECMA_LIST_SYMBOLS);
1606425bb815Sopenharmony_ci
1607425bb815Sopenharmony_ci  /* 14. */
1608425bb815Sopenharmony_ci  if (target_keys == NULL)
1609425bb815Sopenharmony_ci  {
1610425bb815Sopenharmony_ci    ecma_collection_free (trap_result);
1611425bb815Sopenharmony_ci    return target_keys;
1612425bb815Sopenharmony_ci  }
1613425bb815Sopenharmony_ci
1614425bb815Sopenharmony_ci  /* 16. */
1615425bb815Sopenharmony_ci  ecma_collection_t *target_configurable_keys = ecma_new_collection ();
1616425bb815Sopenharmony_ci
1617425bb815Sopenharmony_ci  /* 17. */
1618425bb815Sopenharmony_ci  ecma_collection_t *target_non_configurable_keys = ecma_new_collection ();
1619425bb815Sopenharmony_ci
1620425bb815Sopenharmony_ci  ecma_collection_t *ret_value = NULL;
1621425bb815Sopenharmony_ci
1622425bb815Sopenharmony_ci  /* 18. */
1623425bb815Sopenharmony_ci  for (uint32_t i = 0; i < target_keys->item_count; i++)
1624425bb815Sopenharmony_ci  {
1625425bb815Sopenharmony_ci    ecma_property_descriptor_t target_desc;
1626425bb815Sopenharmony_ci
1627425bb815Sopenharmony_ci    ecma_string_t *prop_name_p = ecma_get_prop_name_from_value (target_keys->buffer_p[i]);
1628425bb815Sopenharmony_ci
1629425bb815Sopenharmony_ci    ecma_value_t status = ecma_op_object_get_own_property_descriptor (target_obj_p,
1630425bb815Sopenharmony_ci                                                                      prop_name_p,
1631425bb815Sopenharmony_ci                                                                      &target_desc);
1632425bb815Sopenharmony_ci
1633425bb815Sopenharmony_ci    if (ECMA_IS_VALUE_ERROR (status))
1634425bb815Sopenharmony_ci    {
1635425bb815Sopenharmony_ci      ecma_collection_free (trap_result);
1636425bb815Sopenharmony_ci      goto free_target_collections;
1637425bb815Sopenharmony_ci    }
1638425bb815Sopenharmony_ci
1639425bb815Sopenharmony_ci    ecma_value_t prop_value = ecma_make_prop_name_value (prop_name_p);
1640425bb815Sopenharmony_ci
1641425bb815Sopenharmony_ci    if (ecma_is_value_true (status)
1642425bb815Sopenharmony_ci        && !(target_desc.flags & ECMA_PROP_IS_CONFIGURABLE))
1643425bb815Sopenharmony_ci    {
1644425bb815Sopenharmony_ci      ecma_collection_push_back (target_non_configurable_keys, prop_value);
1645425bb815Sopenharmony_ci    }
1646425bb815Sopenharmony_ci    else
1647425bb815Sopenharmony_ci    {
1648425bb815Sopenharmony_ci      ecma_collection_push_back (target_configurable_keys, prop_value);
1649425bb815Sopenharmony_ci    }
1650425bb815Sopenharmony_ci
1651425bb815Sopenharmony_ci    if (ecma_is_value_true (status))
1652425bb815Sopenharmony_ci    {
1653425bb815Sopenharmony_ci      ecma_free_property_descriptor (&target_desc);
1654425bb815Sopenharmony_ci    }
1655425bb815Sopenharmony_ci  }
1656425bb815Sopenharmony_ci
1657425bb815Sopenharmony_ci  /* 19. */
1658425bb815Sopenharmony_ci  if (ecma_is_value_true (extensible_target) && target_non_configurable_keys->item_count == 0)
1659425bb815Sopenharmony_ci  {
1660425bb815Sopenharmony_ci    ret_value = trap_result;
1661425bb815Sopenharmony_ci  }
1662425bb815Sopenharmony_ci  /* 20-25. */
1663425bb815Sopenharmony_ci  else if (ecma_proxy_check_invariants_for_own_prop_keys (trap_result,
1664425bb815Sopenharmony_ci                                                          target_non_configurable_keys,
1665425bb815Sopenharmony_ci                                                          target_configurable_keys,
1666425bb815Sopenharmony_ci                                                          extensible_target))
1667425bb815Sopenharmony_ci  {
1668425bb815Sopenharmony_ci    ret_value = trap_result;
1669425bb815Sopenharmony_ci  }
1670425bb815Sopenharmony_ci  else
1671425bb815Sopenharmony_ci  {
1672425bb815Sopenharmony_ci    JERRY_ASSERT (ret_value == NULL);
1673425bb815Sopenharmony_ci    ecma_collection_free (trap_result);
1674425bb815Sopenharmony_ci  }
1675425bb815Sopenharmony_ci
1676425bb815Sopenharmony_cifree_target_collections:
1677425bb815Sopenharmony_ci  ecma_collection_destroy (target_keys);
1678425bb815Sopenharmony_ci  ecma_collection_free (target_configurable_keys);
1679425bb815Sopenharmony_ci  ecma_collection_free (target_non_configurable_keys);
1680425bb815Sopenharmony_ci
1681425bb815Sopenharmony_ci  return ret_value;
1682425bb815Sopenharmony_ci} /* ecma_proxy_object_own_property_keys */
1683425bb815Sopenharmony_ci
1684425bb815Sopenharmony_ci/**
1685425bb815Sopenharmony_ci * The Proxy object [[Call]] internal routine
1686425bb815Sopenharmony_ci *
1687425bb815Sopenharmony_ci * See also:
1688425bb815Sopenharmony_ci *          ECMAScript v6, 9.5.13
1689425bb815Sopenharmony_ci *
1690425bb815Sopenharmony_ci * Note: Returned value must be freed with ecma_free_value.
1691425bb815Sopenharmony_ci *
1692425bb815Sopenharmony_ci * @return ECMA_VALUE_ERROR - if the operation fails
1693425bb815Sopenharmony_ci *         result of the function call - otherwise
1694425bb815Sopenharmony_ci */
1695425bb815Sopenharmony_ciecma_value_t
1696425bb815Sopenharmony_ciecma_proxy_object_call (ecma_object_t *obj_p, /**< proxy object */
1697425bb815Sopenharmony_ci                        ecma_value_t this_argument, /**< this argument to invoke the function */
1698425bb815Sopenharmony_ci                        const ecma_value_t *args_p, /**< argument list */
1699425bb815Sopenharmony_ci                        ecma_length_t argc) /**< number of arguments */
1700425bb815Sopenharmony_ci{
1701425bb815Sopenharmony_ci  JERRY_ASSERT (ECMA_OBJECT_IS_PROXY (obj_p));
1702425bb815Sopenharmony_ci
1703425bb815Sopenharmony_ci  ecma_proxy_object_t *proxy_obj_p = (ecma_proxy_object_t *) obj_p;
1704425bb815Sopenharmony_ci
1705425bb815Sopenharmony_ci  /* 1. */
1706425bb815Sopenharmony_ci  ecma_value_t handler = proxy_obj_p->handler;
1707425bb815Sopenharmony_ci
1708425bb815Sopenharmony_ci  /* 2-5.*/
1709425bb815Sopenharmony_ci  ecma_value_t trap = ecma_validate_proxy_object (handler, LIT_MAGIC_STRING_APPLY);
1710425bb815Sopenharmony_ci
1711425bb815Sopenharmony_ci  /* 6. */
1712425bb815Sopenharmony_ci  if (ECMA_IS_VALUE_ERROR (trap))
1713425bb815Sopenharmony_ci  {
1714425bb815Sopenharmony_ci    return trap;
1715425bb815Sopenharmony_ci  }
1716425bb815Sopenharmony_ci
1717425bb815Sopenharmony_ci  ecma_value_t target = proxy_obj_p->target;
1718425bb815Sopenharmony_ci
1719425bb815Sopenharmony_ci  /* 7. */
1720425bb815Sopenharmony_ci  if (ecma_is_value_undefined (trap))
1721425bb815Sopenharmony_ci  {
1722425bb815Sopenharmony_ci    ecma_object_t *target_obj_p = ecma_get_object_from_value (target);
1723425bb815Sopenharmony_ci    return ecma_op_function_call (target_obj_p, this_argument, args_p, argc);
1724425bb815Sopenharmony_ci  }
1725425bb815Sopenharmony_ci
1726425bb815Sopenharmony_ci  /* 8. */
1727425bb815Sopenharmony_ci  ecma_value_t args_array = ecma_op_create_array_object (args_p, argc, false);
1728425bb815Sopenharmony_ci  ecma_value_t value_array[] = {target, this_argument, args_array};
1729425bb815Sopenharmony_ci  ecma_object_t *func_obj_p = ecma_get_object_from_value (trap);
1730425bb815Sopenharmony_ci  /* 9. */
1731425bb815Sopenharmony_ci  ecma_value_t ret_value = ecma_op_function_call (func_obj_p, handler, value_array, 3);
1732425bb815Sopenharmony_ci  ecma_deref_object (func_obj_p);
1733425bb815Sopenharmony_ci  ecma_deref_object (ecma_get_object_from_value (args_array));
1734425bb815Sopenharmony_ci
1735425bb815Sopenharmony_ci  return ret_value;
1736425bb815Sopenharmony_ci} /* ecma_proxy_object_call */
1737425bb815Sopenharmony_ci
1738425bb815Sopenharmony_ci/**
1739425bb815Sopenharmony_ci * The Proxy object [[Construct]] internal routine
1740425bb815Sopenharmony_ci *
1741425bb815Sopenharmony_ci * See also:
1742425bb815Sopenharmony_ci *          ECMAScript v6, 9.5.14
1743425bb815Sopenharmony_ci *
1744425bb815Sopenharmony_ci * Note: Returned value must be freed with ecma_free_value.
1745425bb815Sopenharmony_ci *
1746425bb815Sopenharmony_ci * @return ECMA_VALUE_ERROR - if the operation fails
1747425bb815Sopenharmony_ci *         result of the construct call - otherwise
1748425bb815Sopenharmony_ci */
1749425bb815Sopenharmony_ciecma_value_t
1750425bb815Sopenharmony_ciecma_proxy_object_construct (ecma_object_t *obj_p, /**< proxy object */
1751425bb815Sopenharmony_ci                             ecma_object_t *new_target_p, /**< new target */
1752425bb815Sopenharmony_ci                             const ecma_value_t *args_p, /**< argument list */
1753425bb815Sopenharmony_ci                             ecma_length_t argc) /**< number of arguments */
1754425bb815Sopenharmony_ci{
1755425bb815Sopenharmony_ci  JERRY_ASSERT (ECMA_OBJECT_IS_PROXY (obj_p));
1756425bb815Sopenharmony_ci
1757425bb815Sopenharmony_ci  ecma_proxy_object_t * proxy_obj_p = (ecma_proxy_object_t *) obj_p;
1758425bb815Sopenharmony_ci
1759425bb815Sopenharmony_ci  /* 1. */
1760425bb815Sopenharmony_ci  ecma_value_t handler = proxy_obj_p->handler;
1761425bb815Sopenharmony_ci
1762425bb815Sopenharmony_ci  /* 2-5. */
1763425bb815Sopenharmony_ci  ecma_value_t trap = ecma_validate_proxy_object (handler, LIT_MAGIC_STRING_CONSTRUCT);
1764425bb815Sopenharmony_ci
1765425bb815Sopenharmony_ci  /* 6. */
1766425bb815Sopenharmony_ci  if (ECMA_IS_VALUE_ERROR (trap))
1767425bb815Sopenharmony_ci  {
1768425bb815Sopenharmony_ci    return trap;
1769425bb815Sopenharmony_ci  }
1770425bb815Sopenharmony_ci
1771425bb815Sopenharmony_ci  ecma_value_t target = proxy_obj_p->target;
1772425bb815Sopenharmony_ci  ecma_object_t *target_obj_p = ecma_get_object_from_value (target);
1773425bb815Sopenharmony_ci
1774425bb815Sopenharmony_ci  /* 7. */
1775425bb815Sopenharmony_ci  if (ecma_is_value_undefined (trap))
1776425bb815Sopenharmony_ci  {
1777425bb815Sopenharmony_ci    JERRY_ASSERT (ecma_object_is_constructor (target_obj_p));
1778425bb815Sopenharmony_ci
1779425bb815Sopenharmony_ci    return ecma_op_function_construct (target_obj_p, new_target_p, args_p, argc);
1780425bb815Sopenharmony_ci  }
1781425bb815Sopenharmony_ci
1782425bb815Sopenharmony_ci  /* 8. */
1783425bb815Sopenharmony_ci  ecma_value_t arg_array = ecma_op_create_array_object (args_p, argc, false);
1784425bb815Sopenharmony_ci
1785425bb815Sopenharmony_ci  ecma_object_t *func_obj_p = ecma_get_object_from_value (trap);
1786425bb815Sopenharmony_ci  ecma_value_t new_target_value = ecma_make_object_value (new_target_p);
1787425bb815Sopenharmony_ci  ecma_value_t function_call_args[] = {target, arg_array, new_target_value};
1788425bb815Sopenharmony_ci
1789425bb815Sopenharmony_ci  /* 9. */
1790425bb815Sopenharmony_ci  ecma_value_t new_obj = ecma_op_function_call (func_obj_p, handler, function_call_args, 3);
1791425bb815Sopenharmony_ci
1792425bb815Sopenharmony_ci  ecma_free_value (arg_array);
1793425bb815Sopenharmony_ci  ecma_deref_object (func_obj_p);
1794425bb815Sopenharmony_ci
1795425bb815Sopenharmony_ci  /* 10 .*/
1796425bb815Sopenharmony_ci  if (ECMA_IS_VALUE_ERROR (new_obj))
1797425bb815Sopenharmony_ci  {
1798425bb815Sopenharmony_ci    return new_obj;
1799425bb815Sopenharmony_ci  }
1800425bb815Sopenharmony_ci
1801425bb815Sopenharmony_ci  /* 11. */
1802425bb815Sopenharmony_ci  if (!ecma_is_value_object (new_obj))
1803425bb815Sopenharmony_ci  {
1804425bb815Sopenharmony_ci    ecma_free_value (new_obj);
1805425bb815Sopenharmony_ci
1806425bb815Sopenharmony_ci    return ecma_raise_type_error (ECMA_ERR_MSG ("Trap returned non-object"));
1807425bb815Sopenharmony_ci  }
1808425bb815Sopenharmony_ci
1809425bb815Sopenharmony_ci  /* 12. */
1810425bb815Sopenharmony_ci  return new_obj;
1811425bb815Sopenharmony_ci} /* ecma_proxy_object_construct */
1812425bb815Sopenharmony_ci
1813425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */
1814425bb815Sopenharmony_ci
1815425bb815Sopenharmony_ci/**
1816425bb815Sopenharmony_ci * @}
1817425bb815Sopenharmony_ci * @}
1818425bb815Sopenharmony_ci */
1819