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