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