d490d421b0e8ed2ba6629a462660a251b10a6692
[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 ValueNegate: {
765         clobberWorld();
766         setTypeForNode(node, SpecBytecodeNumber | SpecBigInt);
767         break;
768     }
769
770     case ArithNegate: {
771         JSValue child = forNode(node->child1()).value();
772         switch (node->child1().useKind()) {
773         case Int32Use:
774             if (child && child.isInt32()) {
775                 if (!shouldCheckOverflow(node->arithMode())) {
776                     setConstant(node, jsNumber(-child.asInt32()));
777                     break;
778                 }
779                 double doubleResult;
780                 if (shouldCheckNegativeZero(node->arithMode()))
781                     doubleResult = -child.asNumber();
782                 else
783                     doubleResult = 0 - child.asNumber();
784                 JSValue valueResult = jsNumber(doubleResult);
785                 if (valueResult.isInt32()) {
786                     setConstant(node, valueResult);
787                     break;
788                 }
789             }
790             setNonCellTypeForNode(node, SpecInt32Only);
791             break;
792         case Int52RepUse:
793             if (child && child.isAnyInt()) {
794                 double doubleResult;
795                 if (shouldCheckNegativeZero(node->arithMode()))
796                     doubleResult = -child.asNumber();
797                 else
798                     doubleResult = 0 - child.asNumber();
799                 JSValue valueResult = jsNumber(doubleResult);
800                 if (valueResult.isAnyInt()) {
801                     setConstant(node, valueResult);
802                     break;
803                 }
804             }
805             setNonCellTypeForNode(node, SpecAnyInt);
806             break;
807         case DoubleRepUse:
808             if (child && child.isNumber()) {
809                 setConstant(node, jsDoubleNumber(-child.asNumber()));
810                 break;
811             }
812             setNonCellTypeForNode(node, 
813                 typeOfDoubleNegation(
814                     forNode(node->child1()).m_type));
815             break;
816         default:
817             RELEASE_ASSERT_NOT_REACHED();
818             break;
819         }
820         break;
821     }
822         
823     case ArithMul: {
824         JSValue left = forNode(node->child1()).value();
825         JSValue right = forNode(node->child2()).value();
826         switch (node->binaryUseKind()) {
827         case Int32Use:
828             if (left && right && left.isInt32() && right.isInt32()) {
829                 if (!shouldCheckOverflow(node->arithMode())) {
830                     setConstant(node, jsNumber(left.asInt32() * right.asInt32()));
831                     break;
832                 }
833                 double doubleResult = left.asNumber() * right.asNumber();
834                 if (!shouldCheckNegativeZero(node->arithMode()))
835                     doubleResult += 0; // Sanitizes zero.
836                 JSValue valueResult = jsNumber(doubleResult);
837                 if (valueResult.isInt32()) {
838                     setConstant(node, valueResult);
839                     break;
840                 }
841             }
842             setNonCellTypeForNode(node, SpecInt32Only);
843             break;
844         case Int52RepUse:
845             if (left && right && left.isAnyInt() && right.isAnyInt()) {
846                 double doubleResult = left.asNumber() * right.asNumber();
847                 if (!shouldCheckNegativeZero(node->arithMode()))
848                     doubleResult += 0;
849                 JSValue valueResult = jsNumber(doubleResult);
850                 if (valueResult.isAnyInt()) {
851                     setConstant(node, valueResult);
852                     break;
853                 }
854             }
855             setNonCellTypeForNode(node, SpecAnyInt);
856             break;
857         case DoubleRepUse:
858             if (left && right && left.isNumber() && right.isNumber()) {
859                 setConstant(node, jsDoubleNumber(left.asNumber() * right.asNumber()));
860                 break;
861             }
862             setNonCellTypeForNode(node, 
863                 typeOfDoubleProduct(
864                     forNode(node->child1()).m_type, forNode(node->child2()).m_type));
865             break;
866         case UntypedUse:
867             clobberWorld();
868             setNonCellTypeForNode(node, SpecBytecodeNumber);
869             break;
870         default:
871             RELEASE_ASSERT_NOT_REACHED();
872             break;
873         }
874         break;
875     }
876         
877     case ArithDiv: {
878         JSValue left = forNode(node->child1()).value();
879         JSValue right = forNode(node->child2()).value();
880         switch (node->binaryUseKind()) {
881         case Int32Use:
882             if (left && right && left.isInt32() && right.isInt32()) {
883                 double doubleResult = left.asNumber() / right.asNumber();
884                 if (!shouldCheckOverflow(node->arithMode()))
885                     doubleResult = toInt32(doubleResult);
886                 else if (!shouldCheckNegativeZero(node->arithMode()))
887                     doubleResult += 0; // Sanitizes zero.
888                 JSValue valueResult = jsNumber(doubleResult);
889                 if (valueResult.isInt32()) {
890                     setConstant(node, valueResult);
891                     break;
892                 }
893             }
894             setNonCellTypeForNode(node, SpecInt32Only);
895             break;
896         case DoubleRepUse:
897             if (left && right && left.isNumber() && right.isNumber()) {
898                 setConstant(node, jsDoubleNumber(left.asNumber() / right.asNumber()));
899                 break;
900             }
901             setNonCellTypeForNode(node, 
902                 typeOfDoubleQuotient(
903                     forNode(node->child1()).m_type, forNode(node->child2()).m_type));
904             break;
905         case UntypedUse:
906             clobberWorld();
907             setNonCellTypeForNode(node, SpecBytecodeNumber);
908             break;
909         default:
910             RELEASE_ASSERT_NOT_REACHED();
911             break;
912         }
913         break;
914     }
915
916     case ArithMod: {
917         JSValue left = forNode(node->child1()).value();
918         JSValue right = forNode(node->child2()).value();
919         switch (node->binaryUseKind()) {
920         case Int32Use:
921             if (left && right && left.isInt32() && right.isInt32()) {
922                 double doubleResult = fmod(left.asNumber(), right.asNumber());
923                 if (!shouldCheckOverflow(node->arithMode()))
924                     doubleResult = toInt32(doubleResult);
925                 else if (!shouldCheckNegativeZero(node->arithMode()))
926                     doubleResult += 0; // Sanitizes zero.
927                 JSValue valueResult = jsNumber(doubleResult);
928                 if (valueResult.isInt32()) {
929                     setConstant(node, valueResult);
930                     break;
931                 }
932             }
933             setNonCellTypeForNode(node, SpecInt32Only);
934             break;
935         case DoubleRepUse:
936             if (left && right && left.isNumber() && right.isNumber()) {
937                 setConstant(node, jsDoubleNumber(fmod(left.asNumber(), right.asNumber())));
938                 break;
939             }
940             setNonCellTypeForNode(node, 
941                 typeOfDoubleBinaryOp(
942                     forNode(node->child1()).m_type, forNode(node->child2()).m_type));
943             break;
944         default:
945             RELEASE_ASSERT_NOT_REACHED();
946             break;
947         }
948         break;
949     }
950
951     case ArithMin: {
952         JSValue left = forNode(node->child1()).value();
953         JSValue right = forNode(node->child2()).value();
954         switch (node->binaryUseKind()) {
955         case Int32Use:
956             if (left && right && left.isInt32() && right.isInt32()) {
957                 setConstant(node, jsNumber(std::min(left.asInt32(), right.asInt32())));
958                 break;
959             }
960             setNonCellTypeForNode(node, SpecInt32Only);
961             break;
962         case DoubleRepUse:
963             if (left && right && left.isNumber() && right.isNumber()) {
964                 double a = left.asNumber();
965                 double b = right.asNumber();
966                 setConstant(node, jsDoubleNumber(a < b ? a : (b <= a ? b : a + b)));
967                 break;
968             }
969             setNonCellTypeForNode(node, 
970                 typeOfDoubleMinMax(
971                     forNode(node->child1()).m_type, forNode(node->child2()).m_type));
972             break;
973         default:
974             RELEASE_ASSERT_NOT_REACHED();
975             break;
976         }
977         break;
978     }
979             
980     case ArithMax: {
981         JSValue left = forNode(node->child1()).value();
982         JSValue right = forNode(node->child2()).value();
983         switch (node->binaryUseKind()) {
984         case Int32Use:
985             if (left && right && left.isInt32() && right.isInt32()) {
986                 setConstant(node, jsNumber(std::max(left.asInt32(), right.asInt32())));
987                 break;
988             }
989             setNonCellTypeForNode(node, SpecInt32Only);
990             break;
991         case DoubleRepUse:
992             if (left && right && left.isNumber() && right.isNumber()) {
993                 double a = left.asNumber();
994                 double b = right.asNumber();
995                 setConstant(node, jsDoubleNumber(a > b ? a : (b >= a ? b : a + b)));
996                 break;
997             }
998             setNonCellTypeForNode(node, 
999                 typeOfDoubleMinMax(
1000                     forNode(node->child1()).m_type, forNode(node->child2()).m_type));
1001             break;
1002         default:
1003             RELEASE_ASSERT_NOT_REACHED();
1004             break;
1005         }
1006         break;
1007     }
1008             
1009     case ArithAbs: {
1010         JSValue child = forNode(node->child1()).value();
1011         switch (node->child1().useKind()) {
1012         case Int32Use:
1013             if (std::optional<double> number = child.toNumberFromPrimitive()) {
1014                 JSValue result = jsNumber(fabs(*number));
1015                 if (result.isInt32()) {
1016                     setConstant(node, result);
1017                     break;
1018                 }
1019             }
1020             setNonCellTypeForNode(node, SpecInt32Only);
1021             break;
1022         case DoubleRepUse:
1023             if (std::optional<double> number = child.toNumberFromPrimitive()) {
1024                 setConstant(node, jsDoubleNumber(fabs(*number)));
1025                 break;
1026             }
1027             setNonCellTypeForNode(node, typeOfDoubleAbs(forNode(node->child1()).m_type));
1028             break;
1029         default:
1030             DFG_ASSERT(m_graph, node, node->child1().useKind() == UntypedUse, node->child1().useKind());
1031             clobberWorld();
1032             setNonCellTypeForNode(node, SpecBytecodeNumber);
1033             break;
1034         }
1035         break;
1036     }
1037
1038     case ArithPow: {
1039         JSValue childY = forNode(node->child2()).value();
1040         if (childY && childY.isNumber()) {
1041             if (!childY.asNumber()) {
1042                 setConstant(node, jsDoubleNumber(1));
1043                 break;
1044             }
1045
1046             JSValue childX = forNode(node->child1()).value();
1047             if (childX && childX.isNumber()) {
1048                 setConstant(node, jsDoubleNumber(operationMathPow(childX.asNumber(), childY.asNumber())));
1049                 break;
1050             }
1051         }
1052         setNonCellTypeForNode(node, typeOfDoublePow(forNode(node->child1()).m_type, forNode(node->child2()).m_type));
1053         break;
1054     }
1055
1056     case ArithRandom: {
1057         setNonCellTypeForNode(node, SpecDoubleReal);
1058         break;
1059     }
1060
1061     case ArithRound:
1062     case ArithFloor:
1063     case ArithCeil:
1064     case ArithTrunc: {
1065         JSValue operand = forNode(node->child1()).value();
1066         if (std::optional<double> number = operand.toNumberFromPrimitive()) {
1067             if (node->child1().useKind() != DoubleRepUse)
1068                 didFoldClobberWorld();
1069             
1070             double roundedValue = 0;
1071             if (node->op() == ArithRound)
1072                 roundedValue = jsRound(*number);
1073             else if (node->op() == ArithFloor)
1074                 roundedValue = floor(*number);
1075             else if (node->op() == ArithCeil)
1076                 roundedValue = ceil(*number);
1077             else {
1078                 ASSERT(node->op() == ArithTrunc);
1079                 roundedValue = trunc(*number);
1080             }
1081
1082             if (node->child1().useKind() == UntypedUse) {
1083                 setConstant(node, jsNumber(roundedValue));
1084                 break;
1085             }
1086             if (producesInteger(node->arithRoundingMode())) {
1087                 int32_t roundedValueAsInt32 = static_cast<int32_t>(roundedValue);
1088                 if (roundedValueAsInt32 == roundedValue) {
1089                     if (shouldCheckNegativeZero(node->arithRoundingMode())) {
1090                         if (roundedValueAsInt32 || !std::signbit(roundedValue)) {
1091                             setConstant(node, jsNumber(roundedValueAsInt32));
1092                             break;
1093                         }
1094                     } else {
1095                         setConstant(node, jsNumber(roundedValueAsInt32));
1096                         break;
1097                     }
1098                 }
1099             } else {
1100                 setConstant(node, jsDoubleNumber(roundedValue));
1101                 break;
1102             }
1103         }
1104         if (node->child1().useKind() == DoubleRepUse) {
1105             if (producesInteger(node->arithRoundingMode()))
1106                 setNonCellTypeForNode(node, SpecInt32Only);
1107             else if (node->child1().useKind() == DoubleRepUse)
1108                 setNonCellTypeForNode(node, typeOfDoubleRounding(forNode(node->child1()).m_type));
1109         } else {
1110             DFG_ASSERT(m_graph, node, node->child1().useKind() == UntypedUse, node->child1().useKind());
1111             clobberWorld();
1112             setNonCellTypeForNode(node, SpecBytecodeNumber);
1113         }
1114         break;
1115     }
1116             
1117     case ArithSqrt:
1118         executeDoubleUnaryOpEffects(node, sqrt);
1119         break;
1120
1121     case ArithFRound:
1122         executeDoubleUnaryOpEffects(node, [](double value) -> double { return static_cast<float>(value); });
1123         break;
1124         
1125     case ArithUnary:
1126         executeDoubleUnaryOpEffects(node, arithUnaryFunction(node->arithUnaryType()));
1127         break;
1128             
1129     case LogicalNot: {
1130         switch (booleanResult(node, forNode(node->child1()))) {
1131         case DefinitelyTrue:
1132             setConstant(node, jsBoolean(false));
1133             break;
1134         case DefinitelyFalse:
1135             setConstant(node, jsBoolean(true));
1136             break;
1137         default:
1138             setNonCellTypeForNode(node, SpecBoolean);
1139             break;
1140         }
1141         break;
1142     }
1143
1144     case MapHash: {
1145         if (JSValue key = forNode(node->child1()).value()) {
1146             if (std::optional<uint32_t> hash = concurrentJSMapHash(key)) {
1147                 // Although C++ code uses uint32_t for the hash, the closest type in DFG IR is Int32
1148                 // and that's what MapHash returns. So, we have to cast to int32_t to avoid large
1149                 // unsigned values becoming doubles. This casting between signed and unsigned
1150                 // happens in the assembly code we emit when we don't constant fold this node.
1151                 setConstant(node, jsNumber(static_cast<int32_t>(*hash)));
1152                 break;
1153             }
1154         }
1155         setNonCellTypeForNode(node, SpecInt32Only);
1156         break;
1157     }
1158
1159     case NormalizeMapKey: {
1160         if (JSValue key = forNode(node->child1()).value()) {
1161             setConstant(node, *m_graph.freeze(normalizeMapKey(key)));
1162             break;
1163         }
1164
1165         SpeculatedType typeMaybeNormalized = (SpecFullNumber & ~SpecInt32Only);
1166         if (!(forNode(node->child1()).m_type & typeMaybeNormalized)) {
1167             m_state.setFoundConstants(true);
1168             forNode(node) = forNode(node->child1());
1169             break;
1170         }
1171
1172         makeHeapTopForNode(node);
1173         break;
1174     }
1175
1176     case StringSlice: {
1177         setTypeForNode(node, SpecString);
1178         break;
1179     }
1180
1181     case ToLowerCase: {
1182         setTypeForNode(node, SpecString);
1183         break;
1184     }
1185
1186     case LoadKeyFromMapBucket:
1187     case LoadValueFromMapBucket:
1188     case ExtractValueFromWeakMapGet:
1189         makeHeapTopForNode(node);
1190         break;
1191
1192     case GetMapBucket:
1193     case GetMapBucketHead:
1194         if (node->child1().useKind() == MapObjectUse)
1195             setForNode(node, m_vm.hashMapBucketMapStructure.get());
1196         else {
1197             ASSERT(node->child1().useKind() == SetObjectUse);
1198             setForNode(node, m_vm.hashMapBucketSetStructure.get());
1199         }
1200         break;
1201
1202     case GetMapBucketNext:
1203         if (node->bucketOwnerType() == BucketOwnerType::Map)
1204             setForNode(node, m_vm.hashMapBucketMapStructure.get());
1205         else {
1206             ASSERT(node->bucketOwnerType() == BucketOwnerType::Set);
1207             setForNode(node, m_vm.hashMapBucketSetStructure.get());
1208         }
1209         break;
1210
1211     case SetAdd:
1212         setForNode(node, m_vm.hashMapBucketSetStructure.get());
1213         break;
1214
1215     case MapSet:
1216         setForNode(node, m_vm.hashMapBucketMapStructure.get());
1217         break;
1218
1219     case WeakSetAdd:
1220     case WeakMapSet:
1221         break;
1222
1223     case WeakMapGet:
1224         makeBytecodeTopForNode(node);
1225         break;
1226
1227     case IsEmpty:
1228     case IsUndefined:
1229     case IsBoolean:
1230     case IsNumber:
1231     case NumberIsInteger:
1232     case IsObject:
1233     case IsObjectOrNull:
1234     case IsFunction:
1235     case IsCellWithType:
1236     case IsTypedArrayView: {
1237         AbstractValue child = forNode(node->child1());
1238         if (child.value()) {
1239             bool constantWasSet = true;
1240             switch (node->op()) {
1241             case IsCellWithType:
1242                 setConstant(node, jsBoolean(child.value().isCell() && child.value().asCell()->type() == node->queriedType()));
1243                 break;
1244             case IsUndefined:
1245                 setConstant(node, jsBoolean(
1246                     child.value().isCell()
1247                     ? child.value().asCell()->structure(m_vm)->masqueradesAsUndefined(m_codeBlock->globalObjectFor(node->origin.semantic))
1248                     : child.value().isUndefined()));
1249                 break;
1250             case IsBoolean:
1251                 setConstant(node, jsBoolean(child.value().isBoolean()));
1252                 break;
1253             case IsNumber:
1254                 setConstant(node, jsBoolean(child.value().isNumber()));
1255                 break;
1256             case NumberIsInteger:
1257                 setConstant(node, jsBoolean(NumberConstructor::isIntegerImpl(child.value())));
1258                 break;
1259             case IsObject:
1260                 setConstant(node, jsBoolean(child.value().isObject()));
1261                 break;
1262             case IsObjectOrNull:
1263                 if (child.value().isObject()) {
1264                     JSObject* object = asObject(child.value());
1265                     if (object->type() == JSFunctionType)
1266                         setConstant(node, jsBoolean(false));
1267                     else if (!(object->inlineTypeFlags() & OverridesGetCallData))
1268                         setConstant(node, jsBoolean(!child.value().asCell()->structure(m_vm)->masqueradesAsUndefined(m_codeBlock->globalObjectFor(node->origin.semantic))));
1269                     else {
1270                         // FIXME: This could just call getCallData.
1271                         // https://bugs.webkit.org/show_bug.cgi?id=144457
1272                         constantWasSet = false;
1273                     }
1274                 } else
1275                     setConstant(node, jsBoolean(child.value().isNull()));
1276                 break;
1277             case IsFunction:
1278                 if (child.value().isObject()) {
1279                     JSObject* object = asObject(child.value());
1280                     if (object->type() == JSFunctionType)
1281                         setConstant(node, jsBoolean(true));
1282                     else if (!(object->inlineTypeFlags() & OverridesGetCallData))
1283                         setConstant(node, jsBoolean(false));
1284                     else {
1285                         // FIXME: This could just call getCallData.
1286                         // https://bugs.webkit.org/show_bug.cgi?id=144457
1287                         constantWasSet = false;
1288                     }
1289                 } else
1290                     setConstant(node, jsBoolean(false));
1291                 break;
1292             case IsEmpty:
1293                 setConstant(node, jsBoolean(child.value().isEmpty()));
1294                 break;
1295             case IsTypedArrayView:
1296                 setConstant(node, jsBoolean(child.value().isObject() && isTypedView(child.value().getObject()->classInfo(m_vm)->typedArrayStorageType)));
1297                 break;
1298             default:
1299                 constantWasSet = false;
1300                 break;
1301             }
1302             if (constantWasSet)
1303                 break;
1304         }
1305         
1306         // FIXME: This code should really use AbstractValue::isType() and
1307         // AbstractValue::couldBeType().
1308         // https://bugs.webkit.org/show_bug.cgi?id=146870
1309         
1310         bool constantWasSet = false;
1311         switch (node->op()) {
1312         case IsEmpty: {
1313             if (child.m_type && !(child.m_type & SpecEmpty)) {
1314                 setConstant(node, jsBoolean(false));
1315                 constantWasSet = true;
1316                 break;
1317             }
1318
1319             if (child.m_type && !(child.m_type & ~SpecEmpty)) {
1320                 setConstant(node, jsBoolean(true));
1321                 constantWasSet = true;
1322                 break;
1323             }
1324
1325             break;
1326         }
1327         case IsUndefined:
1328             // FIXME: Use the masquerades-as-undefined watchpoint thingy.
1329             // https://bugs.webkit.org/show_bug.cgi?id=144456
1330             
1331             if (!(child.m_type & (SpecOther | SpecObjectOther))) {
1332                 setConstant(node, jsBoolean(false));
1333                 constantWasSet = true;
1334                 break;
1335             }
1336             
1337             break;
1338         case IsBoolean:
1339             if (!(child.m_type & ~SpecBoolean)) {
1340                 setConstant(node, jsBoolean(true));
1341                 constantWasSet = true;
1342                 break;
1343             }
1344             
1345             if (!(child.m_type & SpecBoolean)) {
1346                 setConstant(node, jsBoolean(false));
1347                 constantWasSet = true;
1348                 break;
1349             }
1350             
1351             break;
1352         case IsNumber:
1353             if (!(child.m_type & ~SpecFullNumber)) {
1354                 setConstant(node, jsBoolean(true));
1355                 constantWasSet = true;
1356                 break;
1357             }
1358             
1359             if (!(child.m_type & SpecFullNumber)) {
1360                 setConstant(node, jsBoolean(false));
1361                 constantWasSet = true;
1362                 break;
1363             }
1364             
1365             break;
1366
1367         case NumberIsInteger:
1368             if (!(child.m_type & ~SpecInt32Only)) {
1369                 setConstant(node, jsBoolean(true));
1370                 constantWasSet = true;
1371                 break;
1372             }
1373             
1374             if (!(child.m_type & SpecFullNumber)) {
1375                 setConstant(node, jsBoolean(false));
1376                 constantWasSet = true;
1377                 break;
1378             }
1379             
1380             break;
1381
1382         case IsObject:
1383             if (!(child.m_type & ~SpecObject)) {
1384                 setConstant(node, jsBoolean(true));
1385                 constantWasSet = true;
1386                 break;
1387             }
1388             
1389             if (!(child.m_type & SpecObject)) {
1390                 setConstant(node, jsBoolean(false));
1391                 constantWasSet = true;
1392                 break;
1393             }
1394             
1395             break;
1396         case IsObjectOrNull:
1397             // FIXME: Use the masquerades-as-undefined watchpoint thingy.
1398             // https://bugs.webkit.org/show_bug.cgi?id=144456
1399             
1400             // These expressions are complicated to parse. A helpful way to parse this is that
1401             // "!(T & ~S)" means "T is a subset of S". Conversely, "!(T & S)" means "T is a
1402             // disjoint set from S". Things like "T - S" means that, provided that S is a
1403             // subset of T, it's the "set of all things in T but not in S". Things like "T | S"
1404             // mean the "union of T and S".
1405             
1406             // Is the child's type an object that isn't an other-object (i.e. object that could
1407             // have masquaredes-as-undefined traps) and isn't a function?  Then: we should fold
1408             // this to true.
1409             if (!(child.m_type & ~(SpecObject - SpecObjectOther - SpecFunction))) {
1410                 setConstant(node, jsBoolean(true));
1411                 constantWasSet = true;
1412                 break;
1413             }
1414             
1415             // Is the child's type definitely not either of: an object that isn't a function,
1416             // or either undefined or null?  Then: we should fold this to false.  This means
1417             // for example that if it's any non-function object, including those that have
1418             // masquerades-as-undefined traps, then we don't fold. It also means we won't fold
1419             // if it's undefined-or-null, since the type bits don't distinguish between
1420             // undefined (which should fold to false) and null (which should fold to true).
1421             if (!(child.m_type & ((SpecObject - SpecFunction) | SpecOther))) {
1422                 setConstant(node, jsBoolean(false));
1423                 constantWasSet = true;
1424                 break;
1425             }
1426             
1427             break;
1428         case IsFunction:
1429             if (!(child.m_type & ~SpecFunction)) {
1430                 setConstant(node, jsBoolean(true));
1431                 constantWasSet = true;
1432                 break;
1433             }
1434             
1435             if (!(child.m_type & (SpecFunction | SpecObjectOther | SpecProxyObject))) {
1436                 setConstant(node, jsBoolean(false));
1437                 constantWasSet = true;
1438                 break;
1439             }
1440             break;
1441
1442         case IsCellWithType:
1443             if (!(child.m_type & ~node->speculatedTypeForQuery())) {
1444                 setConstant(node, jsBoolean(true));
1445                 constantWasSet = true;
1446                 break;
1447             }
1448             if (!(child.m_type & node->speculatedTypeForQuery())) {
1449                 setConstant(node, jsBoolean(false));
1450                 constantWasSet = true;
1451                 break;
1452             }
1453             break;
1454
1455         case IsTypedArrayView:
1456             if (!(child.m_type & ~SpecTypedArrayView)) {
1457                 setConstant(node, jsBoolean(true));
1458                 constantWasSet = true;
1459                 break;
1460             }
1461             if (!(child.m_type & SpecTypedArrayView)) {
1462                 setConstant(node, jsBoolean(false));
1463                 constantWasSet = true;
1464                 break;
1465             }
1466             break;
1467
1468         default:
1469             break;
1470         }
1471         if (constantWasSet)
1472             break;
1473         
1474         setNonCellTypeForNode(node, SpecBoolean);
1475         break;
1476     }
1477
1478     case TypeOf: {
1479         JSValue child = forNode(node->child1()).value();
1480         AbstractValue& abstractChild = forNode(node->child1());
1481         if (child) {
1482             JSValue typeString = jsTypeStringForValue(m_vm, m_codeBlock->globalObjectFor(node->origin.semantic), child);
1483             setConstant(node, *m_graph.freeze(typeString));
1484             break;
1485         }
1486         
1487         if (isFullNumberSpeculation(abstractChild.m_type)) {
1488             setConstant(node, *m_graph.freeze(m_vm.smallStrings.numberString()));
1489             break;
1490         }
1491         
1492         if (isStringSpeculation(abstractChild.m_type)) {
1493             setConstant(node, *m_graph.freeze(m_vm.smallStrings.stringString()));
1494             break;
1495         }
1496
1497         // FIXME: We could use the masquerades-as-undefined watchpoint here.
1498         // https://bugs.webkit.org/show_bug.cgi?id=144456
1499         if (!(abstractChild.m_type & ~(SpecObject - SpecObjectOther - SpecFunction))) {
1500             setConstant(node, *m_graph.freeze(m_vm.smallStrings.objectString()));
1501             break;
1502         }
1503         
1504         if (isFunctionSpeculation(abstractChild.m_type)) {
1505             setConstant(node, *m_graph.freeze(m_vm.smallStrings.functionString()));
1506             break;
1507         }
1508         
1509         if (isBooleanSpeculation(abstractChild.m_type)) {
1510             setConstant(node, *m_graph.freeze(m_vm.smallStrings.booleanString()));
1511             break;
1512         }
1513
1514         if (isSymbolSpeculation(abstractChild.m_type)) {
1515             setConstant(node, *m_graph.freeze(m_vm.smallStrings.symbolString()));
1516             break;
1517         }
1518
1519         if (isBigIntSpeculation(abstractChild.m_type)) {
1520             setConstant(node, *m_graph.freeze(m_vm.smallStrings.bigintString()));
1521             break;
1522         }
1523
1524         setTypeForNode(node, SpecStringIdent);
1525         break;
1526     }
1527
1528     case CompareBelow:
1529     case CompareBelowEq: {
1530         JSValue leftConst = forNode(node->child1()).value();
1531         JSValue rightConst = forNode(node->child2()).value();
1532         if (leftConst && rightConst) {
1533             if (leftConst.isInt32() && rightConst.isInt32()) {
1534                 uint32_t a = static_cast<uint32_t>(leftConst.asInt32());
1535                 uint32_t b = static_cast<uint32_t>(rightConst.asInt32());
1536                 switch (node->op()) {
1537                 case CompareBelow:
1538                     setConstant(node, jsBoolean(a < b));
1539                     break;
1540                 case CompareBelowEq:
1541                     setConstant(node, jsBoolean(a <= b));
1542                     break;
1543                 default:
1544                     RELEASE_ASSERT_NOT_REACHED();
1545                     break;
1546                 }
1547                 break;
1548             }
1549         }
1550
1551         if (node->child1() == node->child2()) {
1552             switch (node->op()) {
1553             case CompareBelow:
1554                 setConstant(node, jsBoolean(false));
1555                 break;
1556             case CompareBelowEq:
1557                 setConstant(node, jsBoolean(true));
1558                 break;
1559             default:
1560                 DFG_CRASH(m_graph, node, "Unexpected node type");
1561                 break;
1562             }
1563             break;
1564         }
1565         setNonCellTypeForNode(node, SpecBoolean);
1566         break;
1567     }
1568
1569     case CompareLess:
1570     case CompareLessEq:
1571     case CompareGreater:
1572     case CompareGreaterEq:
1573     case CompareEq: {
1574         bool isClobbering = node->isBinaryUseKind(UntypedUse);
1575         
1576         if (isClobbering)
1577             didFoldClobberWorld();
1578         
1579         JSValue leftConst = forNode(node->child1()).value();
1580         JSValue rightConst = forNode(node->child2()).value();
1581         if (leftConst && rightConst) {
1582             if (leftConst.isNumber() && rightConst.isNumber()) {
1583                 double a = leftConst.asNumber();
1584                 double b = rightConst.asNumber();
1585                 switch (node->op()) {
1586                 case CompareLess:
1587                     setConstant(node, jsBoolean(a < b));
1588                     break;
1589                 case CompareLessEq:
1590                     setConstant(node, jsBoolean(a <= b));
1591                     break;
1592                 case CompareGreater:
1593                     setConstant(node, jsBoolean(a > b));
1594                     break;
1595                 case CompareGreaterEq:
1596                     setConstant(node, jsBoolean(a >= b));
1597                     break;
1598                 case CompareEq:
1599                     setConstant(node, jsBoolean(a == b));
1600                     break;
1601                 default:
1602                     RELEASE_ASSERT_NOT_REACHED();
1603                     break;
1604                 }
1605                 break;
1606             }
1607             
1608             if (leftConst.isString() && rightConst.isString()) {
1609                 const StringImpl* a = asString(leftConst)->tryGetValueImpl();
1610                 const StringImpl* b = asString(rightConst)->tryGetValueImpl();
1611                 if (a && b) {
1612                     bool result;
1613                     if (node->op() == CompareEq)
1614                         result = WTF::equal(a, b);
1615                     else if (node->op() == CompareLess)
1616                         result = codePointCompare(a, b) < 0;
1617                     else if (node->op() == CompareLessEq)
1618                         result = codePointCompare(a, b) <= 0;
1619                     else if (node->op() == CompareGreater)
1620                         result = codePointCompare(a, b) > 0;
1621                     else if (node->op() == CompareGreaterEq)
1622                         result = codePointCompare(a, b) >= 0;
1623                     else
1624                         RELEASE_ASSERT_NOT_REACHED();
1625                     setConstant(node, jsBoolean(result));
1626                     break;
1627                 }
1628             }
1629
1630             if (node->op() == CompareEq && leftConst.isSymbol() && rightConst.isSymbol()) {
1631                 setConstant(node, jsBoolean(asSymbol(leftConst) == asSymbol(rightConst)));
1632                 break;
1633             }
1634         }
1635         
1636         if (node->op() == CompareEq) {
1637             SpeculatedType leftType = forNode(node->child1()).m_type;
1638             SpeculatedType rightType = forNode(node->child2()).m_type;
1639             if (!valuesCouldBeEqual(leftType, rightType)) {
1640                 setConstant(node, jsBoolean(false));
1641                 break;
1642             }
1643
1644             if (leftType == SpecOther)
1645                 std::swap(leftType, rightType);
1646             if (rightType == SpecOther) {
1647                 // Undefined and Null are always equal when compared to eachother.
1648                 if (!(leftType & ~SpecOther)) {
1649                     setConstant(node, jsBoolean(true));
1650                     break;
1651                 }
1652
1653                 // Any other type compared to Null or Undefined is always false
1654                 // as long as the MasqueradesAsUndefined watchpoint is valid.
1655                 //
1656                 // MasqueradesAsUndefined only matters for SpecObjectOther, other
1657                 // cases are always "false".
1658                 if (!(leftType & (SpecObjectOther | SpecOther))) {
1659                     setConstant(node, jsBoolean(false));
1660                     break;
1661                 }
1662
1663                 if (!(leftType & SpecOther) && m_graph.masqueradesAsUndefinedWatchpointIsStillValid(node->origin.semantic)) {
1664                     JSGlobalObject* globalObject = m_graph.globalObjectFor(node->origin.semantic);
1665                     m_graph.watchpoints().addLazily(globalObject->masqueradesAsUndefinedWatchpoint());
1666                     setConstant(node, jsBoolean(false));
1667                     break;
1668                 }
1669             }
1670         }
1671         
1672         if (node->child1() == node->child2()) {
1673             if (node->isBinaryUseKind(Int32Use) ||
1674                 node->isBinaryUseKind(Int52RepUse) ||
1675                 node->isBinaryUseKind(StringUse) ||
1676                 node->isBinaryUseKind(BooleanUse) ||
1677                 node->isBinaryUseKind(SymbolUse) ||
1678                 node->isBinaryUseKind(StringIdentUse) ||
1679                 node->isBinaryUseKind(ObjectUse) ||
1680                 node->isBinaryUseKind(ObjectUse, ObjectOrOtherUse) ||
1681                 node->isBinaryUseKind(ObjectOrOtherUse, ObjectUse)) {
1682                 switch (node->op()) {
1683                 case CompareLess:
1684                 case CompareGreater:
1685                     setConstant(node, jsBoolean(false));
1686                     break;
1687                 case CompareLessEq:
1688                 case CompareGreaterEq:
1689                 case CompareEq:
1690                     setConstant(node, jsBoolean(true));
1691                     break;
1692                 default:
1693                     DFG_CRASH(m_graph, node, "Unexpected node type");
1694                     break;
1695                 }
1696                 break;
1697             }
1698         }
1699
1700         if (isClobbering)
1701             clobberWorld();
1702         setNonCellTypeForNode(node, SpecBoolean);
1703         break;
1704     }
1705             
1706     case CompareStrictEq:
1707     case SameValue: {
1708         Node* leftNode = node->child1().node();
1709         Node* rightNode = node->child2().node();
1710         JSValue left = forNode(leftNode).value();
1711         JSValue right = forNode(rightNode).value();
1712         if (left && right) {
1713             if (left.isString() && right.isString()) {
1714                 // We need this case because JSValue::strictEqual is otherwise too racy for
1715                 // string comparisons.
1716                 const StringImpl* a = asString(left)->tryGetValueImpl();
1717                 const StringImpl* b = asString(right)->tryGetValueImpl();
1718                 if (a && b) {
1719                     setConstant(node, jsBoolean(WTF::equal(a, b)));
1720                     break;
1721                 }
1722             } else {
1723                 if (node->op() == CompareStrictEq)
1724                     setConstant(node, jsBoolean(JSValue::strictEqual(nullptr, left, right)));
1725                 else
1726                     setConstant(node, jsBoolean(sameValue(nullptr, left, right)));
1727                 break;
1728             }
1729         }
1730
1731         if (node->isBinaryUseKind(UntypedUse)) {
1732             // FIXME: Revisit this condition when introducing BigInt to JSC.
1733             auto isNonStringCellConstant = [] (JSValue value) {
1734                 return value && value.isCell() && !value.isString();
1735             };
1736
1737             if (isNonStringCellConstant(left) || isNonStringCellConstant(right)) {
1738                 m_state.setFoundConstants(true);
1739                 setNonCellTypeForNode(node, SpecBoolean);
1740                 break;
1741             }
1742         }
1743         
1744         SpeculatedType leftLUB = leastUpperBoundOfStrictlyEquivalentSpeculations(forNode(leftNode).m_type);
1745         SpeculatedType rightLUB = leastUpperBoundOfStrictlyEquivalentSpeculations(forNode(rightNode).m_type);
1746         if (!(leftLUB & rightLUB)) {
1747             setConstant(node, jsBoolean(false));
1748             break;
1749         }
1750         
1751         if (node->child1() == node->child2()) {
1752             if (node->isBinaryUseKind(BooleanUse) ||
1753                 node->isBinaryUseKind(Int32Use) ||
1754                 node->isBinaryUseKind(Int52RepUse) ||
1755                 node->isBinaryUseKind(StringUse) ||
1756                 node->isBinaryUseKind(StringIdentUse) ||
1757                 node->isBinaryUseKind(SymbolUse) ||
1758                 node->isBinaryUseKind(ObjectUse) ||
1759                 node->isBinaryUseKind(MiscUse, UntypedUse) ||
1760                 node->isBinaryUseKind(UntypedUse, MiscUse) ||
1761                 node->isBinaryUseKind(StringIdentUse, NotStringVarUse) ||
1762                 node->isBinaryUseKind(NotStringVarUse, StringIdentUse) ||
1763                 node->isBinaryUseKind(StringUse, UntypedUse) ||
1764                 node->isBinaryUseKind(UntypedUse, StringUse)) {
1765                 setConstant(node, jsBoolean(true));
1766                 break;
1767             }
1768         }
1769
1770         setNonCellTypeForNode(node, SpecBoolean);
1771         break;
1772     }
1773         
1774     case CompareEqPtr: {
1775         Node* childNode = node->child1().node();
1776         JSValue childValue = forNode(childNode).value();
1777         if (childValue) {
1778             setConstant(node, jsBoolean(childValue.isCell() && childValue.asCell() == node->cellOperand()->cell()));
1779             break;
1780         }
1781         
1782         setNonCellTypeForNode(node, SpecBoolean);
1783         break;
1784     }
1785         
1786     case StringCharCodeAt:
1787         setNonCellTypeForNode(node, SpecInt32Only);
1788         break;
1789         
1790     case StringFromCharCode:
1791         switch (node->child1().useKind()) {
1792         case Int32Use:
1793             break;
1794         case UntypedUse:
1795             clobberWorld();
1796             break;
1797         default:
1798             DFG_CRASH(m_graph, node, "Bad use kind");
1799             break;
1800         }
1801         setTypeForNode(node, SpecString);
1802         break;
1803
1804     case StringCharAt:
1805         setForNode(node, m_vm.stringStructure.get());
1806         break;
1807             
1808     case GetByVal:
1809     case AtomicsAdd:
1810     case AtomicsAnd:
1811     case AtomicsCompareExchange:
1812     case AtomicsExchange:
1813     case AtomicsLoad:
1814     case AtomicsOr:
1815     case AtomicsStore:
1816     case AtomicsSub:
1817     case AtomicsXor: {
1818         if (node->op() != GetByVal) {
1819             unsigned numExtraArgs = numExtraAtomicsArgs(node->op());
1820             Edge storageEdge = m_graph.child(node, 2 + numExtraArgs);
1821             if (!storageEdge)
1822                 clobberWorld();
1823         }
1824         switch (node->arrayMode().type()) {
1825         case Array::SelectUsingPredictions:
1826         case Array::Unprofiled:
1827         case Array::SelectUsingArguments:
1828             RELEASE_ASSERT_NOT_REACHED();
1829             break;
1830         case Array::ForceExit:
1831             m_state.setIsValid(false);
1832             break;
1833         case Array::Undecided: {
1834             JSValue index = forNode(m_graph.child(node, 1)).value();
1835             if (index && index.isInt32() && index.asInt32() >= 0) {
1836                 setConstant(node, jsUndefined());
1837                 break;
1838             }
1839             setNonCellTypeForNode(node, SpecOther);
1840             break;
1841         }
1842         case Array::Generic:
1843             clobberWorld();
1844             makeHeapTopForNode(node);
1845             break;
1846         case Array::String:
1847             if (node->arrayMode().isOutOfBounds()) {
1848                 // If the watchpoint was still valid we could totally set this to be
1849                 // SpecString | SpecOther. Except that we'd have to be careful. If we
1850                 // tested the watchpoint state here then it could change by the time
1851                 // we got to the backend. So to do this right, we'd have to get the
1852                 // fixup phase to check the watchpoint state and then bake into the
1853                 // GetByVal operation the fact that we're using a watchpoint, using
1854                 // something like Array::SaneChain (except not quite, because that
1855                 // implies an in-bounds access). None of this feels like it's worth it,
1856                 // so we're going with TOP for now. The same thing applies to
1857                 // clobbering the world.
1858                 clobberWorld();
1859                 makeHeapTopForNode(node);
1860             } else
1861                 setForNode(node, m_vm.stringStructure.get());
1862             break;
1863         case Array::DirectArguments:
1864         case Array::ScopedArguments:
1865             if (node->arrayMode().isOutOfBounds())
1866                 clobberWorld();
1867             makeHeapTopForNode(node);
1868             break;
1869         case Array::Int32:
1870             if (node->arrayMode().isOutOfBounds()) {
1871                 clobberWorld();
1872                 makeHeapTopForNode(node);
1873             } else
1874                 setNonCellTypeForNode(node, SpecInt32Only);
1875             break;
1876         case Array::Double:
1877             if (node->arrayMode().isOutOfBounds()) {
1878                 clobberWorld();
1879                 makeHeapTopForNode(node);
1880             } else if (node->arrayMode().isSaneChain())
1881                 setNonCellTypeForNode(node, SpecBytecodeDouble);
1882             else
1883                 setNonCellTypeForNode(node, SpecDoubleReal);
1884             break;
1885         case Array::Contiguous:
1886         case Array::ArrayStorage:
1887         case Array::SlowPutArrayStorage:
1888             if (node->arrayMode().isOutOfBounds())
1889                 clobberWorld();
1890             makeHeapTopForNode(node);
1891             break;
1892         case Array::Int8Array:
1893             setNonCellTypeForNode(node, SpecInt32Only);
1894             break;
1895         case Array::Int16Array:
1896             setNonCellTypeForNode(node, SpecInt32Only);
1897             break;
1898         case Array::Int32Array:
1899             setNonCellTypeForNode(node, SpecInt32Only);
1900             break;
1901         case Array::Uint8Array:
1902             setNonCellTypeForNode(node, SpecInt32Only);
1903             break;
1904         case Array::Uint8ClampedArray:
1905             setNonCellTypeForNode(node, SpecInt32Only);
1906             break;
1907         case Array::Uint16Array:
1908             setNonCellTypeForNode(node, SpecInt32Only);
1909             break;
1910         case Array::Uint32Array:
1911             if (node->shouldSpeculateInt32())
1912                 setNonCellTypeForNode(node, SpecInt32Only);
1913             else if (enableInt52() && node->shouldSpeculateAnyInt())
1914                 setNonCellTypeForNode(node, SpecAnyInt);
1915             else
1916                 setNonCellTypeForNode(node, SpecAnyIntAsDouble);
1917             break;
1918         case Array::Float32Array:
1919             setNonCellTypeForNode(node, SpecFullDouble);
1920             break;
1921         case Array::Float64Array:
1922             setNonCellTypeForNode(node, SpecFullDouble);
1923             break;
1924         default:
1925             RELEASE_ASSERT_NOT_REACHED();
1926             break;
1927         }
1928         break;
1929     }
1930             
1931     case PutByValDirect:
1932     case PutByVal:
1933     case PutByValAlias: {
1934         switch (node->arrayMode().modeForPut().type()) {
1935         case Array::ForceExit:
1936             m_state.setIsValid(false);
1937             break;
1938         case Array::Generic:
1939             clobberWorld();
1940             break;
1941         case Array::Int32:
1942             if (node->arrayMode().isOutOfBounds())
1943                 clobberWorld();
1944             break;
1945         case Array::Double:
1946             if (node->arrayMode().isOutOfBounds())
1947                 clobberWorld();
1948             break;
1949         case Array::Contiguous:
1950         case Array::ArrayStorage:
1951             if (node->arrayMode().isOutOfBounds())
1952                 clobberWorld();
1953             break;
1954         case Array::SlowPutArrayStorage:
1955             if (node->arrayMode().mayStoreToHole())
1956                 clobberWorld();
1957             break;
1958         default:
1959             break;
1960         }
1961         break;
1962     }
1963             
1964     case ArrayPush:
1965         clobberWorld();
1966         setNonCellTypeForNode(node, SpecBytecodeNumber);
1967         break;
1968
1969     case ArraySlice: {
1970         JSGlobalObject* globalObject = m_graph.globalObjectFor(node->origin.semantic);
1971
1972         // FIXME: We could do better here if we prove that the
1973         // incoming value has only a single structure.
1974         RegisteredStructureSet structureSet;
1975         structureSet.add(m_graph.registerStructure(globalObject->originalArrayStructureForIndexingType(ArrayWithInt32)));
1976         structureSet.add(m_graph.registerStructure(globalObject->originalArrayStructureForIndexingType(ArrayWithContiguous)));
1977         structureSet.add(m_graph.registerStructure(globalObject->originalArrayStructureForIndexingType(ArrayWithDouble)));
1978
1979         setForNode(node, structureSet);
1980         break;
1981     }
1982
1983     case ArrayIndexOf: {
1984         setNonCellTypeForNode(node, SpecInt32Only);
1985         break;
1986     }
1987             
1988     case ArrayPop:
1989         clobberWorld();
1990         makeHeapTopForNode(node);
1991         break;
1992         
1993     case GetMyArgumentByVal:
1994     case GetMyArgumentByValOutOfBounds: {
1995         JSValue index = forNode(node->child2()).m_value;
1996         InlineCallFrame* inlineCallFrame = node->child1()->origin.semantic.inlineCallFrame;
1997
1998         if (index && index.isUInt32()) {
1999             // This pretends to return TOP for accesses that are actually proven out-of-bounds because
2000             // that's the conservative thing to do. Otherwise we'd need to write more code to mark such
2001             // paths as unreachable, or to return undefined. We could implement that eventually.
2002
2003             Checked<unsigned, RecordOverflow> argumentIndexChecked = index.asUInt32();
2004             argumentIndexChecked += node->numberOfArgumentsToSkip();
2005             unsigned argumentIndex;
2006             if (argumentIndexChecked.safeGet(argumentIndex) != CheckedState::DidOverflow) {
2007                 if (inlineCallFrame) {
2008                     if (argumentIndex < inlineCallFrame->argumentCountIncludingThis - 1) {
2009                         setForNode(node, m_state.operand(
2010                             virtualRegisterForArgument(argumentIndex + 1) + inlineCallFrame->stackOffset));
2011                         m_state.setFoundConstants(true);
2012                         break;
2013                     }
2014                 } else {
2015                     if (argumentIndex < m_state.numberOfArguments() - 1) {
2016                         setForNode(node, m_state.argument(argumentIndex + 1));
2017                         m_state.setFoundConstants(true);
2018                         break;
2019                     }
2020                 }
2021             }
2022         }
2023         
2024         if (inlineCallFrame) {
2025             // We have a bound on the types even though it's random access. Take advantage of this.
2026             
2027             AbstractValue result;
2028             for (unsigned i = 1 + node->numberOfArgumentsToSkip(); i < inlineCallFrame->argumentCountIncludingThis; ++i) {
2029                 result.merge(
2030                     m_state.operand(
2031                         virtualRegisterForArgument(i) + inlineCallFrame->stackOffset));
2032             }
2033             
2034             if (node->op() == GetMyArgumentByValOutOfBounds)
2035                 result.merge(SpecOther);
2036             
2037             if (result.value())
2038                 m_state.setFoundConstants(true);
2039             
2040             setForNode(node, result);
2041             break;
2042         }
2043         
2044         makeHeapTopForNode(node);
2045         break;
2046     }
2047             
2048     case RegExpExec:
2049     case RegExpExecNonGlobalOrSticky:
2050         if (node->op() == RegExpExec) {
2051             // Even if we've proven known input types as RegExpObject and String,
2052             // accessing lastIndex is effectful if it's a global regexp.
2053             clobberWorld();
2054         }
2055
2056         if (JSValue globalObjectValue = forNode(node->child1()).m_value) {
2057             if (JSGlobalObject* globalObject = jsDynamicCast<JSGlobalObject*>(m_vm, globalObjectValue)) {
2058                 if (!globalObject->isHavingABadTime()) {
2059                     m_graph.watchpoints().addLazily(globalObject->havingABadTimeWatchpoint());
2060                     RegisteredStructureSet structureSet;
2061                     structureSet.add(m_graph.registerStructure(globalObject->regExpMatchesArrayStructure()));
2062                     structureSet.add(m_graph.registerStructure(globalObject->regExpMatchesArrayWithGroupsStructure()));
2063                     setForNode(node, structureSet);
2064                     forNode(node).merge(SpecOther);
2065                     break;
2066                 }
2067             }
2068         }
2069         setTypeForNode(node, SpecOther | SpecArray);
2070         break;
2071
2072     case RegExpTest:
2073         // Even if we've proven known input types as RegExpObject and String,
2074         // accessing lastIndex is effectful if it's a global regexp.
2075         clobberWorld();
2076         setNonCellTypeForNode(node, SpecBoolean);
2077         break;
2078
2079     case RegExpMatchFast:
2080         ASSERT(node->child2().useKind() == RegExpObjectUse);
2081         ASSERT(node->child3().useKind() == StringUse);
2082         setTypeForNode(node, SpecOther | SpecArray);
2083         break;
2084
2085     case RegExpMatchFastGlobal:
2086         ASSERT(node->child2().useKind() == StringUse);
2087         setTypeForNode(node, SpecOther | SpecArray);
2088         break;
2089             
2090     case StringReplace:
2091     case StringReplaceRegExp:
2092         if (node->child1().useKind() == StringUse
2093             && node->child2().useKind() == RegExpObjectUse
2094             && node->child3().useKind() == StringUse) {
2095             // This doesn't clobber the world. It just reads and writes regexp state.
2096         } else
2097             clobberWorld();
2098         setForNode(node, m_vm.stringStructure.get());
2099         break;
2100
2101     case Jump:
2102         break;
2103             
2104     case Branch: {
2105         Node* child = node->child1().node();
2106         BooleanResult result = booleanResult(node, forNode(child));
2107         if (result == DefinitelyTrue) {
2108             m_state.setBranchDirection(TakeTrue);
2109             break;
2110         }
2111         if (result == DefinitelyFalse) {
2112             m_state.setBranchDirection(TakeFalse);
2113             break;
2114         }
2115         // FIXME: The above handles the trivial cases of sparse conditional
2116         // constant propagation, but we can do better:
2117         // We can specialize the source variable's value on each direction of
2118         // the branch.
2119         m_state.setBranchDirection(TakeBoth);
2120         break;
2121     }
2122         
2123     case Switch: {
2124         // Nothing to do for now.
2125         // FIXME: Do sparse conditional things.
2126         break;
2127     }
2128
2129     case EntrySwitch:
2130         break;
2131
2132     case Return:
2133         m_state.setIsValid(false);
2134         break;
2135
2136     case Throw:
2137     case ThrowStaticError:
2138     case TailCall:
2139     case DirectTailCall:
2140     case TailCallVarargs:
2141     case TailCallForwardVarargs:
2142         clobberWorld();
2143         m_state.setIsValid(false);
2144         break;
2145         
2146     case ToPrimitive: {
2147         JSValue childConst = forNode(node->child1()).value();
2148         if (childConst && childConst.isNumber()) {
2149             didFoldClobberWorld();
2150             setConstant(node, childConst);
2151             break;
2152         }
2153         
2154         ASSERT(node->child1().useKind() == UntypedUse);
2155         
2156         if (!(forNode(node->child1()).m_type & ~(SpecFullNumber | SpecBoolean | SpecString | SpecSymbol | SpecBigInt))) {
2157             m_state.setFoundConstants(true);
2158             didFoldClobberWorld();
2159             setForNode(node, forNode(node->child1()));
2160             break;
2161         }
2162         
2163         clobberWorld();
2164         
2165         setTypeForNode(node, SpecHeapTop & ~SpecObject);
2166         break;
2167     }
2168
2169     case ToNumber: {
2170         JSValue childConst = forNode(node->child1()).value();
2171         if (childConst && childConst.isNumber()) {
2172             didFoldClobberWorld();
2173             setConstant(node, childConst);
2174             break;
2175         }
2176
2177         ASSERT(node->child1().useKind() == UntypedUse);
2178
2179         if (!(forNode(node->child1()).m_type & ~SpecBytecodeNumber)) {
2180             m_state.setFoundConstants(true);
2181             didFoldClobberWorld();
2182             setForNode(node, forNode(node->child1()));
2183             break;
2184         }
2185
2186         clobberWorld();
2187         setNonCellTypeForNode(node, SpecBytecodeNumber);
2188         break;
2189     }
2190         
2191     case ToString:
2192     case CallStringConstructor: {
2193         switch (node->child1().useKind()) {
2194         case StringObjectUse:
2195             // This also filters that the StringObject has the primordial StringObject
2196             // structure.
2197             filter(
2198                 node->child1(),
2199                 m_graph.registerStructure(m_graph.globalObjectFor(node->origin.semantic)->stringObjectStructure()));
2200             break;
2201         case StringOrStringObjectUse:
2202         case Int32Use:
2203         case Int52RepUse:
2204         case DoubleRepUse:
2205         case NotCellUse:
2206             break;
2207         case CellUse:
2208         case UntypedUse:
2209             clobberWorld();
2210             break;
2211         default:
2212             RELEASE_ASSERT_NOT_REACHED();
2213             break;
2214         }
2215         setForNode(node, m_vm.stringStructure.get());
2216         break;
2217     }
2218
2219     case NumberToStringWithRadix: {
2220         JSValue radixValue = forNode(node->child2()).m_value;
2221         if (radixValue && radixValue.isInt32()) {
2222             int32_t radix = radixValue.asInt32();
2223             if (2 <= radix && radix <= 36) {
2224                 m_state.setFoundConstants(true);
2225                 didFoldClobberWorld();
2226                 setForNode(node, m_graph.m_vm.stringStructure.get());
2227                 break;
2228             }
2229         }
2230         clobberWorld();
2231         setForNode(node, m_graph.m_vm.stringStructure.get());
2232         break;
2233     }
2234
2235     case NumberToStringWithValidRadixConstant: {
2236         setForNode(node, m_graph.m_vm.stringStructure.get());
2237         break;
2238     }
2239         
2240     case NewStringObject: {
2241         ASSERT(node->structure()->classInfo() == StringObject::info());
2242         setForNode(node, node->structure());
2243         break;
2244     }
2245             
2246     case NewArray:
2247         ASSERT(node->indexingMode() == node->indexingType()); // Copy on write arrays should only be created by NewArrayBuffer.
2248         setForNode(node,
2249             m_graph.globalObjectFor(node->origin.semantic)->arrayStructureForIndexingTypeDuringAllocation(node->indexingType()));
2250         break;
2251
2252     case NewArrayWithSpread:
2253         if (m_graph.isWatchingHavingABadTimeWatchpoint(node)) {
2254             // We've compiled assuming we're not having a bad time, so to be consistent
2255             // with StructureRegisterationPhase we must say we produce an original array
2256             // allocation structure.
2257             setForNode(node, 
2258                 m_graph.globalObjectFor(node->origin.semantic)->originalArrayStructureForIndexingType(ArrayWithContiguous));
2259         } else {
2260             setForNode(node, 
2261                 m_graph.globalObjectFor(node->origin.semantic)->arrayStructureForIndexingTypeDuringAllocation(ArrayWithContiguous));
2262         }
2263
2264         break;
2265
2266     case Spread:
2267         switch (node->child1()->op()) {
2268         case PhantomNewArrayBuffer:
2269         case PhantomCreateRest:
2270             break;
2271         default:
2272             if (!m_graph.canDoFastSpread(node, forNode(node->child1())))
2273                 clobberWorld();
2274             else
2275                 didFoldClobberWorld();
2276             break;
2277         }
2278
2279         setForNode(node, 
2280             m_vm.fixedArrayStructure.get());
2281         break;
2282         
2283     case NewArrayBuffer:
2284         setForNode(node,
2285             m_graph.globalObjectFor(node->origin.semantic)->arrayStructureForIndexingTypeDuringAllocation(node->indexingMode()));
2286         break;
2287
2288     case NewArrayWithSize:
2289         setTypeForNode(node, SpecArray);
2290         break;
2291         
2292     case NewTypedArray:
2293         switch (node->child1().useKind()) {
2294         case Int32Use:
2295             break;
2296         case UntypedUse:
2297             clobberWorld();
2298             break;
2299         default:
2300             RELEASE_ASSERT_NOT_REACHED();
2301             break;
2302         }
2303         setForNode(node, 
2304             m_graph.globalObjectFor(node->origin.semantic)->typedArrayStructureConcurrently(
2305                 node->typedArrayType()));
2306         break;
2307         
2308     case NewRegexp:
2309         setForNode(node, m_graph.globalObjectFor(node->origin.semantic)->regExpStructure());
2310         break;
2311             
2312     case ToThis: {
2313         AbstractValue& source = forNode(node->child1());
2314         AbstractValue& destination = forNode(node);
2315         bool strictMode = m_graph.executableFor(node->origin.semantic)->isStrictMode();
2316
2317         ToThisResult result = isToThisAnIdentity(m_vm, strictMode, source);
2318         if (result != ToThisResult::Dynamic) {
2319             switch (result) {
2320             case ToThisResult::Identity:
2321                 m_state.setFoundConstants(true);
2322                 destination = source;
2323                 break;
2324             case ToThisResult::Undefined:
2325                 setConstant(node, jsUndefined());
2326                 break;
2327             case ToThisResult::GlobalThis:
2328                 m_state.setFoundConstants(true);
2329                 destination.setType(m_graph, SpecObject);
2330                 break;
2331             case ToThisResult::Dynamic:
2332                 RELEASE_ASSERT_NOT_REACHED();
2333             }
2334             break;
2335         }
2336
2337         if (strictMode)
2338             destination.makeHeapTop();
2339         else {
2340             destination = source;
2341             destination.merge(SpecObject);
2342         }
2343         break;
2344     }
2345
2346     case CreateThis: {
2347         if (JSValue base = forNode(node->child1()).m_value) {
2348             if (auto* function = jsDynamicCast<JSFunction*>(m_vm, base)) {
2349                 if (FunctionRareData* rareData = function->rareData()) {
2350                     if (Structure* structure = rareData->objectAllocationStructure()) {
2351                         m_graph.freeze(rareData);
2352                         m_graph.watchpoints().addLazily(rareData->allocationProfileWatchpointSet());
2353                         m_state.setFoundConstants(true);
2354                         didFoldClobberWorld();
2355                         setForNode(node, structure);
2356                         break;
2357                     }
2358                 }
2359             }
2360         }
2361         clobberWorld();
2362         setTypeForNode(node, SpecFinalObject);
2363         break;
2364     }
2365         
2366     case NewObject:
2367         ASSERT(!!node->structure().get());
2368         setForNode(node, node->structure());
2369         break;
2370
2371     case ToObject:
2372     case CallObjectConstructor: {
2373         AbstractValue& source = forNode(node->child1());
2374         AbstractValue& destination = forNode(node);
2375
2376         if (!(source.m_type & ~SpecObject)) {
2377             m_state.setFoundConstants(true);
2378             if (node->op() == ToObject)
2379                 didFoldClobberWorld();
2380             destination = source;
2381             break;
2382         }
2383
2384         if (node->op() == ToObject)
2385             clobberWorld();
2386         setTypeForNode(node, SpecObject);
2387         break;
2388     }
2389
2390     case PhantomNewObject:
2391     case PhantomNewFunction:
2392     case PhantomNewGeneratorFunction:
2393     case PhantomNewAsyncGeneratorFunction:
2394     case PhantomNewAsyncFunction:
2395     case PhantomCreateActivation:
2396     case PhantomDirectArguments:
2397     case PhantomClonedArguments:
2398     case PhantomCreateRest:
2399     case PhantomSpread:
2400     case PhantomNewArrayWithSpread:
2401     case PhantomNewArrayBuffer:
2402     case PhantomNewRegexp:
2403     case BottomValue:
2404         // This claims to return bottom.
2405         break;
2406         
2407     case PutHint:
2408         break;
2409         
2410     case MaterializeNewObject: {
2411         setForNode(node, node->structureSet());
2412         break;
2413     }
2414
2415     case PushWithScope:
2416         // We don't use the more precise withScopeStructure() here because it is a LazyProperty and may not yet be allocated.
2417         setTypeForNode(node, SpecObjectOther);
2418         break;
2419
2420     case CreateActivation:
2421     case MaterializeCreateActivation:
2422         setForNode(node, 
2423             m_codeBlock->globalObjectFor(node->origin.semantic)->activationStructure());
2424         break;
2425         
2426     case CreateDirectArguments:
2427         setForNode(node, m_codeBlock->globalObjectFor(node->origin.semantic)->directArgumentsStructure());
2428         break;
2429         
2430     case CreateScopedArguments:
2431         setForNode(node, m_codeBlock->globalObjectFor(node->origin.semantic)->scopedArgumentsStructure());
2432         break;
2433         
2434     case CreateClonedArguments:
2435         if (!m_graph.isWatchingHavingABadTimeWatchpoint(node)) {
2436             setTypeForNode(node, SpecObject);
2437             break;
2438         }
2439         setForNode(node, m_codeBlock->globalObjectFor(node->origin.semantic)->clonedArgumentsStructure());
2440         break;
2441
2442     case NewGeneratorFunction:
2443         setForNode(node, 
2444             m_codeBlock->globalObjectFor(node->origin.semantic)->generatorFunctionStructure());
2445         break;
2446
2447     case NewAsyncGeneratorFunction:
2448         setForNode(node, 
2449             m_codeBlock->globalObjectFor(node->origin.semantic)->asyncGeneratorFunctionStructure());
2450         break;
2451
2452     case NewAsyncFunction:
2453         setForNode(node, 
2454             m_codeBlock->globalObjectFor(node->origin.semantic)->asyncFunctionStructure());
2455         break;
2456
2457     case NewFunction: {
2458         JSGlobalObject* globalObject = m_codeBlock->globalObjectFor(node->origin.semantic);
2459         Structure* structure = JSFunction::selectStructureForNewFuncExp(globalObject, node->castOperand<FunctionExecutable*>());
2460         setForNode(node, structure);
2461         break;
2462     }
2463         
2464     case GetCallee:
2465         if (FunctionExecutable* executable = jsDynamicCast<FunctionExecutable*>(m_vm, m_codeBlock->ownerExecutable())) {
2466             InferredValue* singleton = executable->singletonFunction();
2467             if (JSValue value = singleton->inferredValue()) {
2468                 m_graph.watchpoints().addLazily(singleton);
2469                 JSFunction* function = jsCast<JSFunction*>(value);
2470                 setConstant(node, *m_graph.freeze(function));
2471                 break;
2472             }
2473         }
2474         setTypeForNode(node, SpecFunction);
2475         break;
2476         
2477     case GetArgumentCountIncludingThis:
2478         setTypeForNode(node, SpecInt32Only);
2479         break;
2480
2481     case SetCallee:
2482     case SetArgumentCountIncludingThis:
2483         break;
2484         
2485     case GetRestLength:
2486         setNonCellTypeForNode(node, SpecInt32Only);
2487         break;
2488         
2489     case GetGetter: {
2490         JSValue base = forNode(node->child1()).m_value;
2491         if (base) {
2492             GetterSetter* getterSetter = jsCast<GetterSetter*>(base);
2493             if (!getterSetter->isGetterNull()) {
2494                 setConstant(node, *m_graph.freeze(getterSetter->getterConcurrently()));
2495                 break;
2496             }
2497         }
2498         
2499         setTypeForNode(node, SpecObject);
2500         break;
2501     }
2502         
2503     case GetSetter: {
2504         JSValue base = forNode(node->child1()).m_value;
2505         if (base) {
2506             GetterSetter* getterSetter = jsCast<GetterSetter*>(base);
2507             if (!getterSetter->isSetterNull()) {
2508                 setConstant(node, *m_graph.freeze(getterSetter->setterConcurrently()));
2509                 break;
2510             }
2511         }
2512         
2513         setTypeForNode(node, SpecObject);
2514         break;
2515     }
2516         
2517     case GetScope:
2518         if (JSValue base = forNode(node->child1()).m_value) {
2519             if (JSFunction* function = jsDynamicCast<JSFunction*>(m_vm, base)) {
2520                 setConstant(node, *m_graph.freeze(function->scope()));
2521                 break;
2522             }
2523         }
2524         setTypeForNode(node, SpecObjectOther);
2525         break;
2526
2527     case SkipScope: {
2528         JSValue child = forNode(node->child1()).value();
2529         if (child) {
2530             setConstant(node, *m_graph.freeze(JSValue(jsCast<JSScope*>(child.asCell())->next())));
2531             break;
2532         }
2533         setTypeForNode(node, SpecObjectOther);
2534         break;
2535     }
2536
2537     case GetGlobalObject: {
2538         JSValue child = forNode(node->child1()).value();
2539         if (child) {
2540             setConstant(node, *m_graph.freeze(JSValue(asObject(child)->globalObject(m_vm))));
2541             break;
2542         }
2543
2544         if (forNode(node->child1()).m_structure.isFinite()) {
2545             JSGlobalObject* globalObject = nullptr;
2546             bool ok = true;
2547             forNode(node->child1()).m_structure.forEach(
2548                 [&] (RegisteredStructure structure) {
2549                     if (!globalObject)
2550                         globalObject = structure->globalObject();
2551                     else if (globalObject != structure->globalObject())
2552                         ok = false;
2553                 });
2554             if (globalObject && ok) {
2555                 setConstant(node, *m_graph.freeze(JSValue(globalObject)));
2556                 break;
2557             }
2558         }
2559
2560         setTypeForNode(node, SpecObjectOther);
2561         break;
2562     }
2563
2564     case GetGlobalThis: {
2565         setTypeForNode(node, SpecObject);
2566         break;
2567     }
2568
2569     case GetClosureVar:
2570         if (JSValue value = m_graph.tryGetConstantClosureVar(forNode(node->child1()), node->scopeOffset())) {
2571             setConstant(node, *m_graph.freeze(value));
2572             break;
2573         }
2574         makeBytecodeTopForNode(node);
2575         break;
2576             
2577     case PutClosureVar:
2578         break;
2579
2580     case GetRegExpObjectLastIndex:
2581         makeHeapTopForNode(node);
2582         break;
2583
2584     case SetRegExpObjectLastIndex:
2585     case RecordRegExpCachedResult:
2586         break;
2587         
2588     case GetFromArguments:
2589         makeHeapTopForNode(node);
2590         break;
2591         
2592     case PutToArguments:
2593         break;
2594
2595     case GetArgument:
2596         makeHeapTopForNode(node);
2597         break;
2598
2599     case TryGetById:
2600         // FIXME: This should constant fold at least as well as the normal GetById case.
2601         // https://bugs.webkit.org/show_bug.cgi?id=156422
2602         makeHeapTopForNode(node);
2603         break;
2604
2605     case GetByIdDirect:
2606     case GetByIdDirectFlush:
2607     case GetById:
2608     case GetByIdFlush: {
2609         AbstractValue& value = forNode(node->child1());
2610         if (value.m_structure.isFinite()
2611             && (node->child1().useKind() == CellUse || !(value.m_type & ~SpecCell))) {
2612             UniquedStringImpl* uid = m_graph.identifiers()[node->identifierNumber()];
2613             GetByIdStatus status = GetByIdStatus::computeFor(value.m_structure.toStructureSet(), uid);
2614             if (status.isSimple()) {
2615                 // Figure out what the result is going to be - is it TOP, a constant, or maybe
2616                 // something more subtle?
2617                 AbstractValue result;
2618                 for (unsigned i = status.numVariants(); i--;) {
2619                     // This thing won't give us a variant that involves prototypes. If it did, we'd
2620                     // have more work to do here.
2621                     DFG_ASSERT(m_graph, node, status[i].conditionSet().isEmpty());
2622
2623                     result.merge(
2624                         m_graph.inferredValueForProperty(
2625                             value, uid, status[i].offset(), m_state.structureClobberState()));
2626                 }
2627                 m_state.setFoundConstants(true);
2628                 didFoldClobberWorld();
2629                 forNode(node) = result;
2630                 break;
2631             }
2632         }
2633
2634         clobberWorld();
2635         makeHeapTopForNode(node);
2636         break;
2637     }
2638
2639     case GetByValWithThis:
2640     case GetByIdWithThis:
2641         clobberWorld();
2642         makeHeapTopForNode(node);
2643         break;
2644             
2645     case GetArrayLength: {
2646         JSArrayBufferView* view = m_graph.tryGetFoldableView(
2647             forNode(node->child1()).m_value, node->arrayMode());
2648         if (view) {
2649             setConstant(node, jsNumber(view->length()));
2650             break;
2651         }
2652         setNonCellTypeForNode(node, SpecInt32Only);
2653         break;
2654     }
2655
2656     case GetVectorLength: {
2657         setNonCellTypeForNode(node, SpecInt32Only);
2658         break;
2659     }
2660
2661     case DeleteById:
2662     case DeleteByVal: {
2663         // FIXME: This could decide if the delete will be successful based on the set of structures that
2664         // we get from our base value. https://bugs.webkit.org/show_bug.cgi?id=156611
2665         clobberWorld();
2666         setNonCellTypeForNode(node, SpecBoolean);
2667         break;
2668     }
2669         
2670     case CheckStructure: {
2671         AbstractValue& value = forNode(node->child1());
2672
2673         const RegisteredStructureSet& set = node->structureSet();
2674         
2675         // It's interesting that we could have proven that the object has a larger structure set
2676         // that includes the set we're testing. In that case we could make the structure check
2677         // more efficient. We currently don't.
2678         
2679         if (value.m_structure.isSubsetOf(set))
2680             m_state.setFoundConstants(true);
2681
2682         SpeculatedType admittedTypes = SpecNone;
2683         switch (node->child1().useKind()) {
2684         case CellUse:
2685         case KnownCellUse:
2686             admittedTypes = SpecNone;
2687             break;
2688         case CellOrOtherUse:
2689             admittedTypes = SpecOther;
2690             break;
2691         default:
2692             DFG_CRASH(m_graph, node, "Bad use kind");
2693             break;
2694         }
2695         
2696         filter(value, set, admittedTypes);
2697         break;
2698     }
2699
2700     case CheckStructureOrEmpty: {
2701         AbstractValue& value = forNode(node->child1());
2702
2703         bool mayBeEmpty = value.m_type & SpecEmpty;
2704         if (!mayBeEmpty)
2705             m_state.setFoundConstants(true);
2706
2707         SpeculatedType admittedTypes = mayBeEmpty ? SpecEmpty : SpecNone;
2708         filter(value, node->structureSet(), admittedTypes);
2709         break;
2710     }
2711         
2712     case CheckStructureImmediate: {
2713         // FIXME: This currently can only reason about one structure at a time.
2714         // https://bugs.webkit.org/show_bug.cgi?id=136988
2715         
2716         AbstractValue& value = forNode(node->child1());
2717         const RegisteredStructureSet& set = node->structureSet();
2718         
2719         if (value.value()) {
2720             if (Structure* structure = jsDynamicCast<Structure*>(m_vm, value.value())) {
2721                 if (set.contains(m_graph.registerStructure(structure))) {
2722                     m_state.setFoundConstants(true);
2723                     break;
2724                 }
2725             }
2726             m_state.setIsValid(false);
2727             break;
2728         }
2729         
2730         if (m_phiChildren) {
2731             bool allGood = true;
2732             m_phiChildren->forAllTransitiveIncomingValues(
2733                 node,
2734                 [&] (Node* incoming) {
2735                     if (Structure* structure = incoming->dynamicCastConstant<Structure*>(m_vm)) {
2736                         if (set.contains(m_graph.registerStructure(structure)))
2737                             return;
2738                     }
2739                     allGood = false;
2740                 });
2741             if (allGood) {
2742                 m_state.setFoundConstants(true);
2743                 break;
2744             }
2745         }
2746             
2747         if (RegisteredStructure structure = set.onlyStructure()) {
2748             filterByValue(node->child1(), *m_graph.freeze(structure.get()));
2749             break;
2750         }
2751         
2752         // Aw shucks, we can't do anything!
2753         break;
2754     }
2755         
2756     case PutStructure:
2757         if (!forNode(node->child1()).m_structure.isClear()) {
2758             if (forNode(node->child1()).m_structure.onlyStructure() == node->transition()->next) {
2759                 didFoldClobberStructures();
2760                 m_state.setFoundConstants(true);
2761             } else {
2762                 observeTransition(
2763                     clobberLimit, node->transition()->previous, node->transition()->next);
2764                 forNode(node->child1()).changeStructure(m_graph, node->transition()->next);
2765             }
2766         } else {
2767             // We're going to exit before we get here, but for the sake of validation, we've folded our write to StructureID.
2768             didFoldClobberStructures();
2769         }
2770         break;
2771     case GetButterfly:
2772     case AllocatePropertyStorage:
2773     case ReallocatePropertyStorage:
2774     case NukeStructureAndSetButterfly:
2775         // FIXME: We don't model the fact that the structureID is nuked, simply because currently
2776         // nobody would currently benefit from having that information. But it's a bug nonetheless.
2777         if (node->op() == NukeStructureAndSetButterfly)
2778             didFoldClobberStructures();
2779         clearForNode(node); // The result is not a JS value.
2780         break;
2781     case CheckSubClass: {
2782         JSValue constant = forNode(node->child1()).value();
2783         if (constant) {
2784             if (constant.isCell() && constant.asCell()->inherits(m_vm, node->classInfo())) {
2785                 m_state.setFoundConstants(true);
2786                 ASSERT(constant);
2787                 break;
2788             }
2789         }
2790
2791         AbstractValue& value = forNode(node->child1());
2792
2793         if (value.m_structure.isSubClassOf(node->classInfo()))
2794             m_state.setFoundConstants(true);
2795
2796         filterClassInfo(value, node->classInfo());
2797         break;
2798     }
2799     case CallDOMGetter: {
2800         CallDOMGetterData* callDOMGetterData = node->callDOMGetterData();
2801         DOMJIT::CallDOMGetterSnippet* snippet = callDOMGetterData->snippet;
2802         if (!snippet || snippet->effect.writes)
2803             clobberWorld();
2804         if (callDOMGetterData->domJIT)
2805             setTypeForNode(node, callDOMGetterData->domJIT->resultType());
2806         else
2807             makeBytecodeTopForNode(node);
2808         break;
2809     }
2810     case CallDOM: {
2811         const DOMJIT::Signature* signature = node->signature();
2812         if (signature->effect.writes)
2813             clobberWorld();
2814         setTypeForNode(node, signature->result);
2815         break;
2816     }
2817     case CheckArray: {
2818         if (node->arrayMode().alreadyChecked(m_graph, node, forNode(node->child1()))) {
2819             m_state.setFoundConstants(true);
2820             break;
2821         }
2822         switch (node->arrayMode().type()) {
2823         case Array::String:
2824             filter(node->child1(), SpecString);
2825             break;
2826         case Array::Int32:
2827         case Array::Double:
2828         case Array::Contiguous:
2829         case Array::Undecided:
2830         case Array::ArrayStorage:
2831         case Array::SlowPutArrayStorage:
2832             break;
2833         case Array::DirectArguments:
2834             filter(node->child1(), SpecDirectArguments);
2835             break;
2836         case Array::ScopedArguments:
2837             filter(node->child1(), SpecScopedArguments);
2838             break;
2839         case Array::Int8Array:
2840             filter(node->child1(), SpecInt8Array);
2841             break;
2842         case Array::Int16Array:
2843             filter(node->child1(), SpecInt16Array);
2844             break;
2845         case Array::Int32Array:
2846             filter(node->child1(), SpecInt32Array);
2847             break;
2848         case Array::Uint8Array:
2849             filter(node->child1(), SpecUint8Array);
2850             break;
2851         case Array::Uint8ClampedArray:
2852             filter(node->child1(), SpecUint8ClampedArray);
2853             break;
2854         case Array::Uint16Array:
2855             filter(node->child1(), SpecUint16Array);
2856             break;
2857         case Array::Uint32Array:
2858             filter(node->child1(), SpecUint32Array);
2859             break;
2860         case Array::Float32Array:
2861             filter(node->child1(), SpecFloat32Array);
2862             break;
2863         case Array::Float64Array:
2864             filter(node->child1(), SpecFloat64Array);
2865             break;
2866         case Array::AnyTypedArray:
2867             filter(node->child1(), SpecTypedArrayView);
2868             break;
2869         default:
2870             RELEASE_ASSERT_NOT_REACHED();
2871             break;
2872         }
2873         filterArrayModes(node->child1(), node->arrayMode().arrayModesThatPassFiltering());
2874         break;
2875     }
2876     case Arrayify: {
2877         if (node->arrayMode().alreadyChecked(m_graph, node, forNode(node->child1()))) {
2878             didFoldClobberStructures();
2879             m_state.setFoundConstants(true);
2880             break;
2881         }
2882         ASSERT(node->arrayMode().conversion() == Array::Convert);
2883         clobberStructures();
2884         filterArrayModes(node->child1(), node->arrayMode().arrayModesThatPassFiltering());
2885         break;
2886     }
2887     case ArrayifyToStructure: {
2888         AbstractValue& value = forNode(node->child1());
2889         if (value.m_structure.isSubsetOf(RegisteredStructureSet(node->structure())))
2890             m_state.setFoundConstants(true);
2891         clobberStructures();
2892         
2893         // We have a bunch of options of how to express the abstract set at this point. Let set S
2894         // be the set of structures that the value had before clobbering and assume that all of
2895         // them are watchable. The new value should be the least expressible upper bound of the
2896         // intersection of "values that currently have structure = node->structure()" and "values
2897         // that have structure in S plus any structure transition-reachable from S". Assume that
2898         // node->structure() is not in S but it is transition-reachable from S. Then we would
2899         // like to say that the result is "values that have structure = node->structure() until
2900         // we invalidate", but there is no way to express this using the AbstractValue syntax. So
2901         // we must choose between:
2902         //
2903         // 1) "values that currently have structure = node->structure()". This is a valid
2904         //    superset of the value that we really want, and it's specific enough to satisfy the
2905         //    preconditions of the array access that this is guarding. It's also specific enough
2906         //    to allow relevant optimizations in the case that we didn't have a contradiction
2907         //    like in this example. Notice that in the abscence of any contradiction, this result
2908         //    is precise rather than being a conservative LUB.
2909         //
2910         // 2) "values that currently hava structure in S plus any structure transition-reachable
2911         //    from S". This is also a valid superset of the value that we really want, but it's
2912         //    not specific enough to satisfy the preconditions of the array access that this is
2913         //    guarding - so playing such shenanigans would preclude us from having assertions on
2914         //    the typing preconditions of any array accesses. This would also not be a desirable
2915         //    answer in the absence of a contradiction.
2916         //
2917         // Note that it's tempting to simply say that the resulting value is BOTTOM because of
2918         // the contradiction. That would be wrong, since we haven't hit an invalidation point,
2919         // yet.
2920         forNode(node->child1()).set(m_graph, node->structure());
2921         break;
2922     }
2923     case GetIndexedPropertyStorage: {
2924         JSArrayBufferView* view = m_graph.tryGetFoldableView(
2925             forNode(node->child1()).m_value, node->arrayMode());
2926         if (view)
2927             m_state.setFoundConstants(true);
2928         clearForNode(node);
2929         break;
2930     }
2931     case ConstantStoragePointer: {
2932         clearForNode(node);
2933         break; 
2934     }
2935         
2936     case GetTypedArrayByteOffset: {
2937         JSArrayBufferView* view = m_graph.tryGetFoldableView(forNode(node->child1()).m_value);
2938         if (view) {
2939             setConstant(node, jsNumber(view->byteOffset()));
2940             break;
2941         }
2942         setNonCellTypeForNode(node, SpecInt32Only);
2943         break;
2944     }
2945
2946     case GetPrototypeOf: {
2947         AbstractValue& value = forNode(node->child1());
2948         if ((value.m_type && !(value.m_type & ~SpecObject)) && value.m_structure.isFinite()) {
2949             bool canFold = !value.m_structure.isClear();
2950             JSValue prototype;
2951             value.m_structure.forEach([&] (RegisteredStructure structure) {
2952                 auto getPrototypeMethod = structure->classInfo()->methodTable.getPrototype;
2953                 MethodTable::GetPrototypeFunctionPtr defaultGetPrototype = JSObject::getPrototype;
2954                 if (getPrototypeMethod != defaultGetPrototype) {
2955                     canFold = false;
2956                     return;
2957                 }
2958
2959                 if (structure->hasPolyProto()) {
2960                     canFold = false;
2961                     return;
2962                 }
2963                 if (!prototype)
2964                     prototype = structure->storedPrototype();
2965                 else if (prototype != structure->storedPrototype())
2966                     canFold = false;
2967             });
2968
2969             if (prototype && canFold) {
2970                 switch (node->child1().useKind()) {
2971                 case ArrayUse:
2972                 case FunctionUse:
2973                 case FinalObjectUse:
2974                     break;
2975                 default:
2976                     didFoldClobberWorld();
2977                     break;
2978                 }
2979                 setConstant(node, *m_graph.freeze(prototype));
2980                 break;
2981             }
2982         }
2983
2984         switch (node->child1().useKind()) {
2985         case ArrayUse:
2986         case FunctionUse:
2987         case FinalObjectUse:
2988             break;
2989         default:
2990             clobberWorld();
2991             break;
2992         }
2993         setTypeForNode(node, SpecObject | SpecOther);
2994         break;
2995     }
2996         
2997     case GetByOffset: {
2998         StorageAccessData& data = node->storageAccessData();
2999         UniquedStringImpl* uid = m_graph.identifiers()[data.identifierNumber];
3000
3001         // FIXME: The part of this that handles inferred property types relies on AI knowing the structure
3002         // right now. That's probably not optimal. In some cases, we may perform an optimization (usually
3003         // by something other than AI, maybe by CSE for example) that obscures AI's view of the structure
3004         // at the point where GetByOffset runs. Currently, when that happens, we'll have to rely entirely
3005         // on the type that ByteCodeParser was able to prove.
3006         AbstractValue value = m_graph.inferredValueForProperty(
3007             forNode(node->child2()), uid, data.offset, m_state.structureClobberState());
3008
3009         // It's possible that the type that ByteCodeParser came up with is better.
3010         AbstractValue typeFromParsing;
3011         typeFromParsing.set(m_graph, data.inferredType, m_state.structureClobberState());
3012         value.filter(typeFromParsing);
3013
3014         // If we decide that there does not exist any value that this can return, then it's probably
3015         // because the compilation was already invalidated.
3016         if (value.isClear())
3017             m_state.setIsValid(false);
3018
3019         setForNode(node, value);
3020         if (value.m_value)
3021             m_state.setFoundConstants(true);
3022         break;
3023     }
3024         
3025     case GetGetterSetterByOffset: {
3026         StorageAccessData& data = node->storageAccessData();
3027         JSValue result = m_graph.tryGetConstantProperty(forNode(node->child2()), data.offset);
3028         if (result && jsDynamicCast<GetterSetter*>(m_vm, result)) {
3029             setConstant(node, *m_graph.freeze(result));
3030             break;
3031         }
3032         
3033         setForNode(node, m_graph.globalObjectFor(node->origin.semantic)->getterSetterStructure());
3034         break;
3035     }
3036         
3037     case MultiGetByOffset: {
3038         // This code will filter the base value in a manner that is possibly different (either more
3039         // or less precise) than the way it would be filtered if this was strength-reduced to a
3040         // CheckStructure. This is fine. It's legal for different passes over the code to prove
3041         // different things about the code, so long as all of them are sound. That even includes
3042         // one guy proving that code should never execute (due to a contradiction) and another guy
3043         // not finding that contradiction. If someone ever proved that there would be a
3044         // contradiction then there must always be a contradiction even if subsequent passes don't
3045         // realize it. This is the case here.
3046         
3047         // Ordinarily you have to be careful with calling setFoundConstants()
3048         // because of the effect on compile times, but this node is FTL-only.
3049         m_state.setFoundConstants(true);
3050         
3051         UniquedStringImpl* uid = m_graph.identifiers()[node->multiGetByOffsetData().identifierNumber];
3052
3053         AbstractValue base = forNode(node->child1());
3054         RegisteredStructureSet baseSet;
3055         AbstractValue result;
3056         for (const MultiGetByOffsetCase& getCase : node->multiGetByOffsetData().cases) {
3057             RegisteredStructureSet set = getCase.set();
3058             set.filter(base);
3059             if (set.isEmpty())
3060                 continue;
3061             baseSet.merge(set);
3062
3063             switch (getCase.method().kind()) {
3064             case GetByOffsetMethod::Constant: {
3065                 AbstractValue thisResult;
3066                 thisResult.set(
3067                     m_graph,
3068                     *getCase.method().constant(),
3069                     m_state.structureClobberState());
3070                 result.merge(thisResult);
3071                 break;
3072             }
3073
3074             case GetByOffsetMethod::Load: {
3075                 result.merge(
3076                     m_graph.inferredValueForProperty(
3077                         set, uid, m_state.structureClobberState()));
3078                 break;
3079             }
3080
3081             default: {
3082                 result.makeHeapTop();
3083                 break;
3084             } }
3085         }
3086         
3087         if (forNode(node->child1()).changeStructure(m_graph, baseSet) == Contradiction)
3088             m_state.setIsValid(false);
3089         
3090         setForNode(node, result);
3091         break;
3092     }
3093             
3094     case PutByOffset: {
3095         break;
3096     }
3097         
3098     case MultiPutByOffset: {
3099         RegisteredStructureSet newSet;
3100         TransitionVector transitions;
3101         
3102         // Ordinarily you have to be careful with calling setFoundConstants()
3103         // because of the effect on compile times, but this node is FTL-only.
3104         m_state.setFoundConstants(true);
3105         
3106         AbstractValue base = forNode(node->child1());
3107         AbstractValue originalValue = forNode(node->child2());
3108         AbstractValue resultingValue;
3109         
3110         if (node->multiPutByOffsetData().writesStructures())
3111             didFoldClobberStructures();
3112             
3113         for (unsigned i = node->multiPutByOffsetData().variants.size(); i--;) {
3114             const PutByIdVariant& variant = node->multiPutByOffsetData().variants[i];
3115             RegisteredStructureSet thisSet = *m_graph.addStructureSet(variant.oldStructure());
3116             thisSet.filter(base);
3117             if (thisSet.isEmpty())
3118                 continue;
3119
3120             AbstractValue thisValue = originalValue;
3121             thisValue.filter(m_graph, variant.requiredType());
3122             resultingValue.merge(thisValue);
3123             
3124             if (variant.kind() == PutByIdVariant::Transition) {
3125                 RegisteredStructure newStructure = m_graph.registerStructure(variant.newStructure());
3126                 if (thisSet.onlyStructure() != newStructure) {
3127                     transitions.append(
3128                         Transition(m_graph.registerStructure(variant.oldStructureForTransition()), newStructure));
3129                 } // else this is really a replace.
3130                 newSet.add(newStructure);
3131             } else {
3132                 ASSERT(variant.kind() == PutByIdVariant::Replace);
3133                 newSet.merge(thisSet);
3134             }
3135         }
3136         
3137         observeTransitions(clobberLimit, transitions);
3138         if (forNode(node->child1()).changeStructure(m_graph, newSet) == Contradiction)
3139             m_state.setIsValid(false);
3140         setForNode(node->child2(), resultingValue);
3141         if (!!originalValue && !resultingValue)
3142             m_state.setIsValid(false);
3143         break;
3144     }
3145         
3146     case GetExecutable: {
3147         JSValue value = forNode(node->child1()).value();
3148         if (value) {
3149             JSFunction* function = jsDynamicCast<JSFunction*>(m_vm, value);
3150             if (function) {
3151                 setConstant(node, *m_graph.freeze(function->executable()));
3152                 break;
3153             }
3154         }
3155         setTypeForNode(node, SpecCellOther);
3156         break;
3157     }
3158     
3159     case CheckCell: {
3160         JSValue value = forNode(node->child1()).value();
3161         if (value == node->cellOperand()->value()) {
3162             m_state.setFoundConstants(true);
3163             ASSERT(value);
3164             break;
3165         }
3166         filterByValue(node->child1(), *node->cellOperand());
3167         break;
3168     }
3169
3170     case AssertNotEmpty:
3171     case CheckNotEmpty: {
3172         AbstractValue& value = forNode(node->child1());
3173         if (!(value.m_type & SpecEmpty)) {
3174             m_state.setFoundConstants(true);
3175             break;
3176         }
3177         
3178         filter(value, ~SpecEmpty);
3179         break;
3180     }
3181
3182     case CheckStringIdent: {
3183         AbstractValue& value = forNode(node->child1());
3184         UniquedStringImpl* uid = node->uidOperand();
3185         ASSERT(!(value.m_type & ~SpecStringIdent)); // Edge filtering should have already ensured this.
3186
3187         JSValue childConstant = value.value();
3188         if (childConstant) {
3189             ASSERT(childConstant.isString());
3190             if (asString(childConstant)->tryGetValueImpl() == uid) {
3191                 m_state.setFoundConstants(true);
3192                 break;
3193             }
3194         }
3195
3196         filter(value, SpecStringIdent);
3197         break;
3198     }
3199
3200     case CheckInBounds: {
3201         JSValue left = forNode(node->child1()).value();
3202         JSValue right = forNode(node->child2()).value();
3203         if (left && right && left.isInt32() && right.isInt32()
3204             && static_cast<uint32_t>(left.asInt32()) < static_cast<uint32_t>(right.asInt32())) {
3205             m_state.setFoundConstants(true);
3206             break;
3207         }
3208         break;
3209     }
3210         
3211     case PutById:
3212     case PutByIdFlush:
3213     case PutByIdDirect: {
3214         AbstractValue& value = forNode(node->child1());
3215         if (value.m_structure.isFinite()) {
3216             PutByIdStatus status = PutByIdStatus::computeFor(
3217                 m_graph.globalObjectFor(node->origin.semantic),
3218                 value.m_structure.toStructureSet(),
3219                 m_graph.identifiers()[node->identifierNumber()],
3220                 node->op() == PutByIdDirect);
3221
3222             if (status.isSimple()) {
3223                 RegisteredStructureSet newSet;
3224                 TransitionVector transitions;
3225                 
3226                 for (unsigned i = status.numVariants(); i--;) {
3227                     const PutByIdVariant& variant = status[i];
3228                     if (variant.kind() == PutByIdVariant::Transition) {
3229                         RegisteredStructure newStructure = m_graph.registerStructure(variant.newStructure());
3230                         transitions.append(
3231                             Transition(
3232                                 m_graph.registerStructure(variant.oldStructureForTransition()), newStructure));
3233                         newSet.add(newStructure);
3234                     } else {
3235                         ASSERT(variant.kind() == PutByIdVariant::Replace);
3236                         newSet.merge(*m_graph.addStructureSet(variant.oldStructure()));
3237                     }
3238                 }
3239                 
3240                 if (status.numVariants() == 1 || isFTL(m_graph.m_plan.mode))
3241                     m_state.setFoundConstants(true);
3242                 
3243                 didFoldClobberWorld();
3244                 observeTransitions(clobberLimit, transitions);
3245                 if (forNode(node->child1()).changeStructure(m_graph, newSet) == Contradiction)
3246                     m_state.setIsValid(false);
3247                 break;
3248             }
3249         }
3250         
3251         clobberWorld();
3252         break;
3253     }
3254
3255     case PutByValWithThis:
3256     case PutByIdWithThis:
3257         clobberWorld();
3258         break;
3259
3260     case PutGetterById:
3261     case PutSetterById:
3262     case PutGetterSetterById:
3263     case PutGetterByVal:
3264     case PutSetterByVal: {
3265         clobberWorld();
3266         break;
3267     }
3268
3269     case DefineDataProperty:
3270     case DefineAccessorProperty:
3271         clobberWorld();
3272         break;
3273         
3274     case InById: {
3275         // FIXME: We can determine when the property definitely exists based on abstract
3276         // value information.
3277         clobberWorld();
3278         filter(node->child1(), SpecObject);
3279         setNonCellTypeForNode(node, SpecBoolean);
3280         break;
3281     }
3282
3283     case InByVal: {
3284         AbstractValue& property = forNode(node->child2());
3285         if (JSValue constant = property.value()) {
3286             if (constant.isString()) {
3287                 JSString* string = asString(constant);
3288                 const StringImpl* impl = string->tryGetValueImpl();
3289                 if (impl && impl->isAtomic())
3290                     m_state.setFoundConstants(true);
3291             }
3292         }
3293
3294         // FIXME: We can determine when the property definitely exists based on abstract
3295         // value information.
3296         clobberWorld();
3297         filter(node->child1(), SpecObject);
3298         setNonCellTypeForNode(node, SpecBoolean);
3299         break;
3300     }
3301
3302     case HasOwnProperty: {
3303         clobberWorld();
3304         setNonCellTypeForNode(node, SpecBoolean);
3305         break;
3306     }
3307             
3308     case GetEnumerableLength: {
3309         setNonCellTypeForNode(node, SpecInt32Only);
3310         break;
3311     }
3312     case HasGenericProperty: {
3313         setNonCellTypeForNode(node, SpecBoolean);
3314         clobberWorld();
3315         break;
3316     }
3317     case HasStructureProperty: {
3318         setNonCellTypeForNode(node, SpecBoolean);
3319         clobberWorld();
3320         break;
3321     }
3322     case HasIndexedProperty: {
3323         ArrayMode mode = node->arrayMode();
3324         switch (mode.type()) {
3325         case Array::Int32:
3326         case Array::Double:
3327         case Array::Contiguous:
3328         case Array::ArrayStorage: {
3329             break;
3330         }
3331         default: {
3332             clobberWorld();
3333             break;
3334         }
3335         }
3336         setNonCellTypeForNode(node, SpecBoolean);
3337         break;
3338     }
3339     case GetDirectPname: {
3340         clobberWorld();
3341         makeHeapTopForNode(node);
3342         break;
3343     }
3344     case GetPropertyEnumerator: {
3345         setTypeForNode(node, SpecCell);
3346         clobberWorld();
3347         break;
3348     }
3349     case GetEnumeratorStructurePname: {
3350         setTypeForNode(node, SpecString | SpecOther);
3351         break;
3352     }
3353     case GetEnumeratorGenericPname: {
3354         setTypeForNode(node, SpecString | SpecOther);
3355         break;
3356     }
3357     case ToIndexString: {
3358         setTypeForNode(node, SpecString);
3359         break;
3360     }
3361
3362     case GetGlobalVar:
3363         makeHeapTopForNode(node);
3364         break;
3365
3366     case GetGlobalLexicalVariable:
3367         makeBytecodeTopForNode(node);
3368         break;
3369
3370     case GetDynamicVar:
3371         clobberWorld();
3372         makeBytecodeTopForNode(node);
3373         break;
3374
3375     case PutDynamicVar:
3376         clobberWorld();
3377         break;
3378
3379     case ResolveScope:
3380         clobberWorld();
3381         setTypeForNode(node, SpecObject);
3382         break;
3383
3384     case ResolveScopeForHoistingFuncDeclInEval:
3385         clobberWorld();
3386         makeBytecodeTopForNode(node);
3387         break;
3388
3389     case PutGlobalVariable:
3390     case NotifyWrite:
3391         break;
3392
3393     case OverridesHasInstance:
3394         setNonCellTypeForNode(node, SpecBoolean);
3395         break;
3396             
3397     case InstanceOf:
3398         clobberWorld();
3399         setNonCellTypeForNode(node, SpecBoolean);
3400         break;
3401
3402     case InstanceOfCustom:
3403         clobberWorld();
3404         setNonCellTypeForNode(node, SpecBoolean);
3405         break;
3406         
3407     case MatchStructure: {
3408         AbstractValue base = forNode(node->child1());
3409         RegisteredStructureSet baseSet;
3410         
3411         BooleanLattice result = BooleanLattice::Bottom;
3412         for (MatchStructureVariant& variant : node->matchStructureData().variants) {
3413             RegisteredStructure structure = variant.structure;
3414             if (!base.contains(structure)) {
3415                 m_state.setFoundConstants(true);
3416                 continue;
3417             }
3418             
3419             baseSet.add(structure);
3420             result = leastUpperBoundOfBooleanLattices(
3421                 result, variant.result ? BooleanLattice::True : BooleanLattice::False);
3422         }
3423         
3424         if (forNode(node->child1()).changeStructure(m_graph, baseSet) == Contradiction)
3425             m_state.setIsValid(false);
3426         
3427         switch (result) {
3428         case BooleanLattice::False:
3429             setConstant(node, jsBoolean(false));
3430             break;
3431         case BooleanLattice::True:
3432             setConstant(node, jsBoolean(true));
3433             break;
3434         default:
3435             setNonCellTypeForNode(node, SpecBoolean);
3436             break;
3437         }
3438         break;
3439     }
3440             
3441     case Phi:
3442         RELEASE_ASSERT(m_graph.m_form == SSA);
3443         setForNode(node, forNode(NodeFlowProjection(node, NodeFlowProjection::Shadow)));
3444         // The state of this node would have already been decided, but it may have become a
3445         // constant, in which case we'd like to know.
3446         if (forNode(node).m_value)
3447             m_state.setFoundConstants(true);
3448         break;
3449         
3450     case Upsilon: {
3451         NodeFlowProjection shadow(node->phi(), NodeFlowProjection::Shadow);
3452         if (shadow.isStillValid()) {
3453             m_state.createValueForNode(shadow);
3454             setForNode(shadow, forNode(node->child1()));
3455         }
3456         break;
3457     }
3458         
3459     case Flush:
3460     case PhantomLocal:
3461         break;
3462             
3463     case Call:
3464     case TailCallInlinedCaller:
3465     case Construct:
3466     case CallVarargs:
3467     case CallForwardVarargs:
3468     case TailCallVarargsInlinedCaller:
3469     case ConstructVarargs:
3470     case ConstructForwardVarargs:
3471     case TailCallForwardVarargsInlinedCaller:
3472     case CallEval:
3473     case DirectCall:
3474     case DirectConstruct:
3475     case DirectTailCallInlinedCaller:
3476         clobberWorld();
3477         makeHeapTopForNode(node);
3478         break;
3479
3480     case ForceOSRExit:
3481     case CheckBadCell:
3482         m_state.setIsValid(false);
3483         break;
3484         
3485     case InvalidationPoint:
3486         m_state.setStructureClobberState(StructuresAreWatched);
3487         m_state.observeInvalidationPoint();
3488         break;
3489
3490     case CPUIntrinsic: 
3491         if (node->intrinsic() == CPURdtscIntrinsic)
3492             setNonCellTypeForNode(node, SpecInt32Only);
3493         else
3494             setNonCellTypeForNode(node, SpecOther);
3495         break;
3496
3497     case CheckTraps:
3498     case LogShadowChickenPrologue:
3499     case LogShadowChickenTail:
3500     case ProfileType:
3501     case ProfileControlFlow:
3502     case Phantom:
3503     case CountExecution:
3504