339ab5ec5d7e817589d66d264e4021d77b5ee323
[WebKit.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()->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()->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())));
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         }
2767         break;
2768     case GetButterfly:
2769     case AllocatePropertyStorage:
2770     case ReallocatePropertyStorage:
2771     case NukeStructureAndSetButterfly:
2772         // FIXME: We don't model the fact that the structureID is nuked, simply because currently
2773         // nobody would currently benefit from having that information. But it's a bug nonetheless.
2774         if (node->op() == NukeStructureAndSetButterfly)
2775             didFoldClobberStructures();
2776         clearForNode(node); // The result is not a JS value.
2777         break;
2778     case CheckSubClass: {
2779         JSValue constant = forNode(node->child1()).value();
2780         if (constant) {
2781             if (constant.isCell() && constant.asCell()->inherits(m_vm, node->classInfo())) {
2782                 m_state.setFoundConstants(true);
2783                 ASSERT(constant);
2784                 break;
2785             }
2786         }
2787
2788         AbstractValue& value = forNode(node->child1());
2789
2790         if (value.m_structure.isSubClassOf(node->classInfo()))
2791             m_state.setFoundConstants(true);
2792
2793         filterClassInfo(value, node->classInfo());
2794         break;
2795     }
2796     case CallDOMGetter: {
2797         CallDOMGetterData* callDOMGetterData = node->callDOMGetterData();
2798         DOMJIT::CallDOMGetterSnippet* snippet = callDOMGetterData->snippet;
2799         if (!snippet || snippet->effect.writes)
2800             clobberWorld();
2801         if (callDOMGetterData->domJIT)
2802             setTypeForNode(node, callDOMGetterData->domJIT->resultType());
2803         else
2804             makeBytecodeTopForNode(node);
2805         break;
2806     }
2807     case CallDOM: {
2808         const DOMJIT::Signature* signature = node->signature();
2809         if (signature->effect.writes)
2810             clobberWorld();
2811         setTypeForNode(node, signature->result);
2812         break;
2813     }
2814     case CheckArray: {
2815         if (node->arrayMode().alreadyChecked(m_graph, node, forNode(node->child1()))) {
2816             m_state.setFoundConstants(true);
2817             break;
2818         }
2819         switch (node->arrayMode().type()) {
2820         case Array::String:
2821             filter(node->child1(), SpecString);
2822             break;
2823         case Array::Int32:
2824         case Array::Double:
2825         case Array::Contiguous:
2826         case Array::Undecided:
2827         case Array::ArrayStorage:
2828         case Array::SlowPutArrayStorage:
2829             break;
2830         case Array::DirectArguments:
2831             filter(node->child1(), SpecDirectArguments);
2832             break;
2833         case Array::ScopedArguments:
2834             filter(node->child1(), SpecScopedArguments);
2835             break;
2836         case Array::Int8Array:
2837             filter(node->child1(), SpecInt8Array);
2838             break;
2839         case Array::Int16Array:
2840             filter(node->child1(), SpecInt16Array);
2841             break;
2842         case Array::Int32Array:
2843             filter(node->child1(), SpecInt32Array);
2844             break;
2845         case Array::Uint8Array:
2846             filter(node->child1(), SpecUint8Array);
2847             break;
2848         case Array::Uint8ClampedArray:
2849             filter(node->child1(), SpecUint8ClampedArray);
2850             break;
2851         case Array::Uint16Array:
2852             filter(node->child1(), SpecUint16Array);
2853             break;
2854         case Array::Uint32Array:
2855             filter(node->child1(), SpecUint32Array);
2856             break;
2857         case Array::Float32Array:
2858             filter(node->child1(), SpecFloat32Array);
2859             break;
2860         case Array::Float64Array:
2861             filter(node->child1(), SpecFloat64Array);
2862             break;
2863         case Array::AnyTypedArray:
2864             filter(node->child1(), SpecTypedArrayView);
2865             break;
2866         default:
2867             RELEASE_ASSERT_NOT_REACHED();
2868             break;
2869         }
2870         filterArrayModes(node->child1(), node->arrayMode().arrayModesThatPassFiltering());
2871         break;
2872     }
2873     case Arrayify: {
2874         if (node->arrayMode().alreadyChecked(m_graph, node, forNode(node->child1()))) {
2875             didFoldClobberStructures();
2876             m_state.setFoundConstants(true);
2877             break;
2878         }
2879         ASSERT(node->arrayMode().conversion() == Array::Convert);
2880         clobberStructures();
2881         filterArrayModes(node->child1(), node->arrayMode().arrayModesThatPassFiltering());
2882         break;
2883     }
2884     case ArrayifyToStructure: {
2885         AbstractValue& value = forNode(node->child1());
2886         if (value.m_structure.isSubsetOf(RegisteredStructureSet(node->structure())))
2887             m_state.setFoundConstants(true);
2888         clobberStructures();
2889         
2890         // We have a bunch of options of how to express the abstract set at this point. Let set S
2891         // be the set of structures that the value had before clobbering and assume that all of
2892         // them are watchable. The new value should be the least expressible upper bound of the
2893         // intersection of "values that currently have structure = node->structure()" and "values
2894         // that have structure in S plus any structure transition-reachable from S". Assume that
2895         // node->structure() is not in S but it is transition-reachable from S. Then we would
2896         // like to say that the result is "values that have structure = node->structure() until
2897         // we invalidate", but there is no way to express this using the AbstractValue syntax. So
2898         // we must choose between:
2899         //
2900         // 1) "values that currently have structure = node->structure()". This is a valid
2901         //    superset of the value that we really want, and it's specific enough to satisfy the
2902         //    preconditions of the array access that this is guarding. It's also specific enough
2903         //    to allow relevant optimizations in the case that we didn't have a contradiction
2904         //    like in this example. Notice that in the abscence of any contradiction, this result
2905         //    is precise rather than being a conservative LUB.
2906         //
2907         // 2) "values that currently hava structure in S plus any structure transition-reachable
2908         //    from S". This is also a valid superset of the value that we really want, but it's
2909         //    not specific enough to satisfy the preconditions of the array access that this is
2910         //    guarding - so playing such shenanigans would preclude us from having assertions on
2911         //    the typing preconditions of any array accesses. This would also not be a desirable
2912         //    answer in the absence of a contradiction.
2913         //
2914         // Note that it's tempting to simply say that the resulting value is BOTTOM because of
2915         // the contradiction. That would be wrong, since we haven't hit an invalidation point,
2916         // yet.
2917         forNode(node->child1()).set(m_graph, node->structure());
2918         break;
2919     }
2920     case GetIndexedPropertyStorage: {
2921         JSArrayBufferView* view = m_graph.tryGetFoldableView(
2922             forNode(node->child1()).m_value, node->arrayMode());
2923         if (view)
2924             m_state.setFoundConstants(true);
2925         clearForNode(node);
2926         break;
2927     }
2928     case ConstantStoragePointer: {
2929         clearForNode(node);
2930         break; 
2931     }
2932         
2933     case GetTypedArrayByteOffset: {
2934         JSArrayBufferView* view = m_graph.tryGetFoldableView(forNode(node->child1()).m_value);
2935         if (view) {
2936             setConstant(node, jsNumber(view->byteOffset()));
2937             break;
2938         }
2939         setNonCellTypeForNode(node, SpecInt32Only);
2940         break;
2941     }
2942
2943     case GetPrototypeOf: {
2944         AbstractValue& value = forNode(node->child1());
2945         if ((value.m_type && !(value.m_type & ~SpecObject)) && value.m_structure.isFinite()) {
2946             bool canFold = !value.m_structure.isClear();
2947             JSValue prototype;
2948             value.m_structure.forEach([&] (RegisteredStructure structure) {
2949                 auto getPrototypeMethod = structure->classInfo()->methodTable.getPrototype;
2950                 MethodTable::GetPrototypeFunctionPtr defaultGetPrototype = JSObject::getPrototype;
2951                 if (getPrototypeMethod != defaultGetPrototype) {
2952                     canFold = false;
2953                     return;
2954                 }
2955
2956                 if (structure->hasPolyProto()) {
2957                     canFold = false;
2958                     return;
2959                 }
2960                 if (!prototype)
2961                     prototype = structure->storedPrototype();
2962                 else if (prototype != structure->storedPrototype())
2963                     canFold = false;
2964             });
2965
2966             if (prototype && canFold) {
2967                 switch (node->child1().useKind()) {
2968                 case ArrayUse:
2969                 case FunctionUse:
2970                 case FinalObjectUse:
2971                     break;
2972                 default:
2973                     didFoldClobberWorld();
2974                     break;
2975                 }
2976                 setConstant(node, *m_graph.freeze(prototype));
2977                 break;
2978             }
2979         }
2980
2981         switch (node->child1().useKind()) {
2982         case ArrayUse:
2983         case FunctionUse:
2984         case FinalObjectUse:
2985             break;
2986         default:
2987             clobberWorld();
2988             break;
2989         }
2990         setTypeForNode(node, SpecObject | SpecOther);
2991         break;
2992     }
2993         
2994     case GetByOffset: {
2995         StorageAccessData& data = node->storageAccessData();
2996         UniquedStringImpl* uid = m_graph.identifiers()[data.identifierNumber];
2997
2998         // FIXME: The part of this that handles inferred property types relies on AI knowing the structure
2999         // right now. That's probably not optimal. In some cases, we may perform an optimization (usually
3000         // by something other than AI, maybe by CSE for example) that obscures AI's view of the structure
3001         // at the point where GetByOffset runs. Currently, when that happens, we'll have to rely entirely
3002         // on the type that ByteCodeParser was able to prove.
3003         AbstractValue value = m_graph.inferredValueForProperty(
3004             forNode(node->child2()), uid, data.offset, m_state.structureClobberState());
3005
3006         // It's possible that the type that ByteCodeParser came up with is better.
3007         AbstractValue typeFromParsing;
3008         typeFromParsing.set(m_graph, data.inferredType, m_state.structureClobberState());
3009         value.filter(typeFromParsing);
3010
3011         // If we decide that there does not exist any value that this can return, then it's probably
3012         // because the compilation was already invalidated.
3013         if (value.isClear())
3014             m_state.setIsValid(false);
3015
3016         setForNode(node, value);
3017         if (value.m_value)
3018             m_state.setFoundConstants(true);
3019         break;
3020     }
3021         
3022     case GetGetterSetterByOffset: {
3023         StorageAccessData& data = node->storageAccessData();
3024         JSValue result = m_graph.tryGetConstantProperty(forNode(node->child2()), data.offset);
3025         if (result && jsDynamicCast<GetterSetter*>(m_vm, result)) {
3026             setConstant(node, *m_graph.freeze(result));
3027             break;
3028         }
3029         
3030         setForNode(node, m_graph.globalObjectFor(node->origin.semantic)->getterSetterStructure());
3031         break;
3032     }
3033         
3034     case MultiGetByOffset: {
3035         // This code will filter the base value in a manner that is possibly different (either more
3036         // or less precise) than the way it would be filtered if this was strength-reduced to a
3037         // CheckStructure. This is fine. It's legal for different passes over the code to prove
3038         // different things about the code, so long as all of them are sound. That even includes
3039         // one guy proving that code should never execute (due to a contradiction) and another guy
3040         // not finding that contradiction. If someone ever proved that there would be a
3041         // contradiction then there must always be a contradiction even if subsequent passes don't
3042         // realize it. This is the case here.
3043         
3044         // Ordinarily you have to be careful with calling setFoundConstants()
3045         // because of the effect on compile times, but this node is FTL-only.
3046         m_state.setFoundConstants(true);
3047         
3048         UniquedStringImpl* uid = m_graph.identifiers()[node->multiGetByOffsetData().identifierNumber];
3049
3050         AbstractValue base = forNode(node->child1());
3051         RegisteredStructureSet baseSet;
3052         AbstractValue result;
3053         for (const MultiGetByOffsetCase& getCase : node->multiGetByOffsetData().cases) {
3054             RegisteredStructureSet set = getCase.set();
3055             set.filter(base);
3056             if (set.isEmpty())
3057                 continue;
3058             baseSet.merge(set);
3059
3060             switch (getCase.method().kind()) {
3061             case GetByOffsetMethod::Constant: {
3062                 AbstractValue thisResult;
3063                 thisResult.set(
3064                     m_graph,
3065                     *getCase.method().constant(),
3066                     m_state.structureClobberState());
3067                 result.merge(thisResult);
3068                 break;
3069             }
3070
3071             case GetByOffsetMethod::Load: {
3072                 result.merge(
3073                     m_graph.inferredValueForProperty(
3074                         set, uid, m_state.structureClobberState()));
3075                 break;
3076             }
3077
3078             default: {
3079                 result.makeHeapTop();
3080                 break;
3081             } }
3082         }
3083         
3084         if (forNode(node->child1()).changeStructure(m_graph, baseSet) == Contradiction)
3085             m_state.setIsValid(false);
3086         
3087         setForNode(node, result);
3088         break;
3089     }
3090             
3091     case PutByOffset: {
3092         break;
3093     }
3094         
3095     case MultiPutByOffset: {
3096         RegisteredStructureSet newSet;
3097         TransitionVector transitions;
3098         
3099         // Ordinarily you have to be careful with calling setFoundConstants()
3100         // because of the effect on compile times, but this node is FTL-only.
3101         m_state.setFoundConstants(true);
3102         
3103         AbstractValue base = forNode(node->child1());
3104         AbstractValue originalValue = forNode(node->child2());
3105         AbstractValue resultingValue;
3106         
3107         if (node->multiPutByOffsetData().writesStructures())
3108             didFoldClobberStructures();
3109             
3110         for (unsigned i = node->multiPutByOffsetData().variants.size(); i--;) {
3111             const PutByIdVariant& variant = node->multiPutByOffsetData().variants[i];
3112             RegisteredStructureSet thisSet = *m_graph.addStructureSet(variant.oldStructure());
3113             thisSet.filter(base);
3114             if (thisSet.isEmpty())
3115                 continue;
3116
3117             AbstractValue thisValue = originalValue;
3118             thisValue.filter(m_graph, variant.requiredType());
3119             resultingValue.merge(thisValue);
3120             
3121             if (variant.kind() == PutByIdVariant::Transition) {
3122                 RegisteredStructure newStructure = m_graph.registerStructure(variant.newStructure());
3123                 if (thisSet.onlyStructure() != newStructure) {
3124                     transitions.append(
3125                         Transition(m_graph.registerStructure(variant.oldStructureForTransition()), newStructure));
3126                 } // else this is really a replace.
3127                 newSet.add(newStructure);
3128             } else {
3129                 ASSERT(variant.kind() == PutByIdVariant::Replace);
3130                 newSet.merge(thisSet);
3131             }
3132         }
3133         
3134         observeTransitions(clobberLimit, transitions);
3135         if (forNode(node->child1()).changeStructure(m_graph, newSet) == Contradiction)
3136             m_state.setIsValid(false);
3137         setForNode(node->child2(), resultingValue);
3138         if (!!originalValue && !resultingValue)
3139             m_state.setIsValid(false);
3140         break;
3141     }
3142         
3143     case GetExecutable: {
3144         JSValue value = forNode(node->child1()).value();
3145         if (value) {
3146             JSFunction* function = jsDynamicCast<JSFunction*>(m_vm, value);
3147             if (function) {
3148                 setConstant(node, *m_graph.freeze(function->executable()));
3149                 break;
3150             }
3151         }
3152         setTypeForNode(node, SpecCellOther);
3153         break;
3154     }
3155     
3156     case CheckCell: {
3157         JSValue value = forNode(node->child1()).value();
3158         if (value == node->cellOperand()->value()) {
3159             m_state.setFoundConstants(true);
3160             ASSERT(value);
3161             break;
3162         }
3163         filterByValue(node->child1(), *node->cellOperand());
3164         break;
3165     }
3166
3167     case AssertNotEmpty:
3168     case CheckNotEmpty: {
3169         AbstractValue& value = forNode(node->child1());
3170         if (!(value.m_type & SpecEmpty)) {
3171             m_state.setFoundConstants(true);
3172             break;
3173         }
3174         
3175         filter(value, ~SpecEmpty);
3176         break;
3177     }
3178
3179     case CheckStringIdent: {
3180         AbstractValue& value = forNode(node->child1());
3181         UniquedStringImpl* uid = node->uidOperand();
3182         ASSERT(!(value.m_type & ~SpecStringIdent)); // Edge filtering should have already ensured this.
3183
3184         JSValue childConstant = value.value();
3185         if (childConstant) {
3186             ASSERT(childConstant.isString());
3187             if (asString(childConstant)->tryGetValueImpl() == uid) {
3188                 m_state.setFoundConstants(true);
3189                 break;
3190             }
3191         }
3192
3193         filter(value, SpecStringIdent);
3194         break;
3195     }
3196
3197     case CheckInBounds: {
3198         JSValue left = forNode(node->child1()).value();
3199         JSValue right = forNode(node->child2()).value();
3200         if (left && right && left.isInt32() && right.isInt32()
3201             && static_cast<uint32_t>(left.asInt32()) < static_cast<uint32_t>(right.asInt32())) {
3202             m_state.setFoundConstants(true);
3203             break;
3204         }
3205         break;
3206     }
3207         
3208     case PutById:
3209     case PutByIdFlush:
3210     case PutByIdDirect: {
3211         AbstractValue& value = forNode(node->child1());
3212         if (value.m_structure.isFinite()) {
3213             PutByIdStatus status = PutByIdStatus::computeFor(
3214                 m_graph.globalObjectFor(node->origin.semantic),
3215                 value.m_structure.toStructureSet(),
3216                 m_graph.identifiers()[node->identifierNumber()],
3217                 node->op() == PutByIdDirect);
3218
3219             if (status.isSimple()) {
3220                 RegisteredStructureSet newSet;
3221                 TransitionVector transitions;
3222                 
3223                 for (unsigned i = status.numVariants(); i--;) {
3224                     const PutByIdVariant& variant = status[i];
3225                     if (variant.kind() == PutByIdVariant::Transition) {
3226                         RegisteredStructure newStructure = m_graph.registerStructure(variant.newStructure());
3227                         transitions.append(
3228                             Transition(
3229                                 m_graph.registerStructure(variant.oldStructureForTransition()), newStructure));
3230                         newSet.add(newStructure);
3231                     } else {
3232                         ASSERT(variant.kind() == PutByIdVariant::Replace);
3233                         newSet.merge(*m_graph.addStructureSet(variant.oldStructure()));
3234                     }
3235                 }
3236                 
3237                 if (status.numVariants() == 1 || isFTL(m_graph.m_plan.mode))
3238                     m_state.setFoundConstants(true);
3239                 
3240                 didFoldClobberWorld();
3241                 observeTransitions(clobberLimit, transitions);
3242                 if (forNode(node->child1()).changeStructure(m_graph, newSet) == Contradiction)
3243                     m_state.setIsValid(false);
3244                 break;
3245             }
3246         }
3247         
3248         clobberWorld();
3249         break;
3250     }
3251
3252     case PutByValWithThis:
3253     case PutByIdWithThis:
3254         clobberWorld();
3255         break;
3256
3257     case PutGetterById:
3258     case PutSetterById:
3259     case PutGetterSetterById:
3260     case PutGetterByVal:
3261     case PutSetterByVal: {
3262         clobberWorld();
3263         break;
3264     }
3265
3266     case DefineDataProperty:
3267     case DefineAccessorProperty:
3268         clobberWorld();
3269         break;
3270         
3271     case InById: {
3272         // FIXME: We can determine when the property definitely exists based on abstract
3273         // value information.
3274         clobberWorld();
3275         filter(node->child1(), SpecObject);
3276         setNonCellTypeForNode(node, SpecBoolean);
3277         break;
3278     }
3279
3280     case InByVal: {
3281         AbstractValue& property = forNode(node->child2());
3282         if (JSValue constant = property.value()) {
3283             if (constant.isString()) {
3284                 JSString* string = asString(constant);
3285                 const StringImpl* impl = string->tryGetValueImpl();
3286                 if (impl && impl->isAtomic())
3287                     m_state.setFoundConstants(true);
3288             }
3289         }
3290
3291         // FIXME: We can determine when the property definitely exists based on abstract
3292         // value information.
3293         clobberWorld();
3294         filter(node->child1(), SpecObject);
3295         setNonCellTypeForNode(node, SpecBoolean);
3296         break;
3297     }
3298
3299     case HasOwnProperty: {
3300         clobberWorld();
3301         setNonCellTypeForNode(node, SpecBoolean);
3302         break;
3303     }
3304             
3305     case GetEnumerableLength: {
3306         setNonCellTypeForNode(node, SpecInt32Only);
3307         break;
3308     }
3309     case HasGenericProperty: {
3310         setNonCellTypeForNode(node, SpecBoolean);
3311         clobberWorld();
3312         break;
3313     }
3314     case HasStructureProperty: {
3315         setNonCellTypeForNode(node, SpecBoolean);
3316         clobberWorld();
3317         break;
3318     }
3319     case HasIndexedProperty: {
3320         ArrayMode mode = node->arrayMode();
3321         switch (mode.type()) {
3322         case Array::Int32:
3323         case Array::Double:
3324         case Array::Contiguous:
3325         case Array::ArrayStorage: {
3326             break;
3327         }
3328         default: {
3329             clobberWorld();
3330             break;
3331         }
3332         }
3333         setNonCellTypeForNode(node, SpecBoolean);
3334         break;
3335     }
3336     case GetDirectPname: {
3337         clobberWorld();
3338         makeHeapTopForNode(node);
3339         break;
3340     }
3341     case GetPropertyEnumerator: {
3342         setTypeForNode(node, SpecCell);
3343         clobberWorld();
3344         break;
3345     }
3346     case GetEnumeratorStructurePname: {
3347         setTypeForNode(node, SpecString | SpecOther);
3348         break;
3349     }
3350     case GetEnumeratorGenericPname: {
3351         setTypeForNode(node, SpecString | SpecOther);
3352         break;
3353     }
3354     case ToIndexString: {
3355         setTypeForNode(node, SpecString);
3356         break;
3357     }
3358
3359     case GetGlobalVar:
3360         makeHeapTopForNode(node);
3361         break;
3362
3363     case GetGlobalLexicalVariable:
3364         makeBytecodeTopForNode(node);
3365         break;
3366
3367     case GetDynamicVar:
3368         clobberWorld();
3369         makeBytecodeTopForNode(node);
3370         break;
3371
3372     case PutDynamicVar:
3373         clobberWorld();
3374         break;
3375
3376     case ResolveScope:
3377         clobberWorld();
3378         setTypeForNode(node, SpecObject);
3379         break;
3380
3381     case ResolveScopeForHoistingFuncDeclInEval:
3382         clobberWorld();
3383         makeBytecodeTopForNode(node);
3384         break;
3385
3386     case PutGlobalVariable:
3387     case NotifyWrite:
3388         break;
3389
3390     case OverridesHasInstance:
3391         setNonCellTypeForNode(node, SpecBoolean);
3392         break;
3393             
3394     case InstanceOf:
3395         clobberWorld();
3396         setNonCellTypeForNode(node, SpecBoolean);
3397         break;
3398
3399     case InstanceOfCustom:
3400         clobberWorld();
3401         setNonCellTypeForNode(node, SpecBoolean);
3402         break;
3403         
3404     case MatchStructure: {
3405         AbstractValue base = forNode(node->child1());
3406         RegisteredStructureSet baseSet;
3407         
3408         BooleanLattice result = BooleanLattice::Bottom;
3409         for (MatchStructureVariant& variant : node->matchStructureData().variants) {
3410             RegisteredStructure structure = variant.structure;
3411             if (!base.contains(structure)) {
3412                 m_state.setFoundConstants(true);
3413                 continue;
3414             }
3415             
3416             baseSet.add(structure);
3417             result = leastUpperBoundOfBooleanLattices(
3418                 result, variant.result ? BooleanLattice::True : BooleanLattice::False);
3419         }
3420         
3421         if (forNode(node->child1()).changeStructure(m_graph, baseSet) == Contradiction)
3422             m_state.setIsValid(false);
3423         
3424         switch (result) {
3425         case BooleanLattice::False:
3426             setConstant(node, jsBoolean(false));
3427             break;
3428         case BooleanLattice::True:
3429             setConstant(node, jsBoolean(true));
3430             break;
3431         default:
3432             setNonCellTypeForNode(node, SpecBoolean);
3433             break;
3434         }
3435         break;
3436     }
3437             
3438     case Phi:
3439         RELEASE_ASSERT(m_graph.m_form == SSA);
3440         setForNode(node, forNode(NodeFlowProjection(node, NodeFlowProjection::Shadow)));
3441         // The state of this node would have already been decided, but it may have become a
3442         // constant, in which case we'd like to know.
3443         if (forNode(node).m_value)
3444             m_state.setFoundConstants(true);
3445         break;
3446         
3447     case Upsilon: {
3448         NodeFlowProjection shadow(node->phi(), NodeFlowProjection::Shadow);
3449         if (shadow.isStillValid()) {
3450             m_state.createValueForNode(shadow);
3451             setForNode(shadow, forNode(node->child1()));
3452         }
3453         break;
3454     }
3455         
3456     case Flush:
3457     case PhantomLocal:
3458         break;
3459             
3460     case Call:
3461     case TailCallInlinedCaller:
3462     case Construct:
3463     case CallVarargs:
3464     case CallForwardVarargs:
3465     case TailCallVarargsInlinedCaller:
3466     case ConstructVarargs:
3467     case ConstructForwardVarargs:
3468     case TailCallForwardVarargsInlinedCaller:
3469     case CallEval:
3470     case DirectCall:
3471     case DirectConstruct:
3472     case DirectTailCallInlinedCaller:
3473         clobberWorld();
3474         makeHeapTopForNode(node);
3475         break;
3476
3477     case ForceOSRExit:
3478     case CheckBadCell:
3479         m_state.setIsValid(false);
3480         break;
3481         
3482     case InvalidationPoint:
3483         m_state.setStructureClobberState(StructuresAreWatched);
3484         m_state.observeInvalidationPoint();
3485         break;
3486
3487     case CPUIntrinsic: 
3488         if (node->intrinsic() == CPURdtscIntrinsic)
3489             setNonCellTypeForNode(node, SpecInt32Only);
3490         else
3491             setNonCellTypeForNode(node, SpecOther);
3492         break;
3493
3494     case CheckTraps:
3495     case LogShadowChickenPrologue:
3496     case LogShadowChickenTail:
3497     case ProfileType:
3498     case ProfileControlFlow:
3499     case Phantom:
3500     case CountExecution:
3501     case CheckTierUpInLoop:
3502     case CheckTierUpAtReturn:
3503     case SuperSamplerBegin:
3504     case SuperSamplerEnd:
3505     case CheckTierUpAndOSREnter:
3506     case LoopHint:
3507     case ZombieHint:
3508     case ExitOK:
3509         break;
3510
3511     case CheckTypeInfoFlags: {
3512         const AbstractValue& abstractValue = forNode(node->child1());
3513         unsigned bits = node->typeInfoOperand();
3514         ASSERT(bits);
3515         if (bits == ImplementsDefaultHasInstance) {
3516             if (abstractValue.m_type == SpecFunctionWithDefaultHasInstance) {
3517                 m_state.setFoundConstants(true);
3518                 break;
3519             }
3520         }
3521
3522         if (JSValue value = abstractValue.value()) {
3523             if (value.isCell()) {
3524                 // This works because if we see a cell here, we know it's fully constructed
3525                 // and we can read its inline type info flags. These flags don't change over the
3526                 // object's lifetime.
3527                 if ((value.asCell()->inlineTypeFlags() & bits) == bits) {
3528                     m_state.setFoundConstants(true);
3529                     break;
3530                 }
3531             }
3532         }
3533
3534         if (abstractValue.m_structure.isFinite()) {
3535             bool ok = true;
3536             abstractValue.m_structure.forEach([&] (RegisteredStructure structure) {
3537                 ok &= (structure->typeInfo().inlineTypeFlags() & bits) == bits;
3538             });
3539             if (ok) {
3540                 m_state.setFoundConstants(true);
3541                 break;
3542             }
3543         }
3544
3545         break;
3546     }
3547
3548     case ParseInt: {
3549         AbstractValue value = forNode(node->child1());
3550         if (value.m_type && !(value.m_type & ~SpecInt32Only)) {
3551             JSValue radix;
3552             if (!node->child2())
3553                 radix = jsNumber(0);
3554             else
3555                 radix = forNode(node->child2()).m_value;
3556
3557             if (radix.isNumber()
3558                 && (radix.asNumber() == 0 || radix.asNumber() == 10)) {
3559                 m_state.setFoundConstants(true);
3560                 if (node->child1().useKind() == UntypedUse)
3561                     didFoldClobberWorld();
3562                 setNonCellTypeForNode(node, SpecInt32Only);
3563                 break;
3564             }
3565         }
3566
3567         if (node->child1().useKind() == UntypedUse)
3568             clobberWorld();
3569         setNonCellTypeForNode(node, SpecBytecodeNumber);
3570         break;
3571     }
3572
3573     case CreateRest:
3574         if (!m_graph.isWatchingHavingABadTimeWatchpoint(node)) {
3575             // This means we're already having a bad time.
3576             clobberWorld();
3577             setTypeForNode(node, SpecArray);