diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-reflect.c b/jerry-core/ecma/builtin-objects/ecma-builtin-reflect.c index 07127cb0a..8de9fb1c9 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-reflect.c +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-reflect.c @@ -13,8 +13,11 @@ * limitations under the License. */ +#include "ecma-array-object.h" #include "ecma-builtins.h" #include "ecma-builtin-function-prototype.h" +#include "ecma-iterator-object.h" +#include "ecma-builtin-helpers.h" #include "ecma-builtin-object.h" #include "ecma-exceptions.h" #include "ecma-function-object.h" @@ -37,13 +40,19 @@ enum { ECMA_REFLECT_OBJECT_ROUTINE_START = ECMA_BUILTIN_ID__COUNT - 1, - ECMA_REFLECT_OBJECT_GET_PROTOTYPE_OF_UL, /* ECMA-262 v6, 26.1.8 */ - ECMA_REFLECT_OBJECT_SET_PROTOTYPE_OF_UL, /* ECMA-262 v6, 26.1.14 */ + ECMA_REFLECT_OBJECT_GET, /* ECMA-262 v6, 26.1.6 */ + ECMA_REFLECT_OBJECT_SET, /* ECMA-262 v6, 26.1.13 */ + ECMA_REFLECT_OBJECT_HAS, /* ECMA-262 v6, 26.1.9 */ + ECMA_REFLECT_OBJECT_DELETE_PROPERTY, /* ECMA-262 v6, 26.1.4 */ + ECMA_REFLECT_OBJECT_CONSTRUCT, /* ECMA-262, 26.1.2 */ + ECMA_REFLECT_OBJECT_OWN_KEYS, /* ECMA-262 v6, 26.1.11 */ + ECMA_REFLECT_OBJECT_GET_PROTOTYPE_OF, /* ECMA-262 v6, 26.1.8 */ + ECMA_REFLECT_OBJECT_SET_PROTOTYPE_OF, /* ECMA-262 v6, 26.1.14 */ ECMA_REFLECT_OBJECT_APPLY, /* ECMA-262 v6, 26.1.1 */ ECMA_REFLECT_OBJECT_DEFINE_PROPERTY, /* ECMA-262 v6, 26.1.3 */ - ECMA_REFLECT_OBJECT_GET_OWN_PROPERTY_DESCRIPTOR_UL, /* ECMA-262 v5, 26.1.7 */ + ECMA_REFLECT_OBJECT_GET_OWN_PROPERTY_DESCRIPTOR, /* ECMA-262 v6, 26.1.7 */ ECMA_REFLECT_OBJECT_IS_EXTENSIBLE, /* ECMA-262 v6, 26.1.10 */ - ECMA_REFLECT_OBJECT_PREVENT_EXTENSIONS_UL, /* ECMA-262 v6, 26.1.12 */ + ECMA_REFLECT_OBJECT_PREVENT_EXTENSIONS, /* ECMA-262 v6, 26.1.12 */ }; #define BUILTIN_INC_HEADER_NAME "ecma-builtin-reflect.inc.h" @@ -77,6 +86,136 @@ ecma_builtin_reflect_dispatch_routine (uint16_t builtin_routine_id, /**< built-i JERRY_UNUSED (this_arg); JERRY_UNUSED (arguments_number); + if (builtin_routine_id < ECMA_REFLECT_OBJECT_CONSTRUCT) + { + /* 1. */ + if (arguments_number == 0 || !ecma_is_value_object (arguments_list[0])) + { + return ecma_raise_type_error (ECMA_ERR_MSG ("Argument is not an Object.")); + } + + /* 2. */ + ecma_string_t *name_str_p = ecma_op_to_prop_name (((arguments_number > 1) ? arguments_list[1] + : ECMA_VALUE_UNDEFINED)); + + /* 3. */ + if (name_str_p == NULL) + { + return ECMA_VALUE_ERROR; + } + + ecma_value_t ret_value; + ecma_object_t *target_p = ecma_get_object_from_value (arguments_list[0]); + switch (builtin_routine_id) + { + case ECMA_REFLECT_OBJECT_GET: + { + ecma_value_t receiver = arguments_list[0]; + + /* 4. */ + if (arguments_number > 2) + { + receiver = arguments_list[2]; + } + + ret_value = ecma_op_object_get_with_receiver (target_p, name_str_p, receiver); + break; + } + + case ECMA_REFLECT_OBJECT_HAS: + { + ret_value = ecma_make_boolean_value (ecma_op_object_has_property (target_p, name_str_p)); + break; + } + + case ECMA_REFLECT_OBJECT_DELETE_PROPERTY: + { + ret_value = ecma_op_object_delete (target_p, name_str_p, false); + break; + } + + default: + { + JERRY_ASSERT (builtin_routine_id == ECMA_REFLECT_OBJECT_SET); + + ecma_value_t receiver = arguments_list[0]; + + if (arguments_number > 3) + { + receiver = arguments_list[3]; + } + + ret_value = ecma_op_object_put_with_receiver (target_p, name_str_p, arguments_list[2], receiver, false); + break; + } + } + + ecma_deref_ecma_string (name_str_p); + return ret_value; + } + + if (builtin_routine_id == ECMA_REFLECT_OBJECT_OWN_KEYS) + { + /* 1. */ + if (arguments_number == 0 || !ecma_is_value_object (arguments_list[0])) + { + return ecma_raise_type_error (ECMA_ERR_MSG ("Argument is not an Object.")); + } + + ecma_object_t *target_p = ecma_get_object_from_value (arguments_list[0]); + + /* 2. 3. */ + return ecma_builtin_helper_object_get_properties (target_p, ECMA_LIST_SYMBOLS); + } + + if (builtin_routine_id == ECMA_REFLECT_OBJECT_CONSTRUCT) + { + /* 1. */ + if (arguments_number < 1 || !ecma_is_constructor (arguments_list[0])) + { + return ecma_raise_type_error (ECMA_ERR_MSG ("Target is not a constructor")); + } + + ecma_object_t *target_p = ecma_get_object_from_value (arguments_list[0]); + + /* 2. new_target_p is not supported for now*/ + ecma_object_t *new_target_p = target_p; + + if (arguments_number > 2) + { + /* 3. */ + if (!ecma_is_constructor (arguments_list[2])) + { + return ecma_raise_type_error (ECMA_ERR_MSG ("Target is not a constructor")); + } + + new_target_p = ecma_get_object_from_value (arguments_list[2]); + } + + /* 4. */ + if (arguments_number < 2) + { + return ecma_raise_type_error (ECMA_ERR_MSG ("Reflect.construct requires the second argument be an object")); + } + + ecma_collection_t *coll_p = ecma_op_create_list_from_array_like (arguments_list[1]); + + if (coll_p == NULL) + { + return ECMA_VALUE_ERROR; + } + + // TODO: add new_target_p to construct when it'll be supported + JERRY_UNUSED (new_target_p); + ecma_value_t ret_value = ecma_op_function_construct (target_p, + ECMA_VALUE_UNDEFINED, + coll_p->buffer_p, + coll_p->item_count); + + ecma_collection_free (coll_p); + return ret_value; + } + if (!ecma_is_value_object (arguments_list[0])) { return ecma_raise_type_error (ECMA_ERR_MSG ("Argument is not an Object.")); @@ -84,11 +223,11 @@ ecma_builtin_reflect_dispatch_routine (uint16_t builtin_routine_id, /**< built-i switch (builtin_routine_id) { - case ECMA_REFLECT_OBJECT_GET_PROTOTYPE_OF_UL: + case ECMA_REFLECT_OBJECT_GET_PROTOTYPE_OF: { return ecma_builtin_object_object_get_prototype_of (ecma_get_object_from_value (arguments_list[0])); } - case ECMA_REFLECT_OBJECT_SET_PROTOTYPE_OF_UL: + case ECMA_REFLECT_OBJECT_SET_PROTOTYPE_OF: { ecma_value_t result = ecma_builtin_object_object_set_prototype_of (arguments_list[0], arguments_list[1]); bool is_error = ECMA_IS_VALUE_ERROR (result); @@ -139,7 +278,7 @@ ecma_builtin_reflect_dispatch_routine (uint16_t builtin_routine_id, /**< built-i return ecma_make_boolean_value (!is_error); } - case ECMA_REFLECT_OBJECT_GET_OWN_PROPERTY_DESCRIPTOR_UL: + case ECMA_REFLECT_OBJECT_GET_OWN_PROPERTY_DESCRIPTOR: { ecma_object_t *obj_p = ecma_get_object_from_value (arguments_list[0]); ecma_string_t *name_str_p = ecma_op_to_prop_name (arguments_list[1]); @@ -160,7 +299,7 @@ ecma_builtin_reflect_dispatch_routine (uint16_t builtin_routine_id, /**< built-i } default: { - JERRY_ASSERT (builtin_routine_id == ECMA_REFLECT_OBJECT_PREVENT_EXTENSIONS_UL); + JERRY_ASSERT (builtin_routine_id == ECMA_REFLECT_OBJECT_PREVENT_EXTENSIONS); ecma_object_t *obj_p = ecma_get_object_from_value (arguments_list[0]); return ecma_builtin_object_object_prevent_extensions (obj_p); } diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-reflect.inc.h b/jerry-core/ecma/builtin-objects/ecma-builtin-reflect.inc.h index 68aef6023..17a623a5f 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-reflect.inc.h +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-reflect.inc.h @@ -21,11 +21,17 @@ * (property name, C routine name, arguments number or NON_FIXED, value of the routine's length property) */ ROUTINE (LIT_MAGIC_STRING_APPLY, ECMA_REFLECT_OBJECT_APPLY, 3, 3) ROUTINE (LIT_MAGIC_STRING_DEFINE_PROPERTY_UL, ECMA_REFLECT_OBJECT_DEFINE_PROPERTY, 3, 3) -ROUTINE (LIT_MAGIC_STRING_GET_OWN_PROPERTY_DESCRIPTOR_UL, ECMA_REFLECT_OBJECT_GET_OWN_PROPERTY_DESCRIPTOR_UL, 2, 2) -ROUTINE (LIT_MAGIC_STRING_GET_PROTOTYPE_OF_UL, ECMA_REFLECT_OBJECT_GET_PROTOTYPE_OF_UL, 1, 1) +ROUTINE (LIT_MAGIC_STRING_GET_OWN_PROPERTY_DESCRIPTOR_UL, ECMA_REFLECT_OBJECT_GET_OWN_PROPERTY_DESCRIPTOR, 2, 2) +ROUTINE (LIT_MAGIC_STRING_GET, ECMA_REFLECT_OBJECT_GET, NON_FIXED, 2) +ROUTINE (LIT_MAGIC_STRING_SET, ECMA_REFLECT_OBJECT_SET, NON_FIXED, 3) +ROUTINE (LIT_MAGIC_STRING_HAS, ECMA_REFLECT_OBJECT_HAS, 2, 2) +ROUTINE (LIT_MAGIC_STRING_DELETE_PROPERTY_UL, ECMA_REFLECT_OBJECT_DELETE_PROPERTY, 2, 2) +ROUTINE (LIT_MAGIC_STRING_OWN_KEYS_UL, ECMA_REFLECT_OBJECT_OWN_KEYS, NON_FIXED, 2) +ROUTINE (LIT_MAGIC_STRING_CONSTRUCT, ECMA_REFLECT_OBJECT_CONSTRUCT, NON_FIXED, 2) +ROUTINE (LIT_MAGIC_STRING_GET_PROTOTYPE_OF_UL, ECMA_REFLECT_OBJECT_GET_PROTOTYPE_OF, 1, 1) ROUTINE (LIT_MAGIC_STRING_IS_EXTENSIBLE, ECMA_REFLECT_OBJECT_IS_EXTENSIBLE, 1, 1) -ROUTINE (LIT_MAGIC_STRING_PREVENT_EXTENSIONS_UL, ECMA_REFLECT_OBJECT_PREVENT_EXTENSIONS_UL, 1, 1) -ROUTINE (LIT_MAGIC_STRING_SET_PROTOTYPE_OF_UL, ECMA_REFLECT_OBJECT_SET_PROTOTYPE_OF_UL, 2, 2) +ROUTINE (LIT_MAGIC_STRING_PREVENT_EXTENSIONS_UL, ECMA_REFLECT_OBJECT_PREVENT_EXTENSIONS, 1, 1) +ROUTINE (LIT_MAGIC_STRING_SET_PROTOTYPE_OF_UL, ECMA_REFLECT_OBJECT_SET_PROTOTYPE_OF, 2, 2) #endif /* ENABLED (JERRY_ES2015_BUILTIN_REFLECT) */ diff --git a/jerry-core/ecma/operations/ecma-conversion.c b/jerry-core/ecma/operations/ecma-conversion.c index a62ebf403..c30b6add1 100644 --- a/jerry-core/ecma/operations/ecma-conversion.c +++ b/jerry-core/ecma/operations/ecma-conversion.c @@ -860,7 +860,7 @@ ecma_op_to_property_descriptor (ecma_value_t obj_value, /**< object value */ * conversion error otherwise */ ecma_value_t -ecma_op_to_integer (ecma_value_t value, /**< ecma value*/ +ecma_op_to_integer (ecma_value_t value, /**< ecma value */ ecma_number_t *number_p) /**< [out] ecma number */ { if (ECMA_IS_VALUE_ERROR (value)) @@ -909,7 +909,7 @@ ecma_op_to_integer (ecma_value_t value, /**< ecma value*/ * conversion error otherwise */ ecma_value_t -ecma_op_to_length (ecma_value_t value, /**< ecma value*/ +ecma_op_to_length (ecma_value_t value, /**< ecma value */ uint32_t *length) /**< [out] ecma number */ { /* 1 */ @@ -962,6 +962,59 @@ ecma_op_to_length (ecma_value_t value, /**< ecma value*/ #endif /* ENABLED (JERRY_ES2015) */ } /* ecma_op_to_length */ +#if ENABLED (JERRY_ES2015) +/** + * CreateListFromArrayLike operation. + * Different types are not handled yet. + * + * See also: + * ECMA-262 v6, 7.3.17 + * + * @return ecma_collection_t if successful + * NULL otherwise + */ +ecma_collection_t * +ecma_op_create_list_from_array_like (ecma_value_t arr) /**< array value */ +{ + /* 1. */ + JERRY_ASSERT (!ECMA_IS_VALUE_ERROR (arr)); + + /* 3. */ + if (!ecma_is_value_object (arr)) + { + ecma_raise_type_error (ECMA_ERR_MSG ("Argument is not an Object.")); + return NULL; + } + ecma_object_t *obj_p = ecma_get_object_from_value (arr); + + /* 4. 5. */ + ecma_length_t len; + if (ECMA_IS_VALUE_ERROR (ecma_op_object_get_length (obj_p, &len))) + { + return NULL; + } + + /* 6. */ + ecma_collection_t *list_ptr = ecma_new_collection (); + + /* 7. 8. */ + for (uint32_t idx = 0; idx < len; idx++) + { + ecma_value_t next = ecma_op_object_get_by_uint32_index (obj_p, idx); + if (ECMA_IS_VALUE_ERROR (next)) + { + ecma_collection_free (list_ptr); + return NULL; + } + + ecma_collection_push_back (list_ptr, next); + } + + /* 9. */ + return list_ptr; +} /* ecma_op_create_list_from_array_like */ +#endif /* ENABLED (JERRY_ES2015) */ + /** * @} * @} diff --git a/jerry-core/ecma/operations/ecma-conversion.h b/jerry-core/ecma/operations/ecma-conversion.h index 3ee22ca1d..5b6b5630a 100644 --- a/jerry-core/ecma/operations/ecma-conversion.h +++ b/jerry-core/ecma/operations/ecma-conversion.h @@ -51,6 +51,9 @@ ecma_string_t *ecma_op_to_prop_name (ecma_value_t value); ecma_value_t ecma_op_to_object (ecma_value_t value); ecma_value_t ecma_op_to_integer (ecma_value_t value, ecma_number_t *number_p); ecma_value_t ecma_op_to_length (ecma_value_t value, uint32_t *length); +#if ENABLED (JERRY_ES2015) +ecma_collection_t *ecma_op_create_list_from_array_like (ecma_value_t arr); +#endif /* ENABLED (JERRY_ES2015) */ ecma_object_t *ecma_op_from_property_descriptor (const ecma_property_descriptor_t *src_prop_desc_p); ecma_value_t ecma_op_to_property_descriptor (ecma_value_t obj_value, ecma_property_descriptor_t *out_prop_desc_p); diff --git a/jerry-core/ecma/operations/ecma-objects.c b/jerry-core/ecma/operations/ecma-objects.c index e2e0c72d8..2b46c6a32 100644 --- a/jerry-core/ecma/operations/ecma-objects.c +++ b/jerry-core/ecma/operations/ecma-objects.c @@ -1137,11 +1137,43 @@ ecma_op_object_put_by_number_index (ecma_object_t *object_p, /**< the object */ * Note: even if is_throw is false, the setter can throw an * error, and this function returns with that error. */ -ecma_value_t +inline ecma_value_t JERRY_ATTR_ALWAYS_INLINE ecma_op_object_put (ecma_object_t *object_p, /**< the object */ ecma_string_t *property_name_p, /**< property name */ ecma_value_t value, /**< ecma value */ bool is_throw) /**< flag that controls failure handling */ +{ + return ecma_op_object_put_with_receiver (object_p, + property_name_p, + value, + ecma_make_object_value (object_p), + is_throw); +} /* ecma_op_object_put */ + +/** + * [[Put]] ecma general object's operation with given receiver + * + * See also: + * ECMA-262 v5, 8.6.2; ECMA-262 v5, Table 8 + * ECMA-262 v5, 8.12.5 + * Also incorporates [[CanPut]] ECMA-262 v5, 8.12.4 + * + * @return ecma value + * The returned value must be freed with ecma_free_value. + * + * Returns with ECMA_VALUE_TRUE if the operation is + * successful. Otherwise it returns with an error object + * or ECMA_VALUE_FALSE. + * + * Note: even if is_throw is false, the setter can throw an + * error, and this function returns with that error. + */ +ecma_value_t +ecma_op_object_put_with_receiver (ecma_object_t *object_p, /**< the object */ + ecma_string_t *property_name_p, /**< property name */ + ecma_value_t value, /**< ecma value */ + ecma_value_t receiver, /**< receiver */ + bool is_throw) /**< flag that controls failure handling */ { JERRY_ASSERT (object_p != NULL && !ecma_is_lexical_environment (object_p)); @@ -1431,7 +1463,7 @@ ecma_op_object_put (ecma_object_t *object_p, /**< the object */ } ecma_value_t ret_value = ecma_op_function_call (ECMA_GET_NON_NULL_POINTER (ecma_object_t, setter_cp), - ecma_make_object_value (object_p), + receiver, &value, 1); @@ -1442,7 +1474,7 @@ ecma_op_object_put (ecma_object_t *object_p, /**< the object */ } return ret_value; -} /* ecma_op_object_put */ +} /* ecma_op_object_put_with_receiver */ /** * [[Delete]] ecma object's operation specialized for uint32_t property index diff --git a/jerry-core/ecma/operations/ecma-objects.h b/jerry-core/ecma/operations/ecma-objects.h index e666a9f36..9986d4ca8 100644 --- a/jerry-core/ecma/operations/ecma-objects.h +++ b/jerry-core/ecma/operations/ecma-objects.h @@ -48,6 +48,8 @@ ecma_value_t ecma_op_object_get_by_symbol_id (ecma_object_t *object_p, lit_magic ecma_value_t ecma_op_get_method_by_symbol_id (ecma_value_t value, lit_magic_string_id_t symbol_id); ecma_value_t ecma_op_get_method_by_magic_id (ecma_value_t value, lit_magic_string_id_t magic_id); #endif /* ENABLED (JERRY_ES2015) */ +ecma_value_t ecma_op_object_put_with_receiver (ecma_object_t *object_p, ecma_string_t *property_name_p, + ecma_value_t value, ecma_value_t receiver, bool is_throw); ecma_value_t ecma_op_object_put (ecma_object_t *object_p, ecma_string_t *property_name_p, ecma_value_t value, bool is_throw); ecma_value_t ecma_op_object_put_by_uint32_index (ecma_object_t *object_p, uint32_t index, diff --git a/jerry-core/lit/lit-magic-strings.inc.h b/jerry-core/lit/lit-magic-strings.inc.h index 880a0f47a..00edfcf78 100644 --- a/jerry-core/lit/lit-magic-strings.inc.h +++ b/jerry-core/lit/lit-magic-strings.inc.h @@ -75,6 +75,7 @@ LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_FOR, "for") #endif LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_GET, "get") #if ENABLED (JERRY_ES2015_BUILTIN_MAP) \ +|| ENABLED (JERRY_ES2015_BUILTIN_REFLECT) \ || ENABLED (JERRY_ES2015_BUILTIN_SET) \ || ENABLED (JERRY_ES2015_BUILTIN_WEAKMAP) \ || ENABLED (JERRY_ES2015_BUILTIN_WEAKSET) @@ -419,6 +420,9 @@ LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_INDEX_OF_UL, "indexOf") LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_IS_ARRAY_UL, "isArray") #endif LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_MESSAGE, "message") +#if ENABLED (JERRY_ES2015_BUILTIN_REFLECT) +LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_OWN_KEYS_UL, "ownKeys") +#endif #if ENABLED (JERRY_BUILTIN_REGEXP) && ENABLED (JERRY_BUILTIN_STRING) \ || ENABLED (JERRY_ES2015) LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_REPLACE, "replace") @@ -531,6 +535,9 @@ LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_TYPE_ERROR_UL, "TypeError") #endif LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_UNDEFINED_UL, "Undefined") LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_ARGUMENTS, "arguments") +#if ENABLED (JERRY_ES2015_BUILTIN_REFLECT) +LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_CONSTRUCT, "construct") +#endif LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_DECODE_URI, "decodeURI") LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_ENCODE_URI, "encodeURI") #if ENABLED (JERRY_ES2015) \ @@ -739,6 +746,9 @@ LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_ARRAY_ITERATOR_UL, "Array Iterator") LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_REFERENCE_ERROR_UL, "ReferenceError") #endif LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_DEFINE_PROPERTY_UL, "defineProperty") +#if ENABLED (JERRY_ES2015_BUILTIN_REFLECT) +LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_DELETE_PROPERTY_UL, "deleteProperty") +#endif LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_GET_PROTOTYPE_OF_UL, "getPrototypeOf") #if ENABLED (JERRY_BUILTIN_DATE) LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_GET_UTC_FULL_YEAR_UL, "getUTCFullYear") diff --git a/jerry-core/lit/lit-magic-strings.ini b/jerry-core/lit/lit-magic-strings.ini index 44be66ee1..3c7685b29 100644 --- a/jerry-core/lit/lit-magic-strings.ini +++ b/jerry-core/lit/lit-magic-strings.ini @@ -171,6 +171,7 @@ LIT_MAGIC_STRING_GET_YEAR_UL = "getYear" LIT_MAGIC_STRING_INDEX_OF_UL = "indexOf" LIT_MAGIC_STRING_IS_ARRAY_UL = "isArray" LIT_MAGIC_STRING_MESSAGE = "message" +LIT_MAGIC_STRING_OWN_KEYS_UL = "ownKeys" LIT_MAGIC_STRING_REPLACE = "replace" LIT_MAGIC_STRING_RESOLVE = "resolve" LIT_MAGIC_STRING_REVERSE = "reverse" @@ -214,6 +215,7 @@ LIT_MAGIC_STRING_UNESCAPE = "unescape" LIT_MAGIC_STRING_WRITABLE = "writable" LIT_MAGIC_STRING_NEGATIVE_INFINITY_UL = "-Infinity" LIT_MAGIC_STRING_ARGUMENTS_UL = "Arguments" +LIT_MAGIC_STRING_CONSTRUCT = "construct" LIT_MAGIC_STRING_EVAL_ERROR_UL = "EvalError" LIT_MAGIC_STRING_INT8_ARRAY_UL = "Int8Array" LIT_MAGIC_STRING_IS_INTEGER = "isInteger" @@ -307,6 +309,7 @@ LIT_MAGIC_STRING_TO_EXPONENTIAL_UL = "toExponential" LIT_MAGIC_STRING_ARRAY_ITERATOR_UL = "Array Iterator" LIT_MAGIC_STRING_REFERENCE_ERROR_UL = "ReferenceError" LIT_MAGIC_STRING_DEFINE_PROPERTY_UL = "defineProperty" +LIT_MAGIC_STRING_DELETE_PROPERTY_UL = "deleteProperty" LIT_MAGIC_STRING_GET_PROTOTYPE_OF_UL = "getPrototypeOf" LIT_MAGIC_STRING_GET_UTC_FULL_YEAR_UL = "getUTCFullYear" LIT_MAGIC_STRING_HAS_OWN_PROPERTY_UL = "hasOwnProperty" diff --git a/tests/jerry/es2015/reflect-construct.js b/tests/jerry/es2015/reflect-construct.js new file mode 100644 index 000000000..0baac264b --- /dev/null +++ b/tests/jerry/es2015/reflect-construct.js @@ -0,0 +1,80 @@ +// Copyright JS Foundation and other contributors, http://js.foundation +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +try { + Reflect.construct (); + assert (false); +} catch (e) { + assert (e instanceof TypeError); +} + +try { + Reflect.construct (Date); + assert (false); +} catch (e) { + assert (e instanceof TypeError); +} + +var d = Reflect.construct (Date, [1776, 6, 4]); +assert (d instanceof Date); +assert (d.getFullYear () === 1776); + +function func1 (a, b, c) { + this.sum = a + b + c; +} + +var args = [1, 2, 3]; +var object1 = new func1 (...args); +var object2 = Reflect.construct (func1, args); + +assert (object2.sum === 6); +assert (object1.sum === 6); + +function CatClass () { + this.name = 'Cat'; +} + +function DogClass () { + this.name = 'Dog'; +} + +var obj1 = Reflect.construct (CatClass, args, DogClass); +assert (obj1.name === 'Cat'); +// assert (!(ob1 instanceof CatClass)); This is true because new target is not supported yet +// assert (obj1 instanceof DogClass); This is false because new target is not supported yet + +try { + Reflect.construct (func1, 5, 5); + assert (false); +} catch (e) { + assert (e instanceof TypeError); +} + +try { + Reflect.construct (5, 5); + assert (false); +} catch (e) { + assert (e instanceof TypeError); +} + +function func2 () { + throw 5; +} + +try { + Reflect.construct (func2, {}); + assert (false); +} catch (e) { + assert (e === 5); +} diff --git a/tests/jerry/es2015/reflect-deleteproperty.js b/tests/jerry/es2015/reflect-deleteproperty.js new file mode 100644 index 000000000..f8fdd49ed --- /dev/null +++ b/tests/jerry/es2015/reflect-deleteproperty.js @@ -0,0 +1,61 @@ +// Copyright JS Foundation and other contributors, http://js.foundation +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Copyright 2014 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +var object = { + property: 'Batcat' +}; + +Reflect.deleteProperty (object, 'property'); + +assert (object.property === undefined); + +assert (2 === Reflect.deleteProperty.length); + +try { + Reflect.deleteProperty (); + assert (false); +} catch (e) { + assert (e instanceof TypeError); +} + +try { + Reflect.deleteProperty (42, 'bat'); + assert (false); +} catch (e) { + assert (e instanceof TypeError); +} + +try { + Reflect.deleteProperty (null, 'bat'); + assert (false); +} catch (e) { + assert (e instanceof TypeError); +} + +var target = {bat: 42}; +var a = { [Symbol.toPrimitive]: function() { return 'bat' } }; +var b = { [Symbol.toPrimitive]: function() { throw 'cat' } }; + +assert (Reflect.deleteProperty (target, a)); + +try { + Reflect.deleteProperty (target, b); + assert (false); +} catch (e) { + assert (e === 'cat'); +} diff --git a/tests/jerry/es2015/reflect-get.js b/tests/jerry/es2015/reflect-get.js new file mode 100644 index 000000000..f89700dca --- /dev/null +++ b/tests/jerry/es2015/reflect-get.js @@ -0,0 +1,55 @@ +// Copyright JS Foundation and other contributors, http://js.foundation +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Copyright 2017 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +var object1 = { + x: "Bat", + y: "Cat" +}; + +assert (Reflect.get (object1, 'y') === "Cat"); + +try { + Reflect.get (); + assert (false); +} catch (e) { + assert (e instanceof TypeError); +} + +assert (Reflect.get ({}) === undefined); + +var o = {x: 10}; +function foo () { + try { + return Reflect.get (o, "x"); + } catch (e) { + return 1; + } +} + +assert (10 === foo()); + +var c = {}; +function foo2 (a) { + try { + return Reflect.get (c, a); + } catch (e) { + return 1; + } +} + +assert (1 === foo2 ({[Symbol.toPrimitive]() { throw new Error(); }})); diff --git a/tests/jerry/es2015/reflect-has.js b/tests/jerry/es2015/reflect-has.js new file mode 100644 index 000000000..75a004059 --- /dev/null +++ b/tests/jerry/es2015/reflect-has.js @@ -0,0 +1,64 @@ +// Copyright JS Foundation and other contributors, http://js.foundation +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Copyright 2014 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +assert (Reflect.has ({x: 0}, 'x') === true); +assert (Reflect.has ({x: 0}, 'y') === false); + +assert (Reflect.has ({x: 0}, 'toString') === true); + +var object = { + prop: 'Apple' +}; + +assert (Reflect.has (object, 'prop') === true); + +assert (2 === Reflect.has.length); + +try { + Reflect.has (); + assert (false); +} catch (e) { + assert (e instanceof TypeError); +} + +try { + Reflect.has (42, 'batcat'); + assert (false); +} catch (e) { + assert (e instanceof TypeError); +} + +try { + Reflect.has (null, 'bat'); + assert (false); +} catch (e) { + assert (e instanceof TypeError); +} + +var target = {bat: 42}; +var a = { [Symbol.toPrimitive]: function () { return 'bat' } }; +var b = { [Symbol.toPrimitive]: function () { throw 'cat' } }; + +assert (Reflect.has (target, a) === true); + +try { + Reflect.has (target, b); + assert (false); +} catch (e) { + assert (e === 'cat'); +} diff --git a/tests/jerry/es2015/reflect-own-keys.js b/tests/jerry/es2015/reflect-own-keys.js new file mode 100644 index 000000000..6c89b8fc6 --- /dev/null +++ b/tests/jerry/es2015/reflect-own-keys.js @@ -0,0 +1,144 @@ +// Copyright JS Foundation and other contributors, http://js.foundation +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Copyright 2015 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +var object1 = { + property1: 42, + property2: 13 +}; + +var array1 = []; + +assert (Reflect.ownKeys (object1)[0] === "property1"); +assert (Reflect.ownKeys (object1)[1] === "property2"); +assert (Reflect.ownKeys (object1).length === 2); + +var obj = { a: 1, b: 2}; +var keys = Reflect.ownKeys (obj); +assert (2 === keys.length); +assert ("a" === keys[0]); +assert ("b" === keys[1]); + +var obj = { a: function(){}, b: function(){} }; +var keys = Reflect.ownKeys (obj); +assert (2 === keys.length); +assert ("a" === keys[0]); +assert ("b" === keys[1]); + +// Check slow case +var obj = { a: 1, b: 2, c: 3 }; +delete obj.b; +var keys = Reflect.ownKeys (obj) +assert (2 === keys.length); +assert ("a" === keys[0]); +assert ("c" === keys[1]); + +// Check that non-enumerable properties are being returned. +var keys = Reflect.ownKeys ([1, 2]); +assert (3 === keys.length); +assert ("0" === keys[0]); +assert ("1" === keys[1]); +assert ("string" === typeof keys[0]); +assert ("string" === typeof keys[1]); +assert ("length" === keys[2]); + +// Check that no proto properties are returned. +var obj = { foo: "foo" }; +var obj2 = { bar: "bar" }; +Object.setPrototypeOf (obj, obj2) +keys = Reflect.ownKeys (obj); +assert (1 === keys.length); +assert ("foo" === keys[0]); + +// Check that getter properties are returned. +var obj = {}; +Object.defineProperty (obj, "getter", function() {}) +//obj.__defineGetter__("getter", function() {}); +keys = Reflect.ownKeys (obj); +assert (1 === keys.length); +assert ("getter" === keys[0]); + +// Check that implementation does not access Array.prototype. +var savedConcat = Array.prototype.concat; +Array.prototype.concat = function() { return []; } +keys = Reflect.ownKeys ({0: 'foo', bar: 'baz'}); +assert (2 === keys.length); +assert ('0' === keys[0]); +assert ('bar'=== keys[1]); +assert (Array.prototype === Object.getPrototypeOf (keys)) +Array.prototype.concat = savedConcat; + +try { + Reflect.ownKeys (4); + assert (false); +} catch (e) { + assert (e instanceof TypeError); +} + +try { + Reflect.ownKeys("cica"); + assert (false); +} catch (e) { + assert (e instanceof TypeError); +} + +try { + Reflect.ownKeys(true); + assert (false); +} catch (e) { + assert (e instanceof TypeError); +} + +assert (Reflect.ownKeys (Object (4)) !== []) +assert (Reflect.ownKeys (Object ("foo")) !== ["0", "1", "2", "length"]) +assert (Reflect.ownKeys (Object (4)) !== []); +assert (Reflect.ownKeys (Object ("foo")) !== [0, 1, 2, "length"]); +assert (Reflect.ownKeys (Object (true)) !== []); + +var id = Symbol("my kitten"); +var user = { + name: "Bob", + age: 30, + [id]: "is batcat" +} + +assert (Reflect.ownKeys (user)[0] === "name"); +assert (Reflect.ownKeys (user)[1] === "age"); +assert (Reflect.ownKeys (user)[2] === id); diff --git a/tests/jerry/es2015/reflect-set.js b/tests/jerry/es2015/reflect-set.js new file mode 100644 index 000000000..e3d805377 --- /dev/null +++ b/tests/jerry/es2015/reflect-set.js @@ -0,0 +1,68 @@ +// Copyright JS Foundation and other contributors, http://js.foundation +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Copyright 2014 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +var object = {}; +Reflect.set (object, 'property', 'batcat'); + +assert (object.property === 'batcat'); + +var array = ['cat', 'cat', 'cat']; +Reflect.set (array, 2, 'bat'); + +assert (array[2] === 'bat'); + +assert (3 === Reflect.set.length); + +try { + Reflect.set (); + assert (false); +} catch (e) { + assert (e instanceof TypeError); +} + +try { + Reflect.set (42, 'bat'); + assert (false); +} catch (e) { + assert (e instanceof TypeError); +} + +try { + Reflect.set (null, 'bat'); + assert (false); +} catch (e) { + assert (e instanceof TypeError); +} + +var target = {}; +var a = { [Symbol.toPrimitive]: function () { return 'bat' } }; +var b = { [Symbol.toPrimitive]: function () { throw 'cat' } }; +assert (Reflect.set (target, a, 42) === true); +assert (42 === target.bat); + +try { + Reflect.set (null, 'bat'); + assert (false); +} catch (e) { + assert (e instanceof TypeError); +} + +var y = []; +Object.defineProperty (y, 0, {value: 42, configurable: false}); +assert (Reflect.set (y, 'length', 0) === false); +assert (Reflect.set (y, 'length', 2) === true);