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