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