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