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/** 17425bb815Sopenharmony_ci * Implementation of ECMA-defined conversion routines 18425bb815Sopenharmony_ci */ 19425bb815Sopenharmony_ci 20425bb815Sopenharmony_ci#include <math.h> 21425bb815Sopenharmony_ci 22425bb815Sopenharmony_ci#include "ecma-alloc.h" 23425bb815Sopenharmony_ci#include "ecma-boolean-object.h" 24425bb815Sopenharmony_ci#include "ecma-conversion.h" 25425bb815Sopenharmony_ci#include "ecma-exceptions.h" 26425bb815Sopenharmony_ci#include "ecma-function-object.h" 27425bb815Sopenharmony_ci#include "ecma-gc.h" 28425bb815Sopenharmony_ci#include "ecma-globals.h" 29425bb815Sopenharmony_ci#include "ecma-helpers.h" 30425bb815Sopenharmony_ci#include "ecma-number-object.h" 31425bb815Sopenharmony_ci#include "ecma-objects.h" 32425bb815Sopenharmony_ci#include "ecma-objects-general.h" 33425bb815Sopenharmony_ci#include "ecma-string-object.h" 34425bb815Sopenharmony_ci#include "ecma-symbol-object.h" 35425bb815Sopenharmony_ci#include "ecma-try-catch-macro.h" 36425bb815Sopenharmony_ci#include "jrt-libc-includes.h" 37425bb815Sopenharmony_ci 38425bb815Sopenharmony_ci/** \addtogroup ecma ECMA 39425bb815Sopenharmony_ci * @{ 40425bb815Sopenharmony_ci * 41425bb815Sopenharmony_ci * \addtogroup ecmaconversion ECMA conversion routines 42425bb815Sopenharmony_ci * @{ 43425bb815Sopenharmony_ci */ 44425bb815Sopenharmony_ci 45425bb815Sopenharmony_ci/** 46425bb815Sopenharmony_ci * CheckObjectCoercible operation. 47425bb815Sopenharmony_ci * 48425bb815Sopenharmony_ci * See also: 49425bb815Sopenharmony_ci * ECMA-262 v5, 9.10 50425bb815Sopenharmony_ci * 51425bb815Sopenharmony_ci * @return ecma value 52425bb815Sopenharmony_ci * Returned value must be freed with ecma_free_value 53425bb815Sopenharmony_ci */ 54425bb815Sopenharmony_ciecma_value_t 55425bb815Sopenharmony_ciecma_op_check_object_coercible (ecma_value_t value) /**< ecma value */ 56425bb815Sopenharmony_ci{ 57425bb815Sopenharmony_ci ecma_check_value_type_is_spec_defined (value); 58425bb815Sopenharmony_ci 59425bb815Sopenharmony_ci if (ecma_is_value_undefined (value) 60425bb815Sopenharmony_ci || ecma_is_value_null (value)) 61425bb815Sopenharmony_ci { 62425bb815Sopenharmony_ci return ecma_raise_type_error (ECMA_ERR_MSG ("Argument cannot be converted to an object.")); 63425bb815Sopenharmony_ci } 64425bb815Sopenharmony_ci else 65425bb815Sopenharmony_ci { 66425bb815Sopenharmony_ci return ECMA_VALUE_EMPTY; 67425bb815Sopenharmony_ci } 68425bb815Sopenharmony_ci} /* ecma_op_check_object_coercible */ 69425bb815Sopenharmony_ci 70425bb815Sopenharmony_ci/** 71425bb815Sopenharmony_ci * SameValue operation. 72425bb815Sopenharmony_ci * 73425bb815Sopenharmony_ci * See also: 74425bb815Sopenharmony_ci * ECMA-262 v5, 9.12 75425bb815Sopenharmony_ci * 76425bb815Sopenharmony_ci * @return true - if the value are same according to ECMA-defined SameValue algorithm, 77425bb815Sopenharmony_ci * false - otherwise 78425bb815Sopenharmony_ci */ 79425bb815Sopenharmony_cibool 80425bb815Sopenharmony_ciecma_op_same_value (ecma_value_t x, /**< ecma value */ 81425bb815Sopenharmony_ci ecma_value_t y) /**< ecma value */ 82425bb815Sopenharmony_ci{ 83425bb815Sopenharmony_ci if (x == y) 84425bb815Sopenharmony_ci { 85425bb815Sopenharmony_ci return true; 86425bb815Sopenharmony_ci } 87425bb815Sopenharmony_ci 88425bb815Sopenharmony_ci ecma_type_t type_of_x = ecma_get_value_type_field (x); 89425bb815Sopenharmony_ci 90425bb815Sopenharmony_ci if (type_of_x != ecma_get_value_type_field (y) 91425bb815Sopenharmony_ci || type_of_x == ECMA_TYPE_DIRECT) 92425bb815Sopenharmony_ci { 93425bb815Sopenharmony_ci return false; 94425bb815Sopenharmony_ci } 95425bb815Sopenharmony_ci 96425bb815Sopenharmony_ci if (ecma_is_value_number (x)) 97425bb815Sopenharmony_ci { 98425bb815Sopenharmony_ci ecma_number_t x_num = ecma_get_number_from_value (x); 99425bb815Sopenharmony_ci ecma_number_t y_num = ecma_get_number_from_value (y); 100425bb815Sopenharmony_ci 101425bb815Sopenharmony_ci bool is_x_nan = ecma_number_is_nan (x_num); 102425bb815Sopenharmony_ci bool is_y_nan = ecma_number_is_nan (y_num); 103425bb815Sopenharmony_ci 104425bb815Sopenharmony_ci if (is_x_nan || is_y_nan) 105425bb815Sopenharmony_ci { 106425bb815Sopenharmony_ci return is_x_nan && is_y_nan; 107425bb815Sopenharmony_ci } 108425bb815Sopenharmony_ci 109425bb815Sopenharmony_ci if (ecma_number_is_zero (x_num) 110425bb815Sopenharmony_ci && ecma_number_is_zero (y_num) 111425bb815Sopenharmony_ci && ecma_number_is_negative (x_num) != ecma_number_is_negative (y_num)) 112425bb815Sopenharmony_ci { 113425bb815Sopenharmony_ci return false; 114425bb815Sopenharmony_ci } 115425bb815Sopenharmony_ci 116425bb815Sopenharmony_ci return (x_num == y_num); 117425bb815Sopenharmony_ci } 118425bb815Sopenharmony_ci 119425bb815Sopenharmony_ci if (ecma_is_value_string (x)) 120425bb815Sopenharmony_ci { 121425bb815Sopenharmony_ci ecma_string_t *x_str_p = ecma_get_string_from_value (x); 122425bb815Sopenharmony_ci ecma_string_t *y_str_p = ecma_get_string_from_value (y); 123425bb815Sopenharmony_ci 124425bb815Sopenharmony_ci return ecma_compare_ecma_strings (x_str_p, y_str_p); 125425bb815Sopenharmony_ci } 126425bb815Sopenharmony_ci 127425bb815Sopenharmony_ci JERRY_ASSERT (ecma_is_value_object (x) || ECMA_ASSERT_VALUE_IS_SYMBOL (x)); 128425bb815Sopenharmony_ci 129425bb815Sopenharmony_ci return false; 130425bb815Sopenharmony_ci} /* ecma_op_same_value */ 131425bb815Sopenharmony_ci 132425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015_BUILTIN_MAP) 133425bb815Sopenharmony_ci/** 134425bb815Sopenharmony_ci * SameValueZero operation. 135425bb815Sopenharmony_ci * 136425bb815Sopenharmony_ci * See also: 137425bb815Sopenharmony_ci * ECMA-262 v6, 7.2.10 138425bb815Sopenharmony_ci * 139425bb815Sopenharmony_ci * @return true - if the value are same according to ECMA-defined SameValueZero algorithm, 140425bb815Sopenharmony_ci * false - otherwise 141425bb815Sopenharmony_ci */ 142425bb815Sopenharmony_cibool 143425bb815Sopenharmony_ciecma_op_same_value_zero (ecma_value_t x, /**< ecma value */ 144425bb815Sopenharmony_ci ecma_value_t y) /**< ecma value */ 145425bb815Sopenharmony_ci{ 146425bb815Sopenharmony_ci if (ecma_is_value_number (x) && ecma_is_value_number (y)) 147425bb815Sopenharmony_ci { 148425bb815Sopenharmony_ci ecma_number_t x_num = ecma_get_number_from_value (x); 149425bb815Sopenharmony_ci ecma_number_t y_num = ecma_get_number_from_value (y); 150425bb815Sopenharmony_ci 151425bb815Sopenharmony_ci bool is_x_nan = ecma_number_is_nan (x_num); 152425bb815Sopenharmony_ci bool is_y_nan = ecma_number_is_nan (y_num); 153425bb815Sopenharmony_ci 154425bb815Sopenharmony_ci if (is_x_nan || is_y_nan) 155425bb815Sopenharmony_ci { 156425bb815Sopenharmony_ci /* 157425bb815Sopenharmony_ci * If both are NaN 158425bb815Sopenharmony_ci * return true; 159425bb815Sopenharmony_ci * else 160425bb815Sopenharmony_ci * one of the numbers is NaN, and another - is not 161425bb815Sopenharmony_ci * return false; 162425bb815Sopenharmony_ci */ 163425bb815Sopenharmony_ci return (is_x_nan && is_y_nan); 164425bb815Sopenharmony_ci } 165425bb815Sopenharmony_ci 166425bb815Sopenharmony_ci if (ecma_number_is_zero (x_num) 167425bb815Sopenharmony_ci && ecma_number_is_zero (y_num) 168425bb815Sopenharmony_ci && ecma_number_is_negative (x_num) != ecma_number_is_negative (y_num)) 169425bb815Sopenharmony_ci { 170425bb815Sopenharmony_ci return true; 171425bb815Sopenharmony_ci } 172425bb815Sopenharmony_ci 173425bb815Sopenharmony_ci return (x_num == y_num); 174425bb815Sopenharmony_ci } 175425bb815Sopenharmony_ci 176425bb815Sopenharmony_ci return ecma_op_same_value (x, y); 177425bb815Sopenharmony_ci} /* ecma_op_same_value_zero */ 178425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015_BUILTIN_MAP) */ 179425bb815Sopenharmony_ci 180425bb815Sopenharmony_ci/** 181425bb815Sopenharmony_ci * ToPrimitive operation. 182425bb815Sopenharmony_ci * 183425bb815Sopenharmony_ci * See also: 184425bb815Sopenharmony_ci * ECMA-262 v5, 9.1 185425bb815Sopenharmony_ci * 186425bb815Sopenharmony_ci * @return ecma value 187425bb815Sopenharmony_ci * Returned value must be freed with ecma_free_value 188425bb815Sopenharmony_ci */ 189425bb815Sopenharmony_ciecma_value_t 190425bb815Sopenharmony_ciecma_op_to_primitive (ecma_value_t value, /**< ecma value */ 191425bb815Sopenharmony_ci ecma_preferred_type_hint_t preferred_type) /**< preferred type hint */ 192425bb815Sopenharmony_ci{ 193425bb815Sopenharmony_ci ecma_check_value_type_is_spec_defined (value); 194425bb815Sopenharmony_ci 195425bb815Sopenharmony_ci if (ecma_is_value_object (value)) 196425bb815Sopenharmony_ci { 197425bb815Sopenharmony_ci ecma_object_t *obj_p = ecma_get_object_from_value (value); 198425bb815Sopenharmony_ci 199425bb815Sopenharmony_ci return ecma_op_object_default_value (obj_p, preferred_type); 200425bb815Sopenharmony_ci } 201425bb815Sopenharmony_ci else 202425bb815Sopenharmony_ci { 203425bb815Sopenharmony_ci return ecma_copy_value (value); 204425bb815Sopenharmony_ci } 205425bb815Sopenharmony_ci} /* ecma_op_to_primitive */ 206425bb815Sopenharmony_ci 207425bb815Sopenharmony_ci/** 208425bb815Sopenharmony_ci * ToBoolean operation. Cannot throw an exception. 209425bb815Sopenharmony_ci * 210425bb815Sopenharmony_ci * See also: 211425bb815Sopenharmony_ci * ECMA-262 v5, 9.2 212425bb815Sopenharmony_ci * 213425bb815Sopenharmony_ci * @return true - if the logical value is true 214425bb815Sopenharmony_ci * false - otherwise 215425bb815Sopenharmony_ci */ 216425bb815Sopenharmony_cibool 217425bb815Sopenharmony_ciecma_op_to_boolean (ecma_value_t value) /**< ecma value */ 218425bb815Sopenharmony_ci{ 219425bb815Sopenharmony_ci ecma_check_value_type_is_spec_defined (value); 220425bb815Sopenharmony_ci 221425bb815Sopenharmony_ci if (ecma_is_value_simple (value)) 222425bb815Sopenharmony_ci { 223425bb815Sopenharmony_ci JERRY_ASSERT (ecma_is_value_boolean (value) 224425bb815Sopenharmony_ci || ecma_is_value_undefined (value) 225425bb815Sopenharmony_ci || ecma_is_value_null (value)); 226425bb815Sopenharmony_ci 227425bb815Sopenharmony_ci return ecma_is_value_true (value); 228425bb815Sopenharmony_ci } 229425bb815Sopenharmony_ci 230425bb815Sopenharmony_ci if (ecma_is_value_integer_number (value)) 231425bb815Sopenharmony_ci { 232425bb815Sopenharmony_ci return (value != ecma_make_integer_value (0)); 233425bb815Sopenharmony_ci } 234425bb815Sopenharmony_ci 235425bb815Sopenharmony_ci if (ecma_is_value_float_number (value)) 236425bb815Sopenharmony_ci { 237425bb815Sopenharmony_ci ecma_number_t num = ecma_get_float_from_value (value); 238425bb815Sopenharmony_ci 239425bb815Sopenharmony_ci return (!ecma_number_is_nan (num) && !ecma_number_is_zero (num)); 240425bb815Sopenharmony_ci } 241425bb815Sopenharmony_ci 242425bb815Sopenharmony_ci if (ecma_is_value_string (value)) 243425bb815Sopenharmony_ci { 244425bb815Sopenharmony_ci ecma_string_t *str_p = ecma_get_string_from_value (value); 245425bb815Sopenharmony_ci 246425bb815Sopenharmony_ci return !ecma_string_is_empty (str_p); 247425bb815Sopenharmony_ci } 248425bb815Sopenharmony_ci 249425bb815Sopenharmony_ci JERRY_ASSERT (ecma_is_value_object (value) || ECMA_ASSERT_VALUE_IS_SYMBOL (value)); 250425bb815Sopenharmony_ci 251425bb815Sopenharmony_ci return true; 252425bb815Sopenharmony_ci} /* ecma_op_to_boolean */ 253425bb815Sopenharmony_ci 254425bb815Sopenharmony_ci/** 255425bb815Sopenharmony_ci * ToNumber operation. 256425bb815Sopenharmony_ci * 257425bb815Sopenharmony_ci * See also: 258425bb815Sopenharmony_ci * ECMA-262 v5, 9.3 259425bb815Sopenharmony_ci * 260425bb815Sopenharmony_ci * @return ecma value 261425bb815Sopenharmony_ci * Returned value must be freed with ecma_free_value 262425bb815Sopenharmony_ci */ 263425bb815Sopenharmony_ciecma_value_t 264425bb815Sopenharmony_ciecma_op_to_number (ecma_value_t value) /**< ecma value */ 265425bb815Sopenharmony_ci{ 266425bb815Sopenharmony_ci ecma_check_value_type_is_spec_defined (value); 267425bb815Sopenharmony_ci 268425bb815Sopenharmony_ci if (ecma_is_value_integer_number (value)) 269425bb815Sopenharmony_ci { 270425bb815Sopenharmony_ci return value; 271425bb815Sopenharmony_ci } 272425bb815Sopenharmony_ci 273425bb815Sopenharmony_ci if (ecma_is_value_float_number (value)) 274425bb815Sopenharmony_ci { 275425bb815Sopenharmony_ci return ecma_copy_value (value); 276425bb815Sopenharmony_ci } 277425bb815Sopenharmony_ci 278425bb815Sopenharmony_ci if (ecma_is_value_string (value)) 279425bb815Sopenharmony_ci { 280425bb815Sopenharmony_ci ecma_string_t *str_p = ecma_get_string_from_value (value); 281425bb815Sopenharmony_ci return ecma_make_number_value (ecma_string_to_number (str_p)); 282425bb815Sopenharmony_ci } 283425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 284425bb815Sopenharmony_ci if (ecma_is_value_symbol (value)) 285425bb815Sopenharmony_ci { 286425bb815Sopenharmony_ci return ecma_raise_type_error (ECMA_ERR_MSG ("Cannot convert a Symbol value to a number.")); 287425bb815Sopenharmony_ci } 288425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 289425bb815Sopenharmony_ci 290425bb815Sopenharmony_ci if (ecma_is_value_object (value)) 291425bb815Sopenharmony_ci { 292425bb815Sopenharmony_ci ecma_value_t primitive_value = ecma_op_to_primitive (value, ECMA_PREFERRED_TYPE_NUMBER); 293425bb815Sopenharmony_ci 294425bb815Sopenharmony_ci if (ECMA_IS_VALUE_ERROR (primitive_value)) 295425bb815Sopenharmony_ci { 296425bb815Sopenharmony_ci return primitive_value; 297425bb815Sopenharmony_ci } 298425bb815Sopenharmony_ci 299425bb815Sopenharmony_ci ecma_value_t ret_value = ecma_op_to_number (primitive_value); 300425bb815Sopenharmony_ci ecma_fast_free_value (primitive_value); 301425bb815Sopenharmony_ci return ret_value; 302425bb815Sopenharmony_ci } 303425bb815Sopenharmony_ci 304425bb815Sopenharmony_ci if (ecma_is_value_undefined (value)) 305425bb815Sopenharmony_ci { 306425bb815Sopenharmony_ci return ecma_make_nan_value (); 307425bb815Sopenharmony_ci } 308425bb815Sopenharmony_ci 309425bb815Sopenharmony_ci ecma_integer_value_t num = 0; 310425bb815Sopenharmony_ci 311425bb815Sopenharmony_ci if (ecma_is_value_null (value)) 312425bb815Sopenharmony_ci { 313425bb815Sopenharmony_ci num = 0; 314425bb815Sopenharmony_ci } 315425bb815Sopenharmony_ci else 316425bb815Sopenharmony_ci { 317425bb815Sopenharmony_ci JERRY_ASSERT (ecma_is_value_boolean (value)); 318425bb815Sopenharmony_ci 319425bb815Sopenharmony_ci num = ecma_is_value_true (value) ? 1 : 0; 320425bb815Sopenharmony_ci } 321425bb815Sopenharmony_ci 322425bb815Sopenharmony_ci return ecma_make_integer_value (num); 323425bb815Sopenharmony_ci} /* ecma_op_to_number */ 324425bb815Sopenharmony_ci 325425bb815Sopenharmony_ci/** 326425bb815Sopenharmony_ci * Helper to get the number contained in an ecma value. 327425bb815Sopenharmony_ci * 328425bb815Sopenharmony_ci * See also: 329425bb815Sopenharmony_ci * ECMA-262 v5, 9.3 330425bb815Sopenharmony_ci * 331425bb815Sopenharmony_ci * @return ECMA_VALUE_EMPTY if successful 332425bb815Sopenharmony_ci * conversion error otherwise 333425bb815Sopenharmony_ci * Returned value must be freed with ecma_free_value 334425bb815Sopenharmony_ci */ 335425bb815Sopenharmony_ciecma_value_t 336425bb815Sopenharmony_ciecma_get_number (ecma_value_t value, /**< ecma value*/ 337425bb815Sopenharmony_ci ecma_number_t *number_p) /**< [out] ecma number */ 338425bb815Sopenharmony_ci{ 339425bb815Sopenharmony_ci if (ecma_is_value_integer_number (value)) 340425bb815Sopenharmony_ci { 341425bb815Sopenharmony_ci *number_p = ecma_get_integer_from_value (value); 342425bb815Sopenharmony_ci return ECMA_VALUE_EMPTY; 343425bb815Sopenharmony_ci } 344425bb815Sopenharmony_ci 345425bb815Sopenharmony_ci if (ecma_is_value_float_number (value)) 346425bb815Sopenharmony_ci { 347425bb815Sopenharmony_ci *number_p = ecma_get_float_from_value (value); 348425bb815Sopenharmony_ci return ECMA_VALUE_EMPTY; 349425bb815Sopenharmony_ci } 350425bb815Sopenharmony_ci 351425bb815Sopenharmony_ci if (ecma_is_value_string (value)) 352425bb815Sopenharmony_ci { 353425bb815Sopenharmony_ci ecma_string_t *str_p = ecma_get_string_from_value (value); 354425bb815Sopenharmony_ci *number_p = ecma_string_to_number (str_p); 355425bb815Sopenharmony_ci return ECMA_VALUE_EMPTY; 356425bb815Sopenharmony_ci } 357425bb815Sopenharmony_ci 358425bb815Sopenharmony_ci if (ecma_is_value_object (value)) 359425bb815Sopenharmony_ci { 360425bb815Sopenharmony_ci ecma_value_t primitive_value = ecma_op_to_primitive (value, ECMA_PREFERRED_TYPE_NUMBER); 361425bb815Sopenharmony_ci 362425bb815Sopenharmony_ci if (ECMA_IS_VALUE_ERROR (primitive_value)) 363425bb815Sopenharmony_ci { 364425bb815Sopenharmony_ci return primitive_value; 365425bb815Sopenharmony_ci } 366425bb815Sopenharmony_ci 367425bb815Sopenharmony_ci ecma_value_t ret_value = ecma_get_number (primitive_value, number_p); 368425bb815Sopenharmony_ci ecma_fast_free_value (primitive_value); 369425bb815Sopenharmony_ci return ret_value; 370425bb815Sopenharmony_ci } 371425bb815Sopenharmony_ci 372425bb815Sopenharmony_ci if (ecma_is_value_undefined (value)) 373425bb815Sopenharmony_ci { 374425bb815Sopenharmony_ci *number_p = ecma_number_make_nan (); 375425bb815Sopenharmony_ci return ECMA_VALUE_EMPTY; 376425bb815Sopenharmony_ci } 377425bb815Sopenharmony_ci 378425bb815Sopenharmony_ci if (ecma_is_value_null (value)) 379425bb815Sopenharmony_ci { 380425bb815Sopenharmony_ci *number_p = 0; 381425bb815Sopenharmony_ci return ECMA_VALUE_EMPTY; 382425bb815Sopenharmony_ci } 383425bb815Sopenharmony_ci 384425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 385425bb815Sopenharmony_ci if (ecma_is_value_symbol (value)) 386425bb815Sopenharmony_ci { 387425bb815Sopenharmony_ci return ecma_raise_type_error (ECMA_ERR_MSG ("Cannot convert a Symbol value to a number.")); 388425bb815Sopenharmony_ci } 389425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 390425bb815Sopenharmony_ci 391425bb815Sopenharmony_ci JERRY_ASSERT (ecma_is_value_boolean (value)); 392425bb815Sopenharmony_ci 393425bb815Sopenharmony_ci *number_p = ecma_is_value_true (value) ? 1 : 0; 394425bb815Sopenharmony_ci return ECMA_VALUE_EMPTY; 395425bb815Sopenharmony_ci} /* ecma_get_number */ 396425bb815Sopenharmony_ci 397425bb815Sopenharmony_ci/** 398425bb815Sopenharmony_ci * ToString operation. 399425bb815Sopenharmony_ci * 400425bb815Sopenharmony_ci * See also: 401425bb815Sopenharmony_ci * ECMA-262 v5, 9.8 402425bb815Sopenharmony_ci * 403425bb815Sopenharmony_ci * @return NULL - if the conversion fails 404425bb815Sopenharmony_ci * pointer to the string descriptor - otherwise 405425bb815Sopenharmony_ci */ 406425bb815Sopenharmony_ciecma_string_t * 407425bb815Sopenharmony_ciecma_op_to_string (ecma_value_t value) /**< ecma value */ 408425bb815Sopenharmony_ci{ 409425bb815Sopenharmony_ci ecma_check_value_type_is_spec_defined (value); 410425bb815Sopenharmony_ci 411425bb815Sopenharmony_ci if (JERRY_UNLIKELY (ecma_is_value_object (value))) 412425bb815Sopenharmony_ci { 413425bb815Sopenharmony_ci ecma_value_t prim_value = ecma_op_to_primitive (value, ECMA_PREFERRED_TYPE_STRING); 414425bb815Sopenharmony_ci 415425bb815Sopenharmony_ci if (ECMA_IS_VALUE_ERROR (prim_value)) 416425bb815Sopenharmony_ci { 417425bb815Sopenharmony_ci return NULL; 418425bb815Sopenharmony_ci } 419425bb815Sopenharmony_ci 420425bb815Sopenharmony_ci ecma_string_t *ret_string_p = ecma_op_to_string (prim_value); 421425bb815Sopenharmony_ci 422425bb815Sopenharmony_ci ecma_free_value (prim_value); 423425bb815Sopenharmony_ci 424425bb815Sopenharmony_ci return ret_string_p; 425425bb815Sopenharmony_ci } 426425bb815Sopenharmony_ci 427425bb815Sopenharmony_ci if (ecma_is_value_string (value)) 428425bb815Sopenharmony_ci { 429425bb815Sopenharmony_ci ecma_string_t *res_p = ecma_get_string_from_value (value); 430425bb815Sopenharmony_ci ecma_ref_ecma_string (res_p); 431425bb815Sopenharmony_ci return res_p; 432425bb815Sopenharmony_ci } 433425bb815Sopenharmony_ci else if (ecma_is_value_integer_number (value)) 434425bb815Sopenharmony_ci { 435425bb815Sopenharmony_ci ecma_integer_value_t num = ecma_get_integer_from_value (value); 436425bb815Sopenharmony_ci 437425bb815Sopenharmony_ci if (num < 0) 438425bb815Sopenharmony_ci { 439425bb815Sopenharmony_ci return ecma_new_ecma_string_from_number ((ecma_number_t) num); 440425bb815Sopenharmony_ci } 441425bb815Sopenharmony_ci else 442425bb815Sopenharmony_ci { 443425bb815Sopenharmony_ci return ecma_new_ecma_string_from_uint32 ((uint32_t) num); 444425bb815Sopenharmony_ci } 445425bb815Sopenharmony_ci } 446425bb815Sopenharmony_ci else if (ecma_is_value_float_number (value)) 447425bb815Sopenharmony_ci { 448425bb815Sopenharmony_ci ecma_number_t num = ecma_get_float_from_value (value); 449425bb815Sopenharmony_ci return ecma_new_ecma_string_from_number (num); 450425bb815Sopenharmony_ci } 451425bb815Sopenharmony_ci else if (ecma_is_value_undefined (value)) 452425bb815Sopenharmony_ci { 453425bb815Sopenharmony_ci return ecma_get_magic_string (LIT_MAGIC_STRING_UNDEFINED); 454425bb815Sopenharmony_ci } 455425bb815Sopenharmony_ci else if (ecma_is_value_null (value)) 456425bb815Sopenharmony_ci { 457425bb815Sopenharmony_ci return ecma_get_magic_string (LIT_MAGIC_STRING_NULL); 458425bb815Sopenharmony_ci } 459425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 460425bb815Sopenharmony_ci else if (ecma_is_value_symbol (value)) 461425bb815Sopenharmony_ci { 462425bb815Sopenharmony_ci ecma_raise_type_error (ECMA_ERR_MSG ("Cannot convert a Symbol value to a string.")); 463425bb815Sopenharmony_ci return NULL; 464425bb815Sopenharmony_ci } 465425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 466425bb815Sopenharmony_ci JERRY_ASSERT (ecma_is_value_boolean (value)); 467425bb815Sopenharmony_ci 468425bb815Sopenharmony_ci if (ecma_is_value_true (value)) 469425bb815Sopenharmony_ci { 470425bb815Sopenharmony_ci return ecma_get_magic_string (LIT_MAGIC_STRING_TRUE); 471425bb815Sopenharmony_ci } 472425bb815Sopenharmony_ci 473425bb815Sopenharmony_ci return ecma_get_magic_string (LIT_MAGIC_STRING_FALSE); 474425bb815Sopenharmony_ci} /* ecma_op_to_string */ 475425bb815Sopenharmony_ci 476425bb815Sopenharmony_ci/** 477425bb815Sopenharmony_ci * ToPropertyName operation. 478425bb815Sopenharmony_ci * 479425bb815Sopenharmony_ci * @return NULL - if the conversion fails 480425bb815Sopenharmony_ci * ecma-string - otherwise 481425bb815Sopenharmony_ci */ 482425bb815Sopenharmony_ciecma_string_t * 483425bb815Sopenharmony_ciecma_op_to_prop_name (ecma_value_t value) /**< ecma value */ 484425bb815Sopenharmony_ci{ 485425bb815Sopenharmony_ci ecma_check_value_type_is_spec_defined (value); 486425bb815Sopenharmony_ci 487425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 488425bb815Sopenharmony_ci if (ecma_is_value_symbol (value)) 489425bb815Sopenharmony_ci { 490425bb815Sopenharmony_ci ecma_string_t *symbol_p = ecma_get_symbol_from_value (value); 491425bb815Sopenharmony_ci ecma_ref_ecma_string (symbol_p); 492425bb815Sopenharmony_ci return symbol_p; 493425bb815Sopenharmony_ci } 494425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 495425bb815Sopenharmony_ci 496425bb815Sopenharmony_ci return ecma_op_to_string (value); 497425bb815Sopenharmony_ci} /* ecma_op_to_prop_name */ 498425bb815Sopenharmony_ci 499425bb815Sopenharmony_ci/** 500425bb815Sopenharmony_ci * ToObject operation. 501425bb815Sopenharmony_ci * 502425bb815Sopenharmony_ci * See also: 503425bb815Sopenharmony_ci * ECMA-262 v5, 9.9 504425bb815Sopenharmony_ci * 505425bb815Sopenharmony_ci * @return ecma value 506425bb815Sopenharmony_ci * Returned value must be freed with ecma_free_value 507425bb815Sopenharmony_ci */ 508425bb815Sopenharmony_ciecma_value_t 509425bb815Sopenharmony_ciecma_op_to_object (ecma_value_t value) /**< ecma value */ 510425bb815Sopenharmony_ci{ 511425bb815Sopenharmony_ci ecma_check_value_type_is_spec_defined (value); 512425bb815Sopenharmony_ci 513425bb815Sopenharmony_ci if (ecma_is_value_number (value)) 514425bb815Sopenharmony_ci { 515425bb815Sopenharmony_ci return ecma_op_create_number_object (value); 516425bb815Sopenharmony_ci } 517425bb815Sopenharmony_ci else if (ecma_is_value_string (value)) 518425bb815Sopenharmony_ci { 519425bb815Sopenharmony_ci return ecma_op_create_string_object (&value, 1); 520425bb815Sopenharmony_ci } 521425bb815Sopenharmony_ci else if (ecma_is_value_object (value)) 522425bb815Sopenharmony_ci { 523425bb815Sopenharmony_ci return ecma_copy_value (value); 524425bb815Sopenharmony_ci } 525425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 526425bb815Sopenharmony_ci else if (ecma_is_value_symbol (value)) 527425bb815Sopenharmony_ci { 528425bb815Sopenharmony_ci return ecma_op_create_symbol_object (value); 529425bb815Sopenharmony_ci } 530425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 531425bb815Sopenharmony_ci else 532425bb815Sopenharmony_ci { 533425bb815Sopenharmony_ci if (ecma_is_value_undefined (value) 534425bb815Sopenharmony_ci || ecma_is_value_null (value)) 535425bb815Sopenharmony_ci { 536425bb815Sopenharmony_ci return ecma_raise_type_error (ECMA_ERR_MSG ("Argument cannot be converted to an object.")); 537425bb815Sopenharmony_ci } 538425bb815Sopenharmony_ci else 539425bb815Sopenharmony_ci { 540425bb815Sopenharmony_ci JERRY_ASSERT (ecma_is_value_boolean (value)); 541425bb815Sopenharmony_ci 542425bb815Sopenharmony_ci return ecma_op_create_boolean_object (value); 543425bb815Sopenharmony_ci } 544425bb815Sopenharmony_ci } 545425bb815Sopenharmony_ci} /* ecma_op_to_object */ 546425bb815Sopenharmony_ci 547425bb815Sopenharmony_ci/** 548425bb815Sopenharmony_ci * FromPropertyDescriptor operation. 549425bb815Sopenharmony_ci * 550425bb815Sopenharmony_ci * See also: 551425bb815Sopenharmony_ci * ECMA-262 v5, 8.10.4 552425bb815Sopenharmony_ci * 553425bb815Sopenharmony_ci * @return constructed object 554425bb815Sopenharmony_ci */ 555425bb815Sopenharmony_ciecma_object_t * 556425bb815Sopenharmony_ciecma_op_from_property_descriptor (const ecma_property_descriptor_t *src_prop_desc_p) /**< property descriptor */ 557425bb815Sopenharmony_ci{ 558425bb815Sopenharmony_ci /* 2. */ 559425bb815Sopenharmony_ci ecma_object_t *obj_p = ecma_op_create_object_object_noarg (); 560425bb815Sopenharmony_ci 561425bb815Sopenharmony_ci ecma_value_t completion; 562425bb815Sopenharmony_ci ecma_property_descriptor_t prop_desc = ecma_make_empty_property_descriptor (); 563425bb815Sopenharmony_ci { 564425bb815Sopenharmony_ci prop_desc.flags = (ECMA_PROP_IS_VALUE_DEFINED 565425bb815Sopenharmony_ci | ECMA_PROP_IS_WRITABLE_DEFINED 566425bb815Sopenharmony_ci | ECMA_PROP_IS_WRITABLE 567425bb815Sopenharmony_ci | ECMA_PROP_IS_ENUMERABLE_DEFINED 568425bb815Sopenharmony_ci | ECMA_PROP_IS_ENUMERABLE 569425bb815Sopenharmony_ci | ECMA_PROP_IS_CONFIGURABLE_DEFINED 570425bb815Sopenharmony_ci | ECMA_PROP_IS_CONFIGURABLE); 571425bb815Sopenharmony_ci } 572425bb815Sopenharmony_ci 573425bb815Sopenharmony_ci /* 3. */ 574425bb815Sopenharmony_ci if (src_prop_desc_p->flags & (ECMA_PROP_IS_VALUE_DEFINED | ECMA_PROP_IS_WRITABLE_DEFINED)) 575425bb815Sopenharmony_ci { 576425bb815Sopenharmony_ci JERRY_ASSERT ((prop_desc.flags & (ECMA_PROP_IS_VALUE_DEFINED | ECMA_PROP_IS_WRITABLE_DEFINED)) 577425bb815Sopenharmony_ci == (ECMA_PROP_IS_VALUE_DEFINED | ECMA_PROP_IS_WRITABLE_DEFINED)); 578425bb815Sopenharmony_ci 579425bb815Sopenharmony_ci /* a. */ 580425bb815Sopenharmony_ci prop_desc.value = src_prop_desc_p->value; 581425bb815Sopenharmony_ci 582425bb815Sopenharmony_ci completion = ecma_op_object_define_own_property (obj_p, 583425bb815Sopenharmony_ci ecma_get_magic_string (LIT_MAGIC_STRING_VALUE), 584425bb815Sopenharmony_ci &prop_desc); 585425bb815Sopenharmony_ci JERRY_ASSERT (ecma_is_value_true (completion)); 586425bb815Sopenharmony_ci 587425bb815Sopenharmony_ci /* b. */ 588425bb815Sopenharmony_ci prop_desc.value = ecma_make_boolean_value (src_prop_desc_p->flags & ECMA_PROP_IS_WRITABLE); 589425bb815Sopenharmony_ci 590425bb815Sopenharmony_ci completion = ecma_op_object_define_own_property (obj_p, 591425bb815Sopenharmony_ci ecma_get_magic_string (LIT_MAGIC_STRING_WRITABLE), 592425bb815Sopenharmony_ci &prop_desc); 593425bb815Sopenharmony_ci JERRY_ASSERT (ecma_is_value_true (completion)); 594425bb815Sopenharmony_ci } 595425bb815Sopenharmony_ci else 596425bb815Sopenharmony_ci { 597425bb815Sopenharmony_ci#if !ENABLED (JERRY_ES2015) 598425bb815Sopenharmony_ci JERRY_ASSERT (src_prop_desc_p->flags & (ECMA_PROP_IS_GET_DEFINED | ECMA_PROP_IS_SET_DEFINED)); 599425bb815Sopenharmony_ci#else /* ENABLED (JERRY_ES2015) */ 600425bb815Sopenharmony_ci if (src_prop_desc_p->flags & (ECMA_PROP_IS_GET_DEFINED | ECMA_PROP_IS_SET_DEFINED)) 601425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 602425bb815Sopenharmony_ci { 603425bb815Sopenharmony_ci /* a. */ 604425bb815Sopenharmony_ci if (src_prop_desc_p->get_p == NULL) 605425bb815Sopenharmony_ci { 606425bb815Sopenharmony_ci prop_desc.value = ECMA_VALUE_UNDEFINED; 607425bb815Sopenharmony_ci } 608425bb815Sopenharmony_ci else 609425bb815Sopenharmony_ci { 610425bb815Sopenharmony_ci prop_desc.value = ecma_make_object_value (src_prop_desc_p->get_p); 611425bb815Sopenharmony_ci } 612425bb815Sopenharmony_ci 613425bb815Sopenharmony_ci completion = ecma_op_object_define_own_property (obj_p, 614425bb815Sopenharmony_ci ecma_get_magic_string (LIT_MAGIC_STRING_GET), 615425bb815Sopenharmony_ci &prop_desc); 616425bb815Sopenharmony_ci JERRY_ASSERT (ecma_is_value_true (completion)); 617425bb815Sopenharmony_ci 618425bb815Sopenharmony_ci /* b. */ 619425bb815Sopenharmony_ci if (src_prop_desc_p->set_p == NULL) 620425bb815Sopenharmony_ci { 621425bb815Sopenharmony_ci prop_desc.value = ECMA_VALUE_UNDEFINED; 622425bb815Sopenharmony_ci } 623425bb815Sopenharmony_ci else 624425bb815Sopenharmony_ci { 625425bb815Sopenharmony_ci prop_desc.value = ecma_make_object_value (src_prop_desc_p->set_p); 626425bb815Sopenharmony_ci } 627425bb815Sopenharmony_ci 628425bb815Sopenharmony_ci completion = ecma_op_object_define_own_property (obj_p, 629425bb815Sopenharmony_ci ecma_get_magic_string (LIT_MAGIC_STRING_SET), 630425bb815Sopenharmony_ci &prop_desc); 631425bb815Sopenharmony_ci JERRY_ASSERT (ecma_is_value_true (completion)); 632425bb815Sopenharmony_ci } 633425bb815Sopenharmony_ci } 634425bb815Sopenharmony_ci 635425bb815Sopenharmony_ci prop_desc.value = ecma_make_boolean_value (src_prop_desc_p->flags & ECMA_PROP_IS_ENUMERABLE); 636425bb815Sopenharmony_ci 637425bb815Sopenharmony_ci completion = ecma_op_object_define_own_property (obj_p, 638425bb815Sopenharmony_ci ecma_get_magic_string (LIT_MAGIC_STRING_ENUMERABLE), 639425bb815Sopenharmony_ci &prop_desc); 640425bb815Sopenharmony_ci JERRY_ASSERT (ecma_is_value_true (completion)); 641425bb815Sopenharmony_ci 642425bb815Sopenharmony_ci prop_desc.value = ecma_make_boolean_value (src_prop_desc_p->flags & ECMA_PROP_IS_CONFIGURABLE); 643425bb815Sopenharmony_ci 644425bb815Sopenharmony_ci completion = ecma_op_object_define_own_property (obj_p, 645425bb815Sopenharmony_ci ecma_get_magic_string (LIT_MAGIC_STRING_CONFIGURABLE), 646425bb815Sopenharmony_ci &prop_desc); 647425bb815Sopenharmony_ci JERRY_ASSERT (ecma_is_value_true (completion)); 648425bb815Sopenharmony_ci 649425bb815Sopenharmony_ci return obj_p; 650425bb815Sopenharmony_ci} /* ecma_op_from_property_descriptor */ 651425bb815Sopenharmony_ci 652425bb815Sopenharmony_ci/** 653425bb815Sopenharmony_ci * ToPropertyDescriptor operation. 654425bb815Sopenharmony_ci * 655425bb815Sopenharmony_ci * See also: 656425bb815Sopenharmony_ci * ECMA-262 v5, 8.10.5 657425bb815Sopenharmony_ci * 658425bb815Sopenharmony_ci * @return ecma value 659425bb815Sopenharmony_ci * Returned value must be freed with ecma_free_value 660425bb815Sopenharmony_ci */ 661425bb815Sopenharmony_ciecma_value_t 662425bb815Sopenharmony_ciecma_op_to_property_descriptor (ecma_value_t obj_value, /**< object value */ 663425bb815Sopenharmony_ci ecma_property_descriptor_t *out_prop_desc_p) /**< [out] filled property descriptor 664425bb815Sopenharmony_ci if return value is normal 665425bb815Sopenharmony_ci empty completion value */ 666425bb815Sopenharmony_ci{ 667425bb815Sopenharmony_ci ecma_value_t ret_value = ECMA_VALUE_EMPTY; 668425bb815Sopenharmony_ci 669425bb815Sopenharmony_ci /* 1. */ 670425bb815Sopenharmony_ci if (!ecma_is_value_object (obj_value)) 671425bb815Sopenharmony_ci { 672425bb815Sopenharmony_ci ret_value = ecma_raise_type_error (ECMA_ERR_MSG ("Expected an object.")); 673425bb815Sopenharmony_ci } 674425bb815Sopenharmony_ci else 675425bb815Sopenharmony_ci { 676425bb815Sopenharmony_ci ecma_object_t *obj_p = ecma_get_object_from_value (obj_value); 677425bb815Sopenharmony_ci 678425bb815Sopenharmony_ci /* 2. */ 679425bb815Sopenharmony_ci ecma_property_descriptor_t prop_desc = ecma_make_empty_property_descriptor (); 680425bb815Sopenharmony_ci 681425bb815Sopenharmony_ci /* 3. */ 682425bb815Sopenharmony_ci ECMA_TRY_CATCH (enumerable_prop_value, 683425bb815Sopenharmony_ci ecma_op_object_find (obj_p, ecma_get_magic_string (LIT_MAGIC_STRING_ENUMERABLE)), 684425bb815Sopenharmony_ci ret_value); 685425bb815Sopenharmony_ci 686425bb815Sopenharmony_ci if (ecma_is_value_found (enumerable_prop_value)) 687425bb815Sopenharmony_ci { 688425bb815Sopenharmony_ci uint32_t is_enumerable = (ecma_op_to_boolean (enumerable_prop_value) ? ECMA_PROP_IS_ENUMERABLE 689425bb815Sopenharmony_ci : ECMA_PROP_NO_OPTS); 690425bb815Sopenharmony_ci 691425bb815Sopenharmony_ci prop_desc.flags |= (uint16_t) (ECMA_PROP_IS_ENUMERABLE_DEFINED | is_enumerable); 692425bb815Sopenharmony_ci } 693425bb815Sopenharmony_ci 694425bb815Sopenharmony_ci ECMA_FINALIZE (enumerable_prop_value); 695425bb815Sopenharmony_ci 696425bb815Sopenharmony_ci if (!ECMA_IS_VALUE_ERROR (ret_value)) 697425bb815Sopenharmony_ci { 698425bb815Sopenharmony_ci JERRY_ASSERT (ecma_is_value_empty (ret_value)); 699425bb815Sopenharmony_ci 700425bb815Sopenharmony_ci /* 4. */ 701425bb815Sopenharmony_ci ECMA_TRY_CATCH (configurable_prop_value, 702425bb815Sopenharmony_ci ecma_op_object_find (obj_p, ecma_get_magic_string (LIT_MAGIC_STRING_CONFIGURABLE)), 703425bb815Sopenharmony_ci ret_value); 704425bb815Sopenharmony_ci 705425bb815Sopenharmony_ci if (ecma_is_value_found (configurable_prop_value)) 706425bb815Sopenharmony_ci { 707425bb815Sopenharmony_ci uint32_t is_configurable = (ecma_op_to_boolean (configurable_prop_value) ? ECMA_PROP_IS_CONFIGURABLE 708425bb815Sopenharmony_ci : ECMA_PROP_NO_OPTS); 709425bb815Sopenharmony_ci 710425bb815Sopenharmony_ci prop_desc.flags |= (uint16_t) (ECMA_PROP_IS_CONFIGURABLE_DEFINED | is_configurable); 711425bb815Sopenharmony_ci } 712425bb815Sopenharmony_ci 713425bb815Sopenharmony_ci ECMA_FINALIZE (configurable_prop_value); 714425bb815Sopenharmony_ci } 715425bb815Sopenharmony_ci 716425bb815Sopenharmony_ci if (!ECMA_IS_VALUE_ERROR (ret_value)) 717425bb815Sopenharmony_ci { 718425bb815Sopenharmony_ci JERRY_ASSERT (ecma_is_value_empty (ret_value)); 719425bb815Sopenharmony_ci 720425bb815Sopenharmony_ci /* 5. */ 721425bb815Sopenharmony_ci ECMA_TRY_CATCH (value_prop_value, 722425bb815Sopenharmony_ci ecma_op_object_find (obj_p, ecma_get_magic_string (LIT_MAGIC_STRING_VALUE)), 723425bb815Sopenharmony_ci ret_value); 724425bb815Sopenharmony_ci 725425bb815Sopenharmony_ci if (ecma_is_value_found (value_prop_value)) 726425bb815Sopenharmony_ci { 727425bb815Sopenharmony_ci prop_desc.flags |= ECMA_PROP_IS_VALUE_DEFINED; 728425bb815Sopenharmony_ci prop_desc.value = ecma_copy_value (value_prop_value); 729425bb815Sopenharmony_ci } 730425bb815Sopenharmony_ci 731425bb815Sopenharmony_ci ECMA_FINALIZE (value_prop_value); 732425bb815Sopenharmony_ci } 733425bb815Sopenharmony_ci 734425bb815Sopenharmony_ci if (!ECMA_IS_VALUE_ERROR (ret_value)) 735425bb815Sopenharmony_ci { 736425bb815Sopenharmony_ci JERRY_ASSERT (ecma_is_value_empty (ret_value)); 737425bb815Sopenharmony_ci 738425bb815Sopenharmony_ci /* 6. */ 739425bb815Sopenharmony_ci ECMA_TRY_CATCH (writable_prop_value, 740425bb815Sopenharmony_ci ecma_op_object_find (obj_p, ecma_get_magic_string (LIT_MAGIC_STRING_WRITABLE)), 741425bb815Sopenharmony_ci ret_value); 742425bb815Sopenharmony_ci 743425bb815Sopenharmony_ci if (ecma_is_value_found (writable_prop_value)) 744425bb815Sopenharmony_ci { 745425bb815Sopenharmony_ci uint32_t is_writable = (ecma_op_to_boolean (writable_prop_value) ? ECMA_PROP_IS_WRITABLE 746425bb815Sopenharmony_ci : ECMA_PROP_NO_OPTS); 747425bb815Sopenharmony_ci 748425bb815Sopenharmony_ci prop_desc.flags |= (uint16_t) (ECMA_PROP_IS_WRITABLE_DEFINED | is_writable); 749425bb815Sopenharmony_ci } 750425bb815Sopenharmony_ci 751425bb815Sopenharmony_ci ECMA_FINALIZE (writable_prop_value); 752425bb815Sopenharmony_ci } 753425bb815Sopenharmony_ci 754425bb815Sopenharmony_ci if (!ECMA_IS_VALUE_ERROR (ret_value)) 755425bb815Sopenharmony_ci { 756425bb815Sopenharmony_ci JERRY_ASSERT (ecma_is_value_empty (ret_value)); 757425bb815Sopenharmony_ci 758425bb815Sopenharmony_ci /* 7. */ 759425bb815Sopenharmony_ci ECMA_TRY_CATCH (get_prop_value, 760425bb815Sopenharmony_ci ecma_op_object_find (obj_p, ecma_get_magic_string (LIT_MAGIC_STRING_GET)), 761425bb815Sopenharmony_ci ret_value); 762425bb815Sopenharmony_ci 763425bb815Sopenharmony_ci if (ecma_is_value_found (get_prop_value)) 764425bb815Sopenharmony_ci { 765425bb815Sopenharmony_ci if (!ecma_op_is_callable (get_prop_value) 766425bb815Sopenharmony_ci && !ecma_is_value_undefined (get_prop_value)) 767425bb815Sopenharmony_ci { 768425bb815Sopenharmony_ci ret_value = ecma_raise_type_error (ECMA_ERR_MSG ("Expected a function.")); 769425bb815Sopenharmony_ci } 770425bb815Sopenharmony_ci else 771425bb815Sopenharmony_ci { 772425bb815Sopenharmony_ci prop_desc.flags |= ECMA_PROP_IS_GET_DEFINED; 773425bb815Sopenharmony_ci 774425bb815Sopenharmony_ci if (ecma_is_value_undefined (get_prop_value)) 775425bb815Sopenharmony_ci { 776425bb815Sopenharmony_ci prop_desc.get_p = NULL; 777425bb815Sopenharmony_ci } 778425bb815Sopenharmony_ci else 779425bb815Sopenharmony_ci { 780425bb815Sopenharmony_ci JERRY_ASSERT (ecma_is_value_object (get_prop_value)); 781425bb815Sopenharmony_ci 782425bb815Sopenharmony_ci ecma_object_t *get_p = ecma_get_object_from_value (get_prop_value); 783425bb815Sopenharmony_ci ecma_ref_object (get_p); 784425bb815Sopenharmony_ci 785425bb815Sopenharmony_ci prop_desc.get_p = get_p; 786425bb815Sopenharmony_ci } 787425bb815Sopenharmony_ci } 788425bb815Sopenharmony_ci } 789425bb815Sopenharmony_ci 790425bb815Sopenharmony_ci ECMA_FINALIZE (get_prop_value); 791425bb815Sopenharmony_ci } 792425bb815Sopenharmony_ci 793425bb815Sopenharmony_ci if (!ECMA_IS_VALUE_ERROR (ret_value)) 794425bb815Sopenharmony_ci { 795425bb815Sopenharmony_ci JERRY_ASSERT (ecma_is_value_empty (ret_value)); 796425bb815Sopenharmony_ci 797425bb815Sopenharmony_ci /* 8. */ 798425bb815Sopenharmony_ci ECMA_TRY_CATCH (set_prop_value, 799425bb815Sopenharmony_ci ecma_op_object_find (obj_p, ecma_get_magic_string (LIT_MAGIC_STRING_SET)), 800425bb815Sopenharmony_ci ret_value); 801425bb815Sopenharmony_ci 802425bb815Sopenharmony_ci if (ecma_is_value_found (set_prop_value)) 803425bb815Sopenharmony_ci { 804425bb815Sopenharmony_ci if (!ecma_op_is_callable (set_prop_value) 805425bb815Sopenharmony_ci && !ecma_is_value_undefined (set_prop_value)) 806425bb815Sopenharmony_ci { 807425bb815Sopenharmony_ci ret_value = ecma_raise_type_error (ECMA_ERR_MSG ("Expected a function.")); 808425bb815Sopenharmony_ci } 809425bb815Sopenharmony_ci else 810425bb815Sopenharmony_ci { 811425bb815Sopenharmony_ci prop_desc.flags |= ECMA_PROP_IS_SET_DEFINED; 812425bb815Sopenharmony_ci 813425bb815Sopenharmony_ci if (ecma_is_value_undefined (set_prop_value)) 814425bb815Sopenharmony_ci { 815425bb815Sopenharmony_ci prop_desc.set_p = NULL; 816425bb815Sopenharmony_ci } 817425bb815Sopenharmony_ci else 818425bb815Sopenharmony_ci { 819425bb815Sopenharmony_ci JERRY_ASSERT (ecma_is_value_object (set_prop_value)); 820425bb815Sopenharmony_ci 821425bb815Sopenharmony_ci ecma_object_t *set_p = ecma_get_object_from_value (set_prop_value); 822425bb815Sopenharmony_ci ecma_ref_object (set_p); 823425bb815Sopenharmony_ci 824425bb815Sopenharmony_ci prop_desc.set_p = set_p; 825425bb815Sopenharmony_ci } 826425bb815Sopenharmony_ci } 827425bb815Sopenharmony_ci } 828425bb815Sopenharmony_ci 829425bb815Sopenharmony_ci ECMA_FINALIZE (set_prop_value); 830425bb815Sopenharmony_ci } 831425bb815Sopenharmony_ci 832425bb815Sopenharmony_ci if (!ECMA_IS_VALUE_ERROR (ret_value)) 833425bb815Sopenharmony_ci { 834425bb815Sopenharmony_ci JERRY_ASSERT (ecma_is_value_empty (ret_value)); 835425bb815Sopenharmony_ci 836425bb815Sopenharmony_ci /* 9. */ 837425bb815Sopenharmony_ci if ((prop_desc.flags & (ECMA_PROP_IS_VALUE_DEFINED | ECMA_PROP_IS_WRITABLE_DEFINED)) 838425bb815Sopenharmony_ci && (prop_desc.flags & (ECMA_PROP_IS_GET_DEFINED | ECMA_PROP_IS_SET_DEFINED))) 839425bb815Sopenharmony_ci { 840425bb815Sopenharmony_ci ret_value = ecma_raise_type_error (ECMA_ERR_MSG ("Accessors cannot be writable.")); 841425bb815Sopenharmony_ci } 842425bb815Sopenharmony_ci } 843425bb815Sopenharmony_ci 844425bb815Sopenharmony_ci if (!ECMA_IS_VALUE_ERROR (ret_value)) 845425bb815Sopenharmony_ci { 846425bb815Sopenharmony_ci JERRY_ASSERT (ecma_is_value_empty (ret_value)); 847425bb815Sopenharmony_ci } 848425bb815Sopenharmony_ci else 849425bb815Sopenharmony_ci { 850425bb815Sopenharmony_ci ecma_free_property_descriptor (&prop_desc); 851425bb815Sopenharmony_ci } 852425bb815Sopenharmony_ci 853425bb815Sopenharmony_ci *out_prop_desc_p = prop_desc; 854425bb815Sopenharmony_ci } 855425bb815Sopenharmony_ci 856425bb815Sopenharmony_ci return ret_value; 857425bb815Sopenharmony_ci} /* ecma_op_to_property_descriptor */ 858425bb815Sopenharmony_ci 859425bb815Sopenharmony_ci/** 860425bb815Sopenharmony_ci * ToInteger operation. 861425bb815Sopenharmony_ci * 862425bb815Sopenharmony_ci * See also: 863425bb815Sopenharmony_ci * ECMA-262 v5, 9.4 864425bb815Sopenharmony_ci * ECMA-262 v6, 7.1.4 865425bb815Sopenharmony_ci * 866425bb815Sopenharmony_ci * @return ECMA_VALUE_EMPTY if successful 867425bb815Sopenharmony_ci * conversion error otherwise 868425bb815Sopenharmony_ci */ 869425bb815Sopenharmony_ciecma_value_t 870425bb815Sopenharmony_ciecma_op_to_integer (ecma_value_t value, /**< ecma value */ 871425bb815Sopenharmony_ci ecma_number_t *number_p) /**< [out] ecma number */ 872425bb815Sopenharmony_ci{ 873425bb815Sopenharmony_ci if (ECMA_IS_VALUE_ERROR (value)) 874425bb815Sopenharmony_ci { 875425bb815Sopenharmony_ci return value; 876425bb815Sopenharmony_ci } 877425bb815Sopenharmony_ci 878425bb815Sopenharmony_ci /* 1 */ 879425bb815Sopenharmony_ci ecma_value_t to_number = ecma_get_number (value, number_p); 880425bb815Sopenharmony_ci 881425bb815Sopenharmony_ci /* 2 */ 882425bb815Sopenharmony_ci if (ECMA_IS_VALUE_ERROR (to_number)) 883425bb815Sopenharmony_ci { 884425bb815Sopenharmony_ci return to_number; 885425bb815Sopenharmony_ci } 886425bb815Sopenharmony_ci 887425bb815Sopenharmony_ci ecma_number_t number = *number_p; 888425bb815Sopenharmony_ci 889425bb815Sopenharmony_ci /* 3 */ 890425bb815Sopenharmony_ci if (ecma_number_is_nan (number)) 891425bb815Sopenharmony_ci { 892425bb815Sopenharmony_ci *number_p = ECMA_NUMBER_ZERO; 893425bb815Sopenharmony_ci return ECMA_VALUE_EMPTY; 894425bb815Sopenharmony_ci } 895425bb815Sopenharmony_ci 896425bb815Sopenharmony_ci /* 4 */ 897425bb815Sopenharmony_ci if (ecma_number_is_zero (number) || ecma_number_is_infinity (number)) 898425bb815Sopenharmony_ci { 899425bb815Sopenharmony_ci return ECMA_VALUE_EMPTY; 900425bb815Sopenharmony_ci } 901425bb815Sopenharmony_ci 902425bb815Sopenharmony_ci ecma_number_t floor_fabs = floor (fabs (number)); 903425bb815Sopenharmony_ci 904425bb815Sopenharmony_ci /* 5 */ 905425bb815Sopenharmony_ci *number_p = ecma_number_is_negative (number) ? -floor_fabs : floor_fabs; 906425bb815Sopenharmony_ci return ECMA_VALUE_EMPTY; 907425bb815Sopenharmony_ci} /* ecma_op_to_integer */ 908425bb815Sopenharmony_ci 909425bb815Sopenharmony_ci/** 910425bb815Sopenharmony_ci * ToLength operation. 911425bb815Sopenharmony_ci * 912425bb815Sopenharmony_ci * See also: 913425bb815Sopenharmony_ci * ECMA-262 v6, 7.1.15 914425bb815Sopenharmony_ci * 915425bb815Sopenharmony_ci * @return ECMA_VALUE_EMPTY if successful 916425bb815Sopenharmony_ci * conversion error otherwise 917425bb815Sopenharmony_ci */ 918425bb815Sopenharmony_ciecma_value_t 919425bb815Sopenharmony_ciecma_op_to_length (ecma_value_t value, /**< ecma value */ 920425bb815Sopenharmony_ci uint32_t *length) /**< [out] ecma number */ 921425bb815Sopenharmony_ci{ 922425bb815Sopenharmony_ci /* 1 */ 923425bb815Sopenharmony_ci if (ECMA_IS_VALUE_ERROR (value)) 924425bb815Sopenharmony_ci { 925425bb815Sopenharmony_ci return value; 926425bb815Sopenharmony_ci } 927425bb815Sopenharmony_ci 928425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 929425bb815Sopenharmony_ci /* 2 */ 930425bb815Sopenharmony_ci ecma_number_t num; 931425bb815Sopenharmony_ci ecma_value_t length_num = ecma_op_to_integer (value, &num); 932425bb815Sopenharmony_ci 933425bb815Sopenharmony_ci /* 3 */ 934425bb815Sopenharmony_ci if (ECMA_IS_VALUE_ERROR (length_num)) 935425bb815Sopenharmony_ci { 936425bb815Sopenharmony_ci return length_num; 937425bb815Sopenharmony_ci } 938425bb815Sopenharmony_ci 939425bb815Sopenharmony_ci /* 4 */ 940425bb815Sopenharmony_ci if (num <= 0.0f) 941425bb815Sopenharmony_ci { 942425bb815Sopenharmony_ci *length = 0; 943425bb815Sopenharmony_ci return ECMA_VALUE_EMPTY; 944425bb815Sopenharmony_ci } 945425bb815Sopenharmony_ci 946425bb815Sopenharmony_ci /* 5 */ 947425bb815Sopenharmony_ci if (num >= (ecma_number_t) UINT32_MAX) 948425bb815Sopenharmony_ci { 949425bb815Sopenharmony_ci *length = UINT32_MAX; 950425bb815Sopenharmony_ci return ECMA_VALUE_EMPTY; 951425bb815Sopenharmony_ci } 952425bb815Sopenharmony_ci 953425bb815Sopenharmony_ci /* 6 */ 954425bb815Sopenharmony_ci *length = (uint32_t) num; 955425bb815Sopenharmony_ci return ECMA_VALUE_EMPTY; 956425bb815Sopenharmony_ci#else /* !ENABLED (JERRY_ES2015) */ 957425bb815Sopenharmony_ci /* In the case of ES5, ToLength(ES6) operation is the same as ToUint32(ES5) */ 958425bb815Sopenharmony_ci ecma_number_t num; 959425bb815Sopenharmony_ci ecma_value_t to_number = ecma_get_number (value, &num); 960425bb815Sopenharmony_ci 961425bb815Sopenharmony_ci /* 2 */ 962425bb815Sopenharmony_ci if (ECMA_IS_VALUE_ERROR (to_number)) 963425bb815Sopenharmony_ci { 964425bb815Sopenharmony_ci return to_number; 965425bb815Sopenharmony_ci } 966425bb815Sopenharmony_ci 967425bb815Sopenharmony_ci *length = ecma_number_to_uint32 (num); 968425bb815Sopenharmony_ci return ECMA_VALUE_EMPTY; 969425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 970425bb815Sopenharmony_ci} /* ecma_op_to_length */ 971425bb815Sopenharmony_ci 972425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 973425bb815Sopenharmony_ci/** 974425bb815Sopenharmony_ci * CreateListFromArrayLike operation. 975425bb815Sopenharmony_ci * Different types are not handled yet. 976425bb815Sopenharmony_ci * 977425bb815Sopenharmony_ci * See also: 978425bb815Sopenharmony_ci * ECMA-262 v6, 7.3.17 979425bb815Sopenharmony_ci * 980425bb815Sopenharmony_ci * @return ecma_collection_t if successful 981425bb815Sopenharmony_ci * NULL otherwise 982425bb815Sopenharmony_ci */ 983425bb815Sopenharmony_ciecma_collection_t * 984425bb815Sopenharmony_ciecma_op_create_list_from_array_like (ecma_value_t arr, /**< array value */ 985425bb815Sopenharmony_ci bool prop_names_only) /**< true - accept only property names 986425bb815Sopenharmony_ci false - otherwise */ 987425bb815Sopenharmony_ci{ 988425bb815Sopenharmony_ci /* 1. */ 989425bb815Sopenharmony_ci JERRY_ASSERT (!ECMA_IS_VALUE_ERROR (arr)); 990425bb815Sopenharmony_ci 991425bb815Sopenharmony_ci /* 3. */ 992425bb815Sopenharmony_ci if (!ecma_is_value_object (arr)) 993425bb815Sopenharmony_ci { 994425bb815Sopenharmony_ci ecma_raise_type_error (ECMA_ERR_MSG ("Argument is not an Object.")); 995425bb815Sopenharmony_ci return NULL; 996425bb815Sopenharmony_ci } 997425bb815Sopenharmony_ci ecma_object_t *obj_p = ecma_get_object_from_value (arr); 998425bb815Sopenharmony_ci 999425bb815Sopenharmony_ci /* 4. 5. */ 1000425bb815Sopenharmony_ci ecma_length_t len; 1001425bb815Sopenharmony_ci if (ECMA_IS_VALUE_ERROR (ecma_op_object_get_length (obj_p, &len))) 1002425bb815Sopenharmony_ci { 1003425bb815Sopenharmony_ci return NULL; 1004425bb815Sopenharmony_ci } 1005425bb815Sopenharmony_ci 1006425bb815Sopenharmony_ci /* 6. */ 1007425bb815Sopenharmony_ci ecma_collection_t *list_ptr = ecma_new_collection (); 1008425bb815Sopenharmony_ci 1009425bb815Sopenharmony_ci /* 7. 8. */ 1010425bb815Sopenharmony_ci for (uint32_t idx = 0; idx < len; idx++) 1011425bb815Sopenharmony_ci { 1012425bb815Sopenharmony_ci ecma_value_t next = ecma_op_object_get_by_uint32_index (obj_p, idx); 1013425bb815Sopenharmony_ci if (ECMA_IS_VALUE_ERROR (next)) 1014425bb815Sopenharmony_ci { 1015425bb815Sopenharmony_ci ecma_collection_free (list_ptr); 1016425bb815Sopenharmony_ci return NULL; 1017425bb815Sopenharmony_ci } 1018425bb815Sopenharmony_ci 1019425bb815Sopenharmony_ci if (prop_names_only 1020425bb815Sopenharmony_ci && !ecma_is_value_prop_name (next)) 1021425bb815Sopenharmony_ci { 1022425bb815Sopenharmony_ci ecma_free_value (next); 1023425bb815Sopenharmony_ci ecma_collection_free (list_ptr); 1024425bb815Sopenharmony_ci ecma_raise_type_error (ECMA_ERR_MSG ("Property name is neither Symbol nor String.")); 1025425bb815Sopenharmony_ci return NULL; 1026425bb815Sopenharmony_ci } 1027425bb815Sopenharmony_ci 1028425bb815Sopenharmony_ci ecma_collection_push_back (list_ptr, next); 1029425bb815Sopenharmony_ci } 1030425bb815Sopenharmony_ci 1031425bb815Sopenharmony_ci /* 9. */ 1032425bb815Sopenharmony_ci return list_ptr; 1033425bb815Sopenharmony_ci} /* ecma_op_create_list_from_array_like */ 1034425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015) */ 1035425bb815Sopenharmony_ci 1036425bb815Sopenharmony_ci/** 1037425bb815Sopenharmony_ci * @} 1038425bb815Sopenharmony_ci * @} 1039425bb815Sopenharmony_ci */ 1040