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