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