From be83ff6b712401a0769a328c99eb575ea65734e4 Mon Sep 17 00:00:00 2001 From: Robert Fancsik Date: Mon, 13 Jan 2020 11:43:11 +0100 Subject: [PATCH] Update Function.prototype.bind to conform ES6 requirements (#3504) JerryScript-DCO-1.0-Signed-off-by: Robert Fancsik frobert@inf.u-szeged.hu --- .../ecma-builtin-function-prototype.c | 8 ++- tests/jerry/es2015/function-prototype-bind.js | 69 +++++++++++++++++++ 2 files changed, 76 insertions(+), 1 deletion(-) create mode 100644 tests/jerry/es2015/function-prototype-bind.js diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-function-prototype.c b/jerry-core/ecma/builtin-objects/ecma-builtin-function-prototype.c index 032f5deb3..cfe3bcecf 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-function-prototype.c +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-function-prototype.c @@ -208,7 +208,13 @@ ecma_builtin_function_prototype_object_bind (ecma_object_t *this_arg_obj_p , /** ecma_length_t arguments_number) /**< number of arguments */ { /* 4. 11. 18. */ - ecma_object_t *prototype_obj_p = ecma_builtin_get (ECMA_BUILTIN_ID_FUNCTION_PROTOTYPE); + ecma_object_t *prototype_obj_p; + +#if ENABLED (JERRY_ES2015) + prototype_obj_p = ECMA_GET_POINTER (ecma_object_t, this_arg_obj_p->u2.prototype_cp); +#else /* !ENABLED (JERRY_ES2015) */ + prototype_obj_p = ecma_builtin_get (ECMA_BUILTIN_ID_FUNCTION_PROTOTYPE); +#endif /* ENABLED (JERRY_ES2015) */ ecma_object_t *function_p; ecma_extended_object_t *ext_function_p; diff --git a/tests/jerry/es2015/function-prototype-bind.js b/tests/jerry/es2015/function-prototype-bind.js new file mode 100644 index 000000000..8d0f1e18c --- /dev/null +++ b/tests/jerry/es2015/function-prototype-bind.js @@ -0,0 +1,69 @@ +// 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. + +/* extended class */ +(function() { + class C extends Function {} + var c = new C("x", "y", "return this.foo + x + y;").bind({foo : 1}, 2); + assert(c(3) === 6); + assert(c instanceof C); +})(); + +function boundPrototypeChecker(f, proto) { + Object.setPrototypeOf(f, proto); + + var boundFunc = Function.prototype.bind.call(f, null); + assert(Object.getPrototypeOf(boundFunc) === proto); +} + +/* generator function */ +(function() { + var f = function*(){}; + boundPrototypeChecker(f, Function.prototype) + boundPrototypeChecker(f, {}) + boundPrototypeChecker(f, null); +})(); + +/* arrow function */ +(function() { + var f = () => 5; + boundPrototypeChecker(f, Function.prototype) + boundPrototypeChecker(f, {}) + boundPrototypeChecker(f, null); +})(); + +/* simple class */ +(function() { + class C {}; + boundPrototypeChecker(C, Function.prototype) + boundPrototypeChecker(C, {}) + boundPrototypeChecker(C, null); +})(); + +/* subclasses */ +(function() { + function boundPrototypeChecker(superclass) { + class C extends superclass { + constructor() { + return Object.create(null); + } + } + var boundF = Function.prototype.bind.call(C, null); + assert(Object.getPrototypeOf(boundF) === Object.getPrototypeOf(C)); + } + + boundPrototypeChecker(function(){}); + boundPrototypeChecker(Array); + boundPrototypeChecker(null); +})();