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