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