Bug 225397

Summary: [JSC] Abolish using resolved scope as |this| value when calling functions
Product: WebKit Reporter: Alexey Shvayka <ashvayka>
Component: JavaScriptCoreAssignee: Alexey Shvayka <ashvayka>
Status: NEW ---    
Severity: Normal CC: ahmad.saleem792, alecflett, annulen, ap, beidson, bfulgham, calvaris, cdumez, changseok, eric.carlson, esprehn+autocc, ews-watchlist, fpizlo, glenn, gyuyoung.kim, hi, jer.noble, joepeck, jsbell, keith_miller, kondapallykalyan, mark.lam, msaboff, philipj, rniwa, ryuan.choi, saam, sergio, tzagallo, webkit-bug-importer
Priority: P2 Keywords: InRadar
Version: WebKit Nightly Build   
Hardware: Unspecified   
OS: Unspecified   
Bug Depends on: 276788    
Bug Blocks:    
Attachments:
Description Flags
Patch
none
Patch
none
Patch
none
Patch
none
Patch
none
Patch
ews-feeder: commit-queue-
Patch
none
Patch
ews-feeder: commit-queue-
Patch fpizlo: review+

Description Alexey Shvayka 2021-05-05 10:19:32 PDT
[JSC] Abolish using resolved scope as |this| value when calling functions
Comment 1 Alexey Shvayka 2021-05-05 10:24:04 PDT
Created attachment 427777 [details]
Patch
Comment 2 Alexey Shvayka 2021-05-05 11:29:48 PDT
Created attachment 427784 [details]
Patch

Add missing prediction for GetThisValueForCall and call operationToObject with JSValueRegs.
Comment 3 Alexey Shvayka 2021-05-05 20:00:21 PDT
Created attachment 427844 [details]
Patch

Call getters / setters with JSProxy as |this| value, fix SpeculativeJIT::compileGetThisValueForCall(), fix EvalFunctionCallNode, fix 32-bit builds, remove JSObject::isEnvironment().
Comment 4 Radar WebKit Bug Importer 2021-05-12 10:20:22 PDT
<rdar://problem/77915872>
Comment 5 Alexey Shvayka 2021-05-24 11:38:03 PDT
Created attachment 429549 [details]
Patch

Remove loadVariable() from 32-bit to_this LLInt op to fix segfaults, rebase on top of r277830, and adjust some LayoutTests.
Comment 6 Alexey Shvayka 2021-05-24 21:42:45 PDT
Created attachment 429630 [details]
Patch

Remove incorrect exception check after toGlobalThis(), fix JSErrorHandler to pass JSProxy as |this| value, and adjust more LayoutTests.
Comment 7 Alexey Shvayka 2021-05-27 05:07:08 PDT
Created attachment 429869 [details]
Patch

Adjust flaky test, tweak JS API avoid any behavior change (+ add coverage), and fix multiple cases of WebCore using raw GlobalObject as |this| value for [[Call]] (+ add ASSERTs for that).
Comment 8 Alexey Shvayka 2021-05-27 06:11:37 PDT
Created attachment 429873 [details]
Patch

Fix build and rename JSScope::receiverForScope() to JSObject::toPublicThisValue().
Comment 9 Alexey Shvayka 2021-05-27 23:10:20 PDT
Created attachment 429991 [details]
Patch

Test [PutForwards] WebIDL attribute on global interface, turn JSObject::toPublicThisValue() into a function to fix --debug buil, and utilize it to fix plugins & SparseArrayEntry::put() (+ improve coverage).
Comment 10 Alexey Shvayka 2021-05-27 23:45:53 PDT
Created attachment 429993 [details]
Patch

Rebase patch and use std::nullopt to fix the build.
Comment 11 Filip Pizlo 2021-06-10 11:08:40 PDT
Comment on attachment 429993 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=429993&action=review

> Source/JavaScriptCore/ChangeLog:8
> +        Reviewed by NOBODY (OOPS!).
> +
> +        * API/APICallbackFunction.h:

Can you write some stuff about what you did?

> Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp:13497
> +    addSlowPathGenerator(slowPathCall(slowCases, this, operationToObject, valueGPR, TrustedImmPtr::weakPointer(m_graph, globalObject), valueRegs, TrustedImmPtr(nullptr)));

What are some example programs where the slow path would be taken?

> Source/JavaScriptCore/jit/JITOpcodes.cpp:2097
> +void JIT::emit_op_get_this_value_for_call(const Instruction* currentInstruction)
> +{
> +    auto bytecode = currentInstruction->as<OpGetThisValueForCall>();
> +#if USE(JSVALUE64)
> +    JSValueRegs valueRegs(regT0);
> +#else
> +    JSValueRegs valueRegs(regT1, regT0);
> +#endif
> +    emitGetVirtualRegister(bytecode.m_scope, valueRegs);
> +
> +    Jump isWithScope = branchIfNotType(valueRegs.payloadGPR(), JSTypeRange { FirstJSScopeType, LastJSScopeType });
> +    moveTrustedValue(jsUndefined(), valueRegs);
> +    isWithScope.link(this);
> +
> +    emitPutVirtualRegister(bytecode.m_dst, valueRegs);
> +}

I really like this.
Comment 12 Alexey Shvayka 2021-06-10 11:40:48 PDT
(In reply to Filip Pizlo from comment #11)
> Comment on attachment 429993 [details]
> Patch

Thank you for reviewing so quickly, Filip! And sorry for missing ChangeLog.

> > Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp:13497
> > +    addSlowPathGenerator(slowPathCall(slowCases, this, operationToObject, valueGPR, TrustedImmPtr::weakPointer(m_graph, globalObject), valueRegs, TrustedImmPtr(nullptr)));
> 
> What are some example programs where the slow path would be taken?

Sloppy mode functions called with |this| value of a primitive string/number/boolean/bigint, which requires allocation: `(function() { return this; }.call(42);`.
Comment 13 Ahmad Saleem 2022-09-03 06:22:59 PDT
I checked and it seems this r+ patch didn't landed yet and also this FIXME is still present:

https://github.com/WebKit/WebKit/blob/6bb75cf119f4cf3c077ec234af476fb575b28509/Source/WebCore/bindings/js/JSDOMOperation.h#L38

Is something pending or this is no longer required? Thanks!