1425bb815Sopenharmony_ci/* Copyright JS Foundation and other contributors, http://js.foundation 2425bb815Sopenharmony_ci * 3425bb815Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4425bb815Sopenharmony_ci * you may not use this file except in compliance with the License. 5425bb815Sopenharmony_ci * You may obtain a copy of the License at 6425bb815Sopenharmony_ci * 7425bb815Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8425bb815Sopenharmony_ci * 9425bb815Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10425bb815Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS 11425bb815Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12425bb815Sopenharmony_ci * See the License for the specific language governing permissions and 13425bb815Sopenharmony_ci * limitations under the License. 14425bb815Sopenharmony_ci */ 15425bb815Sopenharmony_ci 16425bb815Sopenharmony_ci#include "ecma-array-object.h" 17425bb815Sopenharmony_ci#include "ecma-builtins.h" 18425bb815Sopenharmony_ci#include "ecma-builtin-function-prototype.h" 19425bb815Sopenharmony_ci#include "ecma-iterator-object.h" 20425bb815Sopenharmony_ci#include "ecma-builtin-helpers.h" 21425bb815Sopenharmony_ci#include "ecma-builtin-object.h" 22425bb815Sopenharmony_ci#include "ecma-exceptions.h" 23425bb815Sopenharmony_ci#include "ecma-function-object.h" 24425bb815Sopenharmony_ci#include "ecma-gc.h" 25425bb815Sopenharmony_ci#include "ecma-proxy-object.h" 26425bb815Sopenharmony_ci#include "jcontext.h" 27425bb815Sopenharmony_ci 28425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015_BUILTIN_REFLECT) 29425bb815Sopenharmony_ci 30425bb815Sopenharmony_ci#define ECMA_BUILTINS_INTERNAL 31425bb815Sopenharmony_ci#include "ecma-builtins-internal.h" 32425bb815Sopenharmony_ci 33425bb815Sopenharmony_ci/** 34425bb815Sopenharmony_ci * This object has a custom dispatch function. 35425bb815Sopenharmony_ci */ 36425bb815Sopenharmony_ci#define BUILTIN_CUSTOM_DISPATCH 37425bb815Sopenharmony_ci 38425bb815Sopenharmony_ci/** 39425bb815Sopenharmony_ci * List of built-in routine identifiers. 40425bb815Sopenharmony_ci */ 41425bb815Sopenharmony_cienum 42425bb815Sopenharmony_ci{ 43425bb815Sopenharmony_ci ECMA_REFLECT_OBJECT_ROUTINE_START = ECMA_BUILTIN_ID__COUNT - 1, 44425bb815Sopenharmony_ci ECMA_REFLECT_OBJECT_GET, /* ECMA-262 v6, 26.1.6 */ 45425bb815Sopenharmony_ci ECMA_REFLECT_OBJECT_SET, /* ECMA-262 v6, 26.1.13 */ 46425bb815Sopenharmony_ci ECMA_REFLECT_OBJECT_HAS, /* ECMA-262 v6, 26.1.9 */ 47425bb815Sopenharmony_ci ECMA_REFLECT_OBJECT_DELETE_PROPERTY, /* ECMA-262 v6, 26.1.4 */ 48425bb815Sopenharmony_ci ECMA_REFLECT_OBJECT_CONSTRUCT, /* ECMA-262, 26.1.2 */ 49425bb815Sopenharmony_ci ECMA_REFLECT_OBJECT_OWN_KEYS, /* ECMA-262 v6, 26.1.11 */ 50425bb815Sopenharmony_ci ECMA_REFLECT_OBJECT_GET_PROTOTYPE_OF, /* ECMA-262 v6, 26.1.8 */ 51425bb815Sopenharmony_ci ECMA_REFLECT_OBJECT_SET_PROTOTYPE_OF, /* ECMA-262 v6, 26.1.14 */ 52425bb815Sopenharmony_ci ECMA_REFLECT_OBJECT_APPLY, /* ECMA-262 v6, 26.1.1 */ 53425bb815Sopenharmony_ci ECMA_REFLECT_OBJECT_DEFINE_PROPERTY, /* ECMA-262 v6, 26.1.3 */ 54425bb815Sopenharmony_ci ECMA_REFLECT_OBJECT_GET_OWN_PROPERTY_DESCRIPTOR, /* ECMA-262 v6, 26.1.7 */ 55425bb815Sopenharmony_ci ECMA_REFLECT_OBJECT_IS_EXTENSIBLE, /* ECMA-262 v6, 26.1.10 */ 56425bb815Sopenharmony_ci ECMA_REFLECT_OBJECT_PREVENT_EXTENSIONS, /* ECMA-262 v6, 26.1.12 */ 57425bb815Sopenharmony_ci}; 58425bb815Sopenharmony_ci 59425bb815Sopenharmony_ci#define BUILTIN_INC_HEADER_NAME "ecma-builtin-reflect.inc.h" 60425bb815Sopenharmony_ci#define BUILTIN_UNDERSCORED_ID reflect 61425bb815Sopenharmony_ci#include "ecma-builtin-internal-routines-template.inc.h" 62425bb815Sopenharmony_ci 63425bb815Sopenharmony_ci/** \addtogroup ecma ECMA 64425bb815Sopenharmony_ci * @{ 65425bb815Sopenharmony_ci * 66425bb815Sopenharmony_ci * \addtogroup ecmabuiltins 67425bb815Sopenharmony_ci * @{ 68425bb815Sopenharmony_ci * 69425bb815Sopenharmony_ci * \addtogroup object ECMA Reflect object built-in 70425bb815Sopenharmony_ci * @{ 71425bb815Sopenharmony_ci */ 72425bb815Sopenharmony_ci 73425bb815Sopenharmony_ci/** 74425bb815Sopenharmony_ci * Dispatcher for the built-in's routines. 75425bb815Sopenharmony_ci * 76425bb815Sopenharmony_ci * @return ecma value 77425bb815Sopenharmony_ci * Returned value must be freed with ecma_free_value. 78425bb815Sopenharmony_ci */ 79425bb815Sopenharmony_ciecma_value_t 80425bb815Sopenharmony_ciecma_builtin_reflect_dispatch_routine (uint16_t builtin_routine_id, /**< built-in wide routine 81425bb815Sopenharmony_ci * identifier */ 82425bb815Sopenharmony_ci ecma_value_t this_arg, /**< 'this' argument value */ 83425bb815Sopenharmony_ci const ecma_value_t arguments_list[], /**< list of arguments 84425bb815Sopenharmony_ci * passed to routine */ 85425bb815Sopenharmony_ci ecma_length_t arguments_number) /**< length of arguments' list */ 86425bb815Sopenharmony_ci{ 87425bb815Sopenharmony_ci JERRY_UNUSED (this_arg); 88425bb815Sopenharmony_ci JERRY_UNUSED (arguments_number); 89425bb815Sopenharmony_ci 90425bb815Sopenharmony_ci if (builtin_routine_id < ECMA_REFLECT_OBJECT_CONSTRUCT) 91425bb815Sopenharmony_ci { 92425bb815Sopenharmony_ci /* 1. */ 93425bb815Sopenharmony_ci if (arguments_number == 0 || !ecma_is_value_object (arguments_list[0])) 94425bb815Sopenharmony_ci { 95425bb815Sopenharmony_ci return ecma_raise_type_error (ECMA_ERR_MSG ("Argument is not an Object.")); 96425bb815Sopenharmony_ci } 97425bb815Sopenharmony_ci 98425bb815Sopenharmony_ci /* 2. */ 99425bb815Sopenharmony_ci ecma_string_t *name_str_p = ecma_op_to_prop_name (((arguments_number > 1) ? arguments_list[1] 100425bb815Sopenharmony_ci : ECMA_VALUE_UNDEFINED)); 101425bb815Sopenharmony_ci 102425bb815Sopenharmony_ci /* 3. */ 103425bb815Sopenharmony_ci if (name_str_p == NULL) 104425bb815Sopenharmony_ci { 105425bb815Sopenharmony_ci return ECMA_VALUE_ERROR; 106425bb815Sopenharmony_ci } 107425bb815Sopenharmony_ci 108425bb815Sopenharmony_ci ecma_value_t ret_value; 109425bb815Sopenharmony_ci ecma_object_t *target_p = ecma_get_object_from_value (arguments_list[0]); 110425bb815Sopenharmony_ci switch (builtin_routine_id) 111425bb815Sopenharmony_ci { 112425bb815Sopenharmony_ci case ECMA_REFLECT_OBJECT_GET: 113425bb815Sopenharmony_ci { 114425bb815Sopenharmony_ci ecma_value_t receiver = arguments_list[0]; 115425bb815Sopenharmony_ci 116425bb815Sopenharmony_ci /* 4. */ 117425bb815Sopenharmony_ci if (arguments_number > 2) 118425bb815Sopenharmony_ci { 119425bb815Sopenharmony_ci receiver = arguments_list[2]; 120425bb815Sopenharmony_ci } 121425bb815Sopenharmony_ci 122425bb815Sopenharmony_ci ret_value = ecma_op_object_get_with_receiver (target_p, name_str_p, receiver); 123425bb815Sopenharmony_ci break; 124425bb815Sopenharmony_ci } 125425bb815Sopenharmony_ci 126425bb815Sopenharmony_ci case ECMA_REFLECT_OBJECT_HAS: 127425bb815Sopenharmony_ci { 128425bb815Sopenharmony_ci ret_value = ecma_op_object_has_property (target_p, name_str_p); 129425bb815Sopenharmony_ci break; 130425bb815Sopenharmony_ci } 131425bb815Sopenharmony_ci 132425bb815Sopenharmony_ci case ECMA_REFLECT_OBJECT_DELETE_PROPERTY: 133425bb815Sopenharmony_ci { 134425bb815Sopenharmony_ci ret_value = ecma_op_object_delete (target_p, name_str_p, false); 135425bb815Sopenharmony_ci break; 136425bb815Sopenharmony_ci } 137425bb815Sopenharmony_ci 138425bb815Sopenharmony_ci default: 139425bb815Sopenharmony_ci { 140425bb815Sopenharmony_ci JERRY_ASSERT (builtin_routine_id == ECMA_REFLECT_OBJECT_SET); 141425bb815Sopenharmony_ci 142425bb815Sopenharmony_ci ecma_value_t receiver = arguments_list[0]; 143425bb815Sopenharmony_ci 144425bb815Sopenharmony_ci if (arguments_number > 3) 145425bb815Sopenharmony_ci { 146425bb815Sopenharmony_ci receiver = arguments_list[3]; 147425bb815Sopenharmony_ci } 148425bb815Sopenharmony_ci 149425bb815Sopenharmony_ci ret_value = ecma_op_object_put_with_receiver (target_p, name_str_p, arguments_list[2], receiver, false); 150425bb815Sopenharmony_ci break; 151425bb815Sopenharmony_ci } 152425bb815Sopenharmony_ci } 153425bb815Sopenharmony_ci 154425bb815Sopenharmony_ci ecma_deref_ecma_string (name_str_p); 155425bb815Sopenharmony_ci return ret_value; 156425bb815Sopenharmony_ci } 157425bb815Sopenharmony_ci 158425bb815Sopenharmony_ci if (builtin_routine_id == ECMA_REFLECT_OBJECT_OWN_KEYS) 159425bb815Sopenharmony_ci { 160425bb815Sopenharmony_ci /* 1. */ 161425bb815Sopenharmony_ci if (arguments_number == 0 || !ecma_is_value_object (arguments_list[0])) 162425bb815Sopenharmony_ci { 163425bb815Sopenharmony_ci return ecma_raise_type_error (ECMA_ERR_MSG ("Argument is not an Object.")); 164425bb815Sopenharmony_ci } 165425bb815Sopenharmony_ci 166425bb815Sopenharmony_ci ecma_object_t *target_p = ecma_get_object_from_value (arguments_list[0]); 167425bb815Sopenharmony_ci 168425bb815Sopenharmony_ci /* 2. 3. */ 169425bb815Sopenharmony_ci return ecma_builtin_helper_object_get_properties (target_p, ECMA_LIST_SYMBOLS); 170425bb815Sopenharmony_ci } 171425bb815Sopenharmony_ci 172425bb815Sopenharmony_ci if (builtin_routine_id == ECMA_REFLECT_OBJECT_CONSTRUCT) 173425bb815Sopenharmony_ci { 174425bb815Sopenharmony_ci /* 1. */ 175425bb815Sopenharmony_ci if (arguments_number < 1 || !ecma_is_constructor (arguments_list[0])) 176425bb815Sopenharmony_ci { 177425bb815Sopenharmony_ci return ecma_raise_type_error (ECMA_ERR_MSG ("Target is not a constructor")); 178425bb815Sopenharmony_ci } 179425bb815Sopenharmony_ci 180425bb815Sopenharmony_ci ecma_object_t *target_p = ecma_get_object_from_value (arguments_list[0]); 181425bb815Sopenharmony_ci 182425bb815Sopenharmony_ci /* 2. */ 183425bb815Sopenharmony_ci ecma_object_t *new_target_p = target_p; 184425bb815Sopenharmony_ci 185425bb815Sopenharmony_ci if (arguments_number > 2) 186425bb815Sopenharmony_ci { 187425bb815Sopenharmony_ci /* 3. */ 188425bb815Sopenharmony_ci if (!ecma_is_constructor (arguments_list[2])) 189425bb815Sopenharmony_ci { 190425bb815Sopenharmony_ci return ecma_raise_type_error (ECMA_ERR_MSG ("Target is not a constructor")); 191425bb815Sopenharmony_ci } 192425bb815Sopenharmony_ci 193425bb815Sopenharmony_ci new_target_p = ecma_get_object_from_value (arguments_list[2]); 194425bb815Sopenharmony_ci } 195425bb815Sopenharmony_ci 196425bb815Sopenharmony_ci /* 4. */ 197425bb815Sopenharmony_ci if (arguments_number < 2) 198425bb815Sopenharmony_ci { 199425bb815Sopenharmony_ci return ecma_raise_type_error (ECMA_ERR_MSG ("Reflect.construct requires the second argument be an object")); 200425bb815Sopenharmony_ci } 201425bb815Sopenharmony_ci 202425bb815Sopenharmony_ci ecma_collection_t *coll_p = ecma_op_create_list_from_array_like (arguments_list[1], false); 203425bb815Sopenharmony_ci 204425bb815Sopenharmony_ci if (coll_p == NULL) 205425bb815Sopenharmony_ci { 206425bb815Sopenharmony_ci return ECMA_VALUE_ERROR; 207425bb815Sopenharmony_ci } 208425bb815Sopenharmony_ci 209425bb815Sopenharmony_ci ecma_value_t ret_value = ecma_op_function_construct (target_p, 210425bb815Sopenharmony_ci new_target_p, 211425bb815Sopenharmony_ci coll_p->buffer_p, 212425bb815Sopenharmony_ci coll_p->item_count); 213425bb815Sopenharmony_ci 214425bb815Sopenharmony_ci ecma_collection_free (coll_p); 215425bb815Sopenharmony_ci return ret_value; 216425bb815Sopenharmony_ci } 217425bb815Sopenharmony_ci 218425bb815Sopenharmony_ci if (!ecma_is_value_object (arguments_list[0])) 219425bb815Sopenharmony_ci { 220425bb815Sopenharmony_ci return ecma_raise_type_error (ECMA_ERR_MSG ("Argument is not an Object.")); 221425bb815Sopenharmony_ci } 222425bb815Sopenharmony_ci 223425bb815Sopenharmony_ci switch (builtin_routine_id) 224425bb815Sopenharmony_ci { 225425bb815Sopenharmony_ci case ECMA_REFLECT_OBJECT_GET_PROTOTYPE_OF: 226425bb815Sopenharmony_ci { 227425bb815Sopenharmony_ci return ecma_builtin_object_object_get_prototype_of (ecma_get_object_from_value (arguments_list[0])); 228425bb815Sopenharmony_ci } 229425bb815Sopenharmony_ci case ECMA_REFLECT_OBJECT_SET_PROTOTYPE_OF: 230425bb815Sopenharmony_ci { 231425bb815Sopenharmony_ci if (!ecma_is_value_object (arguments_list[1]) && !ecma_is_value_null (arguments_list[1])) 232425bb815Sopenharmony_ci { 233425bb815Sopenharmony_ci return ecma_raise_type_error (ECMA_ERR_MSG ("proto is neither Object nor Null.")); 234425bb815Sopenharmony_ci } 235425bb815Sopenharmony_ci 236425bb815Sopenharmony_ci ecma_object_t *obj_p = ecma_get_object_from_value (arguments_list[0]); 237425bb815Sopenharmony_ci ecma_value_t status; 238425bb815Sopenharmony_ci 239425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015_BUILTIN_PROXY) 240425bb815Sopenharmony_ci if (ECMA_OBJECT_IS_PROXY (obj_p)) 241425bb815Sopenharmony_ci { 242425bb815Sopenharmony_ci status = ecma_proxy_object_set_prototype_of (obj_p, arguments_list[1]); 243425bb815Sopenharmony_ci } 244425bb815Sopenharmony_ci else 245425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */ 246425bb815Sopenharmony_ci { 247425bb815Sopenharmony_ci status = ecma_op_ordinary_object_set_prototype_of (obj_p, arguments_list[1]); 248425bb815Sopenharmony_ci } 249425bb815Sopenharmony_ci 250425bb815Sopenharmony_ci return status; 251425bb815Sopenharmony_ci } 252425bb815Sopenharmony_ci case ECMA_REFLECT_OBJECT_APPLY: 253425bb815Sopenharmony_ci { 254425bb815Sopenharmony_ci if (!ecma_op_is_callable (arguments_list[0])) 255425bb815Sopenharmony_ci { 256425bb815Sopenharmony_ci return ecma_raise_type_error (ECMA_ERR_MSG ("Argument 'this' is not a function.")); 257425bb815Sopenharmony_ci } 258425bb815Sopenharmony_ci 259425bb815Sopenharmony_ci ecma_object_t *func_obj_p = ecma_get_object_from_value (arguments_list[0]); 260425bb815Sopenharmony_ci return ecma_builtin_function_prototype_object_apply (func_obj_p, arguments_list[1], arguments_list[2]); 261425bb815Sopenharmony_ci } 262425bb815Sopenharmony_ci case ECMA_REFLECT_OBJECT_DEFINE_PROPERTY: 263425bb815Sopenharmony_ci { 264425bb815Sopenharmony_ci ecma_object_t *obj_p = ecma_get_object_from_value (arguments_list[0]); 265425bb815Sopenharmony_ci ecma_string_t *name_str_p = ecma_op_to_prop_name (arguments_list[1]); 266425bb815Sopenharmony_ci 267425bb815Sopenharmony_ci if (name_str_p == NULL) 268425bb815Sopenharmony_ci { 269425bb815Sopenharmony_ci return ECMA_VALUE_ERROR; 270425bb815Sopenharmony_ci } 271425bb815Sopenharmony_ci 272425bb815Sopenharmony_ci ecma_property_descriptor_t prop_desc; 273425bb815Sopenharmony_ci ecma_value_t conv_result = ecma_op_to_property_descriptor (arguments_list[2], &prop_desc); 274425bb815Sopenharmony_ci 275425bb815Sopenharmony_ci if (ECMA_IS_VALUE_ERROR (conv_result)) 276425bb815Sopenharmony_ci { 277425bb815Sopenharmony_ci ecma_deref_ecma_string (name_str_p); 278425bb815Sopenharmony_ci return conv_result; 279425bb815Sopenharmony_ci } 280425bb815Sopenharmony_ci 281425bb815Sopenharmony_ci ecma_value_t result = ecma_op_object_define_own_property (obj_p, 282425bb815Sopenharmony_ci name_str_p, 283425bb815Sopenharmony_ci &prop_desc); 284425bb815Sopenharmony_ci 285425bb815Sopenharmony_ci ecma_deref_ecma_string (name_str_p); 286425bb815Sopenharmony_ci ecma_free_property_descriptor (&prop_desc); 287425bb815Sopenharmony_ci 288425bb815Sopenharmony_ci if (ECMA_IS_VALUE_ERROR (result)) 289425bb815Sopenharmony_ci { 290425bb815Sopenharmony_ci return result; 291425bb815Sopenharmony_ci } 292425bb815Sopenharmony_ci 293425bb815Sopenharmony_ci bool boolean_result = ecma_op_to_boolean (result); 294425bb815Sopenharmony_ci 295425bb815Sopenharmony_ci return ecma_make_boolean_value (boolean_result); 296425bb815Sopenharmony_ci } 297425bb815Sopenharmony_ci case ECMA_REFLECT_OBJECT_GET_OWN_PROPERTY_DESCRIPTOR: 298425bb815Sopenharmony_ci { 299425bb815Sopenharmony_ci ecma_object_t *obj_p = ecma_get_object_from_value (arguments_list[0]); 300425bb815Sopenharmony_ci ecma_string_t *name_str_p = ecma_op_to_prop_name (arguments_list[1]); 301425bb815Sopenharmony_ci 302425bb815Sopenharmony_ci if (name_str_p == NULL) 303425bb815Sopenharmony_ci { 304425bb815Sopenharmony_ci return ECMA_VALUE_ERROR; 305425bb815Sopenharmony_ci } 306425bb815Sopenharmony_ci 307425bb815Sopenharmony_ci ecma_value_t ret_val = ecma_builtin_object_object_get_own_property_descriptor (obj_p, name_str_p); 308425bb815Sopenharmony_ci ecma_deref_ecma_string (name_str_p); 309425bb815Sopenharmony_ci return ret_val; 310425bb815Sopenharmony_ci } 311425bb815Sopenharmony_ci case ECMA_REFLECT_OBJECT_IS_EXTENSIBLE: 312425bb815Sopenharmony_ci { 313425bb815Sopenharmony_ci ecma_object_t *obj_p = ecma_get_object_from_value (arguments_list[0]); 314425bb815Sopenharmony_ci return ecma_builtin_object_object_is_extensible (obj_p); 315425bb815Sopenharmony_ci } 316425bb815Sopenharmony_ci default: 317425bb815Sopenharmony_ci { 318425bb815Sopenharmony_ci JERRY_ASSERT (builtin_routine_id == ECMA_REFLECT_OBJECT_PREVENT_EXTENSIONS); 319425bb815Sopenharmony_ci ecma_object_t *obj_p = ecma_get_object_from_value (arguments_list[0]); 320425bb815Sopenharmony_ci 321425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015_BUILTIN_PROXY) 322425bb815Sopenharmony_ci if (ECMA_OBJECT_IS_PROXY (obj_p)) 323425bb815Sopenharmony_ci { 324425bb815Sopenharmony_ci return ecma_proxy_object_prevent_extensions (obj_p); 325425bb815Sopenharmony_ci } 326425bb815Sopenharmony_ci#endif /* !ENABLED (JERRY_ES2015_BUILTIN_PROXY) */ 327425bb815Sopenharmony_ci 328425bb815Sopenharmony_ci ecma_op_ordinary_object_prevent_extensions (obj_p); 329425bb815Sopenharmony_ci 330425bb815Sopenharmony_ci return ECMA_VALUE_TRUE; 331425bb815Sopenharmony_ci } 332425bb815Sopenharmony_ci } 333425bb815Sopenharmony_ci} /* ecma_builtin_reflect_dispatch_routine */ 334425bb815Sopenharmony_ci 335425bb815Sopenharmony_ci/** 336425bb815Sopenharmony_ci * @} 337425bb815Sopenharmony_ci * @} 338425bb815Sopenharmony_ci * @} 339425bb815Sopenharmony_ci */ 340425bb815Sopenharmony_ci 341425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015_BUILTIN_REFLECT) */ 342