Bug 147064 - Getter and setter on super are called with wrong "this" object
Summary: Getter and setter on super are called with wrong "this" object
Status: RESOLVED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: JavaScriptCore (show other bugs)
Version: 528+ (Nightly build)
Hardware: Unspecified Unspecified
: P2 Normal
Assignee: Saam Barati
URL:
Keywords: InRadar
: 157136 (view as bug list)
Depends on: 157524
Blocks: 140491 148021
  Show dependency treegraph
 
Reported: 2015-07-17 20:12 PDT by Joseph Pecoraro
Modified: 2016-08-16 21:19 PDT (History)
14 users (show)

See Also:


Attachments
[TEST] Test Page (632 bytes, text/html)
2016-04-26 15:39 PDT, Joseph Pecoraro
no flags Details
WIP (45.65 KB, patch)
2016-04-28 00:22 PDT, Saam Barati
no flags Details | Formatted Diff | Diff
WIP (85.25 KB, patch)
2016-04-29 01:26 PDT, Saam Barati
no flags Details | Formatted Diff | Diff
WIP (94.36 KB, patch)
2016-04-29 13:41 PDT, Saam Barati
no flags Details | Formatted Diff | Diff
WIP (105.07 KB, patch)
2016-04-29 17:01 PDT, Saam Barati
no flags Details | Formatted Diff | Diff
WIP (116.21 KB, patch)
2016-04-30 00:24 PDT, Saam Barati
no flags Details | Formatted Diff | Diff
WIP (116.66 KB, patch)
2016-04-30 17:26 PDT, Saam Barati
no flags Details | Formatted Diff | Diff
patch (124.90 KB, patch)
2016-05-01 16:36 PDT, Saam Barati
fpizlo: review+
Details | Formatted Diff | Diff
benchmark results (75.36 KB, application/octet-stream)
2016-05-02 07:45 PDT, Saam Barati
no flags Details
patch for landing (126.20 KB, patch)
2016-05-09 11:36 PDT, Saam Barati
no flags Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Joseph Pecoraro 2015-07-17 20:12:43 PDT
* SUMMARY
Cannot override getter / setter.

* TEST
<script>
"use strict";
var Base = class Base {
    constructor() { this._name = "Name"; }
    get name() { return this._name; } // If this instead returns a static: return "Foo" things somewhat work.
    set name(x) { this._name = x; }
};

var Subclass = class Subclass extends Base {
    get name() { return super.name; }
};

var instance = new Subclass;
console.log(instance.name); // undefined, but expected "Name"
</script>
Comment 1 Radar WebKit Bug Importer 2015-07-17 20:13:06 PDT
<rdar://problem/21885916>
Comment 2 Joseph Pecoraro 2015-07-17 20:15:21 PDT
After discussing with Ryosuke Niwa it sounds like we are invoking the `super.name` getter, but with the wrong "this" object.

Sounds like we were replacing `super` with `this.__proto__` which would be `Base.prototype`. So we are actually getting `Base.prototype._name` instead of `this._name`. You can verify this by setting `Base.prototype._name` to a value, and then instance.name returns that value.
Comment 3 Ryosuke Niwa 2015-08-14 14:22:57 PDT
I talked with Geoff about this, and it seems like we'd need to add an extra argument to op_get_by_id, which specifies "this" for the getter/setter.

We should probably split the patch into two.  The first one that just does this refactoring and the second one that actually fixes the bug.
Comment 4 Joseph Pecoraro 2016-04-26 15:39:08 PDT
Created attachment 277416 [details]
[TEST] Test Page
Comment 5 Saam Barati 2016-04-28 00:22:57 PDT
Created attachment 277600 [details]
WIP

It begins
Comment 6 Saam Barati 2016-04-28 08:31:17 PDT
*** Bug 157136 has been marked as a duplicate of this bug. ***
Comment 7 Saam Barati 2016-04-29 01:26:19 PDT
Created attachment 277684 [details]
WIP
Comment 8 Saam Barati 2016-04-29 13:41:29 PDT
Created attachment 277730 [details]
WIP

