Branch: refs/heads/main
  Home:   https://github.com/WebKit/WebKit
  Commit: cf863e88b16aac089e7d3264a4b59f30a2c51479
      
https://github.com/WebKit/WebKit/commit/cf863e88b16aac089e7d3264a4b59f30a2c51479
  Author: itsu-dev <[email protected]>
  Date:   2026-05-12 (Tue, 12 May 2026)

  Changed paths:
    A 
JSTests/stress/default-derived-constructor-should-not-observe-array-iterator.js
    M Source/JavaScriptCore/bytecode/ExecutableInfo.h
    M Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.cpp
    M Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.h
    M Source/JavaScriptCore/bytecode/UnlinkedFunctionExecutable.cpp
    M Source/JavaScriptCore/bytecode/UnlinkedFunctionExecutable.h
    M Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp
    M Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h
    M Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp
    M Source/JavaScriptCore/runtime/CachedTypes.cpp

  Log Message:
  -----------
  [JSC] Default derived constructors incorrectly observing 
Array.prototype[@@iterator]
https://bugs.webkit.org/show_bug.cgi?id=295660

Reviewed by Yusuke Suzuki.

Default derived constructors should not observably access 
`Array.prototype[@@iterator]` [1],
but JSC currently does due to rest/spread-based argument forwarding.

This change avoids emitting a `spread` instruction when a 
`FunctionCallValueNode`
representing `super(...args)` originates from a default derived constructor.

To implement this, a flag `m_isBuiltinDefaultClassConstructor` is added to
`UnlinkedCodeBlock`, and propagated to `BytecodeGenerator`, where
it is exposed via `BytecodeGenerator::isBuiltinDefaultClassConstructor()`.

sizeof(UnlinkedCodeBlock) is unchanged at 264 bytes so safe.

[1]: 
https://tc39.es/proposal-class-brand-check/#sec-runtime-semantics-classdefinitionevaluation
 (Last accessed at 2026/4/27)

The following shows the bytecode generated for the default derived constructor
before and after this change.

Before:

bb#1
Predecessors: [ ]
[   0] enter
[   1] mov                dst:loc5, src:callee
[   4] mov                dst:loc6, src:this
[   7] mov                dst:this, src:<JSValue()>(const0)
[  10] mov                dst:loc7, src:<JSValue()>(const0)
[  13] create_rest        dst:loc7, numParametersToSkip:0
[  16] get_prototype_of   dst:loc8, value:callee, valueProfile:1
[  20] mov                dst:loc11, src:loc7
[  23] spread             dst:loc11, argument:loc11
[  26] mov                dst:loc12, src:loc6
[  29] super_construct_varargs dst:loc8, callee:loc8, thisValue:loc12, 
arguments:loc11, firstFree:loc13, firstVarArg:0, valueProfile:2
[  38] is_empty           dst:loc13, operand:this
[  41] jtrue              condition:loc13, targetLabel:6(->47)
Successors: [ #3 #2 ]

After:

bb#1
Predecessors: [ ]
[   0] enter
[   1] mov                dst:loc5, src:callee
[   4] mov                dst:loc6, src:this
[   7] mov                dst:this, src:<JSValue()>(const0)
[  10] mov                dst:loc7, src:<JSValue()>(const0)
[  13] create_rest        dst:loc7, numParametersToSkip:0
[  16] get_prototype_of   dst:loc8, value:callee, valueProfile:1
[  20] mov                dst:loc11, src:loc7
[  23] mov                dst:loc12, src:loc6
[  26] super_construct_varargs dst:loc8, callee:loc8, thisValue:loc12, 
arguments:loc11, firstFree:loc13, firstVarArg:0, valueProfile:2
[  35] is_empty           dst:loc13, operand:this
[  38] jtrue              condition:loc13, targetLabel:6(->44)
Successors: [ #3 #2 ]

Test: 
JSTests/stress/default-derived-constructor-should-not-observe-array-iterator.js

* 
JSTests/stress/default-derived-constructor-should-not-observe-array-iterator.js:
 Added.
(try.):
(try.B):
(try.Array.prototype.Symbol.iterator):
(catch):
* Source/JavaScriptCore/bytecode/ExecutableInfo.h:
(JSC::ExecutableInfo::ExecutableInfo):
(JSC::ExecutableInfo::isBuiltinDefaultClassConstructor const):
* Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.cpp:
(JSC::UnlinkedCodeBlock::UnlinkedCodeBlock):
* Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.h:
(JSC::UnlinkedCodeBlock::isBuiltinDefaultClassConstructor const):
* Source/JavaScriptCore/bytecode/UnlinkedFunctionExecutable.cpp:
(JSC::generateUnlinkedFunctionCodeBlock):
* Source/JavaScriptCore/bytecode/UnlinkedFunctionExecutable.h:
* Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp:
(JSC::BytecodeGenerator::BytecodeGenerator):
(JSC::BytecodeGenerator::emitConstructImpl):
(JSC::BytecodeGenerator::emitConstruct):
(JSC::BytecodeGenerator::emitSuperConstruct):
* Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h:
(JSC::BytecodeGenerator::isBuiltinDefaultClassConstructor const):
* Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp:
(JSC::FunctionCallValueNode::emitBytecode):
* Source/JavaScriptCore/runtime/CachedTypes.cpp:
(JSC::CachedCodeBlock::isBuiltinDefaultClassConstructor const):
(JSC::UnlinkedCodeBlock::UnlinkedCodeBlock):
(JSC::CachedCodeBlock<CodeBlockType>::encode):

Canonical link: https://commits.webkit.org/313130@main



To unsubscribe from these emails, change your notification settings at 
https://github.com/WebKit/WebKit/settings/notifications

Reply via email to