Bug 171274

Summary: ASSERTION FAILED: generator.isConstructor() || generator.derivedContextType() == DerivedContextType::DerivedConstructorContext
Product: WebKit Reporter: André Bargull <andre.bargull>
Component: JavaScriptCoreAssignee: GSkachkov <gskachkov>
Status: RESOLVED FIXED    
Severity: Normal CC: buildbot, caitp, commit-queue, fpizlo, gskachkov, joepeck, keith_miller, mark.lam, msaboff, natashenka, saam, webkit-bug-importer, ysuzuki
Priority: P2 Keywords: InRadar
Version: WebKit Local Build   
Hardware: Unspecified   
OS: Unspecified   
Bug Depends on: 171543    
Bug Blocks:    
Attachments:
Description Flags
Patch
none
Patch
none
Patch
none
Archive of layout-test-results from ews122 for ios-simulator-wk2
none
Patch
none
Patch none

André Bargull
Reported 2017-04-25 09:01:06 PDT
svn revision: 215724 Test case: --- new class extends Object { constructor() { var f = async(a=super())=>{ super() } f() } } --- Asserts with: --- ASSERTION FAILED: generator.isConstructor() || generator.derivedContextType() == DerivedContextType::DerivedConstructorContext --- Stacktrace: --- #0 0x00007ffff6c4b5af in WTFCrash () at ../../Source/WTF/wtf/Assertions.cpp:292 #1 0x00007ffff6045f40 in JSC::FunctionCallValueNode::emitBytecode (this=0x7fffad7f4188, generator=..., dst=0x7fffee78e580) at ../../Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp:822 #2 0x00007ffff6018bdd in JSC::BytecodeGenerator::emitNodeInTailPosition (this=0x7fffee78e500, dst=0x7fffee78e580, n=0x7fffad7f4188) at ../../Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h:494 #3 0x00007ffff6018ab3 in JSC::BytecodeGenerator::emitNode (this=0x7fffee78e500, dst=0x7fffee78e580, n=0x7fffad7f4188) at ../../Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h:483 #4 0x00007ffff6053b9a in JSC::ExprStatementNode::emitBytecode (this=0x7fffad7f41d8, generator=..., dst=0x7fffee78e580) at ../../Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp:2507 #5 0x00007ffff6060e79 in JSC::BytecodeGenerator::emitNodeInTailPosition (this=0x7fffee78e500, dst=0x7fffee78e580, n=0x7fffad7f41d8) at ../../Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h:467 #6 0x00007ffff6061427 in JSC::SourceElements::emitBytecode (this=0x7fffad7f4150, generator=..., dst=0x7fffee78e580) at ../../Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp:2464 #7 0x00007ffff6053a98 in JSC::BlockNode::emitBytecode (this=0x7fffad7f4210, generator=..., dst=0x7fffee78e580) at ../../Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp:2484 #8 0x00007ffff6060e79 in JSC::BytecodeGenerator::emitNodeInTailPosition (this=0x7fffee78e500, dst=0x7fffee78e580, n=0x7fffad7f4210) at ../../Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h:467 #9 0x00007ffff6061427 in JSC::SourceElements::emitBytecode (this=0x7fffad7f4140, generator=..., dst=0x7fffee78e580) at ../../Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp:2464 #10 0x00007ffff6061506 in JSC::ScopeNode::emitStatementsBytecode (this=0x7fffee7bd4b0, generator=..., dst=0x7fffee78e580) at ../../Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp:3452 #11 0x00007ffff605a580 in JSC::FunctionNode::emitBytecode (this=0x7fffee7bd4b0, generator=...) at ../../Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp:3609 #12 0x00007ffff5ff66ee in JSC::BytecodeGenerator::generate (this=0x7fffee78e500) at ../../Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp:125 #13 0x00007ffff5fef0bb in JSC::BytecodeGenerator::generate<JSC::FunctionNode*, JSC::UnlinkedFunctionCodeBlock*&, JSC::DebuggerMode&, JSC::VariableEnvironment const*> (vm=...) at ../../Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h:369 #14 0x00007ffff5fec9b8 in JSC::generateUnlinkedFunctionCodeBlock (vm=..., executable=0x7fffadf74260, source=..., kind=JSC::CodeForCall, debuggerMode=JSC::DebuggerOff, functionKind=JSC::UnlinkedNormalFunction, error=..., parseMode=JSC::SourceParseMode::AsyncArrowFunctionBodyMode) at ../../Source/JavaScriptCore/bytecode/UnlinkedFunctionExecutable.cpp:71 #15 0x00007ffff5fed781 in JSC::UnlinkedFunctionExecutable::unlinkedCodeBlockFor (this=0x7fffadf74260, vm=..., source=..., specializationKind=JSC::CodeForCall, debuggerMode=JSC::DebuggerOff, error=..., parseMode=JSC::SourceParseMode::AsyncArrowFunctionBodyMode) at ../../Source/JavaScriptCore/bytecode/UnlinkedFunctionExecutable.cpp:212 ... --- Probably related null-pointer crashes with: --- new class extends Object { constructor() { var f = async()=>{ super() } f() } } --- and: --- new class extends Object { constructor() { var f = async(a=super())=>{ } f(0) } } ---
Attachments
Patch (8.76 KB, patch)
2017-05-01 06:54 PDT, GSkachkov
no flags
Patch (13.25 KB, patch)
2017-05-06 05:12 PDT, GSkachkov
no flags
Patch (13.63 KB, patch)
2017-05-06 10:40 PDT, GSkachkov
no flags
Archive of layout-test-results from ews122 for ios-simulator-wk2 (7.93 MB, application/zip)
2017-05-06 12:46 PDT, Build Bot
no flags
Patch (13.61 KB, patch)
2017-05-06 13:20 PDT, GSkachkov
no flags
Patch (14.86 KB, patch)
2017-05-23 07:51 PDT, GSkachkov
no flags
GSkachkov
Comment 1 2017-04-26 08:50:14 PDT
I'll take a look. It seems that it lost constructor context, during execution of the async arrow function. I would expect that there should be SyntaxError, but spec does not said that, so I'll try to fix it.
GSkachkov
Comment 2 2017-05-01 02:12:02 PDT
I prepared fix for both cases of superCall in arguments and async function body, later upload patch with tests. There is a small issue that I little bit worried. In case of using superCall in body of async function, we trying to put 'this' to @generatorThis property of generator object, but 'this' is empty because superCall was not called before, and we just fail silently in following line. https://trac.webkit.org/browser/webkit/trunk/Source/JavaScriptCore/runtime/JSObject.h#L1450 I think we need add there some ASSERT that value is not empty. For now it is not part of this patch. Do I need add such assert in this patch, or create separate issue?
GSkachkov
Comment 3 2017-05-01 06:54:43 PDT
Created attachment 308718 [details] Patch Patch
Build Bot
Comment 4 2017-05-01 07:33:15 PDT
Comment on attachment 308718 [details] Patch Attachment 308718 [details] did not pass jsc-ews (mac): Output: http://webkit-queues.webkit.org/results/3650857 New failing tests: stress/async-arrow-functions-lexical-binding-in-class.js.dfg-maximal-flush-validate-no-cjit stress/async-arrow-functions-lexical-binding-in-class.js.ftl-eager stress/async-arrow-functions-lexical-binding-in-class.js.ftl-eager-no-cjit-b3o1 stress/async-arrow-functions-lexical-binding-in-class.js.ftl-no-cjit-small-pool stress/async-arrow-functions-lexical-binding-in-class.js.no-ftl stress/async-arrow-functions-lexical-binding-in-class.js.no-cjit-validate-phases stress/async-arrow-functions-lexical-binding-in-class.js.ftl-no-cjit-no-put-stack-validate stress/async-arrow-functions-lexical-binding-in-class.js.ftl-eager-no-cjit stress/async-arrow-functions-lexical-binding-in-class.js.ftl-no-cjit-b3o1 stress/async-arrow-functions-lexical-binding-in-class.js.dfg-eager-no-cjit-validate stress/async-arrow-functions-lexical-binding-in-class.js.dfg-eager stress/async-arrow-functions-lexical-binding-in-class.js.no-cjit-collect-continuously stress/async-arrow-functions-lexical-binding-in-class.js.ftl-no-cjit-validate-sampling-profiler stress/async-arrow-functions-lexical-binding-in-class.js.ftl-no-cjit-no-inline-validate stress/async-arrow-functions-lexical-binding-in-class.js.no-llint stress/async-arrow-functions-lexical-binding-in-class.js.default
GSkachkov
Comment 5 2017-05-01 09:37:40 PDT
Comment on attachment 308718 [details] Patch Brocken tests
GSkachkov
Comment 6 2017-05-02 01:40:54 PDT
I faced in error in binding this & superCall in arrow function https://bugs.webkit.org/show_bug.cgi?id=171543. Before I was sure that we always load `this` from virtual scope in arrow function within constructor. I need to fix it first that back to this.
GSkachkov
Comment 7 2017-05-06 05:12:01 PDT
GSkachkov
Comment 8 2017-05-06 10:40:57 PDT
Created attachment 309286 [details] Patch Patch after rebase
Build Bot
Comment 9 2017-05-06 11:18:11 PDT
Comment on attachment 309286 [details] Patch Attachment 309286 [details] did not pass jsc-ews (mac): Output: http://webkit-queues.webkit.org/results/3688675 New failing tests: stress/async-arrow-functions-lexical-binding-in-class.js.dfg-eager stress/async-arrow-functions-lexical-binding-in-class.js.dfg-maximal-flush-validate-no-cjit stress/async-arrow-functions-lexical-binding-in-class.js.ftl-eager stress/async-arrow-functions-lexical-binding-in-class.js.ftl-eager-no-cjit-b3o1 stress/async-arrow-functions-lexical-binding-in-class.js.ftl-no-cjit-small-pool stress/async-arrow-functions-lexical-binding-in-class.js.ftl-no-cjit-no-put-stack-validate stress/async-arrow-functions-lexical-binding-in-class.js.no-cjit-validate-phases ChakraCore.yaml/ChakraCore/test/Strings/HTMLHelpers.js.default stress/async-arrow-functions-lexical-binding-in-class.js.ftl-eager-no-cjit stress/async-arrow-functions-lexical-binding-in-class.js.ftl-no-cjit-b3o1 stress/async-arrow-functions-lexical-binding-in-class.js.dfg-eager-no-cjit-validate stress/async-arrow-functions-lexical-binding-in-class.js.ftl-no-cjit-no-inline-validate stress/async-arrow-functions-lexical-binding-in-class.js.no-cjit-collect-continuously stress/async-arrow-functions-lexical-binding-in-class.js.ftl-no-cjit-validate-sampling-profiler stress/async-arrow-functions-lexical-binding-in-class.js.no-ftl stress/async-arrow-functions-lexical-binding-in-class.js.no-llint stress/async-arrow-functions-lexical-binding-in-class.js.default
Build Bot
Comment 10 2017-05-06 12:46:17 PDT
Comment on attachment 309286 [details] Patch Attachment 309286 [details] did not pass ios-sim-ews (ios-simulator-wk2): Output: http://webkit-queues.webkit.org/results/3688833 New failing tests: compositing/absolute-inside-out-of-view-fixed.html
Build Bot
Comment 11 2017-05-06 12:46:19 PDT
Created attachment 309294 [details] Archive of layout-test-results from ews122 for ios-simulator-wk2 The attached test failures were seen while running run-webkit-tests on the ios-sim-ews. Bot: ews122 Port: ios-simulator-wk2 Platform: Mac OS X 10.11.6
GSkachkov
Comment 12 2017-05-06 13:20:16 PDT
Created attachment 309295 [details] Patch Fix tests
Saam Barati
Comment 13 2017-05-17 13:59:53 PDT
Comment on attachment 309295 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=309295&action=review > Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp:2851 > + if (!(isDerivedConstructorContext() && m_codeBlock->parseMode() == SourceParseMode::AsyncArrowFunctionMode)) When do we do this? > Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp:4611 > + emitLoadThisFromArrowFunctionLexicalEnvironment(); What happens if it’s never stored?
GSkachkov
Comment 14 2017-05-17 14:32:41 PDT
Comment on attachment 309295 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=309295&action=review >> Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp:2851 >> + if (!(isDerivedConstructorContext() && m_codeBlock->parseMode() == SourceParseMode::AsyncArrowFunctionMode)) > > When do we do this? Yes, we store it after calling 'super' In FunctionCallValueNode::emitBytecode we do if (generator.isDerivedConstructorContext() || doWeUseArrowFunctionInConstructor) generator.emitPutThisToArrowFunctionContextScope(); >> Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp:4611 >> + emitLoadThisFromArrowFunctionLexicalEnvironment(); > > What happens if it’s never stored? We will receive TDZ error. Should be the same behavior as it is for common arrow function, that access 'this' before calling super.
Yusuke Suzuki
Comment 15 2017-05-20 03:03:18 PDT
Comment on attachment 309295 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=309295&action=review >>> Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp:2851 >>> + if (!(isDerivedConstructorContext() && m_codeBlock->parseMode() == SourceParseMode::AsyncArrowFunctionMode)) >> >> When do we do this? > > Yes, we store it after calling 'super' > In FunctionCallValueNode::emitBytecode we do > if (generator.isDerivedConstructorContext() || doWeUseArrowFunctionInConstructor) > generator.emitPutThisToArrowFunctionContextScope(); If you do not set generatorThis, what happens with AsyncFunctionPrototype.js' asyncFunctionResume's @generatorThis access?
Saam Barati
Comment 16 2017-05-21 12:59:34 PDT
Comment on attachment 309295 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=309295&action=review >>> Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp:4611 >>> + emitLoadThisFromArrowFunctionLexicalEnvironment(); >> >> What happens if it’s never stored? > > We will receive TDZ error. Should be the same behavior as it is for common arrow function, that access 'this' before calling super. Do we store the empty value somewhere else?
GSkachkov
Comment 17 2017-05-21 16:36:37 PDT
Comment on attachment 309295 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=309295&action=review >>>> Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp:2851 >>>> + if (!(isDerivedConstructorContext() && m_codeBlock->parseMode() == SourceParseMode::AsyncArrowFunctionMode)) >>> >>> When do we do this? >> >> Yes, we store it after calling 'super' >> In FunctionCallValueNode::emitBytecode we do >> if (generator.isDerivedConstructorContext() || doWeUseArrowFunctionInConstructor) >> generator.emitPutThisToArrowFunctionContextScope(); > > If you do not set generatorThis, what happens with AsyncFunctionPrototype.js' asyncFunctionResume's @generatorThis access? Hmm, I think @generatorThis has value `undefined`, when call generator.@generatorNext.@call(generator.@generatorThis with value @undefined, but this `undefined` value would not be used, because it intercepted and taken from virtual scope, when we access to thisValue >>>> Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp:4611 >>>> + emitLoadThisFromArrowFunctionLexicalEnvironment(); >>> >>> What happens if it’s never stored? >> >> We will receive TDZ error. Should be the same behavior as it is for common arrow function, that access 'this' before calling super. > > Do we store the empty value somewhere else? No I think we do not store empty value
Saam Barati
Comment 18 2017-05-21 17:06:50 PDT
Comment on attachment 309295 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=309295&action=review >>>>> Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp:4611 >>>>> + emitLoadThisFromArrowFunctionLexicalEnvironment(); >>>> >>>> What happens if it’s never stored? >>> >>> We will receive TDZ error. Should be the same behavior as it is for common arrow function, that access 'this' before calling super. >> >> Do we store the empty value somewhere else? > > No I think we do not store empty value How does the TDZ check work then?
GSkachkov
Comment 19 2017-05-22 11:08:04 PDT
Comment on attachment 309295 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=309295&action=review >>>>>> Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp:4611 >>>>>> + emitLoadThisFromArrowFunctionLexicalEnvironment(); >>>>> >>>>> What happens if it’s never stored? >>>> >>>> We will receive TDZ error. Should be the same behavior as it is for common arrow function, that access 'this' before calling super. >>> >>> Do we store the empty value somewhere else? >> >> No I think we do not store empty value > > How does the TDZ check work then? Ohh I see why you mean. We create empty variable slot for `this` in virtual scope of ‘constructor’ in initializeArrowFunctionContextScopeIfNeeded method of the BytecodeGenerator, condition isThisUsedInInnerArrowFunction is true in case of async arrow function is true. When we access to `this` within async arrow function when we will try to load `this` from virtual scope and if we have not stored there any value before we would receive TDZ error (‘Cannot access uninitialized variable’). @generatorThis property of the generator that is taken during resume async function in butlins\AsyncFunctionPrototype.js within async arrow function in `constructor` has value `undefined`. When we access to `this` within async arrow function we don't use value from @generatorThis, because it intercepted by `ensureThis()` method, and load `this` value from virtual scope of `constructor`
GSkachkov
Comment 20 2017-05-22 11:42:26 PDT
Comment on attachment 309295 [details] Patch Hmm, I found one not css where TDZ error is not thrower, will investigate what`s wrong: ``` class ChildClass8 extends BaseClass { constructor() { const arr = async () => { let i = this.id; super(); }; arr(); } } ```
GSkachkov
Comment 21 2017-05-23 07:51:21 PDT
Created attachment 311011 [details] Patch Add more tests & rebase
Saam Barati
Comment 22 2017-05-30 13:45:29 PDT
Comment on attachment 311011 [details] Patch r=me
WebKit Commit Bot
Comment 23 2017-05-30 14:29:40 PDT
Comment on attachment 311011 [details] Patch Clearing flags on attachment: 311011 Committed r217577: <http://trac.webkit.org/changeset/217577>
WebKit Commit Bot
Comment 24 2017-05-30 14:29:42 PDT
All reviewed patches have been landed. Closing bug.
Radar WebKit Bug Importer
Comment 25 2017-05-30 20:30:16 PDT
GSkachkov
Comment 26 2017-05-30 23:37:48 PDT
*** Bug 172739 has been marked as a duplicate of this bug. ***
Note You need to log in before you can comment on or make changes to this bug.