diff --git a/jerry-core/ecma/builtin-objects/ecma-builtins.c b/jerry-core/ecma/builtin-objects/ecma-builtins.c index 3ede40ee0..730353675 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtins.c +++ b/jerry-core/ecma/builtin-objects/ecma-builtins.c @@ -650,17 +650,32 @@ ecma_builtin_try_to_instantiate_property (ecma_object_t *object_p, /**< object * { /* * Lazy instantiation of 'length' property - * - * Note: - * We don't need to mark that the property was already lazy instantiated, - * as it is non-configurable and so can't be deleted */ ecma_property_t *len_prop_p; +#if ENABLED (JERRY_ES2015) + ecma_extended_object_t *ext_func_p = (ecma_extended_object_t *) object_p; + uint32_t *bitset_p = ext_func_p->u.built_in.instantiated_bitset; + if (*bitset_p & (1u << 0)) + { + /* length property was already instantiated */ + return NULL; + } + /* We mark that the property was lazily instantiated, + * as it is configurable and so can be deleted (ECMA-262 v6, 19.2.4.1) */ + *bitset_p |= (1u << 0); + ecma_property_value_t *len_prop_value_p = ecma_create_named_data_property (object_p, + string_p, + ECMA_PROPERTY_FLAG_CONFIGURABLE, + &len_prop_p); +#else /* !ENABLED (JERRY_ES2015) */ + /* We don't need to mark that the property was already lazy instantiated, + * as it is non-configurable and so can't be deleted (ECMA-262 v5, 13.2.5) */ ecma_property_value_t *len_prop_value_p = ecma_create_named_data_property (object_p, string_p, ECMA_PROPERTY_FIXED, &len_prop_p); +#endif /* ENABLED (JERRY_ES2015) */ ecma_extended_object_t *ext_obj_p = (ecma_extended_object_t *) object_p; @@ -949,8 +964,17 @@ ecma_builtin_list_lazy_property_names (ecma_object_t *object_p, /**< a built-in if (!is_array_indices_only) { +#if ENABLED (JERRY_ES2015) + ecma_extended_object_t *ext_func_p = (ecma_extended_object_t *) object_p; + if (!(ext_func_p->u.built_in.instantiated_bitset[0] & (1u << 0))) + { + /* Unintialized 'length' property is non-enumerable (ECMA-262 v6, 19.2.4.1) */ + ecma_collection_push_back (for_non_enumerable_p, ecma_make_magic_string_value (LIT_MAGIC_STRING_LENGTH)); + } +#else /* !ENABLED (JERRY_ES2015) */ /* 'length' property is non-enumerable (ECMA-262 v5, 15) */ ecma_collection_push_back (for_non_enumerable_p, ecma_make_magic_string_value (LIT_MAGIC_STRING_LENGTH)); +#endif /* ENABLED (JERRY_ES2015) */ } } else diff --git a/tests/jerry-test-suite/es2015/15.03.04.02-001.js b/tests/jerry-test-suite/es2015/15.03.04.02-001.js new file mode 100644 index 000000000..bf15596d6 --- /dev/null +++ b/tests/jerry-test-suite/es2015/15.03.04.02-001.js @@ -0,0 +1,17 @@ +// 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. + +assert(Function.prototype.toString.hasOwnProperty('length')); +assert(delete Function.prototype.toString.length); +assert(!Function.prototype.toString.hasOwnProperty('length')); diff --git a/tests/jerry-test-suite/es2015/15.03.04.02-004.js b/tests/jerry-test-suite/es2015/15.03.04.02-004.js new file mode 100644 index 000000000..bf15596d6 --- /dev/null +++ b/tests/jerry-test-suite/es2015/15.03.04.02-004.js @@ -0,0 +1,17 @@ +// 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. + +assert(Function.prototype.toString.hasOwnProperty('length')); +assert(delete Function.prototype.toString.length); +assert(!Function.prototype.toString.hasOwnProperty('length')); diff --git a/tests/jerry-test-suite/15/15.03/15.03.04/15.03.04.02/15.03.04.02-001.js b/tests/jerry-test-suite/es5.1/15.03.04.02-001.js similarity index 100% rename from tests/jerry-test-suite/15/15.03/15.03.04/15.03.04.02/15.03.04.02-001.js rename to tests/jerry-test-suite/es5.1/15.03.04.02-001.js diff --git a/tests/jerry-test-suite/15/15.03/15.03.04/15.03.04.02/15.03.04.02-004.js b/tests/jerry-test-suite/es5.1/15.03.04.02-004.js similarity index 100% rename from tests/jerry-test-suite/15/15.03/15.03.04/15.03.04.02/15.03.04.02-004.js rename to tests/jerry-test-suite/es5.1/15.03.04.02-004.js diff --git a/tests/jerry/es2015/length-property.js b/tests/jerry/es2015/length-property.js index 95937d83f..5a9230a1c 100644 --- a/tests/jerry/es2015/length-property.js +++ b/tests/jerry/es2015/length-property.js @@ -39,8 +39,6 @@ var builtin_objects = [ WeakSet, ]; -var builtin_prototypes = [Function.prototype] - var builtin_typedArrays = [ Float32Array, Float64Array, @@ -65,13 +63,6 @@ var builtin_typedArrays = [ assert(desc.configurable === true); } - for (proto of builtin_prototypes) { - desc = Object.getOwnPropertyDescriptor(proto, 'length'); - assert(desc.writable === false); - assert(desc.enumerable === false); - assert(desc.configurable === true); - } - for (ta of builtin_typedArrays) { desc = Object.getOwnPropertyDescriptor(ta, 'length'); assert(desc.writable === false); @@ -88,12 +79,6 @@ var builtin_typedArrays = [ assert(obj.hasOwnProperty('length') === false); } - for (proto of builtin_prototypes) { - assert(proto.hasOwnProperty('length') === true); - assert(delete proto.length); - assert(proto.hasOwnProperty('length') === false); - } - for (ta of builtin_typedArrays) { assert(ta.hasOwnProperty('length') === true); assert(delete ta.length); @@ -101,6 +86,26 @@ var builtin_typedArrays = [ } })(); +(function () { + /* test length property of builtin function */ + for (obj of builtin_objects) { + var property_names = Object.getOwnPropertyNames(obj); + for (var name of property_names) { + if (typeof obj[name] == 'function') { + var func = obj[name]; + var desc = Object.getOwnPropertyDescriptor(func, 'length'); + assert(desc.writable === false); + assert(desc.enumerable === false); + assert(desc.configurable === true); + + assert(func.hasOwnProperty('length') === true); + assert(delete func.length); + assert(func.hasOwnProperty('length') === false); + } + } + } +})(); + (function () { /* test length property of function objects */ var normal_func = function () {}; diff --git a/tests/jerry/string-prototype-charat.js b/tests/jerry/string-prototype-charat.js index 68daf68b8..7c6698421 100644 --- a/tests/jerry/string-prototype-charat.js +++ b/tests/jerry/string-prototype-charat.js @@ -13,7 +13,17 @@ // limitations under the License. // check properties -assert(Object.getOwnPropertyDescriptor(String.prototype.charAt, 'length').configurable === false); + +function length_configurable() +{ + function is_es51() { + return (typeof g === "function"); + { function g() {} } + } + return is_es51() ? false : true; +} + +assert(Object.getOwnPropertyDescriptor(String.prototype.charAt, 'length').configurable === length_configurable()); assert(Object.getOwnPropertyDescriptor(String.prototype.charAt, 'length').enumerable === false); diff --git a/tests/jerry/string-prototype-charcodeat.js b/tests/jerry/string-prototype-charcodeat.js index bfb68f635..35ff6ba34 100644 --- a/tests/jerry/string-prototype-charcodeat.js +++ b/tests/jerry/string-prototype-charcodeat.js @@ -13,7 +13,17 @@ // limitations under the License. // check properties -assert(Object.getOwnPropertyDescriptor(String.prototype.charCodeAt, 'length').configurable === false); + +function length_configurable() +{ + function is_es51() { + return (typeof g === "function"); + { function g() {} } + } + return is_es51() ? false : true; +} + +assert(Object.getOwnPropertyDescriptor(String.prototype.charCodeAt, 'length').configurable === length_configurable()); assert(Object.getOwnPropertyDescriptor(String.prototype.charCodeAt, 'length').enumerable === false); diff --git a/tests/jerry/string-prototype-concat.js b/tests/jerry/string-prototype-concat.js index c00190341..5d4fc07a0 100644 --- a/tests/jerry/string-prototype-concat.js +++ b/tests/jerry/string-prototype-concat.js @@ -13,7 +13,17 @@ // limitations under the License. // check properties -assert(Object.getOwnPropertyDescriptor(String.prototype.concat, 'length').configurable === false); + +function length_configurable() +{ + function is_es51() { + return (typeof g === "function"); + { function g() {} } + } + return is_es51() ? false : true; +} + +assert(Object.getOwnPropertyDescriptor(String.prototype.concat, 'length').configurable === length_configurable()); assert(Object.getOwnPropertyDescriptor(String.prototype.concat, 'length').enumerable === false); diff --git a/tests/jerry/string-prototype-indexof.js b/tests/jerry/string-prototype-indexof.js index a0b55fb43..f7ee266af 100644 --- a/tests/jerry/string-prototype-indexof.js +++ b/tests/jerry/string-prototype-indexof.js @@ -13,7 +13,17 @@ // limitations under the License. // check properties -assert(Object.getOwnPropertyDescriptor(String.prototype.indexOf, 'length').configurable === false); + +function length_configurable() +{ + function is_es51() { + return (typeof g === "function"); + { function g() {} } + } + return is_es51() ? false : true; +} + +assert(Object.getOwnPropertyDescriptor(String.prototype.indexOf, 'length').configurable === length_configurable()); assert(Object.getOwnPropertyDescriptor(String.prototype.indexOf, 'length').enumerable === false); diff --git a/tests/jerry/string-prototype-lastindexof.js b/tests/jerry/string-prototype-lastindexof.js index ca90a7829..5ff0f0bc4 100644 --- a/tests/jerry/string-prototype-lastindexof.js +++ b/tests/jerry/string-prototype-lastindexof.js @@ -13,7 +13,17 @@ // limitations under the License. // check properties -assert(Object.getOwnPropertyDescriptor(String.prototype.lastIndexOf, 'length').configurable === false); + +function length_configurable() +{ + function is_es51() { + return (typeof g === "function"); + { function g() {} } + } + return is_es51() ? false : true; +} + +assert(Object.getOwnPropertyDescriptor(String.prototype.lastIndexOf, 'length').configurable === length_configurable()); assert(Object.getOwnPropertyDescriptor(String.prototype.lastIndexOf, 'length').enumerable === false); diff --git a/tests/jerry/string-prototype-match.js b/tests/jerry/string-prototype-match.js index c8a099963..5318d2a3c 100644 --- a/tests/jerry/string-prototype-match.js +++ b/tests/jerry/string-prototype-match.js @@ -13,7 +13,17 @@ // limitations under the License. // check properties -assert(Object.getOwnPropertyDescriptor(String.prototype.match, 'length').configurable === false); + +function length_configurable() +{ + function is_es51() { + return (typeof g === "function"); + { function g() {} } + } + return is_es51() ? false : true; +} + +assert(Object.getOwnPropertyDescriptor(String.prototype.match, 'length').configurable === length_configurable()); assert(Object.getOwnPropertyDescriptor(String.prototype.match, 'length').enumerable === false); assert(Object.getOwnPropertyDescriptor(String.prototype.match, 'length').writable === false); diff --git a/tests/jerry/string-prototype-substr.js b/tests/jerry/string-prototype-substr.js index 40613b7ff..1e4a662c5 100644 --- a/tests/jerry/string-prototype-substr.js +++ b/tests/jerry/string-prototype-substr.js @@ -13,7 +13,17 @@ // limitations under the License. // check properties -assert(Object.getOwnPropertyDescriptor(String.prototype.substr, 'length').configurable === false); + +function length_configurable() +{ + function is_es51() { + return (typeof g === "function"); + { function g() {} } + } + return is_es51() ? false : true; +} + +assert(Object.getOwnPropertyDescriptor(String.prototype.substr, 'length').configurable === length_configurable()); assert(Object.getOwnPropertyDescriptor(String.prototype.substr, 'length').enumerable === false); diff --git a/tests/jerry/string-prototype-substring.js b/tests/jerry/string-prototype-substring.js index 51d03b1b0..78bda200d 100644 --- a/tests/jerry/string-prototype-substring.js +++ b/tests/jerry/string-prototype-substring.js @@ -13,7 +13,17 @@ // limitations under the License. // check properties -assert(Object.getOwnPropertyDescriptor(String.prototype.substring, 'length').configurable === false); + +function length_configurable() +{ + function is_es51() { + return (typeof g === "function"); + { function g() {} } + } + return is_es51() ? false : true; +} + +assert(Object.getOwnPropertyDescriptor(String.prototype.substring, 'length').configurable === length_configurable()); assert(Object.getOwnPropertyDescriptor(String.prototype.substring, 'length').enumerable === false); diff --git a/tests/jerry/string-prototype-trim.js b/tests/jerry/string-prototype-trim.js index abeb31c74..2750e0ce2 100644 --- a/tests/jerry/string-prototype-trim.js +++ b/tests/jerry/string-prototype-trim.js @@ -13,7 +13,17 @@ // limitations under the License. // check properties -assert(Object.getOwnPropertyDescriptor(String.prototype.trim, 'length').configurable === false); + +function length_configurable() +{ + function is_es51() { + return (typeof g === "function"); + { function g() {} } + } + return is_es51() ? false : true; +} + +assert(Object.getOwnPropertyDescriptor(String.prototype.trim, 'length').configurable === length_configurable()); assert(Object.getOwnPropertyDescriptor(String.prototype.trim, 'length').enumerable === false);