Diff
Modified: trunk/JSTests/ChangeLog (271118 => 271119)
--- trunk/JSTests/ChangeLog 2021-01-02 08:09:41 UTC (rev 271118)
+++ trunk/JSTests/ChangeLog 2021-01-02 18:41:47 UTC (rev 271119)
@@ -1,3 +1,20 @@
+2021-01-02 Alexey Shvayka <[email protected]>
+
+ Don't throw if `function.caller` is a non-strict / generator / async function
+ https://bugs.webkit.org/show_bug.cgi?id=220216
+
+ Reviewed by Yusuke Suzuki.
+
+ * stress/function-caller-async-arrow-function-body.js: Removed.
+ * stress/function-caller-async-function-body.js: Removed.
+ * stress/function-caller-async-generator-body.js: Removed.
+ * stress/function-caller-generator-body.js: Removed.
+ * stress/function-caller-generator-method-body.js: Removed.
+ * stress/function-hidden-as-caller.js: Added.
+ * stress/polymorphic-access-exception-handler-should-not-clobber-used-register.js:
+ * stress/tail-call-recognize.js:
+ * test262/expectations.yaml: Mark 45 test cases as passing.
+
2020-12-31 Alexey Shvayka <[email protected]>
JSFunction::deleteProperty() fails to delete a non-existent "prototype" property
Deleted: trunk/JSTests/stress/function-caller-async-arrow-function-body.js (271118 => 271119)
--- trunk/JSTests/stress/function-caller-async-arrow-function-body.js 2021-01-02 08:09:41 UTC (rev 271118)
+++ trunk/JSTests/stress/function-caller-async-arrow-function-body.js 2021-01-02 18:41:47 UTC (rev 271119)
@@ -1,26 +0,0 @@
-//@ runDefault
-
-(function thingy() {
- function bar()
- {
- return bar.caller;
- }
-
- var ok = false;
- var badError = null;
- var foo = async () => {
- try {
- bar();
- ok = true;
- } catch (e) {
- if (e.toString() != "TypeError: Function.caller used to retrieve async function body")
- badError = e;
- }
- }
-
- foo();
- if (ok)
- throw "Error: did not throw error";
- if (badError)
- throw "Bad error: " + badError;
-})();
Deleted: trunk/JSTests/stress/function-caller-async-function-body.js (271118 => 271119)
--- trunk/JSTests/stress/function-caller-async-function-body.js 2021-01-02 08:09:41 UTC (rev 271118)
+++ trunk/JSTests/stress/function-caller-async-function-body.js 2021-01-02 18:41:47 UTC (rev 271119)
@@ -1,27 +0,0 @@
-//@ runDefault
-
-(function thingy() {
- function bar()
- {
- return bar.caller;
- }
-
- var ok = false;
- var badError = null;
- async function foo()
- {
- try {
- bar();
- ok = true;
- } catch (e) {
- if (e.toString() != "TypeError: Function.caller used to retrieve async function body")
- badError = e;
- }
- }
-
- foo();
- if (ok)
- throw "Error: did not throw error";
- if (badError)
- throw "Bad error: " + badError;
-})();
Deleted: trunk/JSTests/stress/function-caller-async-generator-body.js (271118 => 271119)
--- trunk/JSTests/stress/function-caller-async-generator-body.js 2021-01-02 08:09:41 UTC (rev 271118)
+++ trunk/JSTests/stress/function-caller-async-generator-body.js 2021-01-02 18:41:47 UTC (rev 271119)
@@ -1,27 +0,0 @@
-//@ runDefault
-
-(function thingy() {
- function bar()
- {
- return bar.caller;
- }
-
- var ok = false;
- var badError = null;
- async function* foo()
- {
- try {
- bar();
- ok = true;
- } catch (e) {
- if (e.toString() != "TypeError: Function.caller used to retrieve generator body")
- badError = e;
- }
- }
-
- foo().next();
- if (ok)
- throw "Error: did not throw error";
- if (badError)
- throw "Bad error: " + badError;
-})();
Deleted: trunk/JSTests/stress/function-caller-generator-body.js (271118 => 271119)
--- trunk/JSTests/stress/function-caller-generator-body.js 2021-01-02 08:09:41 UTC (rev 271118)
+++ trunk/JSTests/stress/function-caller-generator-body.js 2021-01-02 18:41:47 UTC (rev 271119)
@@ -1,24 +0,0 @@
-//@ runDefault
-
-(function thingy() {
- function bar()
- {
- return bar.caller;
- }
-
- function* foo()
- {
- bar();
- }
-
- var ok = false;
- try {
- foo().next();
- ok = true;
- } catch (e) {
- if (e.toString() != "TypeError: Function.caller used to retrieve generator body")
- throw "Error: bad error: " + e;
- }
- if (ok)
- throw "Error: did not throw error";
-})();
Deleted: trunk/JSTests/stress/function-caller-generator-method-body.js (271118 => 271119)
--- trunk/JSTests/stress/function-caller-generator-method-body.js 2021-01-02 08:09:41 UTC (rev 271118)
+++ trunk/JSTests/stress/function-caller-generator-method-body.js 2021-01-02 18:41:47 UTC (rev 271119)
@@ -1,26 +0,0 @@
-//@ runDefault
-
-(function thingy() {
- function bar()
- {
- return bar.caller;
- }
-
- class C {
- *foo()
- {
- bar();
- }
- }
-
- var ok = false;
- try {
- new C().foo().next();
- ok = true;
- } catch (e) {
- if (e.toString() != "TypeError: Function.caller used to retrieve generator body")
- throw "Error: bad error: " + e;
- }
- if (ok)
- throw "Error: did not throw error";
-})();
Added: trunk/JSTests/stress/function-hidden-as-caller.js (0 => 271119)
--- trunk/JSTests/stress/function-hidden-as-caller.js (rev 0)
+++ trunk/JSTests/stress/function-hidden-as-caller.js 2021-01-02 18:41:47 UTC (rev 271119)
@@ -0,0 +1,63 @@
+function shouldBe(actual, expected, testInfo) {
+ if (actual !== expected)
+ throw new Error(`Bad value: ${actual} (${testInfo})`);
+}
+
+let caller = null;
+function updateCaller() {
+ caller = updateCaller.caller;
+}
+noInline(updateCaller);
+
+function normalStrictFunction() { "use strict"; updateCaller(); }
+
+const { get, set } = Object.getOwnPropertyDescriptor({
+ get accessor() { updateCaller(); },
+ set accessor(_v) { updateCaller(); },
+}, "accessor");
+
+const arrowFunction = () => { updateCaller(); };
+const asyncArrowFunction = async () => { updateCaller(); };
+
+const functionsHiddenAsCallers = [
+ normalStrictFunction,
+ normalStrictFunction.bind(),
+ get,
+ set,
+ arrowFunction,
+ asyncArrowFunction,
+ function* syncGenerator() { updateCaller(); },
+ { * syncGeneratorMethod() { updateCaller(); } }.syncGeneratorMethod,
+ { method() { updateCaller(); } }.method,
+ async function asyncFunction() { updateCaller(); },
+ { async asyncMethod() { updateCaller(); } }.asyncMethod,
+ async function* asyncGenerator() { updateCaller(); },
+ { async * asyncGeneratorMethod() { updateCaller(); } }.asyncGeneratorMethod,
+];
+
+const constructorsHiddenAsCallers = [
+ class baseConstructor {
+ constructor() { updateCaller(); }
+ },
+ class derivedConstructor extends Array {
+ constructor() { super(); updateCaller(); }
+ },
+];
+
+(function hiddenAsCallers() {
+ for (const fn of functionsHiddenAsCallers) {
+ for (let i = 0; i < 1e4; ++i) {
+ caller = null;
+ fn();
+ shouldBe(caller, null, fn.name);
+ }
+ }
+
+ for (const C of constructorsHiddenAsCallers) {
+ for (let i = 0; i < 1e4; ++i) {
+ caller = null;
+ new C();
+ shouldBe(caller, null, C.name);
+ }
+ }
+})();
Modified: trunk/JSTests/stress/polymorphic-access-exception-handler-should-not-clobber-used-register.js (271118 => 271119)
--- trunk/JSTests/stress/polymorphic-access-exception-handler-should-not-clobber-used-register.js 2021-01-02 08:09:41 UTC (rev 271118)
+++ trunk/JSTests/stress/polymorphic-access-exception-handler-should-not-clobber-used-register.js 2021-01-02 18:41:47 UTC (rev 271119)
@@ -1,6 +1,7 @@
//@ runDefault("--useConcurrentJIT=0", "--useRandomizingFuzzerAgent=1", "--airRandomizeRegs=1", "--airRandomizeRegsSeed=3421187372", "--jitPolicyScale=0")
function foo() {
+ 'use strict';
try {
foo.caller;
} catch (e) {
Modified: trunk/JSTests/stress/tail-call-recognize.js (271118 => 271119)
--- trunk/JSTests/stress/tail-call-recognize.js 2021-01-02 08:09:41 UTC (rev 271118)
+++ trunk/JSTests/stress/tail-call-recognize.js 2021-01-02 18:41:47 UTC (rev 271119)
@@ -4,13 +4,7 @@
}
function callerMustBeStrict() {
- var errorThrown = false;
- try {
- callerMustBeStrict.caller;
- } catch (e) {
- errorThrown = true;
- }
- if (!errorThrown)
+ if (!Object.is(callerMustBeStrict.caller, null))
throw Error("Wrong caller, expected strict caller but got ", callerMustBeStrict.caller);
}
Modified: trunk/JSTests/test262/expectations.yaml (271118 => 271119)
--- trunk/JSTests/test262/expectations.yaml 2021-01-02 08:09:41 UTC (rev 271118)
+++ trunk/JSTests/test262/expectations.yaml 2021-01-02 18:41:47 UTC (rev 271119)
@@ -1334,12 +1334,6 @@
strict mode: 'Test262Error: Expected SameValue(«function TypeError() {'
test/language/expressions/arrow-function/eval-var-scope-syntax-err.js:
default: 'Test262Error: Expected a SyntaxError to be thrown but no exception was thrown at all'
-test/language/expressions/arrow-function/forbidden-ext/b2/arrow-function-forbidden-ext-indirect-access-own-prop-caller-get.js:
- default: 'TypeError: Function.caller used to retrieve strict caller'
-test/language/expressions/arrow-function/forbidden-ext/b2/arrow-function-forbidden-ext-indirect-access-own-prop-caller-value.js:
- default: 'TypeError: Function.caller used to retrieve strict caller'
-test/language/expressions/arrow-function/forbidden-ext/b2/arrow-function-forbidden-ext-indirect-access-prop-caller.js:
- default: 'TypeError: Function.caller used to retrieve strict caller'
test/language/expressions/arrow-function/scope-body-lex-distinct.js:
default: 'Test262Error: Expected a SyntaxError to be thrown but no exception was thrown at all'
test/language/expressions/arrow-function/scope-param-rest-elem-var-open.js:
@@ -1506,30 +1500,6 @@
test/language/expressions/class/elements/nested-private-direct-eval-err-contains-arguments.js:
default: 'Test262Error: Expected a SyntaxError but got a ReferenceError'
strict mode: 'Test262Error: Expected a SyntaxError but got a ReferenceError'
-test/language/expressions/class/gen-method-static/forbidden-ext/b2/cls-expr-gen-meth-static-forbidden-ext-indirect-access-own-prop-caller-get.js:
- default: 'TypeError: Function.caller used to retrieve generator body'
-test/language/expressions/class/gen-method-static/forbidden-ext/b2/cls-expr-gen-meth-static-forbidden-ext-indirect-access-own-prop-caller-value.js:
- default: 'TypeError: Function.caller used to retrieve generator body'
-test/language/expressions/class/gen-method-static/forbidden-ext/b2/cls-expr-gen-meth-static-forbidden-ext-indirect-access-prop-caller.js:
- default: 'TypeError: Function.caller used to retrieve generator body'
-test/language/expressions/class/gen-method/forbidden-ext/b2/cls-expr-gen-meth-forbidden-ext-indirect-access-own-prop-caller-get.js:
- default: 'TypeError: Function.caller used to retrieve generator body'
-test/language/expressions/class/gen-method/forbidden-ext/b2/cls-expr-gen-meth-forbidden-ext-indirect-access-own-prop-caller-value.js:
- default: 'TypeError: Function.caller used to retrieve generator body'
-test/language/expressions/class/gen-method/forbidden-ext/b2/cls-expr-gen-meth-forbidden-ext-indirect-access-prop-caller.js:
- default: 'TypeError: Function.caller used to retrieve generator body'
-test/language/expressions/class/method-static/forbidden-ext/b2/cls-expr-meth-static-forbidden-ext-indirect-access-own-prop-caller-get.js:
- default: 'TypeError: Function.caller used to retrieve strict caller'
-test/language/expressions/class/method-static/forbidden-ext/b2/cls-expr-meth-static-forbidden-ext-indirect-access-own-prop-caller-value.js:
- default: 'TypeError: Function.caller used to retrieve strict caller'
-test/language/expressions/class/method-static/forbidden-ext/b2/cls-expr-meth-static-forbidden-ext-indirect-access-prop-caller.js:
- default: 'TypeError: Function.caller used to retrieve strict caller'
-test/language/expressions/class/method/forbidden-ext/b2/cls-expr-meth-forbidden-ext-indirect-access-own-prop-caller-get.js:
- default: 'TypeError: Function.caller used to retrieve strict caller'
-test/language/expressions/class/method/forbidden-ext/b2/cls-expr-meth-forbidden-ext-indirect-access-own-prop-caller-value.js:
- default: 'TypeError: Function.caller used to retrieve strict caller'
-test/language/expressions/class/method/forbidden-ext/b2/cls-expr-meth-forbidden-ext-indirect-access-prop-caller.js:
- default: 'TypeError: Function.caller used to retrieve strict caller'
test/language/expressions/compound-assignment/S11.13.2_A5.10_T1.js:
default: "ReferenceError: Can't find variable: x"
test/language/expressions/compound-assignment/S11.13.2_A5.10_T2.js:
@@ -1638,12 +1608,6 @@
strict mode: 'Test262:AsyncTestFailure:Test262Error: Test262Error: f Expected SameValue(«null», «foo») to be true'
test/language/expressions/function/eval-var-scope-syntax-err.js:
default: 'Test262Error: Expected a SyntaxError to be thrown but no exception was thrown at all'
-test/language/expressions/function/forbidden-ext/b2/func-expr-forbidden-ext-indirect-access-own-prop-caller-get.js:
- default: 'TypeError: Function.caller used to retrieve strict caller'
-test/language/expressions/function/forbidden-ext/b2/func-expr-forbidden-ext-indirect-access-own-prop-caller-value.js:
- default: 'TypeError: Function.caller used to retrieve strict caller'
-test/language/expressions/function/forbidden-ext/b2/func-expr-forbidden-ext-indirect-access-prop-caller.js:
- default: 'TypeError: Function.caller used to retrieve strict caller'
test/language/expressions/function/scope-body-lex-distinct.js:
default: 'Test262Error: Expected a SyntaxError to be thrown but no exception was thrown at all'
test/language/expressions/function/scope-param-rest-elem-var-open.js:
@@ -1650,12 +1614,6 @@
default: 'Test262Error: Expected SameValue(«outside», «inside») to be true'
test/language/expressions/generators/eval-var-scope-syntax-err.js:
default: 'Test262Error: Expected a SyntaxError to be thrown but no exception was thrown at all'
-test/language/expressions/generators/forbidden-ext/b2/gen-func-expr-forbidden-ext-indirect-access-own-prop-caller-get.js:
- default: 'TypeError: Function.caller used to retrieve generator body'
-test/language/expressions/generators/forbidden-ext/b2/gen-func-expr-forbidden-ext-indirect-access-own-prop-caller-value.js:
- default: 'TypeError: Function.caller used to retrieve generator body'
-test/language/expressions/generators/forbidden-ext/b2/gen-func-expr-forbidden-ext-indirect-access-prop-caller.js:
- default: 'TypeError: Function.caller used to retrieve generator body'
test/language/expressions/generators/generator-created-after-decl-inst.js:
default: 'Test262Error: Expected SameValue(«[object Generator]», «[object Generator]») to be false'
strict mode: 'Test262Error: Expected SameValue(«[object Generator]», «[object Generator]») to be false'
@@ -1683,18 +1641,6 @@
strict mode: 'Test262Error: production including Arguments Expected a TypeError but got a TypeError'
test/language/expressions/object/method-definition/async-gen-meth-eval-var-scope-syntax-err.js:
default: 'Test262Error: Expected a SyntaxError to be thrown but no exception was thrown at all'
-test/language/expressions/object/method-definition/forbidden-ext/b2/gen-meth-forbidden-ext-indirect-access-own-prop-caller-get.js:
- default: 'TypeError: Function.caller used to retrieve generator body'
-test/language/expressions/object/method-definition/forbidden-ext/b2/gen-meth-forbidden-ext-indirect-access-own-prop-caller-value.js:
- default: 'TypeError: Function.caller used to retrieve generator body'
-test/language/expressions/object/method-definition/forbidden-ext/b2/gen-meth-forbidden-ext-indirect-access-prop-caller.js:
- default: 'TypeError: Function.caller used to retrieve generator body'
-test/language/expressions/object/method-definition/forbidden-ext/b2/meth-forbidden-ext-indirect-access-own-prop-caller-get.js:
- default: 'TypeError: Function.caller used to retrieve strict caller'
-test/language/expressions/object/method-definition/forbidden-ext/b2/meth-forbidden-ext-indirect-access-own-prop-caller-value.js:
- default: 'TypeError: Function.caller used to retrieve strict caller'
-test/language/expressions/object/method-definition/forbidden-ext/b2/meth-forbidden-ext-indirect-access-prop-caller.js:
- default: 'TypeError: Function.caller used to retrieve strict caller'
test/language/expressions/object/method-definition/gen-meth-eval-var-scope-syntax-err.js:
default: 'Test262Error: Expected a SyntaxError to be thrown but no exception was thrown at all'
test/language/expressions/object/method-definition/meth-eval-var-scope-syntax-err.js:
@@ -1819,30 +1765,6 @@
test/language/statements/class/elements/nested-private-direct-eval-err-contains-arguments.js:
default: 'Test262Error: Expected a SyntaxError but got a ReferenceError'
strict mode: 'Test262Error: Expected a SyntaxError but got a ReferenceError'
-test/language/statements/class/gen-method-static/forbidden-ext/b2/cls-decl-gen-meth-static-forbidden-ext-indirect-access-own-prop-caller-get.js:
- default: 'TypeError: Function.caller used to retrieve generator body'
-test/language/statements/class/gen-method-static/forbidden-ext/b2/cls-decl-gen-meth-static-forbidden-ext-indirect-access-own-prop-caller-value.js:
- default: 'TypeError: Function.caller used to retrieve generator body'
-test/language/statements/class/gen-method-static/forbidden-ext/b2/cls-decl-gen-meth-static-forbidden-ext-indirect-access-prop-caller.js:
- default: 'TypeError: Function.caller used to retrieve generator body'
-test/language/statements/class/gen-method/forbidden-ext/b2/cls-decl-gen-meth-forbidden-ext-indirect-access-own-prop-caller-get.js:
- default: 'TypeError: Function.caller used to retrieve generator body'
-test/language/statements/class/gen-method/forbidden-ext/b2/cls-decl-gen-meth-forbidden-ext-indirect-access-own-prop-caller-value.js:
- default: 'TypeError: Function.caller used to retrieve generator body'
-test/language/statements/class/gen-method/forbidden-ext/b2/cls-decl-gen-meth-forbidden-ext-indirect-access-prop-caller.js:
- default: 'TypeError: Function.caller used to retrieve generator body'
-test/language/statements/class/method-static/forbidden-ext/b2/cls-decl-meth-static-forbidden-ext-indirect-access-own-prop-caller-get.js:
- default: 'TypeError: Function.caller used to retrieve strict caller'
-test/language/statements/class/method-static/forbidden-ext/b2/cls-decl-meth-static-forbidden-ext-indirect-access-own-prop-caller-value.js:
- default: 'TypeError: Function.caller used to retrieve strict caller'
-test/language/statements/class/method-static/forbidden-ext/b2/cls-decl-meth-static-forbidden-ext-indirect-access-prop-caller.js:
- default: 'TypeError: Function.caller used to retrieve strict caller'
-test/language/statements/class/method/forbidden-ext/b2/cls-decl-meth-forbidden-ext-indirect-access-own-prop-caller-get.js:
- default: 'TypeError: Function.caller used to retrieve strict caller'
-test/language/statements/class/method/forbidden-ext/b2/cls-decl-meth-forbidden-ext-indirect-access-own-prop-caller-value.js:
- default: 'TypeError: Function.caller used to retrieve strict caller'
-test/language/statements/class/method/forbidden-ext/b2/cls-decl-meth-forbidden-ext-indirect-access-prop-caller.js:
- default: 'TypeError: Function.caller used to retrieve strict caller'
test/language/statements/const/dstr/ary-init-iter-get-err-array-prototype.js:
default: 'TypeError: Spread syntax requires ...iterable[Symbol.iterator] to be a function'
strict mode: 'TypeError: Spread syntax requires ...iterable[Symbol.iterator] to be a function'
@@ -1965,12 +1887,6 @@
strict mode: 'Test262Error: Expected SameValue(«inside», «outside») to be true'
test/language/statements/function/eval-var-scope-syntax-err.js:
default: 'Test262Error: Expected a SyntaxError to be thrown but no exception was thrown at all'
-test/language/statements/function/forbidden-ext/b2/func-decl-forbidden-ext-indirect-access-own-prop-caller-get.js:
- default: 'TypeError: Function.caller used to retrieve strict caller'
-test/language/statements/function/forbidden-ext/b2/func-decl-forbidden-ext-indirect-access-own-prop-caller-value.js:
- default: 'TypeError: Function.caller used to retrieve strict caller'
-test/language/statements/function/forbidden-ext/b2/func-decl-forbidden-ext-indirect-access-prop-caller.js:
- default: 'TypeError: Function.caller used to retrieve strict caller'
test/language/statements/function/scope-body-lex-distinct.js:
default: 'Test262Error: Expected a SyntaxError to be thrown but no exception was thrown at all'
test/language/statements/function/scope-param-rest-elem-var-open.js:
@@ -1977,12 +1893,6 @@
default: 'Test262Error: Expected SameValue(«outside», «inside») to be true'
test/language/statements/generators/eval-var-scope-syntax-err.js:
default: 'Test262Error: Expected a SyntaxError to be thrown but no exception was thrown at all'
-test/language/statements/generators/forbidden-ext/b2/gen-func-decl-forbidden-ext-indirect-access-own-prop-caller-get.js:
- default: 'TypeError: Function.caller used to retrieve generator body'
-test/language/statements/generators/forbidden-ext/b2/gen-func-decl-forbidden-ext-indirect-access-own-prop-caller-value.js:
- default: 'TypeError: Function.caller used to retrieve generator body'
-test/language/statements/generators/forbidden-ext/b2/gen-func-decl-forbidden-ext-indirect-access-prop-caller.js:
- default: 'TypeError: Function.caller used to retrieve generator body'
test/language/statements/generators/generator-created-after-decl-inst.js:
default: 'Test262Error: Expected SameValue(«[object Generator]», «[object Generator]») to be false'
strict mode: 'Test262Error: Expected SameValue(«[object Generator]», «[object Generator]») to be false'
Modified: trunk/LayoutTests/ChangeLog (271118 => 271119)
--- trunk/LayoutTests/ChangeLog 2021-01-02 08:09:41 UTC (rev 271118)
+++ trunk/LayoutTests/ChangeLog 2021-01-02 18:41:47 UTC (rev 271119)
@@ -1,3 +1,13 @@
+2021-01-02 Alexey Shvayka <[email protected]>
+
+ Don't throw if `function.caller` is a non-strict / generator / async function
+ https://bugs.webkit.org/show_bug.cgi?id=220216
+
+ Reviewed by Yusuke Suzuki.
+
+ * js/caller-property-expected.txt:
+ * js/script-tests/caller-property.js:
+
2020-12-30 Zalan Bujtas <[email protected]>
[Legacy Line Layout] Remove unnecessary 'vertical-align: middle' integral rounding
Modified: trunk/LayoutTests/js/caller-property-expected.txt (271118 => 271119)
--- trunk/LayoutTests/js/caller-property-expected.txt 2021-01-02 08:09:41 UTC (rev 271118)
+++ trunk/LayoutTests/js/caller-property-expected.txt 2021-01-02 18:41:47 UTC (rev 271119)
@@ -8,13 +8,13 @@
PASS childHasCallerWhenCalledFromWithinParent is true
PASS nonStrictCaller(nonStrictCallee) is nonStrictCaller
PASS nonStrictCaller(strictCallee) threw exception TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in this context..
-PASS strictCaller(nonStrictCallee) threw exception TypeError: Function.caller used to retrieve strict caller.
+PASS strictCaller(nonStrictCallee) is null
PASS strictCaller(strictCallee) threw exception TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in this context..
PASS strictTailCaller(nonStrictCallee) is null
PASS strictTailCaller(strictCallee) threw exception TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in this context..
PASS nonStrictCaller(boundNonStrictCallee) is nonStrictCaller
PASS nonStrictCaller(boundStrictCallee) threw exception TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in this context..
-PASS strictCaller(boundNonStrictCallee) threw exception TypeError: Function.caller used to retrieve strict caller.
+PASS strictCaller(boundNonStrictCallee) is null
PASS strictCaller(boundStrictCallee) threw exception TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in this context..
PASS strictTailCaller(boundNonStrictCallee) is null
PASS strictTailCaller(boundStrictCallee) threw exception TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in this context..
Modified: trunk/LayoutTests/js/script-tests/caller-property.js (271118 => 271119)
--- trunk/LayoutTests/js/script-tests/caller-property.js 2021-01-02 08:09:41 UTC (rev 271118)
+++ trunk/LayoutTests/js/script-tests/caller-property.js 2021-01-02 18:41:47 UTC (rev 271119)
@@ -28,7 +28,7 @@
function strictTailCaller(x) { "use strict"; return x(); }
shouldBe("nonStrictCaller(nonStrictCallee)", "nonStrictCaller");
shouldThrow("nonStrictCaller(strictCallee)", '"TypeError: \'arguments\', \'callee\', and \'caller\' cannot be accessed in this context."');
-shouldThrow("strictCaller(nonStrictCallee)");
+shouldBe("strictCaller(nonStrictCallee)", "null");
shouldThrow("strictCaller(strictCallee)", '"TypeError: \'arguments\', \'callee\', and \'caller\' cannot be accessed in this context."');
shouldBe("strictTailCaller(nonStrictCallee)", "null");
shouldThrow("strictTailCaller(strictCallee)");
@@ -38,7 +38,7 @@
var boundStrictCallee = strictCallee.bind();
shouldBe("nonStrictCaller(boundNonStrictCallee)", "nonStrictCaller");
shouldThrow("nonStrictCaller(boundStrictCallee)");
-shouldThrow("strictCaller(boundNonStrictCallee)", '"TypeError: Function.caller used to retrieve strict caller"');
+shouldBe("strictCaller(boundNonStrictCallee)", "null");
shouldThrow("strictCaller(boundStrictCallee)");
shouldBe("strictTailCaller(boundNonStrictCallee)", "null");
shouldThrow("strictTailCaller(boundStrictCallee)");
Modified: trunk/Source/_javascript_Core/ChangeLog (271118 => 271119)
--- trunk/Source/_javascript_Core/ChangeLog 2021-01-02 08:09:41 UTC (rev 271118)
+++ trunk/Source/_javascript_Core/ChangeLog 2021-01-02 18:41:47 UTC (rev 271119)
@@ -1,3 +1,28 @@
+2021-01-02 Alexey Shvayka <[email protected]>
+
+ Don't throw if `function.caller` is a non-strict / generator / async function
+ https://bugs.webkit.org/show_bug.cgi?id=220216
+
+ Reviewed by Yusuke Suzuki.
+
+ The spec forbids [1] ES6+ and strict mode functions from having their own "caller"
+ property. r230662 went even further, throwing TypeError if `function.caller` attempts
+ to return non-strict / generator / async function, which doesn't contradict ECMA-262,
+ but diverges from V8 and SpiderMonkey (they just return the caller).
+
+ Since throwing TypeError causes quite a lot test262 failures and is a bit dangerous
+ (legacy library which uses `function.caller` is called from ES6 code), this patch
+ replaces it with `null` return.
+
+ Given that r230662 appears to be web-compatible, this change preserves its intent
+ to limit `function.caller` API as much as possible by returning `null` for all ES6+
+ functions, including methods, accessors, and arrow functions.
+
+ [1]: https://tc39.es/ecma262/#sec-forbidden-extensions (paragraphs 1-2)
+
+ * runtime/JSFunction.cpp:
+ (JSC::JSC_DEFINE_CUSTOM_GETTER):
+
2020-12-31 Alexey Shvayka <[email protected]>
JSFunction::deleteProperty() fails to delete a non-existent "prototype" property
Modified: trunk/Source/_javascript_Core/runtime/JSFunction.cpp (271118 => 271119)
--- trunk/Source/_javascript_Core/runtime/JSFunction.cpp 2021-01-02 08:09:41 UTC (rev 271118)
+++ trunk/Source/_javascript_Core/runtime/JSFunction.cpp 2021-01-02 18:41:47 UTC (rev 271119)
@@ -380,7 +380,6 @@
JSC_DEFINE_CUSTOM_GETTER(callerGetter, (JSGlobalObject* globalObject, EncodedJSValue thisValue, PropertyName))
{
VM& vm = globalObject->vm();
- auto scope = DECLARE_THROW_SCOPE(vm);
JSFunction* thisObj = jsCast<JSFunction*>(JSValue::decode(thisValue));
ASSERT(!thisObj->isHostFunction());
@@ -398,35 +397,11 @@
// Firefox returns null for native code callers, so we match that behavior.
if (function->isHostOrBuiltinFunction())
return JSValue::encode(jsNull());
- SourceParseMode parseMode = function->jsExecutable()->parseMode();
- switch (parseMode) {
- case SourceParseMode::GeneratorBodyMode:
- case SourceParseMode::AsyncGeneratorBodyMode:
- return JSValue::encode(throwTypeError(globalObject, scope, "Function.caller used to retrieve generator body"_s));
- case SourceParseMode::AsyncFunctionBodyMode:
- case SourceParseMode::AsyncArrowFunctionBodyMode:
- return JSValue::encode(throwTypeError(globalObject, scope, "Function.caller used to retrieve async function body"_s));
- case SourceParseMode::NormalFunctionMode:
- case SourceParseMode::GeneratorWrapperFunctionMode:
- case SourceParseMode::GetterMode:
- case SourceParseMode::SetterMode:
- case SourceParseMode::MethodMode:
- case SourceParseMode::ArrowFunctionMode:
- case SourceParseMode::AsyncFunctionMode:
- case SourceParseMode::AsyncMethodMode:
- case SourceParseMode::AsyncArrowFunctionMode:
- case SourceParseMode::ProgramMode:
- case SourceParseMode::ModuleAnalyzeMode:
- case SourceParseMode::ModuleEvaluateMode:
- case SourceParseMode::AsyncGeneratorWrapperFunctionMode:
- case SourceParseMode::AsyncGeneratorWrapperMethodMode:
- case SourceParseMode::GeneratorWrapperMethodMode:
- case SourceParseMode::ClassFieldInitializerMode:
- if (!function->jsExecutable()->isInStrictContext())
- return JSValue::encode(caller);
- return JSValue::encode(throwTypeError(globalObject, scope, "Function.caller used to retrieve strict caller"_s));
- }
- RELEASE_ASSERT_NOT_REACHED();
+
+ if (!function->jsExecutable()->hasCallerAndArgumentsProperties())
+ return JSValue::encode(jsNull());
+
+ return JSValue::encode(caller);
}
bool JSFunction::getOwnPropertySlot(JSObject* object, JSGlobalObject* globalObject, PropertyName propertyName, PropertySlot& slot)