Unreviewed, rolling out r194135.
[WebKit-https.git] / Source / JavaScriptCore / dfg / DFGAbstractInterpreterInlines.h
1 /*
2  * Copyright (C) 2013-2015 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         JSValue operand = forNode(node->child1()).value();
838         if (operand && operand.isNumber()) {
839             double roundedValue = jsRound(operand.asNumber());
840
841             if (producesInteger(node->arithRoundingMode())) {
842                 int32_t roundedValueAsInt32 = static_cast<int32_t>(roundedValue);
843                 if (roundedValueAsInt32 == roundedValue) {
844                     if (shouldCheckNegativeZero(node->arithRoundingMode())) {
845                         if (roundedValueAsInt32 || !std::signbit(roundedValue)) {
846                             setConstant(node, jsNumber(roundedValueAsInt32));
847                             break;
848                         }
849                     } else {
850                         setConstant(node, jsNumber(roundedValueAsInt32));
851                         break;
852                     }
853                 }
854             } else {
855                 setConstant(node, jsDoubleNumber(roundedValue));
856                 break;
857             }
858         }
859         if (producesInteger(node->arithRoundingMode()))
860             forNode(node).setType(SpecInt32);
861         else
862             forNode(node).setType(typeOfDoubleRounding(forNode(node->child1()).m_type));
863         break;
864     }
865             
866     case ArithSqrt: {
867         JSValue child = forNode(node->child1()).value();
868         if (child && child.isNumber()) {
869             setConstant(node, jsDoubleNumber(sqrt(child.asNumber())));
870             break;
871         }
872         forNode(node).setType(typeOfDoubleUnaryOp(forNode(node->child1()).m_type));
873         break;
874     }
875         
876     case ArithFRound: {
877         JSValue child = forNode(node->child1()).value();
878         if (child && child.isNumber()) {
879             setConstant(node, jsDoubleNumber(static_cast<float>(child.asNumber())));
880             break;
881         }
882         forNode(node).setType(typeOfDoubleRounding(forNode(node->child1()).m_type));
883         break;
884     }
885         
886     case ArithSin: {
887         JSValue child = forNode(node->child1()).value();
888         if (child && child.isNumber()) {
889             setConstant(node, jsDoubleNumber(sin(child.asNumber())));
890             break;
891         }
892         forNode(node).setType(typeOfDoubleUnaryOp(forNode(node->child1()).m_type));
893         break;
894     }
895     
896     case ArithCos: {
897         JSValue child = forNode(node->child1()).value();
898         if (child && child.isNumber()) {
899             setConstant(node, jsDoubleNumber(cos(child.asNumber())));
900             break;
901         }
902         forNode(node).setType(typeOfDoubleUnaryOp(forNode(node->child1()).m_type));
903         break;
904     }
905
906     case ArithLog: {
907         JSValue child = forNode(node->child1()).value();
908         if (child && child.isNumber()) {
909             setConstant(node, jsDoubleNumber(log(child.asNumber())));
910             break;
911         }
912         forNode(node).setType(typeOfDoubleUnaryOp(forNode(node->child1()).m_type));
913         break;
914     }
915             
916     case LogicalNot: {
917         switch (booleanResult(node, forNode(node->child1()))) {
918         case DefinitelyTrue:
919             setConstant(node, jsBoolean(false));
920             break;
921         case DefinitelyFalse:
922             setConstant(node, jsBoolean(true));
923             break;
924         default:
925             forNode(node).setType(SpecBoolean);
926             break;
927         }
928         break;
929     }
930         
931     case IsUndefined:
932     case IsBoolean:
933     case IsNumber:
934     case IsString:
935     case IsObject:
936     case IsObjectOrNull:
937     case IsFunction: {
938         AbstractValue child = forNode(node->child1());
939         if (child.value()) {
940             bool constantWasSet = true;
941             switch (node->op()) {
942             case IsUndefined:
943                 setConstant(node, jsBoolean(
944                     child.value().isCell()
945                     ? child.value().asCell()->structure()->masqueradesAsUndefined(m_codeBlock->globalObjectFor(node->origin.semantic))
946                     : child.value().isUndefined()));
947                 break;
948             case IsBoolean:
949                 setConstant(node, jsBoolean(child.value().isBoolean()));
950                 break;
951             case IsNumber:
952                 setConstant(node, jsBoolean(child.value().isNumber()));
953                 break;
954             case IsString:
955                 setConstant(node, jsBoolean(isJSString(child.value())));
956                 break;
957             case IsObject:
958                 setConstant(node, jsBoolean(child.value().isObject()));
959                 break;
960             case IsObjectOrNull:
961                 if (child.value().isObject()) {
962                     JSObject* object = asObject(child.value());
963                     if (object->type() == JSFunctionType)
964                         setConstant(node, jsBoolean(false));
965                     else if (!(object->inlineTypeFlags() & TypeOfShouldCallGetCallData))
966                         setConstant(node, jsBoolean(!child.value().asCell()->structure()->masqueradesAsUndefined(m_codeBlock->globalObjectFor(node->origin.semantic))));
967                     else {
968                         // FIXME: This could just call getCallData.
969                         // https://bugs.webkit.org/show_bug.cgi?id=144457
970                         constantWasSet = false;
971                     }
972                 } else
973                     setConstant(node, jsBoolean(child.value().isNull()));
974                 break;
975             case IsFunction:
976                 if (child.value().isObject()) {
977                     JSObject* object = asObject(child.value());
978                     if (object->type() == JSFunctionType)
979                         setConstant(node, jsBoolean(true));
980                     else if (!(object->inlineTypeFlags() & TypeOfShouldCallGetCallData))
981                         setConstant(node, jsBoolean(false));
982                     else {
983                         // FIXME: This could just call getCallData.
984                         // https://bugs.webkit.org/show_bug.cgi?id=144457
985                         constantWasSet = false;
986                     }
987                 } else
988                     setConstant(node, jsBoolean(false));
989                 break;
990             default:
991                 constantWasSet = false;
992                 break;
993             }
994             if (constantWasSet)
995                 break;
996         }
997         
998         // FIXME: This code should really use AbstractValue::isType() and
999         // AbstractValue::couldBeType().
1000         // https://bugs.webkit.org/show_bug.cgi?id=146870
1001         
1002         bool constantWasSet = false;
1003         switch (node->op()) {
1004         case IsUndefined:
1005             // FIXME: Use the masquerades-as-undefined watchpoint thingy.
1006             // https://bugs.webkit.org/show_bug.cgi?id=144456
1007             
1008             if (!(child.m_type & (SpecOther | SpecObjectOther))) {
1009                 setConstant(node, jsBoolean(false));
1010                 constantWasSet = true;
1011                 break;
1012             }
1013             
1014             break;
1015         case IsBoolean:
1016             if (!(child.m_type & ~SpecBoolean)) {
1017                 setConstant(node, jsBoolean(true));
1018                 constantWasSet = true;
1019                 break;
1020             }
1021             
1022             if (!(child.m_type & SpecBoolean)) {
1023                 setConstant(node, jsBoolean(false));
1024                 constantWasSet = true;
1025                 break;
1026             }
1027             
1028             break;
1029         case IsNumber:
1030             if (!(child.m_type & ~SpecFullNumber)) {
1031                 setConstant(node, jsBoolean(true));
1032                 constantWasSet = true;
1033                 break;
1034             }
1035             
1036             if (!(child.m_type & SpecFullNumber)) {
1037                 setConstant(node, jsBoolean(false));
1038                 constantWasSet = true;
1039                 break;
1040             }
1041             
1042             break;
1043         case IsString:
1044             if (!(child.m_type & ~SpecString)) {
1045                 setConstant(node, jsBoolean(true));
1046                 constantWasSet = true;
1047                 break;
1048             }
1049             
1050             if (!(child.m_type & SpecString)) {
1051                 setConstant(node, jsBoolean(false));
1052                 constantWasSet = true;
1053                 break;
1054             }
1055             
1056             break;
1057         case IsObject:
1058             if (!(child.m_type & ~SpecObject)) {
1059                 setConstant(node, jsBoolean(true));
1060                 constantWasSet = true;
1061                 break;
1062             }
1063             
1064             if (!(child.m_type & SpecObject)) {
1065                 setConstant(node, jsBoolean(false));
1066                 constantWasSet = true;
1067                 break;
1068             }
1069             
1070             break;
1071         case IsObjectOrNull:
1072             // FIXME: Use the masquerades-as-undefined watchpoint thingy.
1073             // https://bugs.webkit.org/show_bug.cgi?id=144456
1074             
1075             // These expressions are complicated to parse. A helpful way to parse this is that
1076             // "!(T & ~S)" means "T is a subset of S". Conversely, "!(T & S)" means "T is a
1077             // disjoint set from S". Things like "T - S" means that, provided that S is a
1078             // subset of T, it's the "set of all things in T but not in S". Things like "T | S"
1079             // mean the "union of T and S".
1080             
1081             // Is the child's type an object that isn't an other-object (i.e. object that could
1082             // have masquaredes-as-undefined traps) and isn't a function?  Then: we should fold
1083             // this to true.
1084             if (!(child.m_type & ~(SpecObject - SpecObjectOther - SpecFunction))) {
1085                 setConstant(node, jsBoolean(true));
1086                 constantWasSet = true;
1087                 break;
1088             }
1089             
1090             // Is the child's type definitely not either of: an object that isn't a function,
1091             // or either undefined or null?  Then: we should fold this to false.  This means
1092             // for example that if it's any non-function object, including those that have
1093             // masquerades-as-undefined traps, then we don't fold. It also means we won't fold
1094             // if it's undefined-or-null, since the type bits don't distinguish between
1095             // undefined (which should fold to false) and null (which should fold to true).
1096             if (!(child.m_type & ((SpecObject - SpecFunction) | SpecOther))) {
1097                 setConstant(node, jsBoolean(false));
1098                 constantWasSet = true;
1099                 break;
1100             }
1101             
1102             break;
1103         case IsFunction:
1104             if (!(child.m_type & ~SpecFunction)) {
1105                 setConstant(node, jsBoolean(true));
1106                 constantWasSet = true;
1107                 break;
1108             }
1109             
1110             if (!(child.m_type & (SpecFunction | SpecObjectOther))) {
1111                 setConstant(node, jsBoolean(false));
1112                 constantWasSet = true;
1113                 break;
1114             }
1115             break;
1116         default:
1117             break;
1118         }
1119         if (constantWasSet)
1120             break;
1121         
1122         forNode(node).setType(SpecBoolean);
1123         break;
1124     }
1125
1126     case TypeOf: {
1127         VM* vm = m_codeBlock->vm();
1128         JSValue child = forNode(node->child1()).value();
1129         AbstractValue& abstractChild = forNode(node->child1());
1130         if (child) {
1131             JSValue typeString = jsTypeStringForValue(*vm, m_codeBlock->globalObjectFor(node->origin.semantic), child);
1132             setConstant(node, *m_graph.freeze(typeString));
1133             break;
1134         }
1135         
1136         if (isFullNumberSpeculation(abstractChild.m_type)) {
1137             setConstant(node, *m_graph.freeze(vm->smallStrings.numberString()));
1138             break;
1139         }
1140         
1141         if (isStringSpeculation(abstractChild.m_type)) {
1142             setConstant(node, *m_graph.freeze(vm->smallStrings.stringString()));
1143             break;
1144         }
1145
1146         // FIXME: We could use the masquerades-as-undefined watchpoint here.
1147         // https://bugs.webkit.org/show_bug.cgi?id=144456
1148         if (!(abstractChild.m_type & ~(SpecObject - SpecObjectOther))) {
1149             setConstant(node, *m_graph.freeze(vm->smallStrings.objectString()));
1150             break;
1151         }
1152         
1153         if (isFunctionSpeculation(abstractChild.m_type)) {
1154             setConstant(node, *m_graph.freeze(vm->smallStrings.functionString()));
1155             break;
1156         }
1157         
1158         if (isBooleanSpeculation(abstractChild.m_type)) {
1159             setConstant(node, *m_graph.freeze(vm->smallStrings.booleanString()));
1160             break;
1161         }
1162
1163         if (isSymbolSpeculation(abstractChild.m_type)) {
1164             setConstant(node, *m_graph.freeze(vm->smallStrings.symbolString()));
1165             break;
1166         }
1167
1168         forNode(node).setType(m_graph, SpecStringIdent);
1169         break;
1170     }
1171             
1172     case CompareLess:
1173     case CompareLessEq:
1174     case CompareGreater:
1175     case CompareGreaterEq:
1176     case CompareEq: {
1177         JSValue leftConst = forNode(node->child1()).value();
1178         JSValue rightConst = forNode(node->child2()).value();
1179         if (leftConst && rightConst) {
1180             if (leftConst.isNumber() && rightConst.isNumber()) {
1181                 double a = leftConst.asNumber();
1182                 double b = rightConst.asNumber();
1183                 switch (node->op()) {
1184                 case CompareLess:
1185                     setConstant(node, jsBoolean(a < b));
1186                     break;
1187                 case CompareLessEq:
1188                     setConstant(node, jsBoolean(a <= b));
1189                     break;
1190                 case CompareGreater:
1191                     setConstant(node, jsBoolean(a > b));
1192                     break;
1193                 case CompareGreaterEq:
1194                     setConstant(node, jsBoolean(a >= b));
1195                     break;
1196                 case CompareEq:
1197                     setConstant(node, jsBoolean(a == b));
1198                     break;
1199                 default:
1200                     RELEASE_ASSERT_NOT_REACHED();
1201                     break;
1202                 }
1203                 break;
1204             }
1205             
1206             if (node->op() == CompareEq && leftConst.isString() && rightConst.isString()) {
1207                 const StringImpl* a = asString(leftConst)->tryGetValueImpl();
1208                 const StringImpl* b = asString(rightConst)->tryGetValueImpl();
1209                 if (a && b) {
1210                     setConstant(node, jsBoolean(WTF::equal(a, b)));
1211                     break;
1212                 }
1213             }
1214
1215             if (node->op() == CompareEq && leftConst.isSymbol() && rightConst.isSymbol()) {
1216                 setConstant(node, jsBoolean(asSymbol(leftConst)->privateName() == asSymbol(rightConst)->privateName()));
1217                 break;
1218             }
1219         }
1220         
1221         if (node->op() == CompareEq) {
1222             SpeculatedType leftType = forNode(node->child1()).m_type;
1223             SpeculatedType rightType = forNode(node->child2()).m_type;
1224             if (!valuesCouldBeEqual(leftType, rightType)) {
1225                 setConstant(node, jsBoolean(false));
1226                 break;
1227             }
1228
1229             if (leftType == SpecOther)
1230                 std::swap(leftType, rightType);
1231             if (rightType == SpecOther) {
1232                 // Undefined and Null are always equal when compared to eachother.
1233                 if (!(leftType & ~SpecOther)) {
1234                     setConstant(node, jsBoolean(true));
1235                     break;
1236                 }
1237
1238                 // Any other type compared to Null or Undefined is always false
1239                 // as long as the MasqueradesAsUndefined watchpoint is valid.
1240                 //
1241                 // MasqueradesAsUndefined only matters for SpecObjectOther, other
1242                 // cases are always "false".
1243                 if (!(leftType & (SpecObjectOther | SpecOther))) {
1244                     setConstant(node, jsBoolean(false));
1245                     break;
1246                 }
1247
1248                 if (!(leftType & SpecOther) && m_graph.masqueradesAsUndefinedWatchpointIsStillValid(node->origin.semantic)) {
1249                     JSGlobalObject* globalObject = m_graph.globalObjectFor(node->origin.semantic);
1250                     m_graph.watchpoints().addLazily(globalObject->masqueradesAsUndefinedWatchpoint());
1251                     setConstant(node, jsBoolean(false));
1252                     break;
1253                 }
1254             }
1255         }
1256         
1257         if (node->child1() == node->child2()) {
1258             if (node->isBinaryUseKind(Int32Use) ||
1259                 node->isBinaryUseKind(Int52RepUse) ||
1260                 node->isBinaryUseKind(StringUse) ||
1261                 node->isBinaryUseKind(BooleanUse) ||
1262                 node->isBinaryUseKind(SymbolUse) ||
1263                 node->isBinaryUseKind(StringIdentUse) ||
1264                 node->isBinaryUseKind(ObjectUse) ||
1265                 node->isBinaryUseKind(ObjectUse, ObjectOrOtherUse) ||
1266                 node->isBinaryUseKind(ObjectOrOtherUse, ObjectUse)) {
1267                 switch (node->op()) {
1268                 case CompareLess:
1269                 case CompareGreater:
1270                     setConstant(node, jsBoolean(false));
1271                     break;
1272                 case CompareLessEq:
1273                 case CompareGreaterEq:
1274                 case CompareEq:
1275                     setConstant(node, jsBoolean(true));
1276                     break;
1277                 default:
1278                     DFG_CRASH(m_graph, node, "Unexpected node type");
1279                     break;
1280                 }
1281                 break;
1282             }
1283         }
1284         
1285         forNode(node).setType(SpecBoolean);
1286         break;
1287     }
1288             
1289     case CompareStrictEq: {
1290         Node* leftNode = node->child1().node();
1291         Node* rightNode = node->child2().node();
1292         JSValue left = forNode(leftNode).value();
1293         JSValue right = forNode(rightNode).value();
1294         if (left && right) {
1295             if (left.isString() && right.isString()) {
1296                 // We need this case because JSValue::strictEqual is otherwise too racy for
1297                 // string comparisons.
1298                 const StringImpl* a = asString(left)->tryGetValueImpl();
1299                 const StringImpl* b = asString(right)->tryGetValueImpl();
1300                 if (a && b) {
1301                     setConstant(node, jsBoolean(WTF::equal(a, b)));
1302                     break;
1303                 }
1304             } else {
1305                 setConstant(node, jsBoolean(JSValue::strictEqual(0, left, right)));
1306                 break;
1307             }
1308         }
1309         
1310         SpeculatedType leftLUB = leastUpperBoundOfStrictlyEquivalentSpeculations(forNode(leftNode).m_type);
1311         SpeculatedType rightLUB = leastUpperBoundOfStrictlyEquivalentSpeculations(forNode(rightNode).m_type);
1312         if (!(leftLUB & rightLUB)) {
1313             setConstant(node, jsBoolean(false));
1314             break;
1315         }
1316         
1317         if (node->child1() == node->child2()) {
1318             if (node->isBinaryUseKind(BooleanUse) ||
1319                 node->isBinaryUseKind(Int32Use) ||
1320                 node->isBinaryUseKind(Int52RepUse) ||
1321                 node->isBinaryUseKind(StringUse) ||
1322                 node->isBinaryUseKind(StringIdentUse) ||
1323                 node->isBinaryUseKind(SymbolUse) ||
1324                 node->isBinaryUseKind(ObjectUse) ||
1325                 node->isBinaryUseKind(MiscUse, UntypedUse) ||
1326                 node->isBinaryUseKind(UntypedUse, MiscUse) ||
1327                 node->isBinaryUseKind(StringIdentUse, NotStringVarUse) ||
1328                 node->isBinaryUseKind(NotStringVarUse, StringIdentUse) ||
1329                 node->isBinaryUseKind(StringUse, UntypedUse) ||
1330                 node->isBinaryUseKind(UntypedUse, StringUse)) {
1331                 setConstant(node, jsBoolean(true));
1332                 break;
1333             }
1334         }
1335
1336         forNode(node).setType(SpecBoolean);
1337         break;
1338     }
1339         
1340     case StringCharCodeAt:
1341         forNode(node).setType(SpecInt32);
1342         break;
1343         
1344     case StringFromCharCode:
1345         forNode(node).setType(m_graph, SpecString);
1346         break;
1347
1348     case StringCharAt:
1349         forNode(node).set(m_graph, m_graph.m_vm.stringStructure.get());
1350         break;
1351             
1352     case GetByVal: {
1353         switch (node->arrayMode().type()) {
1354         case Array::SelectUsingPredictions:
1355         case Array::Unprofiled:
1356         case Array::SelectUsingArguments:
1357             RELEASE_ASSERT_NOT_REACHED();
1358             break;
1359         case Array::ForceExit:
1360             m_state.setIsValid(false);
1361             break;
1362         case Array::Undecided: {
1363             JSValue index = forNode(node->child2()).value();
1364             if (index && index.isInt32() && index.asInt32() >= 0) {
1365                 setConstant(node, jsUndefined());
1366                 break;
1367             }
1368             forNode(node).setType(SpecOther);
1369             break;
1370         }
1371         case Array::Generic:
1372             clobberWorld(node->origin.semantic, clobberLimit);
1373             forNode(node).makeHeapTop();
1374             break;
1375         case Array::String:
1376             if (node->arrayMode().isOutOfBounds()) {
1377                 // If the watchpoint was still valid we could totally set this to be
1378                 // SpecString | SpecOther. Except that we'd have to be careful. If we
1379                 // tested the watchpoint state here then it could change by the time
1380                 // we got to the backend. So to do this right, we'd have to get the
1381                 // fixup phase to check the watchpoint state and then bake into the
1382                 // GetByVal operation the fact that we're using a watchpoint, using
1383                 // something like Array::SaneChain (except not quite, because that
1384                 // implies an in-bounds access). None of this feels like it's worth it,
1385                 // so we're going with TOP for now. The same thing applies to
1386                 // clobbering the world.
1387                 clobberWorld(node->origin.semantic, clobberLimit);
1388                 forNode(node).makeHeapTop();
1389             } else
1390                 forNode(node).set(m_graph, m_graph.m_vm.stringStructure.get());
1391             break;
1392         case Array::DirectArguments:
1393         case Array::ScopedArguments:
1394             forNode(node).makeHeapTop();
1395             break;
1396         case Array::Int32:
1397             if (node->arrayMode().isOutOfBounds()) {
1398                 clobberWorld(node->origin.semantic, clobberLimit);
1399                 forNode(node).makeHeapTop();
1400             } else
1401                 forNode(node).setType(SpecInt32);
1402             break;
1403         case Array::Double:
1404             if (node->arrayMode().isOutOfBounds()) {
1405                 clobberWorld(node->origin.semantic, clobberLimit);
1406                 forNode(node).makeHeapTop();
1407             } else if (node->arrayMode().isSaneChain())
1408                 forNode(node).setType(SpecBytecodeDouble);
1409             else
1410                 forNode(node).setType(SpecDoubleReal);
1411             break;
1412         case Array::Contiguous:
1413         case Array::ArrayStorage:
1414         case Array::SlowPutArrayStorage:
1415             if (node->arrayMode().isOutOfBounds())
1416                 clobberWorld(node->origin.semantic, clobberLimit);
1417             forNode(node).makeHeapTop();
1418             break;
1419         case Array::Int8Array:
1420             forNode(node).setType(SpecInt32);
1421             break;
1422         case Array::Int16Array:
1423             forNode(node).setType(SpecInt32);
1424             break;
1425         case Array::Int32Array:
1426             forNode(node).setType(SpecInt32);
1427             break;
1428         case Array::Uint8Array:
1429             forNode(node).setType(SpecInt32);
1430             break;
1431         case Array::Uint8ClampedArray:
1432             forNode(node).setType(SpecInt32);
1433             break;
1434         case Array::Uint16Array:
1435             forNode(node).setType(SpecInt32);
1436             break;
1437         case Array::Uint32Array:
1438             if (node->shouldSpeculateInt32())
1439                 forNode(node).setType(SpecInt32);
1440             else if (enableInt52() && node->shouldSpeculateMachineInt())
1441                 forNode(node).setType(SpecInt52);
1442             else
1443                 forNode(node).setType(SpecInt52AsDouble);
1444             break;
1445         case Array::Float32Array:
1446             forNode(node).setType(SpecFullDouble);
1447             break;
1448         case Array::Float64Array:
1449             forNode(node).setType(SpecFullDouble);
1450             break;
1451         default:
1452             RELEASE_ASSERT_NOT_REACHED();
1453             break;
1454         }
1455         break;
1456     }
1457             
1458     case PutByValDirect:
1459     case PutByVal:
1460     case PutByValAlias: {
1461         switch (node->arrayMode().modeForPut().type()) {
1462         case Array::ForceExit:
1463             m_state.setIsValid(false);
1464             break;
1465         case Array::Generic:
1466             clobberWorld(node->origin.semantic, clobberLimit);
1467             break;
1468         case Array::Int32:
1469             if (node->arrayMode().isOutOfBounds())
1470                 clobberWorld(node->origin.semantic, clobberLimit);
1471             break;
1472         case Array::Double:
1473             if (node->arrayMode().isOutOfBounds())
1474                 clobberWorld(node->origin.semantic, clobberLimit);
1475             break;
1476         case Array::Contiguous:
1477         case Array::ArrayStorage:
1478             if (node->arrayMode().isOutOfBounds())
1479                 clobberWorld(node->origin.semantic, clobberLimit);
1480             break;
1481         case Array::SlowPutArrayStorage:
1482             if (node->arrayMode().mayStoreToHole())
1483                 clobberWorld(node->origin.semantic, clobberLimit);
1484             break;
1485         default:
1486             break;
1487         }
1488         break;
1489     }
1490             
1491     case ArrayPush:
1492         clobberWorld(node->origin.semantic, clobberLimit);
1493         forNode(node).setType(SpecBytecodeNumber);
1494         break;
1495             
1496     case ArrayPop:
1497         clobberWorld(node->origin.semantic, clobberLimit);
1498         forNode(node).makeHeapTop();
1499         break;
1500         
1501     case GetMyArgumentByVal: {
1502         JSValue index = forNode(node->child2()).m_value;
1503         InlineCallFrame* inlineCallFrame = node->child1()->origin.semantic.inlineCallFrame;
1504
1505         if (index && index.isInt32()) {
1506             // This pretends to return TOP for accesses that are actually proven out-of-bounds because
1507             // that's the conservative thing to do. Otherwise we'd need to write more code to mark such
1508             // paths as unreachable, and it's almost certainly not worth the effort.
1509             
1510             if (inlineCallFrame) {
1511                 if (index.asUInt32() < inlineCallFrame->arguments.size() - 1) {
1512                     forNode(node) = m_state.variables().operand(
1513                         virtualRegisterForArgument(index.asInt32() + 1) + inlineCallFrame->stackOffset);
1514                     m_state.setFoundConstants(true);
1515                     break;
1516                 }
1517             } else {
1518                 if (index.asUInt32() < m_state.variables().numberOfArguments() - 1) {
1519                     forNode(node) = m_state.variables().argument(index.asInt32() + 1);
1520                     m_state.setFoundConstants(true);
1521                     break;
1522                 }
1523             }
1524         }
1525         
1526         if (inlineCallFrame) {
1527             // We have a bound on the types even though it's random access. Take advantage of this.
1528             
1529             AbstractValue result;
1530             for (unsigned i = inlineCallFrame->arguments.size(); i-- > 1;) {
1531                 result.merge(
1532                     m_state.variables().operand(
1533                         virtualRegisterForArgument(i) + inlineCallFrame->stackOffset));
1534             }
1535             
1536             if (result.value())
1537                 m_state.setFoundConstants(true);
1538             forNode(node) = result;
1539             break;
1540         }
1541         
1542         forNode(node).makeHeapTop();
1543         break;
1544     }
1545             
1546     case RegExpExec:
1547         forNode(node).makeHeapTop();
1548         break;
1549
1550     case RegExpTest:
1551         forNode(node).setType(SpecBoolean);
1552         break;
1553             
1554     case Jump:
1555         break;
1556             
1557     case Branch: {
1558         Node* child = node->child1().node();
1559         BooleanResult result = booleanResult(node, forNode(child));
1560         if (result == DefinitelyTrue) {
1561             m_state.setBranchDirection(TakeTrue);
1562             break;
1563         }
1564         if (result == DefinitelyFalse) {
1565             m_state.setBranchDirection(TakeFalse);
1566             break;
1567         }
1568         // FIXME: The above handles the trivial cases of sparse conditional
1569         // constant propagation, but we can do better:
1570         // We can specialize the source variable's value on each direction of
1571         // the branch.
1572         m_state.setBranchDirection(TakeBoth);
1573         break;
1574     }
1575         
1576     case Switch: {
1577         // Nothing to do for now.
1578         // FIXME: Do sparse conditional things.
1579         break;
1580     }
1581             
1582     case Return:
1583         m_state.setIsValid(false);
1584         break;
1585
1586     case TailCall:
1587     case TailCallVarargs:
1588     case TailCallForwardVarargs:
1589         clobberWorld(node->origin.semantic, clobberLimit);
1590         m_state.setIsValid(false);
1591         break;
1592         
1593     case Throw:
1594     case ThrowReferenceError:
1595         m_state.setIsValid(false);
1596         break;
1597             
1598     case ToPrimitive: {
1599         JSValue childConst = forNode(node->child1()).value();
1600         if (childConst && childConst.isNumber()) {
1601             setConstant(node, childConst);
1602             break;
1603         }
1604         
1605         ASSERT(node->child1().useKind() == UntypedUse);
1606         
1607         if (!forNode(node->child1()).m_type) {
1608             m_state.setIsValid(false);
1609             break;
1610         }
1611         
1612         if (!(forNode(node->child1()).m_type & ~(SpecFullNumber | SpecBoolean | SpecString | SpecSymbol))) {
1613             m_state.setFoundConstants(true);
1614             forNode(node) = forNode(node->child1());
1615             break;
1616         }
1617         
1618         clobberWorld(node->origin.semantic, clobberLimit);
1619         
1620         forNode(node).setType(m_graph, SpecHeapTop & ~SpecObject);
1621         break;
1622     }
1623         
1624     case ToString:
1625     case CallStringConstructor: {
1626         switch (node->child1().useKind()) {
1627         case StringObjectUse:
1628             // This also filters that the StringObject has the primordial StringObject
1629             // structure.
1630             filter(
1631                 node->child1(),
1632                 m_graph.globalObjectFor(node->origin.semantic)->stringObjectStructure());
1633             break;
1634         case StringOrStringObjectUse:
1635             break;
1636         case CellUse:
1637         case UntypedUse:
1638             clobberWorld(node->origin.semantic, clobberLimit);
1639             break;
1640         default:
1641             RELEASE_ASSERT_NOT_REACHED();
1642             break;
1643         }
1644         forNode(node).set(m_graph, m_graph.m_vm.stringStructure.get());
1645         break;
1646     }
1647         
1648     case NewStringObject: {
1649         ASSERT(node->structure()->classInfo() == StringObject::info());
1650         forNode(node).set(m_graph, node->structure());
1651         break;
1652     }
1653             
1654     case NewArray:
1655         forNode(node).set(
1656             m_graph,
1657             m_graph.globalObjectFor(node->origin.semantic)->arrayStructureForIndexingTypeDuringAllocation(node->indexingType()));
1658         break;
1659         
1660     case NewArrayBuffer:
1661         forNode(node).set(
1662             m_graph,
1663             m_graph.globalObjectFor(node->origin.semantic)->arrayStructureForIndexingTypeDuringAllocation(node->indexingType()));
1664         break;
1665
1666     case NewArrayWithSize:
1667         forNode(node).setType(m_graph, SpecArray);
1668         break;
1669         
1670     case NewTypedArray:
1671         switch (node->child1().useKind()) {
1672         case Int32Use:
1673             break;
1674         case UntypedUse:
1675             clobberWorld(node->origin.semantic, clobberLimit);
1676             break;
1677         default:
1678             RELEASE_ASSERT_NOT_REACHED();
1679             break;
1680         }
1681         forNode(node).set(
1682             m_graph,
1683             m_graph.globalObjectFor(node->origin.semantic)->typedArrayStructure(
1684                 node->typedArrayType()));
1685         break;
1686             
1687     case NewRegexp:
1688         forNode(node).set(m_graph, m_graph.globalObjectFor(node->origin.semantic)->regExpStructure());
1689         break;
1690             
1691     case ToThis: {
1692         AbstractValue& source = forNode(node->child1());
1693         AbstractValue& destination = forNode(node);
1694             
1695         if (m_graph.executableFor(node->origin.semantic)->isStrictMode())
1696             destination.makeHeapTop();
1697         else {
1698             destination = source;
1699             destination.merge(SpecObject);
1700         }
1701         break;
1702     }
1703
1704     case CreateThis: {
1705         // FIXME: We can fold this to NewObject if the incoming callee is a constant.
1706         forNode(node).setType(m_graph, SpecFinalObject);
1707         break;
1708     }
1709         
1710     case NewObject:
1711         ASSERT(node->structure());
1712         forNode(node).set(m_graph, node->structure());
1713         break;
1714         
1715     case PhantomNewObject:
1716     case PhantomNewFunction:
1717     case PhantomCreateActivation:
1718     case PhantomDirectArguments:
1719     case PhantomClonedArguments:
1720     case BottomValue:
1721         m_state.setDidClobber(true); // Prevent constant folding.
1722         // This claims to return bottom.
1723         break;
1724         
1725     case PutHint:
1726         break;
1727         
1728     case MaterializeNewObject: {
1729         StructureSet set;
1730         
1731         m_phiChildren->forAllTransitiveIncomingValues(
1732             m_graph.varArgChild(node, 0).node(),
1733             [&] (Node* incoming) {
1734                 set.add(incoming->castConstant<Structure*>());
1735             });
1736         
1737         forNode(node).set(m_graph, set);
1738         break;
1739     }
1740
1741     case CreateActivation:
1742     case MaterializeCreateActivation:
1743         forNode(node).set(
1744             m_graph, m_codeBlock->globalObjectFor(node->origin.semantic)->activationStructure());
1745         break;
1746         
1747     case CreateDirectArguments:
1748         forNode(node).set(m_graph, m_codeBlock->globalObjectFor(node->origin.semantic)->directArgumentsStructure());
1749         break;
1750         
1751     case CreateScopedArguments:
1752         forNode(node).set(m_graph, m_codeBlock->globalObjectFor(node->origin.semantic)->scopedArgumentsStructure());
1753         break;
1754         
1755     case CreateClonedArguments:
1756         forNode(node).setType(m_graph, SpecObjectOther);
1757         break;
1758             
1759     case NewArrowFunction:
1760         forNode(node).set(
1761             m_graph, m_codeBlock->globalObjectFor(node->origin.semantic)->arrowFunctionStructure());
1762         break;
1763             
1764     case NewFunction:
1765         forNode(node).set(
1766             m_graph, m_codeBlock->globalObjectFor(node->origin.semantic)->functionStructure());
1767         break;
1768         
1769     case GetCallee:
1770         if (FunctionExecutable* executable = jsDynamicCast<FunctionExecutable*>(m_codeBlock->ownerExecutable())) {
1771             InferredValue* singleton = executable->singletonFunction();
1772             if (JSValue value = singleton->inferredValue()) {
1773                 m_graph.watchpoints().addLazily(singleton);
1774                 JSFunction* function = jsCast<JSFunction*>(value);
1775                 setConstant(node, *m_graph.freeze(function));
1776                 break;
1777             }
1778         }
1779         forNode(node).setType(m_graph, SpecFunction);
1780         break;
1781         
1782     case GetArgumentCount:
1783         forNode(node).setType(SpecInt32);
1784         break;
1785         
1786     case GetRestLength:
1787         forNode(node).setType(SpecInt32);
1788         break;
1789         
1790     case GetGetter: {
1791         JSValue base = forNode(node->child1()).m_value;
1792         if (base) {
1793             GetterSetter* getterSetter = jsCast<GetterSetter*>(base);
1794             if (!getterSetter->isGetterNull()) {
1795                 setConstant(node, *m_graph.freeze(getterSetter->getterConcurrently()));
1796                 break;
1797             }
1798         }
1799         
1800         forNode(node).setType(m_graph, SpecObject);
1801         break;
1802     }
1803         
1804     case GetSetter: {
1805         JSValue base = forNode(node->child1()).m_value;
1806         if (base) {
1807             GetterSetter* getterSetter = jsCast<GetterSetter*>(base);
1808             if (!getterSetter->isSetterNull()) {
1809                 setConstant(node, *m_graph.freeze(getterSetter->setterConcurrently()));
1810                 break;
1811             }
1812         }
1813         
1814         forNode(node).setType(m_graph, SpecObject);
1815         break;
1816     }
1817         
1818     case GetScope:
1819         if (JSValue base = forNode(node->child1()).m_value) {
1820             if (JSFunction* function = jsDynamicCast<JSFunction*>(base)) {
1821                 setConstant(node, *m_graph.freeze(function->scope()));
1822                 break;
1823             }
1824         }
1825         forNode(node).setType(m_graph, SpecObjectOther);
1826         break;
1827
1828     case SkipScope: {
1829         JSValue child = forNode(node->child1()).value();
1830         if (child) {
1831             setConstant(node, *m_graph.freeze(JSValue(jsCast<JSScope*>(child.asCell())->next())));
1832             break;
1833         }
1834         forNode(node).setType(m_graph, SpecObjectOther);
1835         break;
1836     }
1837
1838     case GetClosureVar:
1839         if (JSValue value = m_graph.tryGetConstantClosureVar(forNode(node->child1()), node->scopeOffset())) {
1840             setConstant(node, *m_graph.freeze(value));
1841             break;
1842         }
1843         forNode(node).makeBytecodeTop();
1844         break;
1845             
1846     case PutClosureVar:
1847         break;
1848         
1849     case GetFromArguments:
1850         forNode(node).makeHeapTop();
1851         break;
1852         
1853     case PutToArguments:
1854         break;
1855             
1856     case GetById:
1857     case GetByIdFlush: {
1858         if (!node->prediction()) {
1859             m_state.setIsValid(false);
1860             break;
1861         }
1862         
1863         AbstractValue& value = forNode(node->child1());
1864         if (value.m_structure.isFinite()
1865             && (node->child1().useKind() == CellUse || !(value.m_type & ~SpecCell))) {
1866             UniquedStringImpl* uid = m_graph.identifiers()[node->identifierNumber()];
1867             GetByIdStatus status = GetByIdStatus::computeFor(value.m_structure.set(), uid);
1868             if (status.isSimple()) {
1869                 // Figure out what the result is going to be - is it TOP, a constant, or maybe
1870                 // something more subtle?
1871                 AbstractValue result;
1872                 for (unsigned i = status.numVariants(); i--;) {
1873                     // This thing won't give us a variant that involves prototypes. If it did, we'd
1874                     // have more work to do here.
1875                     DFG_ASSERT(m_graph, node, status[i].conditionSet().isEmpty());
1876
1877                     result.merge(
1878                         m_graph.inferredValueForProperty(
1879                             value, uid, status[i].offset(), m_state.structureClobberState()));
1880                 }
1881                 m_state.setFoundConstants(true);
1882                 forNode(node) = result;
1883                 break;
1884             }
1885         }
1886
1887         clobberWorld(node->origin.semantic, clobberLimit);
1888         forNode(node).makeHeapTop();
1889         break;
1890     }
1891             
1892     case GetArrayLength: {
1893         JSArrayBufferView* view = m_graph.tryGetFoldableView(
1894             forNode(node->child1()).m_value, node->arrayMode());
1895         if (view) {
1896             setConstant(node, jsNumber(view->length()));
1897             break;
1898         }
1899         forNode(node).setType(SpecInt32);
1900         break;
1901     }
1902         
1903     case CheckStructure: {
1904         AbstractValue& value = forNode(node->child1());
1905
1906         StructureSet& set = node->structureSet();
1907         
1908         // It's interesting that we could have proven that the object has a larger structure set
1909         // that includes the set we're testing. In that case we could make the structure check
1910         // more efficient. We currently don't.
1911         
1912         if (value.m_structure.isSubsetOf(set))
1913             m_state.setFoundConstants(true);
1914
1915         SpeculatedType admittedTypes = SpecNone;
1916         switch (node->child1().useKind()) {
1917         case CellUse:
1918         case KnownCellUse:
1919             admittedTypes = SpecNone;
1920             break;
1921         case CellOrOtherUse:
1922             admittedTypes = SpecOther;
1923             break;
1924         default:
1925             DFG_CRASH(m_graph, node, "Bad use kind");
1926             break;
1927         }
1928         
1929         filter(value, set, admittedTypes);
1930         break;
1931     }
1932         
1933     case CheckStructureImmediate: {
1934         // FIXME: This currently can only reason about one structure at a time.
1935         // https://bugs.webkit.org/show_bug.cgi?id=136988
1936         
1937         AbstractValue& value = forNode(node->child1());
1938         StructureSet& set = node->structureSet();
1939         
1940         if (value.value()) {
1941             if (Structure* structure = jsDynamicCast<Structure*>(value.value())) {
1942                 if (set.contains(structure)) {
1943                     m_state.setFoundConstants(true);
1944                     break;
1945                 }
1946             }
1947             m_state.setIsValid(false);
1948             break;
1949         }
1950         
1951         if (m_phiChildren) {
1952             bool allGood = true;
1953             m_phiChildren->forAllTransitiveIncomingValues(
1954                 node,
1955                 [&] (Node* incoming) {
1956                     if (Structure* structure = incoming->dynamicCastConstant<Structure*>()) {
1957                         if (set.contains(structure))
1958                             return;
1959                     }
1960                     allGood = false;
1961                 });
1962             if (allGood) {
1963                 m_state.setFoundConstants(true);
1964                 break;
1965             }
1966         }
1967             
1968         if (Structure* structure = set.onlyStructure()) {
1969             filterByValue(node->child1(), *m_graph.freeze(structure));
1970             break;
1971         }
1972         
1973         // Aw shucks, we can't do anything!
1974         break;
1975     }
1976         
1977     case PutStructure:
1978         if (!forNode(node->child1()).m_structure.isClear()) {
1979             if (forNode(node->child1()).m_structure.onlyStructure() == node->transition()->next)
1980                 m_state.setFoundConstants(true);
1981             else {
1982                 observeTransition(
1983                     clobberLimit, node->transition()->previous, node->transition()->next);
1984                 forNode(node->child1()).changeStructure(m_graph, node->transition()->next);
1985             }
1986         }
1987         break;
1988     case GetButterfly:
1989     case GetButterflyReadOnly:
1990     case AllocatePropertyStorage:
1991     case ReallocatePropertyStorage:
1992         forNode(node).clear(); // The result is not a JS value.
1993         break;
1994     case CheckArray: {
1995         if (node->arrayMode().alreadyChecked(m_graph, node, forNode(node->child1()))) {
1996             m_state.setFoundConstants(true);
1997             break;
1998         }
1999         switch (node->arrayMode().type()) {
2000         case Array::String:
2001             filter(node->child1(), SpecString);
2002             break;
2003         case Array::Int32:
2004         case Array::Double:
2005         case Array::Contiguous:
2006         case Array::Undecided:
2007         case Array::ArrayStorage:
2008         case Array::SlowPutArrayStorage:
2009             break;
2010         case Array::DirectArguments:
2011             filter(node->child1(), SpecDirectArguments);
2012             break;
2013         case Array::ScopedArguments:
2014             filter(node->child1(), SpecScopedArguments);
2015             break;
2016         case Array::Int8Array:
2017             filter(node->child1(), SpecInt8Array);
2018             break;
2019         case Array::Int16Array:
2020             filter(node->child1(), SpecInt16Array);
2021             break;
2022         case Array::Int32Array:
2023             filter(node->child1(), SpecInt32Array);
2024             break;
2025         case Array::Uint8Array:
2026             filter(node->child1(), SpecUint8Array);
2027             break;
2028         case Array::Uint8ClampedArray:
2029             filter(node->child1(), SpecUint8ClampedArray);
2030             break;
2031         case Array::Uint16Array:
2032             filter(node->child1(), SpecUint16Array);
2033             break;
2034         case Array::Uint32Array:
2035             filter(node->child1(), SpecUint32Array);
2036             break;
2037         case Array::Float32Array:
2038             filter(node->child1(), SpecFloat32Array);
2039             break;
2040         case Array::Float64Array:
2041             filter(node->child1(), SpecFloat64Array);
2042             break;
2043         case Array::AnyTypedArray:
2044             filter(node->child1(), SpecTypedArrayView);
2045             break;
2046         default:
2047             RELEASE_ASSERT_NOT_REACHED();
2048             break;
2049         }
2050         filterArrayModes(node->child1(), node->arrayMode().arrayModesThatPassFiltering());
2051         break;
2052     }
2053     case Arrayify: {
2054         if (node->arrayMode().alreadyChecked(m_graph, node, forNode(node->child1()))) {
2055             m_state.setFoundConstants(true);
2056             break;
2057         }
2058         ASSERT(node->arrayMode().conversion() == Array::Convert);
2059         clobberStructures(clobberLimit);
2060         filterArrayModes(node->child1(), node->arrayMode().arrayModesThatPassFiltering());
2061         break;
2062     }
2063     case ArrayifyToStructure: {
2064         AbstractValue& value = forNode(node->child1());
2065         if (value.m_structure.isSubsetOf(StructureSet(node->structure())))
2066             m_state.setFoundConstants(true);
2067         clobberStructures(clobberLimit);
2068         
2069         // We have a bunch of options of how to express the abstract set at this point. Let set S
2070         // be the set of structures that the value had before clobbering and assume that all of
2071         // them are watchable. The new value should be the least expressible upper bound of the
2072         // intersection of "values that currently have structure = node->structure()" and "values
2073         // that have structure in S plus any structure transition-reachable from S". Assume that
2074         // node->structure() is not in S but it is transition-reachable from S. Then we would
2075         // like to say that the result is "values that have structure = node->structure() until
2076         // we invalidate", but there is no way to express this using the AbstractValue syntax. So
2077         // we must choose between:
2078         //
2079         // 1) "values that currently have structure = node->structure()". This is a valid
2080         //    superset of the value that we really want, and it's specific enough to satisfy the
2081         //    preconditions of the array access that this is guarding. It's also specific enough
2082         //    to allow relevant optimizations in the case that we didn't have a contradiction
2083         //    like in this example. Notice that in the abscence of any contradiction, this result
2084         //    is precise rather than being a conservative LUB.
2085         //
2086         // 2) "values that currently hava structure in S plus any structure transition-reachable
2087         //    from S". This is also a valid superset of the value that we really want, but it's
2088         //    not specific enough to satisfy the preconditions of the array access that this is
2089         //    guarding - so playing such shenanigans would preclude us from having assertions on
2090         //    the typing preconditions of any array accesses. This would also not be a desirable
2091         //    answer in the absence of a contradiction.
2092         //
2093         // Note that it's tempting to simply say that the resulting value is BOTTOM because of
2094         // the contradiction. That would be wrong, since we haven't hit an invalidation point,
2095         // yet.
2096         value.set(m_graph, node->structure());
2097         break;
2098     }
2099     case GetIndexedPropertyStorage: {
2100         JSArrayBufferView* view = m_graph.tryGetFoldableView(
2101             forNode(node->child1()).m_value, node->arrayMode());
2102         if (view)
2103             m_state.setFoundConstants(true);
2104         forNode(node).clear();
2105         break;
2106     }
2107     case ConstantStoragePointer: {
2108         forNode(node).clear();
2109         break; 
2110     }
2111         
2112     case GetTypedArrayByteOffset: {
2113         JSArrayBufferView* view = m_graph.tryGetFoldableView(forNode(node->child1()).m_value);
2114         if (view) {
2115             setConstant(node, jsNumber(view->byteOffset()));
2116             break;
2117         }
2118         forNode(node).setType(SpecInt32);
2119         break;
2120     }
2121         
2122     case GetByOffset: {
2123         StorageAccessData& data = node->storageAccessData();
2124         UniquedStringImpl* uid = m_graph.identifiers()[data.identifierNumber];
2125
2126         // FIXME: The part of this that handles inferred property types relies on AI knowing the structure
2127         // right now. That's probably not optimal. In some cases, we may perform an optimization (usually
2128         // by something other than AI, maybe by CSE for example) that obscures AI's view of the structure
2129         // at the point where GetByOffset runs. Currently, when that happens, we'll have to rely entirely
2130         // on the type that ByteCodeParser was able to prove.
2131         AbstractValue value = m_graph.inferredValueForProperty(
2132             forNode(node->child2()), uid, data.offset, m_state.structureClobberState());
2133
2134         // It's possible that the type that ByteCodeParser came up with is better.
2135         AbstractValue typeFromParsing;
2136         typeFromParsing.set(m_graph, data.inferredType, m_state.structureClobberState());
2137         value.filter(typeFromParsing);
2138
2139         // If we decide that there does not exist any value that this can return, then it's probably
2140         // because the compilation was already invalidated.
2141         if (value.isClear())
2142             m_state.setIsValid(false);
2143
2144         forNode(node) = value;
2145         if (value.m_value)
2146             m_state.setFoundConstants(true);
2147         break;
2148     }
2149         
2150     case GetGetterSetterByOffset: {
2151         StorageAccessData& data = node->storageAccessData();
2152         JSValue result = m_graph.tryGetConstantProperty(forNode(node->child2()), data.offset);
2153         if (result && jsDynamicCast<GetterSetter*>(result)) {
2154             setConstant(node, *m_graph.freeze(result));
2155             break;
2156         }
2157         
2158         forNode(node).set(m_graph, m_graph.m_vm.getterSetterStructure.get());
2159         break;
2160     }
2161         
2162     case MultiGetByOffset: {
2163         // This code will filter the base value in a manner that is possibly different (either more
2164         // or less precise) than the way it would be filtered if this was strength-reduced to a
2165         // CheckStructure. This is fine. It's legal for different passes over the code to prove
2166         // different things about the code, so long as all of them are sound. That even includes
2167         // one guy proving that code should never execute (due to a contradiction) and another guy
2168         // not finding that contradiction. If someone ever proved that there would be a
2169         // contradiction then there must always be a contradiction even if subsequent passes don't
2170         // realize it. This is the case here.
2171         
2172         // Ordinarily you have to be careful with calling setFoundConstants()
2173         // because of the effect on compile times, but this node is FTL-only.
2174         m_state.setFoundConstants(true);
2175         
2176         UniquedStringImpl* uid = m_graph.identifiers()[node->multiGetByOffsetData().identifierNumber];
2177
2178         AbstractValue base = forNode(node->child1());
2179         StructureSet baseSet;
2180         AbstractValue result;
2181         for (const MultiGetByOffsetCase& getCase : node->multiGetByOffsetData().cases) {
2182             StructureSet set = getCase.set();
2183             set.filter(base);
2184             if (set.isEmpty())
2185                 continue;
2186             baseSet.merge(set);
2187
2188             switch (getCase.method().kind()) {
2189             case GetByOffsetMethod::Constant: {
2190                 AbstractValue thisResult;
2191                 thisResult.set(
2192                     m_graph,
2193                     *getCase.method().constant(),
2194                     m_state.structureClobberState());
2195                 result.merge(thisResult);
2196                 break;
2197             }
2198
2199             case GetByOffsetMethod::Load: {
2200                 result.merge(
2201                     m_graph.inferredValueForProperty(
2202                         set, uid, m_state.structureClobberState()));
2203                 break;
2204             }
2205
2206             default: {
2207                 result.makeHeapTop();
2208                 break;
2209             } }
2210         }
2211         
2212         if (forNode(node->child1()).changeStructure(m_graph, baseSet) == Contradiction)
2213             m_state.setIsValid(false);
2214         
2215         forNode(node) = result;
2216         break;
2217     }
2218             
2219     case PutByOffset: {
2220         break;
2221     }
2222         
2223     case MultiPutByOffset: {
2224         StructureSet newSet;
2225         TransitionVector transitions;
2226         
2227         // Ordinarily you have to be careful with calling setFoundConstants()
2228         // because of the effect on compile times, but this node is FTL-only.
2229         m_state.setFoundConstants(true);
2230         
2231         AbstractValue base = forNode(node->child1());
2232         AbstractValue originalValue = forNode(node->child2());
2233         AbstractValue resultingValue;
2234         
2235         for (unsigned i = node->multiPutByOffsetData().variants.size(); i--;) {
2236             const PutByIdVariant& variant = node->multiPutByOffsetData().variants[i];
2237             StructureSet thisSet = variant.oldStructure();
2238             thisSet.filter(base);
2239             if (thisSet.isEmpty())
2240                 continue;
2241
2242             AbstractValue thisValue = originalValue;
2243             thisValue.filter(m_graph, variant.requiredType());
2244             resultingValue.merge(thisValue);
2245             
2246             if (variant.kind() == PutByIdVariant::Transition) {
2247                 if (thisSet.onlyStructure() != variant.newStructure()) {
2248                     transitions.append(
2249                         Transition(variant.oldStructureForTransition(), variant.newStructure()));
2250                 } // else this is really a replace.
2251                 newSet.add(variant.newStructure());
2252             } else {
2253                 ASSERT(variant.kind() == PutByIdVariant::Replace);
2254                 newSet.merge(thisSet);
2255             }
2256         }
2257         
2258         observeTransitions(clobberLimit, transitions);
2259         if (forNode(node->child1()).changeStructure(m_graph, newSet) == Contradiction)
2260             m_state.setIsValid(false);
2261         forNode(node->child2()) = resultingValue;
2262         if (!!originalValue && !resultingValue)
2263             m_state.setIsValid(false);
2264         break;
2265     }
2266         
2267     case GetExecutable: {
2268         JSValue value = forNode(node->child1()).value();
2269         if (value) {
2270             JSFunction* function = jsDynamicCast<JSFunction*>(value);
2271             if (function) {
2272                 setConstant(node, *m_graph.freeze(function->executable()));
2273                 break;
2274             }
2275         }
2276         forNode(node).setType(m_graph, SpecCellOther);
2277         break;
2278     }
2279     
2280     case CheckCell: {
2281         JSValue value = forNode(node->child1()).value();
2282         if (value == node->cellOperand()->value()) {
2283             m_state.setFoundConstants(true);
2284             ASSERT(value);
2285             break;
2286         }
2287         filterByValue(node->child1(), *node->cellOperand());
2288         break;
2289     }
2290
2291     case CheckNotEmpty: {
2292         AbstractValue& value = forNode(node->child1());
2293         if (!(value.m_type & SpecEmpty)) {
2294             m_state.setFoundConstants(true);
2295             break;
2296         }
2297         
2298         filter(value, ~SpecEmpty);
2299         break;
2300     }
2301
2302     case CheckIdent: {
2303         AbstractValue& value = forNode(node->child1());
2304         UniquedStringImpl* uid = node->uidOperand();
2305         ASSERT(uid->isSymbol() ? !(value.m_type & ~SpecSymbol) : !(value.m_type & ~SpecStringIdent)); // Edge filtering should have already ensured this.
2306
2307         JSValue childConstant = value.value();
2308         if (childConstant) {
2309             if (uid->isSymbol()) {
2310                 ASSERT(childConstant.isSymbol());
2311                 if (asSymbol(childConstant)->privateName().uid() == uid) {
2312                     m_state.setFoundConstants(true);
2313                     break;
2314                 }
2315             } else {
2316                 ASSERT(childConstant.isString());
2317                 if (asString(childConstant)->tryGetValueImpl() == uid) {
2318                     m_state.setFoundConstants(true);
2319                     break;
2320                 }
2321             }
2322         }
2323
2324         filter(value, uid->isSymbol() ? SpecSymbol : SpecStringIdent);
2325         break;
2326     }
2327
2328     case CheckInBounds: {
2329         JSValue left = forNode(node->child1()).value();
2330         JSValue right = forNode(node->child2()).value();
2331         if (left && right && left.isInt32() && right.isInt32()
2332             && static_cast<uint32_t>(left.asInt32()) < static_cast<uint32_t>(right.asInt32())) {
2333             m_state.setFoundConstants(true);
2334             break;
2335         }
2336         break;
2337     }
2338         
2339     case PutById:
2340     case PutByIdFlush:
2341     case PutByIdDirect: {
2342         AbstractValue& value = forNode(node->child1());
2343         if (value.m_structure.isFinite()) {
2344             PutByIdStatus status = PutByIdStatus::computeFor(
2345                 m_graph.globalObjectFor(node->origin.semantic),
2346                 value.m_structure.set(),
2347                 m_graph.identifiers()[node->identifierNumber()],
2348                 node->op() == PutByIdDirect);
2349
2350             if (status.isSimple()) {
2351                 StructureSet newSet;
2352                 TransitionVector transitions;
2353                 
2354                 for (unsigned i = status.numVariants(); i--;) {
2355                     const PutByIdVariant& variant = status[i];
2356                     if (variant.kind() == PutByIdVariant::Transition) {
2357                         transitions.append(
2358                             Transition(
2359                                 variant.oldStructureForTransition(), variant.newStructure()));
2360                         m_graph.registerStructure(variant.newStructure());
2361                         newSet.add(variant.newStructure());
2362                     } else {
2363                         ASSERT(variant.kind() == PutByIdVariant::Replace);
2364                         newSet.merge(variant.oldStructure());
2365                     }
2366                 }
2367                 
2368                 if (status.numVariants() == 1 || isFTL(m_graph.m_plan.mode))
2369                     m_state.setFoundConstants(true);
2370                 
2371                 observeTransitions(clobberLimit, transitions);
2372                 if (forNode(node->child1()).changeStructure(m_graph, newSet) == Contradiction)
2373                     m_state.setIsValid(false);
2374                 break;
2375             }
2376         }
2377         
2378         clobberWorld(node->origin.semantic, clobberLimit);
2379         break;
2380     }
2381
2382     case PutGetterById:
2383     case PutSetterById:
2384     case PutGetterSetterById:
2385     case PutGetterByVal:
2386     case PutSetterByVal: {
2387         clobberWorld(node->origin.semantic, clobberLimit);
2388         break;
2389     }
2390         
2391     case In: {
2392         // FIXME: We can determine when the property definitely exists based on abstract
2393         // value information.
2394         clobberWorld(node->origin.semantic, clobberLimit);
2395         forNode(node).setType(SpecBoolean);
2396         break;
2397     }
2398             
2399     case GetEnumerableLength: {
2400         forNode(node).setType(SpecInt32);
2401         break;
2402     }
2403     case HasGenericProperty: {
2404         forNode(node).setType(SpecBoolean);
2405         break;
2406     }
2407     case HasStructureProperty: {
2408         forNode(node).setType(SpecBoolean);
2409         break;
2410     }
2411     case HasIndexedProperty: {
2412         ArrayMode mode = node->arrayMode();
2413         switch (mode.type()) {
2414         case Array::Int32:
2415         case Array::Double:
2416         case Array::Contiguous:
2417         case Array::ArrayStorage: {
2418             break;
2419         }
2420         default: {
2421             clobberWorld(node->origin.semantic, clobberLimit);
2422             break;
2423         }
2424         }
2425         forNode(node).setType(SpecBoolean);
2426         break;
2427     }
2428     case GetDirectPname: {
2429         clobberWorld(node->origin.semantic, clobberLimit);
2430         forNode(node).makeHeapTop();
2431         break;
2432     }
2433     case GetPropertyEnumerator: {
2434         forNode(node).setType(m_graph, SpecCell);
2435         break;
2436     }
2437     case GetEnumeratorStructurePname: {
2438         forNode(node).setType(m_graph, SpecString | SpecOther);
2439         break;
2440     }
2441     case GetEnumeratorGenericPname: {
2442         forNode(node).setType(m_graph, SpecString | SpecOther);
2443         break;
2444     }
2445     case ToIndexString: {
2446         forNode(node).setType(m_graph, SpecString);
2447         break;
2448     }
2449
2450     case GetGlobalVar:
2451         forNode(node).makeHeapTop();
2452         break;
2453     case GetGlobalLexicalVariable:
2454         forNode(node).makeBytecodeTop();
2455         break;
2456         
2457     case VarInjectionWatchpoint:
2458     case PutGlobalVariable:
2459     case NotifyWrite:
2460         break;
2461             
2462     case CheckHasInstance:
2463         // Sadly, we don't propagate the fact that we've done CheckHasInstance
2464         break;
2465             
2466     case InstanceOf:
2467         // Again, sadly, we don't propagate the fact that we've done InstanceOf
2468         forNode(node).setType(SpecBoolean);
2469         break;
2470             
2471     case Phi:
2472         RELEASE_ASSERT(m_graph.m_form == SSA);
2473         // The state of this node would have already been decided, but it may have become a
2474         // constant, in which case we'd like to know.
2475         if (forNode(node).m_value)
2476             m_state.setFoundConstants(true);
2477         break;
2478         
2479     case Upsilon: {
2480         m_state.createValueForNode(node->phi());
2481         forNode(node->phi()) = forNode(node->child1());
2482         break;
2483     }
2484         
2485     case Flush:
2486     case PhantomLocal:
2487         break;
2488             
2489     case Call:
2490     case TailCallInlinedCaller:
2491     case Construct:
2492     case CallVarargs:
2493     case CallForwardVarargs:
2494     case TailCallVarargsInlinedCaller:
2495     case ConstructVarargs:
2496     case ConstructForwardVarargs:
2497     case TailCallForwardVarargsInlinedCaller:
2498         clobberWorld(node->origin.semantic, clobberLimit);
2499         forNode(node).makeHeapTop();
2500         break;
2501
2502     case ForceOSRExit:
2503     case CheckBadCell:
2504         m_state.setIsValid(false);
2505         break;
2506         
2507     case InvalidationPoint:
2508         forAllValues(clobberLimit, AbstractValue::observeInvalidationPointFor);
2509         m_state.setStructureClobberState(StructuresAreWatched);
2510         break;
2511
2512     case CheckWatchdogTimer:
2513         break;
2514
2515     case Breakpoint:
2516     case ProfileWillCall:
2517     case ProfileDidCall:
2518     case ProfileType:
2519     case ProfileControlFlow:
2520     case Phantom:
2521     case CountExecution:
2522     case CheckTierUpInLoop:
2523     case CheckTierUpAtReturn:
2524         break;
2525
2526     case CopyRest:
2527         break;
2528             
2529     case Check: {
2530         // Simplify out checks that don't actually do checking.
2531         for (unsigned i = 0; i < AdjacencyList::Size; ++i) {
2532             Edge edge = node->children.child(i);
2533             if (!edge)
2534                 break;
2535             if (edge.isProved() || edge.willNotHaveCheck()) {
2536                 m_state.setFoundConstants(true);
2537                 break;
2538             }
2539         }
2540         break;
2541     }
2542
2543     case StoreBarrier: {
2544         filter(node->child1(), SpecCell);
2545         break;
2546     }
2547
2548     case CheckTierUpAndOSREnter:
2549     case CheckTierUpWithNestedTriggerAndOSREnter:
2550     case LoopHint:
2551     case ZombieHint:
2552     case ExitOK:
2553         break;
2554
2555     case Unreachable:
2556     case LastNodeType:
2557     case ArithIMul:
2558     case FiatInt52:
2559         DFG_CRASH(m_graph, node, "Unexpected node type");
2560         break;
2561     }
2562     
2563     return m_state.isValid();
2564 }
2565
2566 template<typename AbstractStateType>
2567 bool AbstractInterpreter<AbstractStateType>::executeEffects(unsigned indexInBlock)
2568 {
2569     return executeEffects(indexInBlock, m_state.block()->at(indexInBlock));
2570 }
2571
2572 template<typename AbstractStateType>
2573 bool AbstractInterpreter<AbstractStateType>::execute(unsigned indexInBlock)
2574 {
2575     Node* node = m_state.block()->at(indexInBlock);
2576     
2577     startExecuting();
2578     executeEdges(node);
2579     return executeEffects(indexInBlock, node);
2580 }
2581
2582 template<typename AbstractStateType>
2583 bool AbstractInterpreter<AbstractStateType>::execute(Node* node)
2584 {
2585     startExecuting();
2586     executeEdges(node);
2587     return executeEffects(UINT_MAX, node);
2588 }
2589
2590 template<typename AbstractStateType>
2591 void AbstractInterpreter<AbstractStateType>::clobberWorld(
2592     const CodeOrigin&, unsigned clobberLimit)
2593 {
2594     clobberStructures(clobberLimit);
2595 }
2596
2597 template<typename AbstractStateType>
2598 template<typename Functor>
2599 void AbstractInterpreter<AbstractStateType>::forAllValues(
2600     unsigned clobberLimit, Functor& functor)
2601 {
2602     SamplingRegion samplingRegion("DFG AI For All Values");
2603     if (clobberLimit >= m_state.block()->size())
2604         clobberLimit = m_state.block()->size();
2605     else
2606         clobberLimit++;
2607     ASSERT(clobberLimit <= m_state.block()->size());
2608     for (size_t i = clobberLimit; i--;)
2609         functor(forNode(m_state.block()->at(i)));
2610     if (m_graph.m_form == SSA) {
2611         HashSet<Node*>::iterator iter = m_state.block()->ssa->liveAtHead.begin();
2612         HashSet<Node*>::iterator end = m_state.block()->ssa->liveAtHead.end();
2613         for (; iter != end; ++iter)
2614             functor(forNode(*iter));
2615     }
2616     for (size_t i = m_state.variables().numberOfArguments(); i--;)
2617         functor(m_state.variables().argument(i));
2618     for (size_t i = m_state.variables().numberOfLocals(); i--;)
2619         functor(m_state.variables().local(i));
2620 }
2621
2622 template<typename AbstractStateType>
2623 void AbstractInterpreter<AbstractStateType>::clobberStructures(unsigned clobberLimit)
2624 {
2625     SamplingRegion samplingRegion("DFG AI Clobber Structures");
2626     forAllValues(clobberLimit, AbstractValue::clobberStructuresFor);
2627     setDidClobber();
2628 }
2629
2630 template<typename AbstractStateType>
2631 void AbstractInterpreter<AbstractStateType>::observeTransition(
2632     unsigned clobberLimit, Structure* from, Structure* to)
2633 {
2634     AbstractValue::TransitionObserver transitionObserver(from, to);
2635     forAllValues(clobberLimit, transitionObserver);
2636     
2637     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.
2638 }
2639
2640 template<typename AbstractStateType>
2641 void AbstractInterpreter<AbstractStateType>::observeTransitions(
2642     unsigned clobberLimit, const TransitionVector& vector)
2643 {
2644     AbstractValue::TransitionsObserver transitionsObserver(vector);
2645     forAllValues(clobberLimit, transitionsObserver);
2646     
2647     if (!ASSERT_DISABLED) {
2648         // We don't need to claim to be in a clobbered state because none of the Transition::previous structures are watchable.
2649         for (unsigned i = vector.size(); i--;)
2650             ASSERT(!vector[i].previous->dfgShouldWatch());
2651     }
2652 }
2653
2654 template<typename AbstractStateType>
2655 void AbstractInterpreter<AbstractStateType>::setDidClobber()
2656 {
2657     m_state.setDidClobber(true);
2658     m_state.setStructureClobberState(StructuresAreClobbered);
2659 }
2660
2661 template<typename AbstractStateType>
2662 void AbstractInterpreter<AbstractStateType>::dump(PrintStream& out) const
2663 {
2664     const_cast<AbstractInterpreter<AbstractStateType>*>(this)->dump(out);
2665 }
2666
2667 template<typename AbstractStateType>
2668 void AbstractInterpreter<AbstractStateType>::dump(PrintStream& out)
2669 {
2670     CommaPrinter comma(" ");
2671     HashSet<Node*> seen;
2672     if (m_graph.m_form == SSA) {
2673         HashSet<Node*>::iterator iter = m_state.block()->ssa->liveAtHead.begin();
2674         HashSet<Node*>::iterator end = m_state.block()->ssa->liveAtHead.end();
2675         for (; iter != end; ++iter) {
2676             Node* node = *iter;
2677             seen.add(node);
2678             AbstractValue& value = forNode(node);
2679             if (value.isClear())
2680                 continue;
2681             out.print(comma, node, ":", value);
2682         }
2683     }
2684     for (size_t i = 0; i < m_state.block()->size(); ++i) {
2685         Node* node = m_state.block()->at(i);
2686         seen.add(node);
2687         AbstractValue& value = forNode(node);
2688         if (value.isClear())
2689             continue;
2690         out.print(comma, node, ":", value);
2691     }
2692     if (m_graph.m_form == SSA) {
2693         HashSet<Node*>::iterator iter = m_state.block()->ssa->liveAtTail.begin();
2694         HashSet<Node*>::iterator end = m_state.block()->ssa->liveAtTail.end();
2695         for (; iter != end; ++iter) {
2696             Node* node = *iter;
2697             if (seen.contains(node))
2698                 continue;
2699             AbstractValue& value = forNode(node);
2700             if (value.isClear())
2701                 continue;
2702             out.print(comma, node, ":", value);
2703         }
2704     }
2705 }
2706
2707 template<typename AbstractStateType>
2708 FiltrationResult AbstractInterpreter<AbstractStateType>::filter(
2709     AbstractValue& value, const StructureSet& set, SpeculatedType admittedTypes)
2710 {
2711     if (value.filter(m_graph, set, admittedTypes) == FiltrationOK)
2712         return FiltrationOK;
2713     m_state.setIsValid(false);
2714     return Contradiction;
2715 }
2716
2717 template<typename AbstractStateType>
2718 FiltrationResult AbstractInterpreter<AbstractStateType>::filterArrayModes(
2719     AbstractValue& value, ArrayModes arrayModes)
2720 {
2721     if (value.filterArrayModes(arrayModes) == FiltrationOK)
2722         return FiltrationOK;
2723     m_state.setIsValid(false);
2724     return Contradiction;
2725 }
2726
2727 template<typename AbstractStateType>
2728 FiltrationResult AbstractInterpreter<AbstractStateType>::filter(
2729     AbstractValue& value, SpeculatedType type)
2730 {
2731     if (value.filter(type) == FiltrationOK)
2732         return FiltrationOK;
2733     m_state.setIsValid(false);
2734     return Contradiction;
2735 }
2736
2737 template<typename AbstractStateType>
2738 FiltrationResult AbstractInterpreter<AbstractStateType>::filterByValue(
2739     AbstractValue& abstractValue, FrozenValue concreteValue)
2740 {
2741     if (abstractValue.filterByValue(concreteValue) == FiltrationOK)
2742         return FiltrationOK;
2743     m_state.setIsValid(false);
2744     return Contradiction;
2745 }
2746
2747 } } // namespace JSC::DFG
2748
2749 #endif // ENABLE(DFG_JIT)
2750
2751 #endif // DFGAbstractInterpreterInlines_h
2752