- Revision
- 280364
- Author
- shvaikal...@gmail.com
- Date
- 2021-07-27 17:21:05 -0700 (Tue, 27 Jul 2021)
Log Message
ProxyObject callees should be skipped during Function.prototype.caller resolution
https://bugs.webkit.org/show_bug.cgi?id=228341
Reviewed by Yusuke Suzuki.
Source/_javascript_Core:
Just like a bound function, a Proxy with nullish "apply" handler merely forwards
[[Call]] to its target [1], without pushing onto the execution context stack.
This fact is also noted in Function.prototype.{caller,arguments} reflection proposal [2].
This patch aligns JSC with V8 and SpiderMonkey if Proxy's "apply" handler is userland
or nullish. However, since JSC implements proper tail calls, `Function.prototype.caller`
result is divergent from other engines if the handler is `Reflect.apply`, which performs
a tail call that gets optimized away [2] (unless called by another Proxy).
[1]: https://tc39.es/ecma262/#sec-proxy-object-internal-methods-and-internal-slots-call-thisargument-argumentslist (step 8)
[2]: https://github.com/claudepache/es-legacy-function-reflection/blob/master/spec.md#get-functionprototypecaller (see notes)
* runtime/FunctionPrototype.cpp:
(JSC::RetrieveCallerFunctionFunctor::operator() const):
LayoutTests:
* js/caller-property-expected.txt:
* js/script-tests/caller-property.js:
Modified Paths
Diff
Modified: trunk/LayoutTests/ChangeLog (280363 => 280364)
--- trunk/LayoutTests/ChangeLog 2021-07-28 00:12:30 UTC (rev 280363)
+++ trunk/LayoutTests/ChangeLog 2021-07-28 00:21:05 UTC (rev 280364)
@@ -1,3 +1,13 @@
+2021-07-27 Alexey Shvayka <shvaikal...@gmail.com>
+
+ ProxyObject callees should be skipped during Function.prototype.caller resolution
+ https://bugs.webkit.org/show_bug.cgi?id=228341
+
+ Reviewed by Yusuke Suzuki.
+
+ * js/caller-property-expected.txt:
+ * js/script-tests/caller-property.js:
+
2021-07-27 Eric Hutchison <ehutchi...@apple.com>
[BigSur wk2 Debug arm64] fast/text/emoji-overlap.html is a flaky image-only failure.
Modified: trunk/LayoutTests/js/caller-property-expected.txt (280363 => 280364)
--- trunk/LayoutTests/js/caller-property-expected.txt 2021-07-28 00:12:30 UTC (rev 280363)
+++ trunk/LayoutTests/js/caller-property-expected.txt 2021-07-28 00:21:05 UTC (rev 280364)
@@ -18,6 +18,13 @@
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..
+PASS nonStrictCaller(new Proxy(nonStrictCallee, {})) is nonStrictCaller
+PASS nonStrictCaller(new Proxy(nonStrictCallee, {}).bind()) is nonStrictCaller
+PASS nonStrictCaller(new Proxy(new Proxy(nonStrictCallee, {}), {})) is nonStrictCaller
+PASS nonStrictCaller(new Proxy(boundNonStrictCallee, {})) is nonStrictCaller
+PASS nonStrictCaller(new Proxy(nonStrictCallee, Reflect)) is nonStrictCaller
+PASS nonStrictCaller(new Proxy(new Proxy(nonStrictCallee, Reflect), {})) is nonStrictCaller
+PASS nonStrictCaller(new Proxy(new Proxy(nonStrictCallee, {}), Reflect)) is null
PASS nonStrictGetter(nonStrictAccessor) threw exception TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in this context..
PASS nonStrictGetter(strictAccessor) threw exception TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in this context..
PASS strictGetter(nonStrictAccessor) threw exception TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in this context..
Modified: trunk/LayoutTests/js/script-tests/caller-property.js (280363 => 280364)
--- trunk/LayoutTests/js/script-tests/caller-property.js 2021-07-28 00:12:30 UTC (rev 280363)
+++ trunk/LayoutTests/js/script-tests/caller-property.js 2021-07-28 00:21:05 UTC (rev 280364)
@@ -43,6 +43,15 @@
shouldBe("strictTailCaller(boundNonStrictCallee)", "null");
shouldThrow("strictTailCaller(boundStrictCallee)");
+shouldBe("nonStrictCaller(new Proxy(nonStrictCallee, {}))", "nonStrictCaller");
+shouldBe("nonStrictCaller(new Proxy(nonStrictCallee, {}).bind())", "nonStrictCaller");
+shouldBe("nonStrictCaller(new Proxy(new Proxy(nonStrictCallee, {}), {}))", "nonStrictCaller");
+shouldBe("nonStrictCaller(new Proxy(boundNonStrictCallee, {}))", "nonStrictCaller");
+
+shouldBe("nonStrictCaller(new Proxy(nonStrictCallee, Reflect))", "nonStrictCaller"); // tail call
+shouldBe("nonStrictCaller(new Proxy(new Proxy(nonStrictCallee, Reflect), {}))", "nonStrictCaller"); // tail call
+shouldBe("nonStrictCaller(new Proxy(new Proxy(nonStrictCallee, {}), Reflect))", "null"); // no tail call in Proxy's [[Call]]
+
// Check that .caller throws as expected, over an accessor call. (per https://tc39.github.io/ecma262/#sec-forbidden-extensions)
function getFooGetter(x) { return Object.getOwnPropertyDescriptor(x, 'foo').get; }
function getFooSetter(x) { return Object.getOwnPropertyDescriptor(x, 'foo').set; }
Modified: trunk/Source/_javascript_Core/ChangeLog (280363 => 280364)
--- trunk/Source/_javascript_Core/ChangeLog 2021-07-28 00:12:30 UTC (rev 280363)
+++ trunk/Source/_javascript_Core/ChangeLog 2021-07-28 00:21:05 UTC (rev 280364)
@@ -1,3 +1,25 @@
+2021-07-27 Alexey Shvayka <shvaikal...@gmail.com>
+
+ ProxyObject callees should be skipped during Function.prototype.caller resolution
+ https://bugs.webkit.org/show_bug.cgi?id=228341
+
+ Reviewed by Yusuke Suzuki.
+
+ Just like a bound function, a Proxy with nullish "apply" handler merely forwards
+ [[Call]] to its target [1], without pushing onto the execution context stack.
+ This fact is also noted in Function.prototype.{caller,arguments} reflection proposal [2].
+
+ This patch aligns JSC with V8 and SpiderMonkey if Proxy's "apply" handler is userland
+ or nullish. However, since JSC implements proper tail calls, `Function.prototype.caller`
+ result is divergent from other engines if the handler is `Reflect.apply`, which performs
+ a tail call that gets optimized away [2] (unless called by another Proxy).
+
+ [1]: https://tc39.es/ecma262/#sec-proxy-object-internal-methods-and-internal-slots-call-thisargument-argumentslist (step 8)
+ [2]: https://github.com/claudepache/es-legacy-function-reflection/blob/master/spec.md#get-functionprototypecaller (see notes)
+
+ * runtime/FunctionPrototype.cpp:
+ (JSC::RetrieveCallerFunctionFunctor::operator() const):
+
2021-07-26 Yusuke Suzuki <ysuz...@apple.com>
Add Temporal to features.json
Modified: trunk/Source/_javascript_Core/runtime/FunctionPrototype.cpp (280363 => 280364)
--- trunk/Source/_javascript_Core/runtime/FunctionPrototype.cpp 2021-07-28 00:12:30 UTC (rev 280363)
+++ trunk/Source/_javascript_Core/runtime/FunctionPrototype.cpp 2021-07-28 00:21:05 UTC (rev 280364)
@@ -181,7 +181,7 @@
JSCell* callee = visitor->callee().asCell();
- if (callee && callee->inherits<JSBoundFunction>(callee->vm()))
+ if (callee && (callee->inherits<JSBoundFunction>(callee->vm()) || callee->type() == ProxyObjectType))
return StackVisitor::Continue;
if (!m_hasFoundFrame && callee != m_targetCallee)