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