DFG should inline InstanceOf ICs
[WebKit-https.git] / Source / JavaScriptCore / dfg / DFGAbstractInterpreterInlines.h
1 /*
2  * Copyright (C) 2013-2018 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
24  */
25
26 #pragma once
27
28 #if ENABLE(DFG_JIT)
29
30 #include "ArrayConstructor.h"
31 #include "DFGAbstractInterpreter.h"
32 #include "DFGAbstractInterpreterClobberState.h"
33 #include "DOMJITGetterSetter.h"
34 #include "DOMJITSignature.h"
35 #include "GetByIdStatus.h"
36 #include "GetterSetter.h"
37 #include "HashMapImpl.h"
38 #include "JITOperations.h"
39 #include "MathCommon.h"
40 #include "NumberConstructor.h"
41 #include "Operations.h"
42 #include "PutByIdStatus.h"
43 #include "StringObject.h"
44 #include <wtf/BooleanLattice.h>
45 #include <wtf/CheckedArithmetic.h>
46
47 namespace JSC { namespace DFG {
48
49 template<typename AbstractStateType>
50 AbstractInterpreter<AbstractStateType>::AbstractInterpreter(Graph& graph, AbstractStateType& state)
51     : m_codeBlock(graph.m_codeBlock)
52     , m_graph(graph)
53     , m_vm(m_graph.m_vm)
54     , m_state(state)
55 {
56     if (m_graph.m_form == SSA)
57         m_phiChildren = std::make_unique<PhiChildren>(m_graph);
58 }
59
60 template<typename AbstractStateType>
61 AbstractInterpreter<AbstractStateType>::~AbstractInterpreter()
62 {
63 }
64
65 template<typename AbstractStateType>
66 typename AbstractInterpreter<AbstractStateType>::BooleanResult
67 AbstractInterpreter<AbstractStateType>::booleanResult(
68     Node* node, AbstractValue& value)
69 {
70     JSValue childConst = value.value();
71     if (childConst) {
72         if (childConst.toBoolean(m_codeBlock->globalObjectFor(node->origin.semantic)->globalExec()))
73             return DefinitelyTrue;
74         return DefinitelyFalse;
75     }
76
77     // Next check if we can fold because we know that the source is an object or string and does not equal undefined.
78     if (isCellSpeculation(value.m_type) && !value.m_structure.isTop()) {
79         bool allTrue = true;
80         for (unsigned i = value.m_structure.size(); i--;) {
81             RegisteredStructure structure = value.m_structure[i];
82             if (structure->masqueradesAsUndefined(m_codeBlock->globalObjectFor(node->origin.semantic))
83                 || structure->typeInfo().type() == StringType) {
84                 allTrue = false;
85                 break;
86             }
87         }
88         if (allTrue)
89             return DefinitelyTrue;
90     }
91     
92     return UnknownBooleanResult;
93 }
94
95 template<typename AbstractStateType>
96 void AbstractInterpreter<AbstractStateType>::startExecuting()
97 {
98     ASSERT(m_state.block());
99     ASSERT(m_state.isValid());
100     
101     m_state.setClobberState(AbstractInterpreterClobberState::NotClobbered);
102 }
103
104 template<typename AbstractStateType>
105 class AbstractInterpreterExecuteEdgesFunc {
106 public:
107     AbstractInterpreterExecuteEdgesFunc(AbstractInterpreter<AbstractStateType>& interpreter)
108         : m_interpreter(interpreter)
109     {
110     }
111     
112     // This func is manually written out so that we can put ALWAYS_INLINE on it.
113     ALWAYS_INLINE void operator()(Edge& edge) const
114     {
115         m_interpreter.filterEdgeByUse(edge);
116     }
117     
118 private:
119     AbstractInterpreter<AbstractStateType>& m_interpreter;
120 };
121
122 template<typename AbstractStateType>
123 void AbstractInterpreter<AbstractStateType>::executeEdges(Node* node)
124 {
125     m_graph.doToChildren(node, AbstractInterpreterExecuteEdgesFunc<AbstractStateType>(*this));
126 }
127
128 template<typename AbstractStateType>
129 void AbstractInterpreter<AbstractStateType>::executeKnownEdgeTypes(Node* node)
130 {
131     // Some use kinds are required to not have checks, because we know somehow that the incoming
132     // value will already have the type we want. In those cases, AI may not be smart enough to
133     // prove that this is indeed the case. But the existance of the edge is enough to prove that
134     // it is indeed the case. Taking advantage of this is not optional, since otherwise the DFG
135     // and FTL backends may emit checks in a node that lacks a valid exit origin.
136     m_graph.doToChildren(
137         node,
138         [&] (Edge& edge) {
139             if (mayHaveTypeCheck(edge.useKind()))
140                 return;
141             
142             filterEdgeByUse(edge);
143         });
144 }
145
146 template<typename AbstractStateType>
147 ALWAYS_INLINE void AbstractInterpreter<AbstractStateType>::filterByType(Edge& edge, SpeculatedType type)
148 {
149     AbstractValue& value = m_state.forNodeWithoutFastForward(edge);
150     if (value.isType(type)) {
151         m_state.setProofStatus(edge, IsProved);
152         return;
153     }
154     m_state.setProofStatus(edge, NeedsCheck);
155     m_state.fastForwardAndFilterUnproven(value, type);
156 }
157
158 template<typename AbstractStateType>
159 void AbstractInterpreter<AbstractStateType>::verifyEdge(Node* node, Edge edge)
160 {
161     if (!(m_state.forNodeWithoutFastForward(edge).m_type & ~typeFilterFor(edge.useKind())))
162         return;
163     
164     DFG_CRASH(m_graph, node, toCString("Edge verification error: ", node, "->", edge, " was expected to have type ", SpeculationDump(typeFilterFor(edge.useKind())), " but has type ", SpeculationDump(forNode(edge).m_type), " (", forNode(edge).m_type, ")").data(), AbstractInterpreterInvalidType, node->op(), edge->op(), edge.useKind(), forNode(edge).m_type);
165 }
166
167 template<typename AbstractStateType>
168 void AbstractInterpreter<AbstractStateType>::verifyEdges(Node* node)
169 {
170     DFG_NODE_DO_TO_CHILDREN(m_graph, node, verifyEdge);
171 }
172
173 enum class ToThisResult {
174     Identity,
175     Undefined,
176     GlobalThis,
177     Dynamic,
178 };
179 inline ToThisResult isToThisAnIdentity(VM& vm, bool isStrictMode, AbstractValue& valueForNode)
180 {
181     // We look at the type first since that will cover most cases and does not require iterating all the structures.
182     if (isStrictMode) {
183         if (valueForNode.m_type && !(valueForNode.m_type & SpecObjectOther))
184             return ToThisResult::Identity;
185     } else {
186         if (valueForNode.m_type && !(valueForNode.m_type & (~SpecObject | SpecObjectOther)))
187             return ToThisResult::Identity;
188     }
189
190     if (JSValue value = valueForNode.value()) {
191         if (value.isCell()) {
192             auto* toThisMethod = value.asCell()->classInfo(vm)->methodTable.toThis;
193             if (toThisMethod == &JSObject::toThis)
194                 return ToThisResult::Identity;
195             if (toThisMethod == &JSScope::toThis) {
196                 if (isStrictMode)
197                     return ToThisResult::Undefined;
198                 return ToThisResult::GlobalThis;
199             }
200         }
201     }
202
203     if ((isStrictMode || (valueForNode.m_type && !(valueForNode.m_type & ~SpecObject))) && valueForNode.m_structure.isFinite()) {
204         bool allStructuresAreJSScope = !valueForNode.m_structure.isClear();
205         bool overridesToThis = false;
206         valueForNode.m_structure.forEach([&](RegisteredStructure structure) {
207             TypeInfo type = structure->typeInfo();
208             ASSERT(type.isObject() || type.type() == StringType || type.type() == SymbolType || type.type() == BigIntType);
209             if (!isStrictMode)
210                 ASSERT(type.isObject());
211             // We don't need to worry about strings/symbols here since either:
212             // 1) We are in strict mode and strings/symbols are not wrapped
213             // 2) The AI has proven that the type of this is a subtype of object
214             if (type.isObject() && type.overridesToThis())
215                 overridesToThis = true;
216
217             // If all the structures are JSScope's ones, we know the details of JSScope::toThis() operation.
218             allStructuresAreJSScope &= structure->classInfo()->methodTable.toThis == JSScope::info()->methodTable.toThis;
219         });
220         if (!overridesToThis)
221             return ToThisResult::Identity;
222         if (allStructuresAreJSScope) {
223             if (isStrictMode)
224                 return ToThisResult::Undefined;
225             return ToThisResult::GlobalThis;
226         }
227     }
228
229     return ToThisResult::Dynamic;
230 }
231
232 template<typename AbstractStateType>
233 bool AbstractInterpreter<AbstractStateType>::executeEffects(unsigned clobberLimit, Node* node)
234 {
235     verifyEdges(node);
236     
237     m_state.createValueForNode(node);
238     
239     switch (node->op()) {
240     case JSConstant:
241     case DoubleConstant:
242     case Int52Constant: {
243         setBuiltInConstant(node, *node->constant());
244         break;
245     }
246
247     case LazyJSConstant: {
248         LazyJSValue value = node->lazyJSValue();
249         switch (value.kind()) {
250         case LazyJSValue::KnownValue:
251             setConstant(node, value.value()->value());
252             break;
253         case LazyJSValue::SingleCharacterString:
254         case LazyJSValue::KnownStringImpl:
255         case LazyJSValue::NewStringImpl:
256             setTypeForNode(node, SpecString);
257             break;
258         }
259         break;
260     }
261
262     case IdentityWithProfile:
263     case Identity: {
264         setForNode(node, forNode(node->child1()));
265         if (forNode(node).value())
266             m_state.setFoundConstants(true);
267         break;
268     }
269         
270     case ExtractCatchLocal:
271     case ExtractOSREntryLocal: {
272         makeBytecodeTopForNode(node);
273         break;
274     }
275             
276     case GetLocal: {
277         VariableAccessData* variableAccessData = node->variableAccessData();
278         AbstractValue value = m_state.operand(variableAccessData->local().offset());
279         // The value in the local should already be checked.
280         DFG_ASSERT(m_graph, node, value.isType(typeFilterFor(variableAccessData->flushFormat())));
281         if (value.value())
282             m_state.setFoundConstants(true);
283         setForNode(node, value);
284         break;
285     }
286         
287     case GetStack: {
288         StackAccessData* data = node->stackAccessData();
289         AbstractValue value = m_state.operand(data->local);
290         // The value in the local should already be checked.
291         DFG_ASSERT(m_graph, node, value.isType(typeFilterFor(data->format)));
292         if (value.value())
293             m_state.setFoundConstants(true);
294         setForNode(node, value);
295         break;
296     }
297         
298     case SetLocal: {
299         m_state.operand(node->local()) = forNode(node->child1());
300         break;
301     }
302         
303     case PutStack: {
304         m_state.operand(node->stackAccessData()->local) = forNode(node->child1());
305         break;
306     }
307         
308     case MovHint: {
309         // Don't need to do anything. A MovHint only informs us about what would have happened
310         // in bytecode, but this code is just concerned with what is actually happening during
311         // DFG execution.
312         break;
313     }
314
315     case KillStack: {
316         // This is just a hint telling us that the OSR state of the local is no longer inside the
317         // flushed data.
318         break;
319     }
320         
321     case SetArgument:
322         // Assert that the state of arguments has been set. SetArgument means that someone set
323         // the argument values out-of-band, and currently this always means setting to a
324         // non-clear value.
325         ASSERT(!m_state.operand(node->local()).isClear());
326         break;
327
328     case InitializeEntrypointArguments: {
329         unsigned entrypointIndex = node->entrypointIndex();
330         const Vector<FlushFormat>& argumentFormats = m_graph.m_argumentFormats[entrypointIndex];
331         for (unsigned argument = 0; argument < argumentFormats.size(); ++argument) {
332             AbstractValue& value = m_state.argument(argument);
333             switch (argumentFormats[argument]) {
334             case FlushedInt32:
335                 value.setNonCellType(SpecInt32Only);
336                 break;
337             case FlushedBoolean:
338                 value.setNonCellType(SpecBoolean);
339                 break;
340             case FlushedCell:
341                 value.setType(m_graph, SpecCell);
342                 break;
343             case FlushedJSValue:
344                 value.makeBytecodeTop();
345                 break;
346             default:
347                 DFG_CRASH(m_graph, node, "Bad flush format for argument");
348                 break;
349             }
350         }
351         break;
352     }
353
354     case LoadVarargs:
355     case ForwardVarargs: {
356         // FIXME: ForwardVarargs should check if the count becomes known, and if it does, it should turn
357         // itself into a straight-line sequence of GetStack/PutStack.
358         // https://bugs.webkit.org/show_bug.cgi?id=143071
359         switch (node->op()) {
360         case LoadVarargs:
361             clobberWorld();
362             break;
363         case ForwardVarargs:
364             break;
365         default:
366             DFG_CRASH(m_graph, node, "Bad opcode");
367             break;
368         }
369         LoadVarargsData* data = node->loadVarargsData();
370         m_state.operand(data->count).setNonCellType(SpecInt32Only);
371         for (unsigned i = data->limit - 1; i--;)
372             m_state.operand(data->start.offset() + i).makeHeapTop();
373         break;
374     }
375             
376     case BitAnd:
377     case BitOr:
378     case BitXor:
379     case BitRShift:
380     case BitLShift:
381     case BitURShift: {
382         if (node->child1().useKind() == UntypedUse || node->child2().useKind() == UntypedUse) {
383             clobberWorld();
384             setNonCellTypeForNode(node, SpecInt32Only);
385             break;
386         }
387
388         JSValue left = forNode(node->child1()).value();
389         JSValue right = forNode(node->child2()).value();
390         if (left && right && left.isInt32() && right.isInt32()) {
391             int32_t a = left.asInt32();
392             int32_t b = right.asInt32();
393             switch (node->op()) {
394             case BitAnd:
395                 setConstant(node, JSValue(a & b));
396                 break;
397             case BitOr:
398                 setConstant(node, JSValue(a | b));
399                 break;
400             case BitXor:
401                 setConstant(node, JSValue(a ^ b));
402                 break;
403             case BitRShift:
404                 setConstant(node, JSValue(a >> static_cast<uint32_t>(b)));
405                 break;
406             case BitLShift:
407                 setConstant(node, JSValue(a << static_cast<uint32_t>(b)));
408                 break;
409             case BitURShift:
410                 setConstant(node, JSValue(static_cast<uint32_t>(a) >> static_cast<uint32_t>(b)));
411                 break;
412             default:
413                 RELEASE_ASSERT_NOT_REACHED();
414                 break;
415             }
416             break;
417         }
418         
419         if (node->op() == BitAnd
420             && (isBoolInt32Speculation(forNode(node->child1()).m_type) ||
421                 isBoolInt32Speculation(forNode(node->child2()).m_type))) {
422             setNonCellTypeForNode(node, SpecBoolInt32);
423             break;
424         }
425         
426         setNonCellTypeForNode(node, SpecInt32Only);
427         break;
428     }
429         
430     case UInt32ToNumber: {
431         JSValue child = forNode(node->child1()).value();
432         if (doesOverflow(node->arithMode())) {
433             if (enableInt52()) {
434                 if (child && child.isAnyInt()) {
435                     int64_t machineInt = child.asAnyInt();
436                     setConstant(node, jsNumber(static_cast<uint32_t>(machineInt)));
437                     break;
438                 }
439                 setNonCellTypeForNode(node, SpecAnyInt);
440                 break;
441             }
442             if (child && child.isInt32()) {
443                 uint32_t value = child.asInt32();
444                 setConstant(node, jsNumber(value));
445                 break;
446             }
447             setNonCellTypeForNode(node, SpecAnyIntAsDouble);
448             break;
449         }
450         if (child && child.isInt32()) {
451             int32_t value = child.asInt32();
452             if (value >= 0) {
453                 setConstant(node, jsNumber(value));
454                 break;
455             }
456         }
457         setNonCellTypeForNode(node, SpecInt32Only);
458         break;
459     }
460         
461     case BooleanToNumber: {
462         JSValue concreteValue = forNode(node->child1()).value();
463         if (concreteValue) {
464             if (concreteValue.isBoolean())
465                 setConstant(node, jsNumber(concreteValue.asBoolean()));
466             else
467                 setConstant(node, *m_graph.freeze(concreteValue));
468             break;
469         }
470         AbstractValue& value = forNode(node);
471         value = forNode(node->child1());
472         if (node->child1().useKind() == UntypedUse && !(value.m_type & ~SpecBoolean))
473             m_state.setFoundConstants(true);
474         if (value.m_type & SpecBoolean) {
475             value.merge(SpecBoolInt32);
476             value.filter(~SpecBoolean);
477         }
478         break;
479     }
480             
481     case DoubleAsInt32: {
482         JSValue child = forNode(node->child1()).value();
483         if (child && child.isNumber()) {
484             double asDouble = child.asNumber();
485             int32_t asInt = JSC::toInt32(asDouble);
486             if (bitwise_cast<int64_t>(static_cast<double>(asInt)) == bitwise_cast<int64_t>(asDouble)) {
487                 setConstant(node, JSValue(asInt));
488                 break;
489             }
490         }
491         setNonCellTypeForNode(node, SpecInt32Only);
492         break;
493     }
494             
495     case ValueToInt32: {
496         JSValue child = forNode(node->child1()).value();
497         if (child) {
498             if (child.isNumber()) {
499                 if (child.isInt32())
500                     setConstant(node, child);
501                 else
502                     setConstant(node, JSValue(JSC::toInt32(child.asDouble())));
503                 break;
504             }
505             if (child.isBoolean()) {
506                 setConstant(node, jsNumber(child.asBoolean()));
507                 break;
508             }
509             if (child.isUndefinedOrNull()) {
510                 setConstant(node, jsNumber(0));
511                 break;
512             }
513         }
514         
515         if (isBooleanSpeculation(forNode(node->child1()).m_type)) {
516             setNonCellTypeForNode(node, SpecBoolInt32);
517             break;
518         }
519         
520         setNonCellTypeForNode(node, SpecInt32Only);
521         break;
522     }
523         
524     case DoubleRep: {
525         JSValue child = forNode(node->child1()).value();
526         if (std::optional<double> number = child.toNumberFromPrimitive()) {
527             setConstant(node, jsDoubleNumber(*number));
528             break;
529         }
530
531         SpeculatedType type = forNode(node->child1()).m_type;
532         switch (node->child1().useKind()) {
533         case NotCellUse: {
534             if (type & SpecOther) {
535                 type &= ~SpecOther;
536                 type |= SpecDoublePureNaN | SpecBoolInt32; // Null becomes zero, undefined becomes NaN.
537             }
538             if (type & SpecBoolean) {
539                 type &= ~SpecBoolean;
540                 type |= SpecBoolInt32; // True becomes 1, false becomes 0.
541             }
542             type &= SpecBytecodeNumber;
543             break;
544         }
545
546         case Int52RepUse:
547         case NumberUse:
548         case RealNumberUse:
549             break;
550
551         default:
552             RELEASE_ASSERT_NOT_REACHED();
553         }
554         setNonCellTypeForNode(node, type);
555         forNode(node).fixTypeForRepresentation(m_graph, node);
556         break;
557     }
558         
559     case Int52Rep: {
560         JSValue child = forNode(node->child1()).value();
561         if (child && child.isAnyInt()) {
562             setConstant(node, child);
563             break;
564         }
565         
566         setNonCellTypeForNode(node, SpecAnyInt);
567         break;
568     }
569         
570     case ValueRep: {
571         JSValue value = forNode(node->child1()).value();
572         if (value) {
573             setConstant(node, value);
574             break;
575         }
576         
577         setTypeForNode(node, forNode(node->child1()).m_type & ~SpecDoubleImpureNaN);
578         forNode(node).fixTypeForRepresentation(m_graph, node);
579         break;
580     }
581         
582     case ValueAdd: {
583         ASSERT(node->binaryUseKind() == UntypedUse);
584         clobberWorld();
585         setTypeForNode(node, SpecString | SpecBytecodeNumber);
586         break;
587     }
588
589     case StrCat: {
590         setTypeForNode(node, SpecString);
591         break;
592     }
593         
594     case ArithAdd: {
595         JSValue left = forNode(node->child1()).value();
596         JSValue right = forNode(node->child2()).value();
597         switch (node->binaryUseKind()) {
598         case Int32Use:
599             if (left && right && left.isInt32() && right.isInt32()) {
600                 if (!shouldCheckOverflow(node->arithMode())) {
601                     setConstant(node, jsNumber(left.asInt32() + right.asInt32()));
602                     break;
603                 }
604                 JSValue result = jsNumber(left.asNumber() + right.asNumber());
605                 if (result.isInt32()) {
606                     setConstant(node, result);
607                     break;
608                 }
609             }
610             setNonCellTypeForNode(node, SpecInt32Only);
611             break;
612         case Int52RepUse:
613             if (left && right && left.isAnyInt() && right.isAnyInt()) {
614                 JSValue result = jsNumber(left.asAnyInt() + right.asAnyInt());
615                 if (result.isAnyInt()) {
616                     setConstant(node, result);
617                     break;
618                 }
619             }
620             setNonCellTypeForNode(node, SpecAnyInt);
621             break;
622         case DoubleRepUse:
623             if (left && right && left.isNumber() && right.isNumber()) {
624                 setConstant(node, jsDoubleNumber(left.asNumber() + right.asNumber()));
625                 break;
626             }
627             setNonCellTypeForNode(node, 
628                 typeOfDoubleSum(
629                     forNode(node->child1()).m_type, forNode(node->child2()).m_type));
630             break;
631         default:
632             RELEASE_ASSERT_NOT_REACHED();
633             break;
634         }
635         break;
636     }
637         
638     case AtomicsIsLockFree: {
639         if (node->child1().useKind() != Int32Use)
640             clobberWorld();
641         setNonCellTypeForNode(node, SpecBoolInt32);
642         break;
643     }
644
645     case ArithClz32: {
646         JSValue operand = forNode(node->child1()).value();
647         if (std::optional<double> number = operand.toNumberFromPrimitive()) {
648             switch (node->child1().useKind()) {
649             case Int32Use:
650             case KnownInt32Use:
651                 break;
652             default:
653                 didFoldClobberWorld();
654                 break;
655             }
656             uint32_t value = toUInt32(*number);
657             setConstant(node, jsNumber(clz32(value)));
658             break;
659         }
660         switch (node->child1().useKind()) {
661         case Int32Use:
662         case KnownInt32Use:
663             break;
664         default:
665             clobberWorld();
666             break;
667         }
668         setNonCellTypeForNode(node, SpecInt32Only);
669         break;
670     }
671
672     case MakeRope: {
673         unsigned numberOfChildren = 0;
674         unsigned numberOfRemovedChildren = 0;
675         std::optional<unsigned> nonEmptyIndex;
676         for (unsigned i = 0; i < AdjacencyList::Size; ++i) {
677             Edge& edge = node->children.child(i);
678             if (!edge)
679                 break;
680             ++numberOfChildren;
681
682             JSValue childConstant = m_state.forNode(edge).value();
683             if (!childConstant) {
684                 nonEmptyIndex = i;
685                 continue;
686             }
687             if (!childConstant.isString()) {
688                 nonEmptyIndex = i;
689                 continue;
690             }
691             if (asString(childConstant)->length()) {
692                 nonEmptyIndex = i;
693                 continue;
694             }
695
696             ++numberOfRemovedChildren;
697         }
698
699         if (numberOfRemovedChildren) {
700             m_state.setFoundConstants(true);
701             if (numberOfRemovedChildren == numberOfChildren) {
702                 // Propagate the last child. This is the way taken in the constant folding phase.
703                 setForNode(node, forNode(node->children.child(numberOfChildren - 1)));
704                 break;
705             }
706             if ((numberOfRemovedChildren + 1) == numberOfChildren) {
707                 ASSERT(nonEmptyIndex);
708                 setForNode(node, forNode(node->children.child(nonEmptyIndex.value())));
709                 break;
710             }
711         }
712         setForNode(node, m_vm.stringStructure.get());
713         break;
714     }
715             
716     case ArithSub: {
717         JSValue left = forNode(node->child1()).value();
718         JSValue right = forNode(node->child2()).value();
719         switch (node->binaryUseKind()) {
720         case Int32Use:
721             if (left && right && left.isInt32() && right.isInt32()) {
722                 if (!shouldCheckOverflow(node->arithMode())) {
723                     setConstant(node, jsNumber(left.asInt32() - right.asInt32()));
724                     break;
725                 }
726                 JSValue result = jsNumber(left.asNumber() - right.asNumber());
727                 if (result.isInt32()) {
728                     setConstant(node, result);
729                     break;
730                 }
731             }
732             setNonCellTypeForNode(node, SpecInt32Only);
733             break;
734         case Int52RepUse:
735             if (left && right && left.isAnyInt() && right.isAnyInt()) {
736                 JSValue result = jsNumber(left.asAnyInt() - right.asAnyInt());
737                 if (result.isAnyInt() || !shouldCheckOverflow(node->arithMode())) {
738                     setConstant(node, result);
739                     break;
740                 }
741             }
742             setNonCellTypeForNode(node, SpecAnyInt);
743             break;
744         case DoubleRepUse:
745             if (left && right && left.isNumber() && right.isNumber()) {
746                 setConstant(node, jsDoubleNumber(left.asNumber() - right.asNumber()));
747                 break;
748             }
749             setNonCellTypeForNode(node, 
750                 typeOfDoubleDifference(
751                     forNode(node->child1()).m_type, forNode(node->child2()).m_type));
752             break;
753         case UntypedUse:
754             clobberWorld();
755             setNonCellTypeForNode(node, SpecBytecodeNumber);
756             break;
757         default:
758             RELEASE_ASSERT_NOT_REACHED();
759             break;
760         }
761         break;
762     }
763         
764     case ArithNegate: {
765         JSValue child = forNode(node->child1()).value();
766         switch (node->child1().useKind()) {
767         case Int32Use:
768             if (child && child.isInt32()) {
769                 if (!shouldCheckOverflow(node->arithMode())) {
770                     setConstant(node, jsNumber(-child.asInt32()));
771                     break;
772                 }
773                 double doubleResult;
774                 if (shouldCheckNegativeZero(node->arithMode()))
775                     doubleResult = -child.asNumber();
776                 else
777                     doubleResult = 0 - child.asNumber();
778                 JSValue valueResult = jsNumber(doubleResult);
779                 if (valueResult.isInt32()) {
780                     setConstant(node, valueResult);
781                     break;
782                 }
783             }
784             setNonCellTypeForNode(node, SpecInt32Only);
785             break;
786         case Int52RepUse:
787             if (child && child.isAnyInt()) {
788                 double doubleResult;
789                 if (shouldCheckNegativeZero(node->arithMode()))
790                     doubleResult = -child.asNumber();
791                 else
792                     doubleResult = 0 - child.asNumber();
793                 JSValue valueResult = jsNumber(doubleResult);
794                 if (valueResult.isAnyInt()) {
795                     setConstant(node, valueResult);
796                     break;
797                 }
798             }
799             setNonCellTypeForNode(node, SpecAnyInt);
800             break;
801         case DoubleRepUse:
802             if (child && child.isNumber()) {
803                 setConstant(node, jsDoubleNumber(-child.asNumber()));
804                 break;
805             }
806             setNonCellTypeForNode(node, 
807                 typeOfDoubleNegation(
808                     forNode(node->child1()).m_type));
809             break;
810         default:
811             DFG_ASSERT(m_graph, node, node->child1().useKind() == UntypedUse, node->child1().useKind());
812             clobberWorld();
813             setNonCellTypeForNode(node, SpecBytecodeNumber);
814             break;
815         }
816         break;
817     }
818         
819     case ArithMul: {
820         JSValue left = forNode(node->child1()).value();
821         JSValue right = forNode(node->child2()).value();
822         switch (node->binaryUseKind()) {
823         case Int32Use:
824             if (left && right && left.isInt32() && right.isInt32()) {
825                 if (!shouldCheckOverflow(node->arithMode())) {
826                     setConstant(node, jsNumber(left.asInt32() * right.asInt32()));
827                     break;
828                 }
829                 double doubleResult = left.asNumber() * right.asNumber();
830                 if (!shouldCheckNegativeZero(node->arithMode()))
831                     doubleResult += 0; // Sanitizes zero.
832                 JSValue valueResult = jsNumber(doubleResult);
833                 if (valueResult.isInt32()) {
834                     setConstant(node, valueResult);
835                     break;
836                 }
837             }
838             setNonCellTypeForNode(node, SpecInt32Only);
839             break;
840         case Int52RepUse:
841             if (left && right && left.isAnyInt() && right.isAnyInt()) {
842                 double doubleResult = left.asNumber() * right.asNumber();
843                 if (!shouldCheckNegativeZero(node->arithMode()))
844                     doubleResult += 0;
845                 JSValue valueResult = jsNumber(doubleResult);
846                 if (valueResult.isAnyInt()) {
847                     setConstant(node, valueResult);
848                     break;
849                 }
850             }
851             setNonCellTypeForNode(node, SpecAnyInt);
852             break;
853         case DoubleRepUse:
854             if (left && right && left.isNumber() && right.isNumber()) {
855                 setConstant(node, jsDoubleNumber(left.asNumber() * right.asNumber()));
856                 break;
857             }
858             setNonCellTypeForNode(node, 
859                 typeOfDoubleProduct(
860                     forNode(node->child1()).m_type, forNode(node->child2()).m_type));
861             break;
862         case UntypedUse:
863             clobberWorld();
864             setNonCellTypeForNode(node, SpecBytecodeNumber);
865             break;
866         default:
867             RELEASE_ASSERT_NOT_REACHED();
868             break;
869         }
870         break;
871     }
872         
873     case ArithDiv: {
874         JSValue left = forNode(node->child1()).value();
875         JSValue right = forNode(node->child2()).value();
876         switch (node->binaryUseKind()) {
877         case Int32Use:
878             if (left && right && left.isInt32() && right.isInt32()) {
879                 double doubleResult = left.asNumber() / right.asNumber();
880                 if (!shouldCheckOverflow(node->arithMode()))
881                     doubleResult = toInt32(doubleResult);
882                 else if (!shouldCheckNegativeZero(node->arithMode()))
883                     doubleResult += 0; // Sanitizes zero.
884                 JSValue valueResult = jsNumber(doubleResult);
885                 if (valueResult.isInt32()) {
886                     setConstant(node, valueResult);
887                     break;
888                 }
889             }
890             setNonCellTypeForNode(node, SpecInt32Only);
891             break;
892         case DoubleRepUse:
893             if (left && right && left.isNumber() && right.isNumber()) {
894                 setConstant(node, jsDoubleNumber(left.asNumber() / right.asNumber()));
895                 break;
896             }
897             setNonCellTypeForNode(node, 
898                 typeOfDoubleQuotient(
899                     forNode(node->child1()).m_type, forNode(node->child2()).m_type));
900             break;
901         case UntypedUse:
902             clobberWorld();
903             setNonCellTypeForNode(node, SpecBytecodeNumber);
904             break;
905         default:
906             RELEASE_ASSERT_NOT_REACHED();
907             break;
908         }
909         break;
910     }
911
912     case ArithMod: {
913         JSValue left = forNode(node->child1()).value();
914         JSValue right = forNode(node->child2()).value();
915         switch (node->binaryUseKind()) {
916         case Int32Use:
917             if (left && right && left.isInt32() && right.isInt32()) {
918                 double doubleResult = fmod(left.asNumber(), right.asNumber());
919                 if (!shouldCheckOverflow(node->arithMode()))
920                     doubleResult = toInt32(doubleResult);
921                 else if (!shouldCheckNegativeZero(node->arithMode()))
922                     doubleResult += 0; // Sanitizes zero.
923                 JSValue valueResult = jsNumber(doubleResult);
924                 if (valueResult.isInt32()) {
925                     setConstant(node, valueResult);
926                     break;
927                 }
928             }
929             setNonCellTypeForNode(node, SpecInt32Only);
930             break;
931         case DoubleRepUse:
932             if (left && right && left.isNumber() && right.isNumber()) {
933                 setConstant(node, jsDoubleNumber(fmod(left.asNumber(), right.asNumber())));
934                 break;
935             }
936             setNonCellTypeForNode(node, 
937                 typeOfDoubleBinaryOp(
938                     forNode(node->child1()).m_type, forNode(node->child2()).m_type));
939             break;
940         default:
941             RELEASE_ASSERT_NOT_REACHED();
942             break;
943         }
944         break;
945     }
946
947     case ArithMin: {
948         JSValue left = forNode(node->child1()).value();
949         JSValue right = forNode(node->child2()).value();
950         switch (node->binaryUseKind()) {
951         case Int32Use:
952             if (left && right && left.isInt32() && right.isInt32()) {
953                 setConstant(node, jsNumber(std::min(left.asInt32(), right.asInt32())));
954                 break;
955             }
956             setNonCellTypeForNode(node, SpecInt32Only);
957             break;
958         case DoubleRepUse:
959             if (left && right && left.isNumber() && right.isNumber()) {
960                 double a = left.asNumber();
961                 double b = right.asNumber();
962                 setConstant(node, jsDoubleNumber(a < b ? a : (b <= a ? b : a + b)));
963                 break;
964             }
965             setNonCellTypeForNode(node, 
966                 typeOfDoubleMinMax(
967                     forNode(node->child1()).m_type, forNode(node->child2()).m_type));
968             break;
969         default:
970             RELEASE_ASSERT_NOT_REACHED();
971             break;
972         }
973         break;
974     }
975             
976     case ArithMax: {
977         JSValue left = forNode(node->child1()).value();
978         JSValue right = forNode(node->child2()).value();
979         switch (node->binaryUseKind()) {
980         case Int32Use:
981             if (left && right && left.isInt32() && right.isInt32()) {
982                 setConstant(node, jsNumber(std::max(left.asInt32(), right.asInt32())));
983                 break;
984             }
985             setNonCellTypeForNode(node, SpecInt32Only);
986             break;
987         case DoubleRepUse:
988             if (left && right && left.isNumber() && right.isNumber()) {
989                 double a = left.asNumber();
990                 double b = right.asNumber();
991                 setConstant(node, jsDoubleNumber(a > b ? a : (b >= a ? b : a + b)));
992                 break;
993             }
994             setNonCellTypeForNode(node, 
995                 typeOfDoubleMinMax(
996                     forNode(node->child1()).m_type, forNode(node->child2()).m_type));
997             break;
998         default:
999             RELEASE_ASSERT_NOT_REACHED();
1000             break;
1001         }
1002         break;
1003     }
1004             
1005     case ArithAbs: {
1006         JSValue child = forNode(node->child1()).value();
1007         switch (node->child1().useKind()) {
1008         case Int32Use:
1009             if (std::optional<double> number = child.toNumberFromPrimitive()) {
1010                 JSValue result = jsNumber(fabs(*number));
1011                 if (result.isInt32()) {
1012                     setConstant(node, result);
1013                     break;
1014                 }
1015             }
1016             setNonCellTypeForNode(node, SpecInt32Only);
1017             break;
1018         case DoubleRepUse:
1019             if (std::optional<double> number = child.toNumberFromPrimitive()) {
1020                 setConstant(node, jsDoubleNumber(fabs(*number)));
1021                 break;
1022             }
1023             setNonCellTypeForNode(node, typeOfDoubleAbs(forNode(node->child1()).m_type));
1024             break;
1025         default:
1026             DFG_ASSERT(m_graph, node, node->child1().useKind() == UntypedUse, node->child1().useKind());
1027             clobberWorld();
1028             setNonCellTypeForNode(node, SpecBytecodeNumber);
1029             break;
1030         }
1031         break;
1032     }
1033
1034     case ArithPow: {
1035         JSValue childY = forNode(node->child2()).value();
1036         if (childY && childY.isNumber()) {
1037             if (!childY.asNumber()) {
1038                 setConstant(node, jsDoubleNumber(1));
1039                 break;
1040             }
1041
1042             JSValue childX = forNode(node->child1()).value();
1043             if (childX && childX.isNumber()) {
1044                 setConstant(node, jsDoubleNumber(operationMathPow(childX.asNumber(), childY.asNumber())));
1045                 break;
1046             }
1047         }
1048         setNonCellTypeForNode(node, typeOfDoublePow(forNode(node->child1()).m_type, forNode(node->child2()).m_type));
1049         break;
1050     }
1051
1052     case ArithRandom: {
1053         setNonCellTypeForNode(node, SpecDoubleReal);
1054         break;
1055     }
1056
1057     case ArithRound:
1058     case ArithFloor:
1059     case ArithCeil:
1060     case ArithTrunc: {
1061         JSValue operand = forNode(node->child1()).value();
1062         if (std::optional<double> number = operand.toNumberFromPrimitive()) {
1063             if (node->child1().useKind() != DoubleRepUse)
1064                 didFoldClobberWorld();
1065             
1066             double roundedValue = 0;
1067             if (node->op() == ArithRound)
1068                 roundedValue = jsRound(*number);
1069             else if (node->op() == ArithFloor)
1070                 roundedValue = floor(*number);
1071             else if (node->op() == ArithCeil)
1072                 roundedValue = ceil(*number);
1073             else {
1074                 ASSERT(node->op() == ArithTrunc);
1075                 roundedValue = trunc(*number);
1076             }
1077
1078             if (node->child1().useKind() == UntypedUse) {
1079                 setConstant(node, jsNumber(roundedValue));
1080                 break;
1081             }
1082             if (producesInteger(node->arithRoundingMode())) {
1083                 int32_t roundedValueAsInt32 = static_cast<int32_t>(roundedValue);
1084                 if (roundedValueAsInt32 == roundedValue) {
1085                     if (shouldCheckNegativeZero(node->arithRoundingMode())) {
1086                         if (roundedValueAsInt32 || !std::signbit(roundedValue)) {
1087                             setConstant(node, jsNumber(roundedValueAsInt32));
1088                             break;
1089                         }
1090                     } else {
1091                         setConstant(node, jsNumber(roundedValueAsInt32));
1092                         break;
1093                     }
1094                 }
1095             } else {
1096                 setConstant(node, jsDoubleNumber(roundedValue));
1097                 break;
1098             }
1099         }
1100         if (node->child1().useKind() == DoubleRepUse) {
1101             if (producesInteger(node->arithRoundingMode()))
1102                 setNonCellTypeForNode(node, SpecInt32Only);
1103             else if (node->child1().useKind() == DoubleRepUse)
1104                 setNonCellTypeForNode(node, typeOfDoubleRounding(forNode(node->child1()).m_type));
1105         } else {
1106             DFG_ASSERT(m_graph, node, node->child1().useKind() == UntypedUse, node->child1().useKind());
1107             clobberWorld();
1108             setNonCellTypeForNode(node, SpecBytecodeNumber);
1109         }
1110         break;
1111     }
1112             
1113     case ArithSqrt:
1114         executeDoubleUnaryOpEffects(node, sqrt);
1115         break;
1116
1117     case ArithFRound:
1118         executeDoubleUnaryOpEffects(node, [](double value) -> double { return static_cast<float>(value); });
1119         break;
1120         
1121     case ArithUnary:
1122         executeDoubleUnaryOpEffects(node, arithUnaryFunction(node->arithUnaryType()));
1123         break;
1124             
1125     case LogicalNot: {
1126         switch (booleanResult(node, forNode(node->child1()))) {
1127         case DefinitelyTrue:
1128             setConstant(node, jsBoolean(false));
1129             break;
1130         case DefinitelyFalse:
1131             setConstant(node, jsBoolean(true));
1132             break;
1133         default:
1134             setNonCellTypeForNode(node, SpecBoolean);
1135             break;
1136         }
1137         break;
1138     }
1139
1140     case MapHash: {
1141         if (JSValue key = forNode(node->child1()).value()) {
1142             if (std::optional<uint32_t> hash = concurrentJSMapHash(key)) {
1143                 // Although C++ code uses uint32_t for the hash, the closest type in DFG IR is Int32
1144                 // and that's what MapHash returns. So, we have to cast to int32_t to avoid large
1145                 // unsigned values becoming doubles. This casting between signed and unsigned
1146                 // happens in the assembly code we emit when we don't constant fold this node.
1147                 setConstant(node, jsNumber(static_cast<int32_t>(*hash)));
1148                 break;
1149             }
1150         }
1151         setNonCellTypeForNode(node, SpecInt32Only);
1152         break;
1153     }
1154
1155     case NormalizeMapKey: {
1156         if (JSValue key = forNode(node->child1()).value()) {
1157             setConstant(node, *m_graph.freeze(normalizeMapKey(key)));
1158             break;
1159         }
1160
1161         SpeculatedType typeMaybeNormalized = (SpecFullNumber & ~SpecInt32Only);
1162         if (!(forNode(node->child1()).m_type & typeMaybeNormalized)) {
1163             m_state.setFoundConstants(true);
1164             forNode(node) = forNode(node->child1());
1165             break;
1166         }
1167
1168         makeHeapTopForNode(node);
1169         break;
1170     }
1171
1172     case StringSlice: {
1173         setTypeForNode(node, SpecString);
1174         break;
1175     }
1176
1177     case ToLowerCase: {
1178         setTypeForNode(node, SpecString);
1179         break;
1180     }
1181
1182     case LoadKeyFromMapBucket:
1183     case LoadValueFromMapBucket:
1184     case ExtractValueFromWeakMapGet:
1185         makeHeapTopForNode(node);
1186         break;
1187
1188     case GetMapBucket:
1189     case GetMapBucketHead:
1190         if (node->child1().useKind() == MapObjectUse)
1191             setForNode(node, m_vm.hashMapBucketMapStructure.get());
1192         else {
1193             ASSERT(node->child1().useKind() == SetObjectUse);
1194             setForNode(node, m_vm.hashMapBucketSetStructure.get());
1195         }
1196         break;
1197
1198     case GetMapBucketNext:
1199         if (node->bucketOwnerType() == BucketOwnerType::Map)
1200             setForNode(node, m_vm.hashMapBucketMapStructure.get());
1201         else {
1202             ASSERT(node->bucketOwnerType() == BucketOwnerType::Set);
1203             setForNode(node, m_vm.hashMapBucketSetStructure.get());
1204         }
1205         break;
1206
1207     case SetAdd:
1208         setForNode(node, m_vm.hashMapBucketSetStructure.get());
1209         break;
1210
1211     case MapSet:
1212         setForNode(node, m_vm.hashMapBucketMapStructure.get());
1213         break;
1214
1215     case WeakSetAdd:
1216     case WeakMapSet:
1217         break;
1218
1219     case WeakMapGet:
1220         makeBytecodeTopForNode(node);
1221         break;
1222
1223     case IsEmpty:
1224     case IsUndefined:
1225     case IsBoolean:
1226     case IsNumber:
1227     case NumberIsInteger:
1228     case IsObject:
1229     case IsObjectOrNull:
1230     case IsFunction:
1231     case IsCellWithType:
1232     case IsTypedArrayView: {
1233         AbstractValue child = forNode(node->child1());
1234         if (child.value()) {
1235             bool constantWasSet = true;
1236             switch (node->op()) {
1237             case IsCellWithType:
1238                 setConstant(node, jsBoolean(child.value().isCell() && child.value().asCell()->type() == node->queriedType()));
1239                 break;
1240             case IsUndefined:
1241                 setConstant(node, jsBoolean(
1242                     child.value().isCell()
1243                     ? child.value().asCell()->structure()->masqueradesAsUndefined(m_codeBlock->globalObjectFor(node->origin.semantic))
1244                     : child.value().isUndefined()));
1245                 break;
1246             case IsBoolean:
1247                 setConstant(node, jsBoolean(child.value().isBoolean()));
1248                 break;
1249             case IsNumber:
1250                 setConstant(node, jsBoolean(child.value().isNumber()));
1251                 break;
1252             case NumberIsInteger:
1253                 setConstant(node, jsBoolean(NumberConstructor::isIntegerImpl(child.value())));
1254                 break;
1255             case IsObject:
1256                 setConstant(node, jsBoolean(child.value().isObject()));
1257                 break;
1258             case IsObjectOrNull:
1259                 if (child.value().isObject()) {
1260                     JSObject* object = asObject(child.value());
1261                     if (object->type() == JSFunctionType)
1262                         setConstant(node, jsBoolean(false));
1263                     else if (!(object->inlineTypeFlags() & OverridesGetCallData))
1264                         setConstant(node, jsBoolean(!child.value().asCell()->structure()->masqueradesAsUndefined(m_codeBlock->globalObjectFor(node->origin.semantic))));
1265                     else {
1266                         // FIXME: This could just call getCallData.
1267                         // https://bugs.webkit.org/show_bug.cgi?id=144457
1268                         constantWasSet = false;
1269                     }
1270                 } else
1271                     setConstant(node, jsBoolean(child.value().isNull()));
1272                 break;
1273             case IsFunction:
1274                 if (child.value().isObject()) {
1275                     JSObject* object = asObject(child.value());
1276                     if (object->type() == JSFunctionType)
1277                         setConstant(node, jsBoolean(true));
1278                     else if (!(object->inlineTypeFlags() & OverridesGetCallData))
1279                         setConstant(node, jsBoolean(false));
1280                     else {
1281                         // FIXME: This could just call getCallData.
1282                         // https://bugs.webkit.org/show_bug.cgi?id=144457
1283                         constantWasSet = false;
1284                     }
1285                 } else
1286                     setConstant(node, jsBoolean(false));
1287                 break;
1288             case IsEmpty:
1289                 setConstant(node, jsBoolean(child.value().isEmpty()));
1290                 break;
1291             case IsTypedArrayView:
1292                 setConstant(node, jsBoolean(child.value().isObject() && isTypedView(child.value().getObject()->classInfo(m_vm)->typedArrayStorageType)));
1293                 break;
1294             default:
1295                 constantWasSet = false;
1296                 break;
1297             }
1298             if (constantWasSet)
1299                 break;
1300         }
1301         
1302         // FIXME: This code should really use AbstractValue::isType() and
1303         // AbstractValue::couldBeType().
1304         // https://bugs.webkit.org/show_bug.cgi?id=146870
1305         
1306         bool constantWasSet = false;
1307         switch (node->op()) {
1308         case IsEmpty: {
1309             if (child.m_type && !(child.m_type & SpecEmpty)) {
1310                 setConstant(node, jsBoolean(false));
1311                 constantWasSet = true;
1312                 break;
1313             }
1314
1315             if (child.m_type && !(child.m_type & ~SpecEmpty)) {
1316                 setConstant(node, jsBoolean(true));
1317                 constantWasSet = true;
1318                 break;
1319             }
1320
1321             break;
1322         }
1323         case IsUndefined:
1324             // FIXME: Use the masquerades-as-undefined watchpoint thingy.
1325             // https://bugs.webkit.org/show_bug.cgi?id=144456
1326             
1327             if (!(child.m_type & (SpecOther | SpecObjectOther))) {
1328                 setConstant(node, jsBoolean(false));
1329                 constantWasSet = true;
1330                 break;
1331             }
1332             
1333             break;
1334         case IsBoolean:
1335             if (!(child.m_type & ~SpecBoolean)) {
1336                 setConstant(node, jsBoolean(true));
1337                 constantWasSet = true;
1338                 break;
1339             }
1340             
1341             if (!(child.m_type & SpecBoolean)) {
1342                 setConstant(node, jsBoolean(false));
1343                 constantWasSet = true;
1344                 break;
1345             }
1346             
1347             break;
1348         case IsNumber:
1349             if (!(child.m_type & ~SpecFullNumber)) {
1350                 setConstant(node, jsBoolean(true));
1351                 constantWasSet = true;
1352                 break;
1353             }
1354             
1355             if (!(child.m_type & SpecFullNumber)) {
1356                 setConstant(node, jsBoolean(false));
1357                 constantWasSet = true;
1358                 break;
1359             }
1360             
1361             break;
1362
1363         case NumberIsInteger:
1364             if (!(child.m_type & ~SpecInt32Only)) {
1365                 setConstant(node, jsBoolean(true));
1366                 constantWasSet = true;
1367                 break;
1368             }
1369             
1370             if (!(child.m_type & SpecFullNumber)) {
1371                 setConstant(node, jsBoolean(false));
1372                 constantWasSet = true;
1373                 break;
1374             }
1375             
1376             break;
1377
1378         case IsObject:
1379             if (!(child.m_type & ~SpecObject)) {
1380                 setConstant(node, jsBoolean(true));
1381                 constantWasSet = true;
1382                 break;
1383             }
1384             
1385             if (!(child.m_type & SpecObject)) {
1386                 setConstant(node, jsBoolean(false));
1387                 constantWasSet = true;
1388                 break;
1389             }
1390             
1391             break;
1392         case IsObjectOrNull:
1393             // FIXME: Use the masquerades-as-undefined watchpoint thingy.
1394             // https://bugs.webkit.org/show_bug.cgi?id=144456
1395             
1396             // These expressions are complicated to parse. A helpful way to parse this is that
1397             // "!(T & ~S)" means "T is a subset of S". Conversely, "!(T & S)" means "T is a
1398             // disjoint set from S". Things like "T - S" means that, provided that S is a
1399             // subset of T, it's the "set of all things in T but not in S". Things like "T | S"
1400             // mean the "union of T and S".
1401             
1402             // Is the child's type an object that isn't an other-object (i.e. object that could
1403             // have masquaredes-as-undefined traps) and isn't a function?  Then: we should fold
1404             // this to true.
1405             if (!(child.m_type & ~(SpecObject - SpecObjectOther - SpecFunction))) {
1406                 setConstant(node, jsBoolean(true));
1407                 constantWasSet = true;
1408                 break;
1409             }
1410             
1411             // Is the child's type definitely not either of: an object that isn't a function,
1412             // or either undefined or null?  Then: we should fold this to false.  This means
1413             // for example that if it's any non-function object, including those that have
1414             // masquerades-as-undefined traps, then we don't fold. It also means we won't fold
1415             // if it's undefined-or-null, since the type bits don't distinguish between
1416             // undefined (which should fold to false) and null (which should fold to true).
1417             if (!(child.m_type & ((SpecObject - SpecFunction) | SpecOther))) {
1418                 setConstant(node, jsBoolean(false));
1419                 constantWasSet = true;
1420                 break;
1421             }
1422             
1423             break;
1424         case IsFunction:
1425             if (!(child.m_type & ~SpecFunction)) {
1426                 setConstant(node, jsBoolean(true));
1427                 constantWasSet = true;
1428                 break;
1429             }
1430             
1431             if (!(child.m_type & (SpecFunction | SpecObjectOther | SpecProxyObject))) {
1432                 setConstant(node, jsBoolean(false));
1433                 constantWasSet = true;
1434                 break;
1435             }
1436             break;
1437
1438         case IsCellWithType:
1439             if (!(child.m_type & ~node->speculatedTypeForQuery())) {
1440                 setConstant(node, jsBoolean(true));
1441                 constantWasSet = true;
1442                 break;
1443             }
1444             if (!(child.m_type & node->speculatedTypeForQuery())) {
1445                 setConstant(node, jsBoolean(false));
1446                 constantWasSet = true;
1447                 break;
1448             }
1449             break;
1450
1451         case IsTypedArrayView:
1452             if (!(child.m_type & ~SpecTypedArrayView)) {
1453                 setConstant(node, jsBoolean(true));
1454                 constantWasSet = true;
1455                 break;
1456             }
1457             if (!(child.m_type & SpecTypedArrayView)) {
1458                 setConstant(node, jsBoolean(false));
1459                 constantWasSet = true;
1460                 break;
1461             }
1462             break;
1463
1464         default:
1465             break;
1466         }
1467         if (constantWasSet)
1468             break;
1469         
1470         setNonCellTypeForNode(node, SpecBoolean);
1471         break;
1472     }
1473
1474     case TypeOf: {
1475         JSValue child = forNode(node->child1()).value();
1476         AbstractValue& abstractChild = forNode(node->child1());
1477         if (child) {
1478             JSValue typeString = jsTypeStringForValue(m_vm, m_codeBlock->globalObjectFor(node->origin.semantic), child);
1479             setConstant(node, *m_graph.freeze(typeString));
1480             break;
1481         }
1482         
1483         if (isFullNumberSpeculation(abstractChild.m_type)) {
1484             setConstant(node, *m_graph.freeze(m_vm.smallStrings.numberString()));
1485             break;
1486         }
1487         
1488         if (isStringSpeculation(abstractChild.m_type)) {
1489             setConstant(node, *m_graph.freeze(m_vm.smallStrings.stringString()));
1490             break;
1491         }
1492
1493         // FIXME: We could use the masquerades-as-undefined watchpoint here.
1494         // https://bugs.webkit.org/show_bug.cgi?id=144456
1495         if (!(abstractChild.m_type & ~(SpecObject - SpecObjectOther - SpecFunction))) {
1496             setConstant(node, *m_graph.freeze(m_vm.smallStrings.objectString()));
1497             break;
1498         }
1499         
1500         if (isFunctionSpeculation(abstractChild.m_type)) {
1501             setConstant(node, *m_graph.freeze(m_vm.smallStrings.functionString()));
1502             break;
1503         }
1504         
1505         if (isBooleanSpeculation(abstractChild.m_type)) {
1506             setConstant(node, *m_graph.freeze(m_vm.smallStrings.booleanString()));
1507             break;
1508         }
1509
1510         if (isSymbolSpeculation(abstractChild.m_type)) {
1511             setConstant(node, *m_graph.freeze(m_vm.smallStrings.symbolString()));
1512             break;
1513         }
1514
1515         if (isBigIntSpeculation(abstractChild.m_type)) {
1516             setConstant(node, *m_graph.freeze(m_vm.smallStrings.bigintString()));
1517             break;
1518         }
1519
1520         setTypeForNode(node, SpecStringIdent);
1521         break;
1522     }
1523
1524     case CompareBelow:
1525     case CompareBelowEq: {
1526         JSValue leftConst = forNode(node->child1()).value();
1527         JSValue rightConst = forNode(node->child2()).value();
1528         if (leftConst && rightConst) {
1529             if (leftConst.isInt32() && rightConst.isInt32()) {
1530                 uint32_t a = static_cast<uint32_t>(leftConst.asInt32());
1531                 uint32_t b = static_cast<uint32_t>(rightConst.asInt32());
1532                 switch (node->op()) {
1533                 case CompareBelow:
1534                     setConstant(node, jsBoolean(a < b));
1535                     break;
1536                 case CompareBelowEq:
1537                     setConstant(node, jsBoolean(a <= b));
1538                     break;
1539                 default:
1540                     RELEASE_ASSERT_NOT_REACHED();
1541                     break;
1542                 }
1543                 break;
1544             }
1545         }
1546
1547         if (node->child1() == node->child2()) {
1548             switch (node->op()) {
1549             case CompareBelow:
1550                 setConstant(node, jsBoolean(false));
1551                 break;
1552             case CompareBelowEq:
1553                 setConstant(node, jsBoolean(true));
1554                 break;
1555             default:
1556                 DFG_CRASH(m_graph, node, "Unexpected node type");
1557                 break;
1558             }
1559             break;
1560         }
1561         setNonCellTypeForNode(node, SpecBoolean);
1562         break;
1563     }
1564
1565     case CompareLess:
1566     case CompareLessEq:
1567     case CompareGreater:
1568     case CompareGreaterEq:
1569     case CompareEq: {
1570         bool isClobbering = node->isBinaryUseKind(UntypedUse);
1571         
1572         if (isClobbering)
1573             didFoldClobberWorld();
1574         
1575         JSValue leftConst = forNode(node->child1()).value();
1576         JSValue rightConst = forNode(node->child2()).value();
1577         if (leftConst && rightConst) {
1578             if (leftConst.isNumber() && rightConst.isNumber()) {
1579                 double a = leftConst.asNumber();
1580                 double b = rightConst.asNumber();
1581                 switch (node->op()) {
1582                 case CompareLess:
1583                     setConstant(node, jsBoolean(a < b));
1584                     break;
1585                 case CompareLessEq:
1586                     setConstant(node, jsBoolean(a <= b));
1587                     break;
1588                 case CompareGreater:
1589                     setConstant(node, jsBoolean(a > b));
1590                     break;
1591                 case CompareGreaterEq:
1592                     setConstant(node, jsBoolean(a >= b));
1593                     break;
1594                 case CompareEq:
1595                     setConstant(node, jsBoolean(a == b));
1596                     break;
1597                 default:
1598                     RELEASE_ASSERT_NOT_REACHED();
1599                     break;
1600                 }
1601                 break;
1602             }
1603             
1604             if (leftConst.isString() && rightConst.isString()) {
1605                 const StringImpl* a = asString(leftConst)->tryGetValueImpl();
1606                 const StringImpl* b = asString(rightConst)->tryGetValueImpl();
1607                 if (a && b) {
1608                     bool result;
1609                     if (node->op() == CompareEq)
1610                         result = WTF::equal(a, b);
1611                     else if (node->op() == CompareLess)
1612                         result = codePointCompare(a, b) < 0;
1613                     else if (node->op() == CompareLessEq)
1614                         result = codePointCompare(a, b) <= 0;
1615                     else if (node->op() == CompareGreater)
1616                         result = codePointCompare(a, b) > 0;
1617                     else if (node->op() == CompareGreaterEq)
1618                         result = codePointCompare(a, b) >= 0;
1619                     else
1620                         RELEASE_ASSERT_NOT_REACHED();
1621                     setConstant(node, jsBoolean(result));
1622                     break;
1623                 }
1624             }
1625
1626             if (node->op() == CompareEq && leftConst.isSymbol() && rightConst.isSymbol()) {
1627                 setConstant(node, jsBoolean(asSymbol(leftConst) == asSymbol(rightConst)));
1628                 break;
1629             }
1630         }
1631         
1632         if (node->op() == CompareEq) {
1633             SpeculatedType leftType = forNode(node->child1()).m_type;
1634             SpeculatedType rightType = forNode(node->child2()).m_type;
1635             if (!valuesCouldBeEqual(leftType, rightType)) {
1636                 setConstant(node, jsBoolean(false));
1637                 break;
1638             }
1639
1640             if (leftType == SpecOther)
1641                 std::swap(leftType, rightType);
1642             if (rightType == SpecOther) {
1643                 // Undefined and Null are always equal when compared to eachother.
1644                 if (!(leftType & ~SpecOther)) {
1645                     setConstant(node, jsBoolean(true));
1646                     break;
1647                 }
1648
1649                 // Any other type compared to Null or Undefined is always false
1650                 // as long as the MasqueradesAsUndefined watchpoint is valid.
1651                 //
1652                 // MasqueradesAsUndefined only matters for SpecObjectOther, other
1653                 // cases are always "false".
1654                 if (!(leftType & (SpecObjectOther | SpecOther))) {
1655                     setConstant(node, jsBoolean(false));
1656                     break;
1657                 }
1658
1659                 if (!(leftType & SpecOther) && m_graph.masqueradesAsUndefinedWatchpointIsStillValid(node->origin.semantic)) {
1660                     JSGlobalObject* globalObject = m_graph.globalObjectFor(node->origin.semantic);
1661                     m_graph.watchpoints().addLazily(globalObject->masqueradesAsUndefinedWatchpoint());
1662                     setConstant(node, jsBoolean(false));
1663                     break;
1664                 }
1665             }
1666         }
1667         
1668         if (node->child1() == node->child2()) {
1669             if (node->isBinaryUseKind(Int32Use) ||
1670                 node->isBinaryUseKind(Int52RepUse) ||
1671                 node->isBinaryUseKind(StringUse) ||
1672                 node->isBinaryUseKind(BooleanUse) ||
1673                 node->isBinaryUseKind(SymbolUse) ||
1674                 node->isBinaryUseKind(StringIdentUse) ||
1675                 node->isBinaryUseKind(ObjectUse) ||
1676                 node->isBinaryUseKind(ObjectUse, ObjectOrOtherUse) ||
1677                 node->isBinaryUseKind(ObjectOrOtherUse, ObjectUse)) {
1678                 switch (node->op()) {
1679                 case CompareLess:
1680                 case CompareGreater:
1681                     setConstant(node, jsBoolean(false));
1682                     break;
1683                 case CompareLessEq:
1684                 case CompareGreaterEq:
1685                 case CompareEq:
1686                     setConstant(node, jsBoolean(true));
1687                     break;
1688                 default:
1689                     DFG_CRASH(m_graph, node, "Unexpected node type");
1690                     break;
1691                 }
1692                 break;
1693             }
1694         }
1695
1696         if (isClobbering)
1697             clobberWorld();
1698         setNonCellTypeForNode(node, SpecBoolean);
1699         break;
1700     }
1701             
1702     case CompareStrictEq:
1703     case SameValue: {
1704         Node* leftNode = node->child1().node();
1705         Node* rightNode = node->child2().node();
1706         JSValue left = forNode(leftNode).value();
1707         JSValue right = forNode(rightNode).value();
1708         if (left && right) {
1709             if (left.isString() && right.isString()) {
1710                 // We need this case because JSValue::strictEqual is otherwise too racy for
1711                 // string comparisons.
1712                 const StringImpl* a = asString(left)->tryGetValueImpl();
1713                 const StringImpl* b = asString(right)->tryGetValueImpl();
1714                 if (a && b) {
1715                     setConstant(node, jsBoolean(WTF::equal(a, b)));
1716                     break;
1717                 }
1718             } else {
1719                 if (node->op() == CompareStrictEq)
1720                     setConstant(node, jsBoolean(JSValue::strictEqual(nullptr, left, right)));
1721                 else
1722                     setConstant(node, jsBoolean(sameValue(nullptr, left, right)));
1723                 break;
1724             }
1725         }
1726
1727         if (node->isBinaryUseKind(UntypedUse)) {
1728             // FIXME: Revisit this condition when introducing BigInt to JSC.
1729             auto isNonStringCellConstant = [] (JSValue value) {
1730                 return value && value.isCell() && !value.isString();
1731             };
1732
1733             if (isNonStringCellConstant(left) || isNonStringCellConstant(right)) {
1734                 m_state.setFoundConstants(true);
1735                 setNonCellTypeForNode(node, SpecBoolean);
1736                 break;
1737             }
1738         }
1739         
1740         SpeculatedType leftLUB = leastUpperBoundOfStrictlyEquivalentSpeculations(forNode(leftNode).m_type);
1741         SpeculatedType rightLUB = leastUpperBoundOfStrictlyEquivalentSpeculations(forNode(rightNode).m_type);
1742         if (!(leftLUB & rightLUB)) {
1743             setConstant(node, jsBoolean(false));
1744             break;
1745         }
1746         
1747         if (node->child1() == node->child2()) {
1748             if (node->isBinaryUseKind(BooleanUse) ||
1749                 node->isBinaryUseKind(Int32Use) ||
1750                 node->isBinaryUseKind(Int52RepUse) ||
1751                 node->isBinaryUseKind(StringUse) ||
1752                 node->isBinaryUseKind(StringIdentUse) ||
1753                 node->isBinaryUseKind(SymbolUse) ||
1754                 node->isBinaryUseKind(ObjectUse) ||
1755                 node->isBinaryUseKind(MiscUse, UntypedUse) ||
1756                 node->isBinaryUseKind(UntypedUse, MiscUse) ||
1757                 node->isBinaryUseKind(StringIdentUse, NotStringVarUse) ||
1758                 node->isBinaryUseKind(NotStringVarUse, StringIdentUse) ||
1759                 node->isBinaryUseKind(StringUse, UntypedUse) ||
1760                 node->isBinaryUseKind(UntypedUse, StringUse)) {
1761                 setConstant(node, jsBoolean(true));
1762                 break;
1763             }
1764         }
1765
1766         setNonCellTypeForNode(node, SpecBoolean);
1767         break;
1768     }
1769         
1770     case CompareEqPtr: {
1771         Node* childNode = node->child1().node();
1772         JSValue childValue = forNode(childNode).value();
1773         if (childValue) {
1774             setConstant(node, jsBoolean(childValue.isCell() && childValue.asCell() == node->cellOperand()->cell()));
1775             break;
1776         }
1777         
1778         setNonCellTypeForNode(node, SpecBoolean);
1779         break;
1780     }
1781         
1782     case StringCharCodeAt:
1783         setNonCellTypeForNode(node, SpecInt32Only);
1784         break;
1785         
1786     case StringFromCharCode:
1787         switch (node->child1().useKind()) {
1788         case Int32Use:
1789             break;
1790         case UntypedUse:
1791             clobberWorld();
1792             break;
1793         default:
1794             DFG_CRASH(m_graph, node, "Bad use kind");
1795             break;
1796         }
1797         setTypeForNode(node, SpecString);
1798         break;
1799
1800     case StringCharAt:
1801         setForNode(node, m_vm.stringStructure.get());
1802         break;
1803             
1804     case GetByVal:
1805     case AtomicsAdd:
1806     case AtomicsAnd:
1807     case AtomicsCompareExchange:
1808     case AtomicsExchange:
1809     case AtomicsLoad:
1810     case AtomicsOr:
1811     case AtomicsStore:
1812     case AtomicsSub:
1813     case AtomicsXor: {
1814         if (node->op() != GetByVal)
1815             clobberWorld();
1816         switch (node->arrayMode().type()) {
1817         case Array::SelectUsingPredictions:
1818         case Array::Unprofiled:
1819         case Array::SelectUsingArguments:
1820             RELEASE_ASSERT_NOT_REACHED();
1821             break;
1822         case Array::ForceExit:
1823             m_state.setIsValid(false);
1824             break;
1825         case Array::Undecided: {
1826             JSValue index = forNode(m_graph.child(node, 1)).value();
1827             if (index && index.isInt32() && index.asInt32() >= 0) {
1828                 setConstant(node, jsUndefined());
1829                 break;
1830             }
1831             setNonCellTypeForNode(node, SpecOther);
1832             break;
1833         }
1834         case Array::Generic:
1835             clobberWorld();
1836             makeHeapTopForNode(node);
1837             break;
1838         case Array::String:
1839             if (node->arrayMode().isOutOfBounds()) {
1840                 // If the watchpoint was still valid we could totally set this to be
1841                 // SpecString | SpecOther. Except that we'd have to be careful. If we
1842                 // tested the watchpoint state here then it could change by the time
1843                 // we got to the backend. So to do this right, we'd have to get the
1844                 // fixup phase to check the watchpoint state and then bake into the
1845                 // GetByVal operation the fact that we're using a watchpoint, using
1846                 // something like Array::SaneChain (except not quite, because that
1847                 // implies an in-bounds access). None of this feels like it's worth it,
1848                 // so we're going with TOP for now. The same thing applies to
1849                 // clobbering the world.
1850                 clobberWorld();
1851                 makeHeapTopForNode(node);
1852             } else
1853                 setForNode(node, m_vm.stringStructure.get());
1854             break;
1855         case Array::DirectArguments:
1856         case Array::ScopedArguments:
1857             if (node->arrayMode().isOutOfBounds())
1858                 clobberWorld();
1859             makeHeapTopForNode(node);
1860             break;
1861         case Array::Int32:
1862             if (node->arrayMode().isOutOfBounds()) {
1863                 clobberWorld();
1864                 makeHeapTopForNode(node);
1865             } else
1866                 setNonCellTypeForNode(node, SpecInt32Only);
1867             break;
1868         case Array::Double:
1869             if (node->arrayMode().isOutOfBounds()) {
1870                 clobberWorld();
1871                 makeHeapTopForNode(node);
1872             } else if (node->arrayMode().isSaneChain())
1873                 setNonCellTypeForNode(node, SpecBytecodeDouble);
1874             else
1875                 setNonCellTypeForNode(node, SpecDoubleReal);
1876             break;
1877         case Array::Contiguous:
1878         case Array::ArrayStorage:
1879         case Array::SlowPutArrayStorage:
1880             if (node->arrayMode().isOutOfBounds())
1881                 clobberWorld();
1882             makeHeapTopForNode(node);
1883             break;
1884         case Array::Int8Array:
1885             setNonCellTypeForNode(node, SpecInt32Only);
1886             break;
1887         case Array::Int16Array:
1888             setNonCellTypeForNode(node, SpecInt32Only);
1889             break;
1890         case Array::Int32Array:
1891             setNonCellTypeForNode(node, SpecInt32Only);
1892             break;
1893         case Array::Uint8Array:
1894             setNonCellTypeForNode(node, SpecInt32Only);
1895             break;
1896         case Array::Uint8ClampedArray:
1897             setNonCellTypeForNode(node, SpecInt32Only);
1898             break;
1899         case Array::Uint16Array:
1900             setNonCellTypeForNode(node, SpecInt32Only);
1901             break;
1902         case Array::Uint32Array:
1903             if (node->shouldSpeculateInt32())
1904                 setNonCellTypeForNode(node, SpecInt32Only);
1905             else if (enableInt52() && node->shouldSpeculateAnyInt())
1906                 setNonCellTypeForNode(node, SpecAnyInt);
1907             else
1908                 setNonCellTypeForNode(node, SpecAnyIntAsDouble);
1909             break;
1910         case Array::Float32Array:
1911             setNonCellTypeForNode(node, SpecFullDouble);
1912             break;
1913         case Array::Float64Array:
1914             setNonCellTypeForNode(node, SpecFullDouble);
1915             break;
1916         default:
1917             RELEASE_ASSERT_NOT_REACHED();
1918             break;
1919         }
1920         break;
1921     }
1922             
1923     case PutByValDirect:
1924     case PutByVal:
1925     case PutByValAlias: {
1926         switch (node->arrayMode().modeForPut().type()) {
1927         case Array::ForceExit:
1928             m_state.setIsValid(false);
1929             break;
1930         case Array::Generic:
1931             clobberWorld();
1932             break;
1933         case Array::Int32:
1934             if (node->arrayMode().isOutOfBounds())
1935                 clobberWorld();
1936             break;
1937         case Array::Double:
1938             if (node->arrayMode().isOutOfBounds())
1939                 clobberWorld();
1940             break;
1941         case Array::Contiguous:
1942         case Array::ArrayStorage:
1943             if (node->arrayMode().isOutOfBounds())
1944                 clobberWorld();
1945             break;
1946         case Array::SlowPutArrayStorage:
1947             if (node->arrayMode().mayStoreToHole())
1948                 clobberWorld();
1949             break;
1950         default:
1951             break;
1952         }
1953         break;
1954     }
1955             
1956     case ArrayPush:
1957         clobberWorld();
1958         setNonCellTypeForNode(node, SpecBytecodeNumber);
1959         break;
1960
1961     case ArraySlice: {
1962         JSGlobalObject* globalObject = m_graph.globalObjectFor(node->origin.semantic);
1963
1964         // FIXME: We could do better here if we prove that the
1965         // incoming value has only a single structure.
1966         RegisteredStructureSet structureSet;
1967         structureSet.add(m_graph.registerStructure(globalObject->originalArrayStructureForIndexingType(ArrayWithInt32)));
1968         structureSet.add(m_graph.registerStructure(globalObject->originalArrayStructureForIndexingType(ArrayWithContiguous)));
1969         structureSet.add(m_graph.registerStructure(globalObject->originalArrayStructureForIndexingType(ArrayWithDouble)));
1970
1971         setForNode(node, structureSet);
1972         break;
1973     }
1974
1975     case ArrayIndexOf: {
1976         setNonCellTypeForNode(node, SpecInt32Only);
1977         break;
1978     }
1979             
1980     case ArrayPop:
1981         clobberWorld();
1982         makeHeapTopForNode(node);
1983         break;
1984         
1985     case GetMyArgumentByVal:
1986     case GetMyArgumentByValOutOfBounds: {
1987         JSValue index = forNode(node->child2()).m_value;
1988         InlineCallFrame* inlineCallFrame = node->child1()->origin.semantic.inlineCallFrame;
1989
1990         if (index && index.isUInt32()) {
1991             // This pretends to return TOP for accesses that are actually proven out-of-bounds because
1992             // that's the conservative thing to do. Otherwise we'd need to write more code to mark such
1993             // paths as unreachable, or to return undefined. We could implement that eventually.
1994
1995             Checked<unsigned, RecordOverflow> argumentIndexChecked = index.asUInt32();
1996             argumentIndexChecked += node->numberOfArgumentsToSkip();
1997             unsigned argumentIndex;
1998             if (argumentIndexChecked.safeGet(argumentIndex) != CheckedState::DidOverflow) {
1999                 if (inlineCallFrame) {
2000                     if (argumentIndex < inlineCallFrame->argumentCountIncludingThis - 1) {
2001                         setForNode(node, m_state.operand(
2002                             virtualRegisterForArgument(argumentIndex + 1) + inlineCallFrame->stackOffset));
2003                         m_state.setFoundConstants(true);
2004                         break;
2005                     }
2006                 } else {
2007                     if (argumentIndex < m_state.numberOfArguments() - 1) {
2008                         setForNode(node, m_state.argument(argumentIndex + 1));
2009                         m_state.setFoundConstants(true);
2010                         break;
2011                     }
2012                 }
2013             }
2014         }
2015         
2016         if (inlineCallFrame) {
2017             // We have a bound on the types even though it's random access. Take advantage of this.
2018             
2019             AbstractValue result;
2020             for (unsigned i = 1 + node->numberOfArgumentsToSkip(); i < inlineCallFrame->argumentCountIncludingThis; ++i) {
2021                 result.merge(
2022                     m_state.operand(
2023                         virtualRegisterForArgument(i) + inlineCallFrame->stackOffset));
2024             }
2025             
2026             if (node->op() == GetMyArgumentByValOutOfBounds)
2027                 result.merge(SpecOther);
2028             
2029             if (result.value())
2030                 m_state.setFoundConstants(true);
2031             
2032             setForNode(node, result);
2033             break;
2034         }
2035         
2036         makeHeapTopForNode(node);
2037         break;
2038     }
2039             
2040     case RegExpExec:
2041     case RegExpExecNonGlobalOrSticky:
2042         if (node->op() == RegExpExec) {
2043             // Even if we've proven known input types as RegExpObject and String,
2044             // accessing lastIndex is effectful if it's a global regexp.
2045             clobberWorld();
2046         }
2047
2048         if (JSValue globalObjectValue = forNode(node->child1()).m_value) {
2049             if (JSGlobalObject* globalObject = jsDynamicCast<JSGlobalObject*>(m_vm, globalObjectValue)) {
2050                 if (!globalObject->isHavingABadTime()) {
2051                     m_graph.watchpoints().addLazily(globalObject->havingABadTimeWatchpoint());
2052                     RegisteredStructureSet structureSet;
2053                     structureSet.add(m_graph.registerStructure(globalObject->regExpMatchesArrayStructure()));
2054                     structureSet.add(m_graph.registerStructure(globalObject->regExpMatchesArrayWithGroupsStructure()));
2055                     setForNode(node, structureSet);
2056                     forNode(node).merge(SpecOther);
2057                     break;
2058                 }
2059             }
2060         }
2061         setTypeForNode(node, SpecOther | SpecArray);
2062         break;
2063
2064     case RegExpTest:
2065         // Even if we've proven known input types as RegExpObject and String,
2066         // accessing lastIndex is effectful if it's a global regexp.
2067         clobberWorld();
2068         setNonCellTypeForNode(node, SpecBoolean);
2069         break;
2070
2071     case RegExpMatchFast:
2072         ASSERT(node->child2().useKind() == RegExpObjectUse);
2073         ASSERT(node->child3().useKind() == StringUse);
2074         setTypeForNode(node, SpecOther | SpecArray);
2075         break;
2076
2077     case RegExpMatchFastGlobal:
2078         ASSERT(node->child2().useKind() == StringUse);
2079         setTypeForNode(node, SpecOther | SpecArray);
2080         break;
2081             
2082     case StringReplace:
2083     case StringReplaceRegExp:
2084         if (node->child1().useKind() == StringUse
2085             && node->child2().useKind() == RegExpObjectUse
2086             && node->child3().useKind() == StringUse) {
2087             // This doesn't clobber the world. It just reads and writes regexp state.
2088         } else
2089             clobberWorld();
2090         setForNode(node, m_vm.stringStructure.get());
2091         break;
2092
2093     case Jump:
2094         break;
2095             
2096     case Branch: {
2097         Node* child = node->child1().node();
2098         BooleanResult result = booleanResult(node, forNode(child));
2099         if (result == DefinitelyTrue) {
2100             m_state.setBranchDirection(TakeTrue);
2101             break;
2102         }
2103         if (result == DefinitelyFalse) {
2104             m_state.setBranchDirection(TakeFalse);
2105             break;
2106         }
2107         // FIXME: The above handles the trivial cases of sparse conditional
2108         // constant propagation, but we can do better:
2109         // We can specialize the source variable's value on each direction of
2110         // the branch.
2111         m_state.setBranchDirection(TakeBoth);
2112         break;
2113     }
2114         
2115     case Switch: {
2116         // Nothing to do for now.
2117         // FIXME: Do sparse conditional things.
2118         break;
2119     }
2120
2121     case EntrySwitch:
2122         break;
2123
2124     case Return:
2125         m_state.setIsValid(false);
2126         break;
2127
2128     case Throw:
2129     case ThrowStaticError:
2130     case TailCall:
2131     case DirectTailCall:
2132     case TailCallVarargs:
2133     case TailCallForwardVarargs:
2134         clobberWorld();
2135         m_state.setIsValid(false);
2136         break;
2137         
2138     case ToPrimitive: {
2139         JSValue childConst = forNode(node->child1()).value();
2140         if (childConst && childConst.isNumber()) {
2141             didFoldClobberWorld();
2142             setConstant(node, childConst);
2143             break;
2144         }
2145         
2146         ASSERT(node->child1().useKind() == UntypedUse);
2147         
2148         if (!(forNode(node->child1()).m_type & ~(SpecFullNumber | SpecBoolean | SpecString | SpecSymbol | SpecBigInt))) {
2149             m_state.setFoundConstants(true);
2150             didFoldClobberWorld();
2151             setForNode(node, forNode(node->child1()));
2152             break;
2153         }
2154         
2155         clobberWorld();
2156         
2157         setTypeForNode(node, SpecHeapTop & ~SpecObject);
2158         break;
2159     }
2160
2161     case ToNumber: {
2162         JSValue childConst = forNode(node->child1()).value();
2163         if (childConst && childConst.isNumber()) {
2164             didFoldClobberWorld();
2165             setConstant(node, childConst);
2166             break;
2167         }
2168
2169         ASSERT(node->child1().useKind() == UntypedUse);
2170
2171         if (!(forNode(node->child1()).m_type & ~SpecBytecodeNumber)) {
2172             m_state.setFoundConstants(true);
2173             didFoldClobberWorld();
2174             setForNode(node, forNode(node->child1()));
2175             break;
2176         }
2177
2178         clobberWorld();
2179         setNonCellTypeForNode(node, SpecBytecodeNumber);
2180         break;
2181     }
2182         
2183     case ToString:
2184     case CallStringConstructor: {
2185         switch (node->child1().useKind()) {
2186         case StringObjectUse:
2187             // This also filters that the StringObject has the primordial StringObject
2188             // structure.
2189             filter(
2190                 node->child1(),
2191                 m_graph.registerStructure(m_graph.globalObjectFor(node->origin.semantic)->stringObjectStructure()));
2192             break;
2193         case StringOrStringObjectUse:
2194         case Int32Use:
2195         case Int52RepUse:
2196         case DoubleRepUse:
2197         case NotCellUse:
2198             break;
2199         case CellUse:
2200         case UntypedUse:
2201             clobberWorld();
2202             break;
2203         default:
2204             RELEASE_ASSERT_NOT_REACHED();
2205             break;
2206         }
2207         setForNode(node, m_vm.stringStructure.get());
2208         break;
2209     }
2210
2211     case NumberToStringWithRadix: {
2212         JSValue radixValue = forNode(node->child2()).m_value;
2213         if (radixValue && radixValue.isInt32()) {
2214             int32_t radix = radixValue.asInt32();
2215             if (2 <= radix && radix <= 36) {
2216                 m_state.setFoundConstants(true);
2217                 didFoldClobberWorld();
2218                 setForNode(node, m_graph.m_vm.stringStructure.get());
2219                 break;
2220             }
2221         }
2222         clobberWorld();
2223         setForNode(node, m_graph.m_vm.stringStructure.get());
2224         break;
2225     }
2226
2227     case NumberToStringWithValidRadixConstant: {
2228         setForNode(node, m_graph.m_vm.stringStructure.get());
2229         break;
2230     }
2231         
2232     case NewStringObject: {
2233         ASSERT(node->structure()->classInfo() == StringObject::info());
2234         setForNode(node, node->structure());
2235         break;
2236     }
2237             
2238     case NewArray:
2239         setForNode(node, 
2240             m_graph.globalObjectFor(node->origin.semantic)->arrayStructureForIndexingTypeDuringAllocation(node->indexingType()));
2241         break;
2242
2243     case NewArrayWithSpread:
2244         if (m_graph.isWatchingHavingABadTimeWatchpoint(node)) {
2245             // We've compiled assuming we're not having a bad time, so to be consistent
2246             // with StructureRegisterationPhase we must say we produce an original array
2247             // allocation structure.
2248             setForNode(node, 
2249                 m_graph.globalObjectFor(node->origin.semantic)->originalArrayStructureForIndexingType(ArrayWithContiguous));
2250         } else {
2251             setForNode(node, 
2252                 m_graph.globalObjectFor(node->origin.semantic)->arrayStructureForIndexingTypeDuringAllocation(ArrayWithContiguous));
2253         }
2254
2255         break;
2256
2257     case Spread:
2258         switch (node->child1()->op()) {
2259         case PhantomNewArrayBuffer:
2260         case PhantomCreateRest:
2261             break;
2262         default:
2263             if (!m_graph.canDoFastSpread(node, forNode(node->child1())))
2264                 clobberWorld();
2265             else
2266                 didFoldClobberWorld();
2267             break;
2268         }
2269
2270         setForNode(node, 
2271             m_vm.fixedArrayStructure.get());
2272         break;
2273         
2274     case NewArrayBuffer:
2275         setForNode(node, 
2276             m_graph.globalObjectFor(node->origin.semantic)->arrayStructureForIndexingTypeDuringAllocation(node->indexingType()));
2277         break;
2278
2279     case NewArrayWithSize:
2280         setTypeForNode(node, SpecArray);
2281         break;
2282         
2283     case NewTypedArray:
2284         switch (node->child1().useKind()) {
2285         case Int32Use:
2286             break;
2287         case UntypedUse:
2288             clobberWorld();
2289             break;
2290         default:
2291             RELEASE_ASSERT_NOT_REACHED();
2292             break;
2293         }
2294         setForNode(node, 
2295             m_graph.globalObjectFor(node->origin.semantic)->typedArrayStructureConcurrently(
2296                 node->typedArrayType()));
2297         break;
2298         
2299     case NewRegexp:
2300         setForNode(node, m_graph.globalObjectFor(node->origin.semantic)->regExpStructure());
2301         break;
2302             
2303     case ToThis: {
2304         AbstractValue& source = forNode(node->child1());
2305         AbstractValue& destination = forNode(node);
2306         bool strictMode = m_graph.executableFor(node->origin.semantic)->isStrictMode();
2307
2308         ToThisResult result = isToThisAnIdentity(m_vm, strictMode, source);
2309         if (result != ToThisResult::Dynamic) {
2310             switch (result) {
2311             case ToThisResult::Identity:
2312                 m_state.setFoundConstants(true);
2313                 destination = source;
2314                 break;
2315             case ToThisResult::Undefined:
2316                 setConstant(node, jsUndefined());
2317                 break;
2318             case ToThisResult::GlobalThis:
2319                 m_state.setFoundConstants(true);
2320                 destination.setType(m_graph, SpecObject);
2321                 break;
2322             case ToThisResult::Dynamic:
2323                 RELEASE_ASSERT_NOT_REACHED();
2324             }
2325             break;
2326         }
2327
2328         if (strictMode)
2329             destination.makeHeapTop();
2330         else {
2331             destination = source;
2332             destination.merge(SpecObject);
2333         }
2334         break;
2335     }
2336
2337     case CreateThis: {
2338         if (JSValue base = forNode(node->child1()).m_value) {
2339             if (auto* function = jsDynamicCast<JSFunction*>(m_vm, base)) {
2340                 if (FunctionRareData* rareData = function->rareData()) {
2341                     if (Structure* structure = rareData->objectAllocationStructure()) {
2342                         m_graph.freeze(rareData);
2343                         m_graph.watchpoints().addLazily(rareData->allocationProfileWatchpointSet());
2344                         m_state.setFoundConstants(true);
2345                         didFoldClobberWorld();
2346                         setForNode(node, structure);
2347                         break;
2348                     }
2349                 }
2350             }
2351         }
2352         clobberWorld();
2353         setTypeForNode(node, SpecFinalObject);
2354         break;
2355     }
2356         
2357     case NewObject:
2358         ASSERT(!!node->structure().get());
2359         setForNode(node, node->structure());
2360         break;
2361
2362     case ToObject:
2363     case CallObjectConstructor: {
2364         AbstractValue& source = forNode(node->child1());
2365         AbstractValue& destination = forNode(node);
2366
2367         if (!(source.m_type & ~SpecObject)) {
2368             m_state.setFoundConstants(true);
2369             if (node->op() == ToObject)
2370                 didFoldClobberWorld();
2371             destination = source;
2372             break;
2373         }
2374
2375         if (node->op() == ToObject)
2376             clobberWorld();
2377         setTypeForNode(node, SpecObject);
2378         break;
2379     }
2380
2381     case PhantomNewObject:
2382     case PhantomNewFunction:
2383     case PhantomNewGeneratorFunction:
2384     case PhantomNewAsyncGeneratorFunction:
2385     case PhantomNewAsyncFunction:
2386     case PhantomCreateActivation:
2387     case PhantomDirectArguments:
2388     case PhantomClonedArguments:
2389     case PhantomCreateRest:
2390     case PhantomSpread:
2391     case PhantomNewArrayWithSpread:
2392     case PhantomNewArrayBuffer:
2393     case PhantomNewRegexp:
2394     case BottomValue:
2395         // This claims to return bottom.
2396         break;
2397         
2398     case PutHint:
2399         break;
2400         
2401     case MaterializeNewObject: {
2402         setForNode(node, node->structureSet());
2403         break;
2404     }
2405
2406     case PushWithScope:
2407         // We don't use the more precise withScopeStructure() here because it is a LazyProperty and may not yet be allocated.
2408         setTypeForNode(node, SpecObjectOther);
2409         break;
2410
2411     case CreateActivation:
2412     case MaterializeCreateActivation:
2413         setForNode(node, 
2414             m_codeBlock->globalObjectFor(node->origin.semantic)->activationStructure());
2415         break;
2416         
2417     case CreateDirectArguments:
2418         setForNode(node, m_codeBlock->globalObjectFor(node->origin.semantic)->directArgumentsStructure());
2419         break;
2420         
2421     case CreateScopedArguments:
2422         setForNode(node, m_codeBlock->globalObjectFor(node->origin.semantic)->scopedArgumentsStructure());
2423         break;
2424         
2425     case CreateClonedArguments:
2426         if (!m_graph.isWatchingHavingABadTimeWatchpoint(node)) {
2427             setTypeForNode(node, SpecObject);
2428             break;
2429         }
2430         setForNode(node, m_codeBlock->globalObjectFor(node->origin.semantic)->clonedArgumentsStructure());
2431         break;
2432
2433     case NewGeneratorFunction:
2434         setForNode(node, 
2435             m_codeBlock->globalObjectFor(node->origin.semantic)->generatorFunctionStructure());
2436         break;
2437
2438     case NewAsyncGeneratorFunction:
2439         setForNode(node, 
2440             m_codeBlock->globalObjectFor(node->origin.semantic)->asyncGeneratorFunctionStructure());
2441         break;
2442
2443     case NewAsyncFunction:
2444         setForNode(node, 
2445             m_codeBlock->globalObjectFor(node->origin.semantic)->asyncFunctionStructure());
2446         break;
2447
2448     case NewFunction: {
2449         JSGlobalObject* globalObject = m_codeBlock->globalObjectFor(node->origin.semantic);
2450         Structure* structure = JSFunction::selectStructureForNewFuncExp(globalObject, node->castOperand<FunctionExecutable*>());
2451         setForNode(node, structure);
2452         break;
2453     }
2454         
2455     case GetCallee:
2456         if (FunctionExecutable* executable = jsDynamicCast<FunctionExecutable*>(m_vm, m_codeBlock->ownerExecutable())) {
2457             InferredValue* singleton = executable->singletonFunction();
2458             if (JSValue value = singleton->inferredValue()) {
2459                 m_graph.watchpoints().addLazily(singleton);
2460                 JSFunction* function = jsCast<JSFunction*>(value);
2461                 setConstant(node, *m_graph.freeze(function));
2462                 break;
2463             }
2464         }
2465         setTypeForNode(node, SpecFunction);
2466         break;
2467         
2468     case GetArgumentCountIncludingThis:
2469         setTypeForNode(node, SpecInt32Only);
2470         break;
2471
2472     case SetCallee:
2473     case SetArgumentCountIncludingThis:
2474         break;
2475         
2476     case GetRestLength:
2477         setNonCellTypeForNode(node, SpecInt32Only);
2478         break;
2479         
2480     case GetGetter: {
2481         JSValue base = forNode(node->child1()).m_value;
2482         if (base) {
2483             GetterSetter* getterSetter = jsCast<GetterSetter*>(base);
2484             if (!getterSetter->isGetterNull()) {
2485                 setConstant(node, *m_graph.freeze(getterSetter->getterConcurrently()));
2486                 break;
2487             }
2488         }
2489         
2490         setTypeForNode(node, SpecObject);
2491         break;
2492     }
2493         
2494     case GetSetter: {
2495         JSValue base = forNode(node->child1()).m_value;
2496         if (base) {
2497             GetterSetter* getterSetter = jsCast<GetterSetter*>(base);
2498             if (!getterSetter->isSetterNull()) {
2499                 setConstant(node, *m_graph.freeze(getterSetter->setterConcurrently()));
2500                 break;
2501             }
2502         }
2503         
2504         setTypeForNode(node, SpecObject);
2505         break;
2506     }
2507         
2508     case GetScope:
2509         if (JSValue base = forNode(node->child1()).m_value) {
2510             if (JSFunction* function = jsDynamicCast<JSFunction*>(m_vm, base)) {
2511                 setConstant(node, *m_graph.freeze(function->scope()));
2512                 break;
2513             }
2514         }
2515         setTypeForNode(node, SpecObjectOther);
2516         break;
2517
2518     case SkipScope: {
2519         JSValue child = forNode(node->child1()).value();
2520         if (child) {
2521             setConstant(node, *m_graph.freeze(JSValue(jsCast<JSScope*>(child.asCell())->next())));
2522             break;
2523         }
2524         setTypeForNode(node, SpecObjectOther);
2525         break;
2526     }
2527
2528     case GetGlobalObject: {
2529         JSValue child = forNode(node->child1()).value();
2530         if (child) {
2531             setConstant(node, *m_graph.freeze(JSValue(asObject(child)->globalObject())));
2532             break;
2533         }
2534
2535         if (forNode(node->child1()).m_structure.isFinite()) {
2536             JSGlobalObject* globalObject = nullptr;
2537             bool ok = true;
2538             forNode(node->child1()).m_structure.forEach(
2539                 [&] (RegisteredStructure structure) {
2540                     if (!globalObject)
2541                         globalObject = structure->globalObject();
2542                     else if (globalObject != structure->globalObject())
2543                         ok = false;
2544                 });
2545             if (globalObject && ok) {
2546                 setConstant(node, *m_graph.freeze(JSValue(globalObject)));
2547                 break;
2548             }
2549         }
2550
2551         setTypeForNode(node, SpecObjectOther);
2552         break;
2553     }
2554
2555     case GetGlobalThis: {
2556         setTypeForNode(node, SpecObject);
2557         break;
2558     }
2559
2560     case GetClosureVar:
2561         if (JSValue value = m_graph.tryGetConstantClosureVar(forNode(node->child1()), node->scopeOffset())) {
2562             setConstant(node, *m_graph.freeze(value));
2563             break;
2564         }
2565         makeBytecodeTopForNode(node);
2566         break;
2567             
2568     case PutClosureVar:
2569         break;
2570
2571     case GetRegExpObjectLastIndex:
2572         makeHeapTopForNode(node);
2573         break;
2574
2575     case SetRegExpObjectLastIndex:
2576     case RecordRegExpCachedResult:
2577         break;
2578         
2579     case GetFromArguments:
2580         makeHeapTopForNode(node);
2581         break;
2582         
2583     case PutToArguments:
2584         break;
2585
2586     case GetArgument:
2587         makeHeapTopForNode(node);
2588         break;
2589
2590     case TryGetById:
2591         // FIXME: This should constant fold at least as well as the normal GetById case.
2592         // https://bugs.webkit.org/show_bug.cgi?id=156422
2593         makeHeapTopForNode(node);
2594         break;
2595
2596     case GetByIdDirect:
2597     case GetByIdDirectFlush:
2598     case GetById:
2599     case GetByIdFlush: {
2600         AbstractValue& value = forNode(node->child1());
2601         if (value.m_structure.isFinite()
2602             && (node->child1().useKind() == CellUse || !(value.m_type & ~SpecCell))) {
2603             UniquedStringImpl* uid = m_graph.identifiers()[node->identifierNumber()];
2604             GetByIdStatus status = GetByIdStatus::computeFor(value.m_structure.toStructureSet(), uid);
2605             if (status.isSimple()) {
2606                 // Figure out what the result is going to be - is it TOP, a constant, or maybe
2607                 // something more subtle?
2608                 AbstractValue result;
2609                 for (unsigned i = status.numVariants(); i--;) {
2610                     // This thing won't give us a variant that involves prototypes. If it did, we'd
2611                     // have more work to do here.
2612                     DFG_ASSERT(m_graph, node, status[i].conditionSet().isEmpty());
2613
2614                     result.merge(
2615                         m_graph.inferredValueForProperty(
2616                             value, uid, status[i].offset(), m_state.structureClobberState()));
2617                 }
2618                 m_state.setFoundConstants(true);
2619                 didFoldClobberWorld();
2620                 forNode(node) = result;
2621                 break;
2622             }
2623         }
2624
2625         clobberWorld();
2626         makeHeapTopForNode(node);
2627         break;
2628     }
2629
2630     case GetByValWithThis:
2631     case GetByIdWithThis:
2632         clobberWorld();
2633         makeHeapTopForNode(node);
2634         break;
2635             
2636     case GetArrayLength: {
2637         JSArrayBufferView* view = m_graph.tryGetFoldableView(
2638             forNode(node->child1()).m_value, node->arrayMode());
2639         if (view) {
2640             setConstant(node, jsNumber(view->length()));
2641             break;
2642         }
2643         setNonCellTypeForNode(node, SpecInt32Only);
2644         break;
2645     }
2646
2647     case GetVectorLength: {
2648         setNonCellTypeForNode(node, SpecInt32Only);
2649         break;
2650     }
2651
2652     case DeleteById:
2653     case DeleteByVal: {
2654         // FIXME: This could decide if the delete will be successful based on the set of structures that
2655         // we get from our base value. https://bugs.webkit.org/show_bug.cgi?id=156611
2656         clobberWorld();
2657         setNonCellTypeForNode(node, SpecBoolean);
2658         break;
2659     }
2660         
2661     case CheckStructure: {
2662         AbstractValue& value = forNode(node->child1());
2663
2664         const RegisteredStructureSet& set = node->structureSet();
2665         
2666         // It's interesting that we could have proven that the object has a larger structure set
2667         // that includes the set we're testing. In that case we could make the structure check
2668         // more efficient. We currently don't.
2669         
2670         if (value.m_structure.isSubsetOf(set))
2671             m_state.setFoundConstants(true);
2672
2673         SpeculatedType admittedTypes = SpecNone;
2674         switch (node->child1().useKind()) {
2675         case CellUse:
2676         case KnownCellUse:
2677             admittedTypes = SpecNone;
2678             break;
2679         case CellOrOtherUse:
2680             admittedTypes = SpecOther;
2681             break;
2682         default:
2683             DFG_CRASH(m_graph, node, "Bad use kind");
2684             break;
2685         }
2686         
2687         filter(value, set, admittedTypes);
2688         break;
2689     }
2690
2691     case CheckStructureOrEmpty: {
2692         AbstractValue& value = forNode(node->child1());
2693
2694         bool mayBeEmpty = value.m_type & SpecEmpty;
2695         if (!mayBeEmpty)
2696             m_state.setFoundConstants(true);
2697
2698         SpeculatedType admittedTypes = mayBeEmpty ? SpecEmpty : SpecNone;
2699         filter(value, node->structureSet(), admittedTypes);
2700         break;
2701     }
2702         
2703     case CheckStructureImmediate: {
2704         // FIXME: This currently can only reason about one structure at a time.
2705         // https://bugs.webkit.org/show_bug.cgi?id=136988
2706         
2707         AbstractValue& value = forNode(node->child1());
2708         const RegisteredStructureSet& set = node->structureSet();
2709         
2710         if (value.value()) {
2711             if (Structure* structure = jsDynamicCast<Structure*>(m_vm, value.value())) {
2712                 if (set.contains(m_graph.registerStructure(structure))) {
2713                     m_state.setFoundConstants(true);
2714                     break;
2715                 }
2716             }
2717             m_state.setIsValid(false);
2718             break;
2719         }
2720         
2721         if (m_phiChildren) {
2722             bool allGood = true;
2723             m_phiChildren->forAllTransitiveIncomingValues(
2724                 node,
2725                 [&] (Node* incoming) {
2726                     if (Structure* structure = incoming->dynamicCastConstant<Structure*>(m_vm)) {
2727                         if (set.contains(m_graph.registerStructure(structure)))
2728                             return;
2729                     }
2730                     allGood = false;
2731                 });
2732             if (allGood) {
2733                 m_state.setFoundConstants(true);
2734                 break;
2735             }
2736         }
2737             
2738         if (RegisteredStructure structure = set.onlyStructure()) {
2739             filterByValue(node->child1(), *m_graph.freeze(structure.get()));
2740             break;
2741         }
2742         
2743         // Aw shucks, we can't do anything!
2744         break;
2745     }
2746         
2747     case PutStructure:
2748         if (!forNode(node->child1()).m_structure.isClear()) {
2749             if (forNode(node->child1()).m_structure.onlyStructure() == node->transition()->next) {
2750                 didFoldClobberStructures();
2751                 m_state.setFoundConstants(true);
2752             } else {
2753                 observeTransition(
2754                     clobberLimit, node->transition()->previous, node->transition()->next);
2755                 forNode(node->child1()).changeStructure(m_graph, node->transition()->next);
2756             }
2757         }
2758         break;
2759     case GetButterfly:
2760     case AllocatePropertyStorage:
2761     case ReallocatePropertyStorage:
2762     case NukeStructureAndSetButterfly:
2763         // FIXME: We don't model the fact that the structureID is nuked, simply because currently
2764         // nobody would currently benefit from having that information. But it's a bug nonetheless.
2765         if (node->op() == NukeStructureAndSetButterfly)
2766             didFoldClobberStructures();
2767         clearForNode(node); // The result is not a JS value.
2768         break;
2769     case CheckSubClass: {
2770         JSValue constant = forNode(node->child1()).value();
2771         if (constant) {
2772             if (constant.isCell() && constant.asCell()->inherits(m_vm, node->classInfo())) {
2773                 m_state.setFoundConstants(true);
2774                 ASSERT(constant);
2775                 break;
2776             }
2777         }
2778
2779         AbstractValue& value = forNode(node->child1());
2780
2781         if (value.m_structure.isSubClassOf(node->classInfo()))
2782             m_state.setFoundConstants(true);
2783
2784         filterClassInfo(value, node->classInfo());
2785         break;
2786     }
2787     case CallDOMGetter: {
2788         CallDOMGetterData* callDOMGetterData = node->callDOMGetterData();
2789         DOMJIT::CallDOMGetterSnippet* snippet = callDOMGetterData->snippet;
2790         if (!snippet || snippet->effect.writes)
2791             clobberWorld();
2792         if (callDOMGetterData->domJIT)
2793             setTypeForNode(node, callDOMGetterData->domJIT->resultType());
2794         else
2795             makeBytecodeTopForNode(node);
2796         break;
2797     }
2798     case CallDOM: {
2799         const DOMJIT::Signature* signature = node->signature();
2800         if (signature->effect.writes)
2801             clobberWorld();
2802         setTypeForNode(node, signature->result);
2803         break;
2804     }
2805     case CheckArray: {
2806         if (node->arrayMode().alreadyChecked(m_graph, node, forNode(node->child1()))) {
2807             m_state.setFoundConstants(true);
2808             break;
2809         }
2810         switch (node->arrayMode().type()) {
2811         case Array::String:
2812             filter(node->child1(), SpecString);
2813             break;
2814         case Array::Int32:
2815         case Array::Double:
2816         case Array::Contiguous:
2817         case Array::Undecided:
2818         case Array::ArrayStorage:
2819         case Array::SlowPutArrayStorage:
2820             break;
2821         case Array::DirectArguments:
2822             filter(node->child1(), SpecDirectArguments);
2823             break;
2824         case Array::ScopedArguments:
2825             filter(node->child1(), SpecScopedArguments);
2826             break;
2827         case Array::Int8Array:
2828             filter(node->child1(), SpecInt8Array);
2829             break;
2830         case Array::Int16Array:
2831             filter(node->child1(), SpecInt16Array);
2832             break;
2833         case Array::Int32Array:
2834             filter(node->child1(), SpecInt32Array);
2835             break;
2836         case Array::Uint8Array:
2837             filter(node->child1(), SpecUint8Array);
2838             break;
2839         case Array::Uint8ClampedArray:
2840             filter(node->child1(), SpecUint8ClampedArray);
2841             break;
2842         case Array::Uint16Array:
2843             filter(node->child1(), SpecUint16Array);
2844             break;
2845         case Array::Uint32Array:
2846             filter(node->child1(), SpecUint32Array);
2847             break;
2848         case Array::Float32Array:
2849             filter(node->child1(), SpecFloat32Array);
2850             break;
2851         case Array::Float64Array:
2852             filter(node->child1(), SpecFloat64Array);
2853             break;
2854         case Array::AnyTypedArray:
2855             filter(node->child1(), SpecTypedArrayView);
2856             break;
2857         default:
2858             RELEASE_ASSERT_NOT_REACHED();
2859             break;
2860         }
2861         filterArrayModes(node->child1(), node->arrayMode().arrayModesThatPassFiltering());
2862         break;
2863     }
2864     case Arrayify: {
2865         if (node->arrayMode().alreadyChecked(m_graph, node, forNode(node->child1()))) {
2866             didFoldClobberStructures();
2867             m_state.setFoundConstants(true);
2868             break;
2869         }
2870         ASSERT(node->arrayMode().conversion() == Array::Convert);
2871         clobberStructures();
2872         filterArrayModes(node->child1(), node->arrayMode().arrayModesThatPassFiltering());
2873         break;
2874     }
2875     case ArrayifyToStructure: {
2876         AbstractValue& value = forNode(node->child1());
2877         if (value.m_structure.isSubsetOf(RegisteredStructureSet(node->structure())))
2878             m_state.setFoundConstants(true);
2879         clobberStructures();
2880         
2881         // We have a bunch of options of how to express the abstract set at this point. Let set S
2882         // be the set of structures that the value had before clobbering and assume that all of
2883         // them are watchable. The new value should be the least expressible upper bound of the
2884         // intersection of "values that currently have structure = node->structure()" and "values
2885         // that have structure in S plus any structure transition-reachable from S". Assume that
2886         // node->structure() is not in S but it is transition-reachable from S. Then we would
2887         // like to say that the result is "values that have structure = node->structure() until
2888         // we invalidate", but there is no way to express this using the AbstractValue syntax. So
2889         // we must choose between:
2890         //
2891         // 1) "values that currently have structure = node->structure()". This is a valid
2892         //    superset of the value that we really want, and it's specific enough to satisfy the
2893         //    preconditions of the array access that this is guarding. It's also specific enough
2894         //    to allow relevant optimizations in the case that we didn't have a contradiction
2895         //    like in this example. Notice that in the abscence of any contradiction, this result
2896         //    is precise rather than being a conservative LUB.
2897         //
2898         // 2) "values that currently hava structure in S plus any structure transition-reachable
2899         //    from S". This is also a valid superset of the value that we really want, but it's
2900         //    not specific enough to satisfy the preconditions of the array access that this is
2901         //    guarding - so playing such shenanigans would preclude us from having assertions on
2902         //    the typing preconditions of any array accesses. This would also not be a desirable
2903         //    answer in the absence of a contradiction.
2904         //
2905         // Note that it's tempting to simply say that the resulting value is BOTTOM because of
2906         // the contradiction. That would be wrong, since we haven't hit an invalidation point,
2907         // yet.
2908         forNode(node->child1()).set(m_graph, node->structure());
2909         break;
2910     }
2911     case GetIndexedPropertyStorage: {
2912         JSArrayBufferView* view = m_graph.tryGetFoldableView(
2913             forNode(node->child1()).m_value, node->arrayMode());
2914         if (view)
2915             m_state.setFoundConstants(true);
2916         clearForNode(node);
2917         break;
2918     }
2919     case ConstantStoragePointer: {
2920         clearForNode(node);
2921         break; 
2922     }
2923         
2924     case GetTypedArrayByteOffset: {
2925         JSArrayBufferView* view = m_graph.tryGetFoldableView(forNode(node->child1()).m_value);
2926         if (view) {
2927             setConstant(node, jsNumber(view->byteOffset()));
2928             break;
2929         }
2930         setNonCellTypeForNode(node, SpecInt32Only);
2931         break;
2932     }
2933
2934     case GetPrototypeOf: {
2935         AbstractValue& value = forNode(node->child1());
2936         if ((value.m_type && !(value.m_type & ~SpecObject)) && value.m_structure.isFinite()) {
2937             bool canFold = !value.m_structure.isClear();
2938             JSValue prototype;
2939             value.m_structure.forEach([&] (RegisteredStructure structure) {
2940                 auto getPrototypeMethod = structure->classInfo()->methodTable.getPrototype;
2941                 MethodTable::GetPrototypeFunctionPtr defaultGetPrototype = JSObject::getPrototype;
2942                 if (getPrototypeMethod != defaultGetPrototype) {
2943                     canFold = false;
2944                     return;
2945                 }
2946
2947                 if (structure->hasPolyProto()) {
2948                     canFold = false;
2949                     return;
2950                 }
2951                 if (!prototype)
2952                     prototype = structure->storedPrototype();
2953                 else if (prototype != structure->storedPrototype())
2954                     canFold = false;
2955             });
2956
2957             if (prototype && canFold) {
2958                 switch (node->child1().useKind()) {
2959                 case ArrayUse:
2960                 case FunctionUse:
2961                 case FinalObjectUse:
2962                     break;
2963                 default:
2964                     didFoldClobberWorld();
2965                     break;
2966                 }
2967                 setConstant(node, *m_graph.freeze(prototype));
2968                 break;
2969             }
2970         }
2971
2972         switch (node->child1().useKind()) {
2973         case ArrayUse:
2974         case FunctionUse:
2975         case FinalObjectUse:
2976             break;
2977         default:
2978             clobberWorld();
2979             break;
2980         }
2981         setTypeForNode(node, SpecObject | SpecOther);
2982         break;
2983     }
2984         
2985     case GetByOffset: {
2986         StorageAccessData& data = node->storageAccessData();
2987         UniquedStringImpl* uid = m_graph.identifiers()[data.identifierNumber];
2988
2989         // FIXME: The part of this that handles inferred property types relies on AI knowing the structure
2990         // right now. That's probably not optimal. In some cases, we may perform an optimization (usually
2991         // by something other than AI, maybe by CSE for example) that obscures AI's view of the structure
2992         // at the point where GetByOffset runs. Currently, when that happens, we'll have to rely entirely
2993         // on the type that ByteCodeParser was able to prove.
2994         AbstractValue value = m_graph.inferredValueForProperty(
2995             forNode(node->child2()), uid, data.offset, m_state.structureClobberState());
2996
2997         // It's possible that the type that ByteCodeParser came up with is better.
2998         AbstractValue typeFromParsing;
2999         typeFromParsing.set(m_graph, data.inferredType, m_state.structureClobberState());
3000         value.filter(typeFromParsing);
3001
3002         // If we decide that there does not exist any value that this can return, then it's probably
3003         // because the compilation was already invalidated.
3004         if (value.isClear())
3005             m_state.setIsValid(false);
3006
3007         setForNode(node, value);
3008         if (value.m_value)
3009             m_state.setFoundConstants(true);
3010         break;
3011     }
3012         
3013     case GetGetterSetterByOffset: {
3014         StorageAccessData& data = node->storageAccessData();
3015         JSValue result = m_graph.tryGetConstantProperty(forNode(node->child2()), data.offset);
3016         if (result && jsDynamicCast<GetterSetter*>(m_vm, result)) {
3017             setConstant(node, *m_graph.freeze(result));
3018             break;
3019         }
3020         
3021         setForNode(node, m_graph.globalObjectFor(node->origin.semantic)->getterSetterStructure());
3022         break;
3023     }
3024         
3025     case MultiGetByOffset: {
3026         // This code will filter the base value in a manner that is possibly different (either more
3027         // or less precise) than the way it would be filtered if this was strength-reduced to a
3028         // CheckStructure. This is fine. It's legal for different passes over the code to prove
3029         // different things about the code, so long as all of them are sound. That even includes
3030         // one guy proving that code should never execute (due to a contradiction) and another guy
3031         // not finding that contradiction. If someone ever proved that there would be a
3032         // contradiction then there must always be a contradiction even if subsequent passes don't
3033         // realize it. This is the case here.