REGRESSION (172175-172177): Change in for...in processing causes properties added in loop to be enumerated
https://bugs.webkit.org/show_bug.cgi?id=142856
Reviewed by Filip Pizlo.
Source/JavaScriptCore:
Refactored the way the for .. in enumeration over objects is done. We used to make three C++ calls to
get info for three loops to iterate over indexed properties, structure properties and other properties,
respectively. We still have the three loops, but now we make one C++ call to get all the info needed
for all loops before we exectue any enumeration.
The JSPropertyEnumerator has a count of the indexed properties and a list of named properties.
The named properties are one list, with structured properties in the range [0,m_endStructurePropertyIndex)
and the generic properties in the range [m_endStructurePropertyIndex, m_endGenericPropertyIndex);
Eliminated the bytecodes op_get_structure_property_enumerator, op_get_generic_property_enumerator and
op_next_enumerator_pname.
Added the bytecodes op_get_property_enumerator, op_enumerator_structure_pname and op_enumerator_generic_pname.
The bytecodes op_enumerator_structure_pname and op_enumerator_generic_pname are similar except for what
end value we stop iterating on.
Made corresponding node changes to the DFG and FTL for the bytecode changes.
* bytecode/BytecodeList.json:
* bytecode/BytecodeUseDef.h:
(JSC::computeUsesForBytecodeOffset):
(JSC::computeDefsForBytecodeOffset):
* bytecode/CodeBlock.cpp:
(JSC::CodeBlock::dumpBytecode):
* bytecompiler/BytecodeGenerator.cpp:
(JSC::BytecodeGenerator::emitGetPropertyEnumerator):
(JSC::BytecodeGenerator::emitEnumeratorStructurePropertyName):
(JSC::BytecodeGenerator::emitEnumeratorGenericPropertyName):
(JSC::BytecodeGenerator::emitGetStructurePropertyEnumerator): Deleted.
(JSC::BytecodeGenerator::emitGetGenericPropertyEnumerator): Deleted.
(JSC::BytecodeGenerator::emitNextEnumeratorPropertyName): Deleted.
* bytecompiler/BytecodeGenerator.h:
* bytecompiler/NodesCodegen.cpp:
(JSC::ForInNode::emitMultiLoopBytecode):
* dfg/DFGAbstractInterpreterInlines.h:
(JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
* dfg/DFGByteCodeParser.cpp:
(JSC::DFG::ByteCodeParser::parseBlock):
* dfg/DFGCapabilities.cpp:
(JSC::DFG::capabilityLevel):
* dfg/DFGClobberize.h:
(JSC::DFG::clobberize):
* dfg/DFGDoesGC.cpp:
(JSC::DFG::doesGC):
* dfg/DFGFixupPhase.cpp:
(JSC::DFG::FixupPhase::fixupNode):
* dfg/DFGNodeType.h:
* dfg/DFGPredictionPropagationPhase.cpp:
(JSC::DFG::PredictionPropagationPhase::propagate):
* dfg/DFGSafeToExecute.h:
(JSC::DFG::safeToExecute):
* dfg/DFGSpeculativeJIT32_64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* dfg/DFGSpeculativeJIT64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* ftl/FTLAbstractHeapRepository.h:
* ftl/FTLCapabilities.cpp:
(JSC::FTL::canCompile):
* ftl/FTLLowerDFGToLLVM.cpp:
(JSC::FTL::LowerDFGToLLVM::compileNode):
(JSC::FTL::LowerDFGToLLVM::compileGetEnumerableLength):
(JSC::FTL::LowerDFGToLLVM::compileGetPropertyEnumerator):
(JSC::FTL::LowerDFGToLLVM::compileGetEnumeratorStructurePname):
(JSC::FTL::LowerDFGToLLVM::compileGetEnumeratorGenericPname):
(JSC::FTL::LowerDFGToLLVM::compileGetStructurePropertyEnumerator): Deleted.
(JSC::FTL::LowerDFGToLLVM::compileGetGenericPropertyEnumerator): Deleted.
(JSC::FTL::LowerDFGToLLVM::compileGetEnumeratorPname): Deleted.
* jit/JIT.cpp:
(JSC::JIT::privateCompileMainPass):
* jit/JIT.h:
* jit/JITOpcodes.cpp:
(JSC::JIT::emit_op_enumerator_structure_pname):
(JSC::JIT::emit_op_enumerator_generic_pname):
(JSC::JIT::emit_op_get_property_enumerator):
(JSC::JIT::emit_op_next_enumerator_pname): Deleted.
(JSC::JIT::emit_op_get_structure_property_enumerator): Deleted.
(JSC::JIT::emit_op_get_generic_property_enumerator): Deleted.
* jit/JITOpcodes32_64.cpp:
(JSC::JIT::emit_op_enumerator_structure_pname):
(JSC::JIT::emit_op_enumerator_generic_pname):
(JSC::JIT::emit_op_next_enumerator_pname): Deleted.
* jit/JITOperations.cpp:
* jit/JITOperations.h:
* llint/LowLevelInterpreter.asm:
* runtime/CommonSlowPaths.cpp:
(JSC::SLOW_PATH_DECL):
* runtime/CommonSlowPaths.h:
* runtime/JSPropertyNameEnumerator.cpp:
(JSC::JSPropertyNameEnumerator::create):
(JSC::JSPropertyNameEnumerator::finishCreation):
* runtime/JSPropertyNameEnumerator.h:
(JSC::JSPropertyNameEnumerator::indexedLength):
(JSC::JSPropertyNameEnumerator::endStructurePropertyIndex):
(JSC::JSPropertyNameEnumerator::endGenericPropertyIndex):
(JSC::JSPropertyNameEnumerator::indexedLengthOffset):
(JSC::JSPropertyNameEnumerator::endStructurePropertyIndexOffset):
(JSC::JSPropertyNameEnumerator::endGenericPropertyIndexOffset):
(JSC::JSPropertyNameEnumerator::cachedInlineCapacityOffset):
(JSC::propertyNameEnumerator):
(JSC::JSPropertyNameEnumerator::cachedPropertyNamesLengthOffset): Deleted.
(JSC::structurePropertyNameEnumerator): Deleted.
(JSC::genericPropertyNameEnumerator): Deleted.
* runtime/Structure.cpp:
(JSC::Structure::setCachedPropertyNameEnumerator):
(JSC::Structure::cachedPropertyNameEnumerator):
(JSC::Structure::canCachePropertyNameEnumerator):
(JSC::Structure::setCachedStructurePropertyNameEnumerator): Deleted.
(JSC::Structure::cachedStructurePropertyNameEnumerator): Deleted.
(JSC::Structure::setCachedGenericPropertyNameEnumerator): Deleted.
(JSC::Structure::cachedGenericPropertyNameEnumerator): Deleted.
(JSC::Structure::canCacheStructurePropertyNameEnumerator): Deleted.
(JSC::Structure::canCacheGenericPropertyNameEnumerator): Deleted.
* runtime/Structure.h:
* runtime/StructureRareData.cpp:
(JSC::StructureRareData::visitChildren):
(JSC::StructureRareData::cachedPropertyNameEnumerator):
(JSC::StructureRareData::setCachedPropertyNameEnumerator):
(JSC::StructureRareData::cachedStructurePropertyNameEnumerator): Deleted.
(JSC::StructureRareData::setCachedStructurePropertyNameEnumerator): Deleted.
(JSC::StructureRareData::cachedGenericPropertyNameEnumerator): Deleted.
(JSC::StructureRareData::setCachedGenericPropertyNameEnumerator): Deleted.
* runtime/StructureRareData.h:
* tests/stress/for-in-delete-during-iteration.js:
LayoutTests:
New tests and rebased one test.
* js/for-in-modify-in-loop-expected.txt: Added.
* js/for-in-modify-in-loop.html: Added.
* js/script-tests/for-in-modify-in-loop.js: Added.
(haveSameProperties):
(each):
(testAdd):
(testAddDelete):
* http/tests/security/cross-frame-access-enumeration-expected.txt: Rebased.
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@181891 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h b/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h
index e3542d1..3769378 100644
--- a/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h
+++ b/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h
@@ -1966,15 +1966,15 @@
forNode(node).makeHeapTop();
break;
}
- case GetStructurePropertyEnumerator: {
+ case GetPropertyEnumerator: {
forNode(node).setType(SpecCell);
break;
}
- case GetGenericPropertyEnumerator: {
- forNode(node).setType(SpecCell);
+ case GetEnumeratorStructurePname: {
+ forNode(node).setType(SpecString | SpecOther);
break;
}
- case GetEnumeratorPname: {
+ case GetEnumeratorGenericPname: {
forNode(node).setType(SpecString | SpecOther);
break;
}
diff --git a/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp b/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp
index 4387cf9..151f162 100644
--- a/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp
+++ b/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp
@@ -3770,28 +3770,26 @@
NEXT_OPCODE(op_get_direct_pname);
}
- case op_get_structure_property_enumerator: {
- set(VirtualRegister(currentInstruction[1].u.operand), addToGraph(GetStructurePropertyEnumerator,
+ case op_get_property_enumerator: {
+ set(VirtualRegister(currentInstruction[1].u.operand), addToGraph(GetPropertyEnumerator,
+ get(VirtualRegister(currentInstruction[2].u.operand))));
+ NEXT_OPCODE(op_get_property_enumerator);
+ }
+
+ case op_enumerator_structure_pname: {
+ set(VirtualRegister(currentInstruction[1].u.operand), addToGraph(GetEnumeratorStructurePname,
get(VirtualRegister(currentInstruction[2].u.operand)),
get(VirtualRegister(currentInstruction[3].u.operand))));
- NEXT_OPCODE(op_get_structure_property_enumerator);
+ NEXT_OPCODE(op_enumerator_structure_pname);
}
- case op_get_generic_property_enumerator: {
- set(VirtualRegister(currentInstruction[1].u.operand), addToGraph(GetGenericPropertyEnumerator,
- get(VirtualRegister(currentInstruction[2].u.operand)),
- get(VirtualRegister(currentInstruction[3].u.operand)),
- get(VirtualRegister(currentInstruction[4].u.operand))));
- NEXT_OPCODE(op_get_generic_property_enumerator);
- }
-
- case op_next_enumerator_pname: {
- set(VirtualRegister(currentInstruction[1].u.operand), addToGraph(GetEnumeratorPname,
+ case op_enumerator_generic_pname: {
+ set(VirtualRegister(currentInstruction[1].u.operand), addToGraph(GetEnumeratorGenericPname,
get(VirtualRegister(currentInstruction[2].u.operand)),
get(VirtualRegister(currentInstruction[3].u.operand))));
- NEXT_OPCODE(op_next_enumerator_pname);
+ NEXT_OPCODE(op_enumerator_generic_pname);
}
-
+
case op_to_index_string: {
set(VirtualRegister(currentInstruction[1].u.operand), addToGraph(ToIndexString,
get(VirtualRegister(currentInstruction[2].u.operand))));
diff --git a/Source/JavaScriptCore/dfg/DFGCapabilities.cpp b/Source/JavaScriptCore/dfg/DFGCapabilities.cpp
index a476572..f54b223 100644
--- a/Source/JavaScriptCore/dfg/DFGCapabilities.cpp
+++ b/Source/JavaScriptCore/dfg/DFGCapabilities.cpp
@@ -202,9 +202,9 @@
case op_has_structure_property:
case op_has_indexed_property:
case op_get_direct_pname:
- case op_get_structure_property_enumerator:
- case op_get_generic_property_enumerator:
- case op_next_enumerator_pname:
+ case op_get_property_enumerator:
+ case op_enumerator_structure_pname:
+ case op_enumerator_generic_pname:
case op_to_index_string:
case op_new_func:
case op_new_func_exp:
diff --git a/Source/JavaScriptCore/dfg/DFGClobberize.h b/Source/JavaScriptCore/dfg/DFGClobberize.h
index 625e2213..a695607 100644
--- a/Source/JavaScriptCore/dfg/DFGClobberize.h
+++ b/Source/JavaScriptCore/dfg/DFGClobberize.h
@@ -162,8 +162,7 @@
case HasGenericProperty:
case HasStructureProperty:
case GetEnumerableLength:
- case GetStructurePropertyEnumerator:
- case GetGenericPropertyEnumerator: {
+ case GetPropertyEnumerator: {
read(Heap);
write(SideState);
return;
@@ -178,7 +177,8 @@
}
case ToIndexString:
- case GetEnumeratorPname: {
+ case GetEnumeratorStructurePname:
+ case GetEnumeratorGenericPname: {
def(PureValue(node));
return;
}
diff --git a/Source/JavaScriptCore/dfg/DFGDoesGC.cpp b/Source/JavaScriptCore/dfg/DFGDoesGC.cpp
index 8f70a18..375ac75 100644
--- a/Source/JavaScriptCore/dfg/DFGDoesGC.cpp
+++ b/Source/JavaScriptCore/dfg/DFGDoesGC.cpp
@@ -231,9 +231,9 @@
case NewFunctionExpression:
case NewTypedArray:
case ThrowReferenceError:
- case GetStructurePropertyEnumerator:
- case GetGenericPropertyEnumerator:
- case GetEnumeratorPname:
+ case GetPropertyEnumerator:
+ case GetEnumeratorStructurePname:
+ case GetEnumeratorGenericPname:
case ToIndexString:
case MaterializeNewObject:
return true;
diff --git a/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp b/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp
index b36fd91..191925a 100644
--- a/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp
+++ b/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp
@@ -1091,7 +1091,7 @@
break;
}
case HasGenericProperty: {
- fixEdge<StringUse>(node->child2());
+ fixEdge<CellUse>(node->child2());
break;
}
case HasStructureProperty: {
@@ -1123,18 +1123,16 @@
fixEdge<KnownCellUse>(enumerator);
break;
}
- case GetStructurePropertyEnumerator: {
+ case GetPropertyEnumerator: {
fixEdge<CellUse>(node->child1());
+ break;
+ }
+ case GetEnumeratorStructurePname: {
+ fixEdge<KnownCellUse>(node->child1());
fixEdge<KnownInt32Use>(node->child2());
break;
}
- case GetGenericPropertyEnumerator: {
- fixEdge<CellUse>(node->child1());
- fixEdge<KnownInt32Use>(node->child2());
- fixEdge<KnownCellUse>(node->child3());
- break;
- }
- case GetEnumeratorPname: {
+ case GetEnumeratorGenericPname: {
fixEdge<KnownCellUse>(node->child1());
fixEdge<KnownInt32Use>(node->child2());
break;
diff --git a/Source/JavaScriptCore/dfg/DFGNodeType.h b/Source/JavaScriptCore/dfg/DFGNodeType.h
index 339ce62..7b09dd7 100644
--- a/Source/JavaScriptCore/dfg/DFGNodeType.h
+++ b/Source/JavaScriptCore/dfg/DFGNodeType.h
@@ -322,9 +322,9 @@
macro(HasStructureProperty, NodeResultBoolean) \
macro(HasGenericProperty, NodeResultBoolean) \
macro(GetDirectPname, NodeMustGenerate | NodeHasVarArgs | NodeResultJS) \
- macro(GetStructurePropertyEnumerator, NodeMustGenerate | NodeResultJS) \
- macro(GetGenericPropertyEnumerator, NodeMustGenerate | NodeResultJS) \
- macro(GetEnumeratorPname, NodeMustGenerate | NodeResultJS) \
+ macro(GetPropertyEnumerator, NodeMustGenerate | NodeResultJS) \
+ macro(GetEnumeratorStructurePname, NodeMustGenerate | NodeResultJS) \
+ macro(GetEnumeratorGenericPname, NodeMustGenerate | NodeResultJS) \
macro(ToIndexString, NodeResultJS)
// This enum generates a monotonically increasing id for all Node types,
diff --git a/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp b/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp
index de7fbd8..5a6271f 100644
--- a/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp
+++ b/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp
@@ -583,12 +583,15 @@
changed |= setPrediction(SpecBoolean);
break;
}
- case GetStructurePropertyEnumerator:
- case GetGenericPropertyEnumerator: {
+ case GetPropertyEnumerator: {
changed |= setPrediction(SpecCell);
break;
}
- case GetEnumeratorPname: {
+ case GetEnumeratorStructurePname: {
+ changed |= setPrediction(SpecCell | SpecOther);
+ break;
+ }
+ case GetEnumeratorGenericPname: {
changed |= setPrediction(SpecCell | SpecOther);
break;
}
diff --git a/Source/JavaScriptCore/dfg/DFGSafeToExecute.h b/Source/JavaScriptCore/dfg/DFGSafeToExecute.h
index f5dbfcb..b1e1e9e 100644
--- a/Source/JavaScriptCore/dfg/DFGSafeToExecute.h
+++ b/Source/JavaScriptCore/dfg/DFGSafeToExecute.h
@@ -272,9 +272,9 @@
case HasStructureProperty:
case HasIndexedProperty:
case GetDirectPname:
- case GetStructurePropertyEnumerator:
- case GetGenericPropertyEnumerator:
- case GetEnumeratorPname:
+ case GetPropertyEnumerator:
+ case GetEnumeratorStructurePname:
+ case GetEnumeratorGenericPname:
case ToIndexString:
case PhantomNewObject:
case PutHint:
diff --git a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp
index 44e8b26..b624de4 100644
--- a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp
+++ b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp
@@ -4715,12 +4715,11 @@
}
case GetEnumerableLength: {
- SpeculateCellOperand base(this, node->child1());
+ SpeculateCellOperand enumerator(this, node->child1());
GPRFlushedCallResult result(this);
GPRReg resultGPR = result.gpr();
- flushRegisters();
- callOperation(operationGetEnumerableLength, resultGPR, base.gpr());
+ m_jit.load32(MacroAssembler::Address(enumerator.gpr(), JSPropertyNameEnumerator::indexedLengthOffset()), resultGPR);
int32Result(resultGPR, node);
break;
}
@@ -4912,30 +4911,18 @@
jsValueResult(resultTagGPR, resultPayloadGPR, node);
break;
}
- case GetStructurePropertyEnumerator: {
+ case GetPropertyEnumerator: {
SpeculateCellOperand base(this, node->child1());
- SpeculateInt32Operand length(this, node->child2());
GPRFlushedCallResult result(this);
GPRReg resultGPR = result.gpr();
flushRegisters();
- callOperation(operationGetStructurePropertyEnumerator, resultGPR, base.gpr(), length.gpr());
+ callOperation(operationGetPropertyEnumerator, resultGPR, base.gpr());
cellResult(resultGPR, node);
break;
}
- case GetGenericPropertyEnumerator: {
- SpeculateCellOperand base(this, node->child1());
- SpeculateInt32Operand length(this, node->child2());
- SpeculateCellOperand enumerator(this, node->child3());
- GPRFlushedCallResult result(this);
- GPRReg resultGPR = result.gpr();
-
- flushRegisters();
- callOperation(operationGetGenericPropertyEnumerator, resultGPR, base.gpr(), length.gpr(), enumerator.gpr());
- cellResult(resultGPR, node);
- break;
- }
- case GetEnumeratorPname: {
+ case GetEnumeratorStructurePname:
+ case GetEnumeratorGenericPname: {
SpeculateCellOperand enumerator(this, node->child1());
SpeculateInt32Operand index(this, node->child2());
GPRTemporary scratch(this);
@@ -4948,8 +4935,10 @@
GPRReg resultTagGPR = resultTag.gpr();
GPRReg resultPayloadGPR = resultPayload.gpr();
- MacroAssembler::Jump inBounds = m_jit.branch32(MacroAssembler::Below,
- indexGPR, MacroAssembler::Address(enumeratorGPR, JSPropertyNameEnumerator::cachedPropertyNamesLengthOffset()));
+ MacroAssembler::Jump inBounds = m_jit.branch32(MacroAssembler::Below, indexGPR,
+ MacroAssembler::Address(enumeratorGPR, (op == GetEnumeratorStructurePname)
+ ? JSPropertyNameEnumerator::endStructurePropertyIndexOffset()
+ : JSPropertyNameEnumerator::endGenericPropertyIndexOffset()));
m_jit.move(MacroAssembler::TrustedImm32(JSValue::NullTag), resultTagGPR);
m_jit.move(MacroAssembler::TrustedImm32(0), resultPayloadGPR);
diff --git a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp
index 17b7eed..96e05c0 100644
--- a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp
+++ b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp
@@ -4772,12 +4772,11 @@
}
case GetEnumerableLength: {
- SpeculateCellOperand base(this, node->child1());
+ SpeculateCellOperand enumerator(this, node->child1());
GPRFlushedCallResult result(this);
GPRReg resultGPR = result.gpr();
- flushRegisters();
- callOperation(operationGetEnumerableLength, resultGPR, base.gpr());
+ m_jit.load32(MacroAssembler::Address(enumerator.gpr(), JSPropertyNameEnumerator::indexedLengthOffset()), resultGPR);
int32Result(resultGPR, node);
break;
}
@@ -4948,30 +4947,18 @@
jsValueResult(resultGPR, node);
break;
}
- case GetStructurePropertyEnumerator: {
+ case GetPropertyEnumerator: {
SpeculateCellOperand base(this, node->child1());
- SpeculateInt32Operand length(this, node->child2());
GPRFlushedCallResult result(this);
GPRReg resultGPR = result.gpr();
flushRegisters();
- callOperation(operationGetStructurePropertyEnumerator, resultGPR, base.gpr(), length.gpr());
+ callOperation(operationGetPropertyEnumerator, resultGPR, base.gpr());
cellResult(resultGPR, node);
break;
}
- case GetGenericPropertyEnumerator: {
- SpeculateCellOperand base(this, node->child1());
- SpeculateInt32Operand length(this, node->child2());
- SpeculateCellOperand enumerator(this, node->child3());
- GPRFlushedCallResult result(this);
- GPRReg resultGPR = result.gpr();
-
- flushRegisters();
- callOperation(operationGetGenericPropertyEnumerator, resultGPR, base.gpr(), length.gpr(), enumerator.gpr());
- cellResult(resultGPR, node);
- break;
- }
- case GetEnumeratorPname: {
+ case GetEnumeratorStructurePname:
+ case GetEnumeratorGenericPname: {
SpeculateCellOperand enumerator(this, node->child1());
SpeculateStrictInt32Operand index(this, node->child2());
GPRTemporary scratch1(this);
@@ -4982,8 +4969,10 @@
GPRReg scratch1GPR = scratch1.gpr();
GPRReg resultGPR = result.gpr();
- MacroAssembler::Jump inBounds = m_jit.branch32(MacroAssembler::Below,
- indexGPR, MacroAssembler::Address(enumeratorGPR, JSPropertyNameEnumerator::cachedPropertyNamesLengthOffset()));
+ MacroAssembler::Jump inBounds = m_jit.branch32(MacroAssembler::Below, indexGPR,
+ MacroAssembler::Address(enumeratorGPR, (op == GetEnumeratorStructurePname)
+ ? JSPropertyNameEnumerator::endStructurePropertyIndexOffset()
+ : JSPropertyNameEnumerator::endGenericPropertyIndexOffset()));
m_jit.move(MacroAssembler::TrustedImm64(JSValue::encode(jsNull())), resultGPR);