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