I think the patch now works and is correct. I need to vet NodesCodegen again to make sure I didn't miss any places where we support super.
I also want to refactor get_by_id_with_this to not have a bunch of unused arguments.
Comment 9 Saam Barati 2016-04-29 17:01:09 PDT
Created attachment 277758 [details]
WIP

Needs 32-bit support then I think I'm done.
Comment 10 WebKit Commit Bot 2016-04-29 17:03:57 PDT
Attachment 277758 [details] did not pass style-queue:


ERROR: Source/JavaScriptCore/runtime/CommonSlowPaths.cpp:886:  Should have a space between // and comment  [whitespace/comments] [4]
ERROR: Source/JavaScriptCore/runtime/CommonSlowPaths.cpp:900:  Should have a space between // and comment  [whitespace/comments] [4]
ERROR: Source/JavaScriptCore/jit/CCallHelpers.h:2049:  Should have a space between // and comment  [whitespace/comments] [4]
ERROR: Source/JavaScriptCore/jit/CCallHelpers.h:2050:  Should have a space between // and comment  [whitespace/comments] [4]
ERROR: Source/JavaScriptCore/jit/CCallHelpers.h:2053:  Should have a space between // and comment  [whitespace/comments] [4]
Total errors found: 5 in 33 files


If any of these errors are false positives, please file a bug against check-webkit-style.
Comment 11 Saam Barati 2016-04-30 00:24:33 PDT
Created attachment 277802 [details]
WIP

maybe 32-bit is done? Lets see what EWS thinks.
Comment 12 WebKit Commit Bot 2016-04-30 00:25:42 PDT
Attachment 277802 [details] did not pass style-queue:


ERROR: Source/JavaScriptCore/runtime/CommonSlowPaths.cpp:887:  Should have a space between // and comment  [whitespace/comments] [4]
ERROR: Source/JavaScriptCore/runtime/CommonSlowPaths.cpp:901:  Should have a space between // and comment  [whitespace/comments] [4]
ERROR: Source/JavaScriptCore/jit/CCallHelpers.h:2075:  Should have a space between // and comment  [whitespace/comments] [4]
ERROR: Source/JavaScriptCore/jit/CCallHelpers.h:2076:  Should have a space between // and comment  [whitespace/comments] [4]
ERROR: Source/JavaScriptCore/jit/CCallHelpers.h:2079:  Should have a space between // and comment  [whitespace/comments] [4]
Total errors found: 5 in 35 files


If any of these errors are false positives, please file a bug against check-webkit-style.
Comment 13 Saam Barati 2016-04-30 17:26:56 PDT
Created attachment 277835 [details]
WIP
Comment 14 WebKit Commit Bot 2016-04-30 17:29:11 PDT
Attachment 277835 [details] did not pass style-queue:


ERROR: Source/JavaScriptCore/runtime/CommonSlowPaths.cpp:887:  Should have a space between // and comment  [whitespace/comments] [4]
ERROR: Source/JavaScriptCore/runtime/CommonSlowPaths.cpp:901:  Should have a space between // and comment  [whitespace/comments] [4]
ERROR: Source/JavaScriptCore/jit/CCallHelpers.h:2085:  Should have a space between // and comment  [whitespace/comments] [4]
ERROR: Source/JavaScriptCore/jit/CCallHelpers.h:2086:  Should have a space between // and comment  [whitespace/comments] [4]
ERROR: Source/JavaScriptCore/jit/CCallHelpers.h:2089:  Should have a space between // and comment  [whitespace/comments] [4]
Total errors found: 5 in 35 files


If any of these errors are false positives, please file a bug against check-webkit-style.
Comment 15 Saam Barati 2016-05-01 16:36:50 PDT
Created attachment 277872 [details]
patch
Comment 16 Saam Barati 2016-05-02 00:58:22 PDT
Comment on attachment 277872 [details]
patch

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

> Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp:2887
> +        if (GPRInfo::numberOfRegisters < 8) {

I need to actually change this code I think. I did this for X86-32bit originally (which doesn't have argument registers).
This code is broken for an ABI that has argument registers but still has less than 8 registers like MIPS.
Writing this code for MIPS seems painful. I think you would have to first push the last 5 registers
onto the stack. Then call setupArgumentsWithExecState to get the four argument registers.

Anyway, this code should really be behind
#if CPU(X86)
...
#else

#endif

And then the MIPS folks can add any code they need to as an #elif
Comment 17 Saam Barati 2016-05-02 07:45:46 PDT
Created attachment 277906 [details]
benchmark results
Comment 18 Saam Barati 2016-05-09 11:36:08 PDT
Created attachment 278414 [details]
patch for landing
Comment 19 WebKit Commit Bot 2016-05-09 13:16:37 PDT
Comment on attachment 278414 [details]
patch for landing

Clearing flags on attachment: 278414

Committed r200586: <http://trac.webkit.org/changeset/200586>
Comment 20 WebKit Commit Bot 2016-05-09 13:16:43 PDT
All reviewed patches have been landed.  Closing bug.
Comment 21 Joseph Pecoraro 2016-05-09 13:47:12 PDT
Nice! We should update the inspector now (bug 157488).
Comment 22 Csaba Osztrogonác 2016-05-10 01:35:01 PDT
(In reply to comment #19)
> Comment on attachment 278414 [details]
> patch for landing
> 
> Clearing flags on attachment: 278414
> 
> Committed r200586: <http://trac.webkit.org/changeset/200586>

The new stress/super-property-access.js test fails (crash/timeout)
on all JSC tester bots, see build.webkit.org for details.
Comment 23 Saam Barati 2016-05-10 08:51:00 PDT
(In reply to comment #22)
> (In reply to comment #19)
> > Comment on attachment 278414 [details]
> > patch for landing
> > 
> > Clearing flags on attachment: 278414
> > 
> > Committed r200586: <http://trac.webkit.org/changeset/200586>
> 
> The new stress/super-property-access.js test fails (crash/timeout)
> on all JSC tester bots, see build.webkit.org for details.

Thanks I'll update the test to be shorter.
Comment 24 Saam Barati 2016-05-10 11:56:59 PDT
landed follow up patch to make test run faster:
http://trac.webkit.org/changeset/200632
Comment 25 Filip Pizlo 2016-08-16 17:06:06 PDT
Comment on attachment 278414 [details]
patch for landing

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

> Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp:4036
> +            Node* getByValWithThis = addToGraph(GetByValWithThis, base, thisValue, property);

It should be possible to get a prediction from a value profile here.

> Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp:4137
> +                addToGraph(GetByIdWithThis, OpInfo(identifierNumber), base, thisValue));

It should be possible to get a prediction from a value profile here.

> Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp:666
> +            setPrediction(SpecBytecodeTop);

It's wrong to ever use any of the Top's in prediction propagation phase.  This tells the prediction propagator that this node will *definitely* return values of all types, which causes us to assume the worst for all downstream code.

This should just be a matter of giving these bytecode instructions a value profile, and pulling in the value profile's results in the bytecode parser.

Filed: https://bugs.webkit.org/show_bug.cgi?id=160922
Comment 26 Saam Barati 2016-08-16 18:00:48 PDT
(In reply to comment #25)
> Comment on attachment 278414 [details]
> patch for landing
> 
> View in context:
> https://bugs.webkit.org/attachment.cgi?id=278414&action=review
> 
> > Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp:4036
> > +            Node* getByValWithThis = addToGraph(GetByValWithThis, base, thisValue, property);
> 
> It should be possible to get a prediction from a value profile here.
> 
> > Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp:4137
> > +                addToGraph(GetByIdWithThis, OpInfo(identifierNumber), base, thisValue));
> 
> It should be possible to get a prediction from a value profile here.
> 
> > Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp:666
> > +            setPrediction(SpecBytecodeTop);
> 
> It's wrong to ever use any of the Top's in prediction propagation phase. 
> This tells the prediction propagator that this node will *definitely* return
> values of all types, which causes us to assume the worst for all downstream
> code.
> 
> This should just be a matter of giving these bytecode instructions a value
> profile, and pulling in the value profile's results in the bytecode parser.
> 
> Filed: https://bugs.webkit.org/show_bug.cgi?id=160922

I think the right thing going forward is just teaching get_by_id
that it can have a different base and |this|. This way, we can remove
get_by_id_with_this completely.
Comment 27 Filip Pizlo 2016-08-16 18:05:59 PDT
(In reply to comment #26)
> (In reply to comment #25)
> > Comment on attachment 278414 [details]
> > patch for landing
> > 
> > View in context:
> > https://bugs.webkit.org/attachment.cgi?id=278414&action=review
> > 
> > > Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp:4036
> > > +            Node* getByValWithThis = addToGraph(GetByValWithThis, base, thisValue, property);
> > 
> > It should be possible to get a prediction from a value profile here.
> > 
> > > Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp:4137
> > > +                addToGraph(GetByIdWithThis, OpInfo(identifierNumber), base, thisValue));
> > 
> > It should be possible to get a prediction from a value profile here.
> > 
> > > Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp:666
> > > +            setPrediction(SpecBytecodeTop);
> > 
> > It's wrong to ever use any of the Top's in prediction propagation phase. 
> > This tells the prediction propagator that this node will *definitely* return
> > values of all types, which causes us to assume the worst for all downstream
> > code.
> > 
> > This should just be a matter of giving these bytecode instructions a value
> > profile, and pulling in the value profile's results in the bytecode parser.
> > 
> > Filed: https://bugs.webkit.org/show_bug.cgi?id=160922
> 
> I think the right thing going forward is just teaching get_by_id
> that it can have a different base and |this|. This way, we can remove
> get_by_id_with_this completely.

Right now, if you have any GetByIdWithThis anywhere in a function, then *everything* in the function is likely to get polluted by the bad prediction propagation.

So, fixing this is *much* higher priority than implementing a proper get_by_id.

In the future, we should be very vigilant about this.  It's OK for some node in DFG IR to emit bad code.  It's never OK for a node in DFG IR to claim that it produces TOP as its output, since that pessimizes all downstream nodes.
Comment 28 Saam Barati 2016-08-16 21:19:12 PDT
(In reply to comment #27)
> (In reply to comment #26)
> > (In reply to comment #25)
> > > Comment on attachment 278414 [details]
> > > patch for landing
> > > 
> > > View in context:
> > > https://bugs.webkit.org/attachment.cgi?id=278414&action=review
> > > 
> > > > Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp:4036
> > > > +            Node* getByValWithThis = addToGraph(GetByValWithThis, base, thisValue, property);
> > > 
> > > It should be possible to get a prediction from a value profile here.
> > > 
> > > > Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp:4137
> > > > +                addToGraph(GetByIdWithThis, OpInfo(identifierNumber), base, thisValue));
> > > 
> > > It should be possible to get a prediction from a value profile here.
> > > 
> > > > Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp:666
> > > > +            setPrediction(SpecBytecodeTop);
> > > 
> > > It's wrong to ever use any of the Top's in prediction propagation phase. 
> > > This tells the prediction propagator that this node will *definitely* return
> > > values of all types, which causes us to assume the worst for all downstream
> > > code.
> > > 
> > > This should just be a matter of giving these bytecode instructions a value
> > > profile, and pulling in the value profile's results in the bytecode parser.
> > > 
> > > Filed: https://bugs.webkit.org/show_bug.cgi?id=160922
> > 
> > I think the right thing going forward is just teaching get_by_id
> > that it can have a different base and |this|. This way, we can remove
> > get_by_id_with_this completely.
> 
> Right now, if you have any GetByIdWithThis anywhere in a function, then
> *everything* in the function is likely to get polluted by the bad prediction
> propagation.
> 
> So, fixing this is *much* higher priority than implementing a proper
> get_by_id.
> 
> In the future, we should be very vigilant about this.  It's OK for some node
> in DFG IR to emit bad code.  It's never OK for a node in DFG IR to claim
> that it produces TOP as its output, since that pessimizes all downstream
> nodes.

Sounds good. We should probably do the same thing for tryGetById. 
Maybe we already have a bug open for that. If not, I can create one.