Source/JavaScriptCore/ChangeLog

 12020-01-22 Keith Miller <keith_miller@apple.com>
 2
 3 InternalField and CheckNeutered DFG nodes are not always safe to execute
 4 https://bugs.webkit.org/show_bug.cgi?id=206632
 5
 6 Reviewed by NOBODY (OOPS!).
 7
 8 We currently mark (Get/Set)InternalField/CheckNeutered nodes as safe to execute everywhere. However,
 9 GetInternalField, etc. rely on a a proof that the cell passed to it is a subclass of InteralFieldObject
 10 but we may hoist it past the check guarding it.
 11
 12 Also, remove a bogus assertion that we will have proven the value passed to CheckNeutered is a TypedArray.
 13 It's not valid to require that AI will preserve any invariant since phases can make changes that AI doesn't
 14 understand.
 15
 16 * dfg/DFGAbstractInterpreterInlines.h:
 17 (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
 18 * dfg/DFGClobberize.h:
 19 (JSC::DFG::clobberize):
 20 * dfg/DFGSafeToExecute.h:
 21 (JSC::DFG::safeToExecute):
 22 * dfg/DFGSpeculativeJIT.cpp:
 23 (JSC::DFG::SpeculativeJIT::compileCheckNeutered):
 24 * ftl/FTLLowerDFGToB3.cpp:
 25 (JSC::FTL::DFG::LowerDFGToB3::compileCheckNeutered):
 26
1272020-01-22 Caio Lima <ticaiolima@gmail.com>
228
329 [32-bits][JIT] Fix build issues.

Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h

@@bool AbstractInterpreter<AbstractStateType>::executeEffects(unsigned clobberLimi
33743374 break;
33753375 }
33763376
3377  case CheckNeutered: {
3378  DFG_ASSERT(m_graph, node, speculationChecked(forNode(node->child1()).m_type, SpecTypedArrayView));
3379  break;
3380  }
3381 
33823377 case CheckArrayOrEmpty:
33833378 case CheckArray: {
33843379 AbstractValue& value = forNode(node->child1());

@@bool AbstractInterpreter<AbstractStateType>::executeEffects(unsigned clobberLimi
41004095 case CountExecution:
41014096 case CheckTierUpInLoop:
41024097 case CheckTierUpAtReturn:
 4098 case CheckNeutered:
41034099 case SuperSamplerBegin:
41044100 case SuperSamplerEnd:
41054101 case CheckTierUpAndOSREnter:

Source/JavaScriptCore/dfg/DFGClobberize.h

@@void clobberize(Graph& graph, Node* node, const ReadFunctor& read, const WriteFu
11041104 return;
11051105
11061106 case CheckNeutered:
1107  read(JSCell_typeInfoType);
1108  read(JSCell_structureID);
11091107 read(MiscFields);
11101108 return;
11111109

Source/JavaScriptCore/dfg/DFGSafeToExecute.h

3131
3232namespace JSC { namespace DFG {
3333
 34// This phase is used to determine if a node can safely run at a new location.
 35// It is important to note that returning false does not mean it's definitely
 36// wrong to run the node at the new location. In other words, returning false
 37// does not imply moving the node would be invalid only that this phase could
 38// not prove it is valid. Thus, it is always
 39
3440template<typename AbstractStateType>
3541class SafeToExecuteEdge {
3642public:

@@bool safeToExecute(AbstractStateType& state, Graph& graph, Node* node, bool igno
280286 case CheckSubClass:
281287 case CheckArray:
282288 case CheckArrayOrEmpty:
283  case CheckNeutered:
284289 case Arrayify:
285290 case ArrayifyToStructure:
286291 case GetScope:

@@bool safeToExecute(AbstractStateType& state, Graph& graph, Node* node, bool igno
292297 case GetGlobalVar:
293298 case GetGlobalLexicalVariable:
294299 case PutGlobalVariable:
295  case GetInternalField:
296  case PutInternalField:
297300 case CheckCell:
298301 case CheckBadCell:
299302 case CheckNotEmpty:

@@bool safeToExecute(AbstractStateType& state, Graph& graph, Node* node, bool igno
552555 case ArrayPush:
553556 return node->arrayMode().alreadyChecked(graph, node, state.forNode(graph.varArgChild(node, 1)));
554557
 558 case CheckNeutered:
555559 case GetTypedArrayByteOffset:
556560 return !(state.forNode(node->child1()).m_type & ~(SpecTypedArrayView));
557561

@@bool safeToExecute(AbstractStateType& state, Graph& graph, Node* node, bool igno
620624 return true;
621625 }
622626
 627 case GetInternalField:
 628 case PutInternalField:
 629 return false;
 630
623631 case DataViewSet:
624632 return false;
625633

Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp

@@void SpeculativeJIT::compileCheckNeutered(Node* node)
18111811 SpeculateCellOperand base(this, node->child1());
18121812 GPRReg baseReg = base.gpr();
18131813
1814  // We only emit this node after we have checked this is a typed array so that better be true now.
1815  DFG_ASSERT(m_graph, node, speculationChecked(m_state.forNode(node->child1()).m_type, SpecTypedArrayView));
1816 
18171814 speculationCheck(
18181815 BadIndexingType, JSValueSource::unboxedCell(baseReg), node->child1(),
18191816 m_jit.branchTestPtr(MacroAssembler::Zero, MacroAssembler::Address(baseReg, JSArrayBufferView::offsetOfVector())));

Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp

@@private:
41054105 {
41064106 Edge edge = m_node->child1();
41074107 LValue cell = lowCell(edge);
4108 
4109  // We only emit this node after we have checked this is a typed array so that better be true now.
4110  DFG_ASSERT(m_graph, m_node, speculationChecked(abstractValue(edge).m_type, SpecTypedArrayView));
41114108
41124109 speculate(
41134110 BadIndexingType, jsValueValue(cell), edge.node(),

JSTests/ChangeLog

 12020-01-22 Keith Miller <keith_miller@apple.com>
 2
 3 InternalField and CheckNeutered DFG nodes are not always safe to execute
 4 https://bugs.webkit.org/show_bug.cgi?id=206632
 5
 6 Reviewed by NOBODY (OOPS!).
 7
 8 * stress/for-of-bad-internal-field-hoist.js: Added.
 9 (foo):
 10
1112020-01-22 Yusuke Suzuki <ysuzuki@apple.com>
212
313 [JSC] DateMath should accept more ISO-8601 timezone designators even if they are not included in ECMA262 to produce expected results in the wild code

JSTests/stress/for-of-bad-internal-field-hoist.js

 1//@ requireOptions("--maximumFunctionForCallInlineCandidateBytecodeCost=500")
 2
 3function foo() {
 4 let x = ''
 5 for (let j = 0; j < 10; j++) {
 6 for (const y of x) {}
 7 x = [0]
 8 }
 9}
 10
 11for (let i=0; i<100000; i++) {
 12 foo();
 13}