Unreviewed, rolling out r156474.
[WebKit-https.git] / Source / JavaScriptCore / dfg / DFGAbstractInterpreterInlines.h
1 /*
2  * Copyright (C) 2013 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 #include <wtf/Platform.h>
30
31 #if ENABLE(DFG_JIT)
32
33 #include "DFGAbstractInterpreter.h"
34 #include "GetByIdStatus.h"
35 #include "Operations.h"
36 #include "PutByIdStatus.h"
37 #include "StringObject.h"
38
39 namespace JSC { namespace DFG {
40
41 template<typename AbstractStateType>
42 AbstractInterpreter<AbstractStateType>::AbstractInterpreter(Graph& graph, AbstractStateType& state)
43     : m_codeBlock(graph.m_codeBlock)
44     , m_graph(graph)
45     , m_state(state)
46 {
47 }
48
49 template<typename AbstractStateType>
50 AbstractInterpreter<AbstractStateType>::~AbstractInterpreter()
51 {
52 }
53
54 template<typename AbstractStateType>
55 typename AbstractInterpreter<AbstractStateType>::BooleanResult
56 AbstractInterpreter<AbstractStateType>::booleanResult(
57     Node* node, AbstractValue& value)
58 {
59     JSValue childConst = value.value();
60     if (childConst) {
61         if (childConst.toBoolean(m_codeBlock->globalObjectFor(node->codeOrigin)->globalExec()))
62             return DefinitelyTrue;
63         return DefinitelyFalse;
64     }
65
66     // Next check if we can fold because we know that the source is an object or string and does not equal undefined.
67     if (isCellSpeculation(value.m_type)
68         && value.m_currentKnownStructure.hasSingleton()) {
69         Structure* structure = value.m_currentKnownStructure.singleton();
70         if (!structure->masqueradesAsUndefined(m_codeBlock->globalObjectFor(node->codeOrigin))
71             && structure->typeInfo().type() != StringType)
72             return DefinitelyTrue;
73     }
74     
75     return UnknownBooleanResult;
76 }
77
78 template<typename AbstractStateType>
79 bool AbstractInterpreter<AbstractStateType>::startExecuting(Node* node)
80 {
81     ASSERT(m_state.block());
82     ASSERT(m_state.isValid());
83     
84     m_state.setDidClobber(false);
85     
86     node->setCanExit(false);
87     
88     return node->shouldGenerate();
89 }
90
91 template<typename AbstractStateType>
92 bool AbstractInterpreter<AbstractStateType>::startExecuting(unsigned indexInBlock)
93 {
94     return startExecuting(m_state.block()->at(indexInBlock));
95 }
96
97 template<typename AbstractStateType>
98 void AbstractInterpreter<AbstractStateType>::executeEdges(Node* node)
99 {
100     DFG_NODE_DO_TO_CHILDREN(m_graph, node, filterEdgeByUse);
101 }
102
103 template<typename AbstractStateType>
104 void AbstractInterpreter<AbstractStateType>::executeEdges(unsigned indexInBlock)
105 {
106     executeEdges(m_state.block()->at(indexInBlock));
107 }
108
109 template<typename AbstractStateType>
110 void AbstractInterpreter<AbstractStateType>::verifyEdge(Node*, Edge edge)
111 {
112     RELEASE_ASSERT(!(forNode(edge).m_type & ~typeFilterFor(edge.useKind())));
113 }
114
115 template<typename AbstractStateType>
116 void AbstractInterpreter<AbstractStateType>::verifyEdges(Node* node)
117 {
118     DFG_NODE_DO_TO_CHILDREN(m_graph, node, verifyEdge);
119 }
120
121 template<typename AbstractStateType>
122 bool AbstractInterpreter<AbstractStateType>::executeEffects(unsigned clobberLimit, Node* node)
123 {
124     if (!ASSERT_DISABLED)
125         verifyEdges(node);
126     
127     m_state.createValueForNode(node);
128     
129     switch (node->op()) {
130     case JSConstant:
131     case WeakJSConstant:
132     case PhantomArguments: {
133         forNode(node).set(m_graph, m_graph.valueOfJSConstant(node));
134         break;
135     }
136         
137     case Identity: {
138         forNode(node) = forNode(node->child1());
139         break;
140     }
141         
142     case GetArgument: {
143         ASSERT(m_graph.m_form == SSA);
144         VariableAccessData* variable = node->variableAccessData();
145         AbstractValue& value = m_state.variables().operand(variable->local());
146         ASSERT(value.isHeapTop());
147         FiltrationResult result =
148             value.filter(typeFilterFor(useKindFor(variable->flushFormat())));
149         ASSERT_UNUSED(result, result == FiltrationOK);
150         forNode(node) = value;
151         break;
152     }
153         
154     case ExtractOSREntryLocal: {
155         if (!operandIsArgument(node->unlinkedLocal())
156             && m_graph.m_lazyVars.get(operandToLocal(node->unlinkedLocal()))) {
157             // This is kind of pessimistic - we could know in some cases that the
158             // DFG code at the point of the OSR had already initialized the lazy
159             // variable. But maybe this is fine, since we're inserting OSR
160             // entrypoints very early in the pipeline - so any lazy initializations
161             // ought to be hoisted out anyway.
162             forNode(node).makeBytecodeTop();
163         } else
164             forNode(node).makeHeapTop();
165         break;
166     }
167             
168     case GetLocal: {
169         VariableAccessData* variableAccessData = node->variableAccessData();
170         if (variableAccessData->prediction() == SpecNone) {
171             m_state.setIsValid(false);
172             break;
173         }
174         AbstractValue value = m_state.variables().operand(variableAccessData->local());
175         if (!variableAccessData->isCaptured()) {
176             if (value.isClear())
177                 node->setCanExit(true);
178         }
179         if (value.value())
180             m_state.setFoundConstants(true);
181         forNode(node) = value;
182         break;
183     }
184         
185     case GetLocalUnlinked: {
186         AbstractValue value = m_state.variables().operand(node->unlinkedLocal());
187         if (value.value())
188             m_state.setFoundConstants(true);
189         forNode(node) = value;
190         break;
191     }
192         
193     case SetLocal: {
194         m_state.variables().operand(node->local()) = forNode(node->child1());
195         break;
196     }
197         
198     case MovHint:
199     case MovHintAndCheck: {
200         // Don't need to do anything. A MovHint is effectively a promise that the SetLocal
201         // was dead.
202         break;
203     }
204         
205     case ZombieHint: {
206         RELEASE_ASSERT_NOT_REACHED();
207         break;
208     }
209             
210     case SetArgument:
211         // Assert that the state of arguments has been set.
212         ASSERT(!m_state.block()->valuesAtHead.operand(node->local()).isClear());
213         break;
214             
215     case BitAnd:
216     case BitOr:
217     case BitXor:
218     case BitRShift:
219     case BitLShift:
220     case BitURShift: {
221         JSValue left = forNode(node->child1()).value();
222         JSValue right = forNode(node->child2()).value();
223         if (left && right && left.isInt32() && right.isInt32()) {
224             int32_t a = left.asInt32();
225             int32_t b = right.asInt32();
226             switch (node->op()) {
227             case BitAnd:
228                 setConstant(node, JSValue(a & b));
229                 break;
230             case BitOr:
231                 setConstant(node, JSValue(a | b));
232                 break;
233             case BitXor:
234                 setConstant(node, JSValue(a ^ b));
235                 break;
236             case BitRShift:
237                 setConstant(node, JSValue(a >> static_cast<uint32_t>(b)));
238                 break;
239             case BitLShift:
240                 setConstant(node, JSValue(a << static_cast<uint32_t>(b)));
241                 break;
242             case BitURShift:
243                 setConstant(node, JSValue(static_cast<uint32_t>(a) >> static_cast<uint32_t>(b)));
244                 break;
245             default:
246                 RELEASE_ASSERT_NOT_REACHED();
247                 break;
248             }
249             break;
250         }
251         forNode(node).setType(SpecInt32);
252         break;
253     }
254         
255     case UInt32ToNumber: {
256         JSValue child = forNode(node->child1()).value();
257         if (child && child.isNumber()) {
258             ASSERT(child.isInt32());
259             setConstant(node, JSValue(child.asUInt32()));
260             break;
261         }
262         if (!node->canSpeculateInt32())
263             forNode(node).setType(SpecDouble);
264         else {
265             forNode(node).setType(SpecInt32);
266             node->setCanExit(true);
267         }
268         break;
269     }
270             
271     case DoubleAsInt32: {
272         JSValue child = forNode(node->child1()).value();
273         if (child && child.isNumber()) {
274             double asDouble = child.asNumber();
275             int32_t asInt = JSC::toInt32(asDouble);
276             if (bitwise_cast<int64_t>(static_cast<double>(asInt)) == bitwise_cast<int64_t>(asDouble)) {
277                 setConstant(node, JSValue(asInt));
278                 break;
279             }
280         }
281         node->setCanExit(true);
282         forNode(node).setType(SpecInt32);
283         break;
284     }
285             
286     case ValueToInt32: {
287         JSValue child = forNode(node->child1()).value();
288         if (child && child.isNumber()) {
289             if (child.isInt32())
290                 setConstant(node, child);
291             else
292                 setConstant(node, JSValue(JSC::toInt32(child.asDouble())));
293             break;
294         }
295         
296         forNode(node).setType(SpecInt32);
297         break;
298     }
299         
300     case Int32ToDouble: {
301         JSValue child = forNode(node->child1()).value();
302         if (child && child.isNumber()) {
303             setConstant(node, JSValue(JSValue::EncodeAsDouble, child.asNumber()));
304             break;
305         }
306         if (isInt32Speculation(forNode(node->child1()).m_type))
307             forNode(node).setType(SpecDoubleReal);
308         else
309             forNode(node).setType(SpecDouble);
310         break;
311     }
312         
313     case Int52ToDouble: {
314         JSValue child = forNode(node->child1()).value();
315         if (child && child.isNumber()) {
316             setConstant(node, child);
317             break;
318         }
319         forNode(node).setType(SpecDouble);
320         break;
321     }
322         
323     case Int52ToValue: {
324         JSValue child = forNode(node->child1()).value();
325         if (child && child.isNumber()) {
326             setConstant(node, child);
327             break;
328         }
329         SpeculatedType type = forNode(node->child1()).m_type;
330         if (type & SpecInt52)
331             type = (type | SpecInt32 | SpecInt52AsDouble) & ~SpecInt52;
332         forNode(node).setType(type);
333         break;
334     }
335         
336     case ValueAdd:
337     case ArithAdd: {
338         JSValue left = forNode(node->child1()).value();
339         JSValue right = forNode(node->child2()).value();
340         if (left && right && left.isNumber() && right.isNumber()) {
341             setConstant(node, JSValue(left.asNumber() + right.asNumber()));
342             break;
343         }
344         switch (node->binaryUseKind()) {
345         case Int32Use:
346             forNode(node).setType(SpecInt32);
347             if (!bytecodeCanTruncateInteger(node->arithNodeFlags()))
348                 node->setCanExit(true);
349             break;
350         case MachineIntUse:
351             forNode(node).setType(SpecInt52);
352             if (!forNode(node->child1()).isType(SpecInt32)
353                 || !forNode(node->child2()).isType(SpecInt32))
354                 node->setCanExit(true);
355             break;
356         case NumberUse:
357             if (isFullRealNumberSpeculation(forNode(node->child1()).m_type)
358                 && isFullRealNumberSpeculation(forNode(node->child2()).m_type))
359                 forNode(node).setType(SpecDoubleReal);
360             else
361                 forNode(node).setType(SpecDouble);
362             break;
363         default:
364             RELEASE_ASSERT(node->op() == ValueAdd);
365             clobberWorld(node->codeOrigin, clobberLimit);
366             forNode(node).setType(SpecString | SpecBytecodeNumber);
367             break;
368         }
369         break;
370     }
371         
372     case MakeRope: {
373         forNode(node).set(m_graph, m_graph.m_vm.stringStructure.get());
374         break;
375     }
376             
377     case ArithSub: {
378         JSValue left = forNode(node->child1()).value();
379         JSValue right = forNode(node->child2()).value();
380         if (left && right && left.isNumber() && right.isNumber()) {
381             setConstant(node, JSValue(left.asNumber() - right.asNumber()));
382             break;
383         }
384         switch (node->binaryUseKind()) {
385         case Int32Use:
386             forNode(node).setType(SpecInt32);
387             if (!bytecodeCanTruncateInteger(node->arithNodeFlags()))
388                 node->setCanExit(true);
389             break;
390         case MachineIntUse:
391             forNode(node).setType(SpecInt52);
392             if (!forNode(node->child1()).isType(SpecInt32)
393                 || !forNode(node->child2()).isType(SpecInt32))
394                 node->setCanExit(true);
395             break;
396         case NumberUse:
397             forNode(node).setType(SpecDouble);
398             break;
399         default:
400             RELEASE_ASSERT_NOT_REACHED();
401             break;
402         }
403         break;
404     }
405         
406     case ArithNegate: {
407         JSValue child = forNode(node->child1()).value();
408         if (child && child.isNumber()) {
409             setConstant(node, JSValue(-child.asNumber()));
410             break;
411         }
412         switch (node->child1().useKind()) {
413         case Int32Use:
414             forNode(node).setType(SpecInt32);
415             if (!bytecodeCanTruncateInteger(node->arithNodeFlags()))
416                 node->setCanExit(true);
417             break;
418         case MachineIntUse:
419             forNode(node).setType(SpecInt52);
420             if (m_state.forNode(node->child1()).couldBeType(SpecInt52))
421                 node->setCanExit(true);
422             if (!bytecodeCanIgnoreNegativeZero(node->arithNodeFlags()))
423                 node->setCanExit(true);
424             break;
425         case NumberUse:
426             forNode(node).setType(SpecDouble);
427             break;
428         default:
429             RELEASE_ASSERT_NOT_REACHED();
430             break;
431         }
432         break;
433     }
434         
435     case ArithMul: {
436         JSValue left = forNode(node->child1()).value();
437         JSValue right = forNode(node->child2()).value();
438         if (left && right && left.isNumber() && right.isNumber()) {
439             setConstant(node, JSValue(left.asNumber() * right.asNumber()));
440             break;
441         }
442         switch (node->binaryUseKind()) {
443         case Int32Use:
444             forNode(node).setType(SpecInt32);
445             if (!bytecodeCanTruncateInteger(node->arithNodeFlags())
446                 || !bytecodeCanIgnoreNegativeZero(node->arithNodeFlags()))
447                 node->setCanExit(true);
448             break;
449         case MachineIntUse:
450             forNode(node).setType(SpecInt52);
451             node->setCanExit(true);
452             break;
453         case NumberUse:
454             if (isFullRealNumberSpeculation(forNode(node->child1()).m_type)
455                 || isFullRealNumberSpeculation(forNode(node->child2()).m_type))
456                 forNode(node).setType(SpecDoubleReal);
457             else
458                 forNode(node).setType(SpecDouble);
459             break;
460         default:
461             RELEASE_ASSERT_NOT_REACHED();
462             break;
463         }
464         break;
465     }
466
467     case ArithIMul: {
468         forNode(node).setType(SpecInt32);
469         break;
470     }
471         
472     case ArithDiv:
473     case ArithMin:
474     case ArithMax:
475     case ArithMod: {
476         JSValue left = forNode(node->child1()).value();
477         JSValue right = forNode(node->child2()).value();
478         if (node->op() == ArithMod && right && right.isNumber() && right.asNumber() == 1) {
479             setConstant(node, JSValue(0));
480             break;
481         }
482         if (left && right && left.isNumber() && right.isNumber()) {
483             double a = left.asNumber();
484             double b = right.asNumber();
485             switch (node->op()) {
486             case ArithDiv:
487                 setConstant(node, JSValue(a / b));
488                 break;
489             case ArithMin:
490                 setConstant(node, JSValue(a < b ? a : (b <= a ? b : a + b)));
491                 break;
492             case ArithMax:
493                 setConstant(node, JSValue(a > b ? a : (b >= a ? b : a + b)));
494                 break;
495             case ArithMod:
496                 setConstant(node, JSValue(fmod(a, b)));
497                 break;
498             default:
499                 RELEASE_ASSERT_NOT_REACHED();
500                 break;
501             }
502             break;
503         }
504         switch (node->binaryUseKind()) {
505         case Int32Use:
506             forNode(node).setType(SpecInt32);
507             node->setCanExit(true);
508             break;
509         case NumberUse:
510             forNode(node).setType(SpecDouble);
511             break;
512         default:
513             RELEASE_ASSERT_NOT_REACHED();
514             break;
515         }
516         break;
517     }
518             
519     case ArithAbs: {
520         JSValue child = forNode(node->child1()).value();
521         if (child && child.isNumber()) {
522             setConstant(node, JSValue(fabs(child.asNumber())));
523             break;
524         }
525         switch (node->child1().useKind()) {
526         case Int32Use:
527             forNode(node).setType(SpecInt32);
528             node->setCanExit(true);
529             break;
530         case NumberUse:
531             forNode(node).setType(SpecDouble);
532             break;
533         default:
534             RELEASE_ASSERT_NOT_REACHED();
535             break;
536         }
537         break;
538     }
539             
540     case ArithSqrt: {
541         JSValue child = forNode(node->child1()).value();
542         if (child && child.isNumber()) {
543             setConstant(node, JSValue(sqrt(child.asNumber())));
544             break;
545         }
546         forNode(node).setType(SpecDouble);
547         break;
548     }
549             
550     case LogicalNot: {
551         switch (booleanResult(node, forNode(node->child1()))) {
552         case DefinitelyTrue:
553             setConstant(node, jsBoolean(false));
554             break;
555         case DefinitelyFalse:
556             setConstant(node, jsBoolean(true));
557             break;
558         default:
559             switch (node->child1().useKind()) {
560             case BooleanUse:
561             case Int32Use:
562             case NumberUse:
563             case UntypedUse:
564                 break;
565             case ObjectOrOtherUse:
566                 node->setCanExit(true);
567                 break;
568             default:
569                 RELEASE_ASSERT_NOT_REACHED();
570                 break;
571             }
572             forNode(node).setType(SpecBoolean);
573             break;
574         }
575         break;
576     }
577         
578     case IsUndefined:
579     case IsBoolean:
580     case IsNumber:
581     case IsString:
582     case IsObject:
583     case IsFunction: {
584         node->setCanExit(
585             node->op() == IsUndefined
586             && m_graph.masqueradesAsUndefinedWatchpointIsStillValid(node->codeOrigin));
587         JSValue child = forNode(node->child1()).value();
588         if (child) {
589             bool constantWasSet = true;
590             switch (node->op()) {
591             case IsUndefined:
592                 setConstant(node, jsBoolean(
593                     child.isCell()
594                     ? child.asCell()->structure()->masqueradesAsUndefined(m_codeBlock->globalObjectFor(node->codeOrigin))
595                     : child.isUndefined()));
596                 break;
597             case IsBoolean:
598                 setConstant(node, jsBoolean(child.isBoolean()));
599                 break;
600             case IsNumber:
601                 setConstant(node, jsBoolean(child.isNumber()));
602                 break;
603             case IsString:
604                 setConstant(node, jsBoolean(isJSString(child)));
605                 break;
606             case IsObject:
607                 if (child.isNull() || !child.isObject()) {
608                     setConstant(node, jsBoolean(child.isNull()));
609                     break;
610                 }
611                 constantWasSet = false;
612                 break;
613             default:
614                 constantWasSet = false;
615                 break;
616             }
617             if (constantWasSet)
618                 break;
619         }
620
621         forNode(node).setType(SpecBoolean);
622         break;
623     }
624
625     case TypeOf: {
626         VM* vm = m_codeBlock->vm();
627         JSValue child = forNode(node->child1()).value();
628         AbstractValue& abstractChild = forNode(node->child1());
629         if (child) {
630             JSValue typeString = jsTypeStringForValue(*vm, m_codeBlock->globalObjectFor(node->codeOrigin), child);
631             setConstant(node, typeString);
632             break;
633         }
634         
635         if (isFullNumberSpeculation(abstractChild.m_type)) {
636             setConstant(node, vm->smallStrings.numberString());
637             break;
638         }
639         
640         if (isStringSpeculation(abstractChild.m_type)) {
641             setConstant(node, vm->smallStrings.stringString());
642             break;
643         }
644         
645         if (isFinalObjectSpeculation(abstractChild.m_type) || isArraySpeculation(abstractChild.m_type) || isArgumentsSpeculation(abstractChild.m_type)) {
646             setConstant(node, vm->smallStrings.objectString());
647             break;
648         }
649         
650         if (isFunctionSpeculation(abstractChild.m_type)) {
651             setConstant(node, vm->smallStrings.functionString());
652             break;
653         }
654         
655         if (isBooleanSpeculation(abstractChild.m_type)) {
656             setConstant(node, vm->smallStrings.booleanString());
657             break;
658         }
659
660         switch (node->child1().useKind()) {
661         case StringUse:
662         case CellUse:
663             node->setCanExit(true);
664             break;
665         case UntypedUse:
666             break;
667         default:
668             RELEASE_ASSERT_NOT_REACHED();
669             break;
670         }
671         forNode(node).set(m_graph, m_graph.m_vm.stringStructure.get());
672         break;
673     }
674             
675     case CompareLess:
676     case CompareLessEq:
677     case CompareGreater:
678     case CompareGreaterEq:
679     case CompareEq:
680     case CompareEqConstant: {
681         JSValue leftConst = forNode(node->child1()).value();
682         JSValue rightConst = forNode(node->child2()).value();
683         if (leftConst && rightConst) {
684             if (leftConst.isNumber() && rightConst.isNumber()) {
685                 double a = leftConst.asNumber();
686                 double b = rightConst.asNumber();
687                 switch (node->op()) {
688                 case CompareLess:
689                     setConstant(node, jsBoolean(a < b));
690                     break;
691                 case CompareLessEq:
692                     setConstant(node, jsBoolean(a <= b));
693                     break;
694                 case CompareGreater:
695                     setConstant(node, jsBoolean(a > b));
696                     break;
697                 case CompareGreaterEq:
698                     setConstant(node, jsBoolean(a >= b));
699                     break;
700                 case CompareEq:
701                     setConstant(node, jsBoolean(a == b));
702                     break;
703                 default:
704                     RELEASE_ASSERT_NOT_REACHED();
705                     break;
706                 }
707                 break;
708             }
709             
710             if (node->op() == CompareEq && leftConst.isString() && rightConst.isString()) {
711                 const StringImpl* a = asString(leftConst)->tryGetValueImpl();
712                 const StringImpl* b = asString(rightConst)->tryGetValueImpl();
713                 if (a && b) {
714                     setConstant(node, jsBoolean(WTF::equal(a, b)));
715                     break;
716                 }
717             }
718         }
719         
720         if (node->op() == CompareEqConstant || node->op() == CompareEq) {
721             SpeculatedType leftType = forNode(node->child1()).m_type;
722             SpeculatedType rightType = forNode(node->child2()).m_type;
723             if ((isInt32Speculation(leftType) && isOtherSpeculation(rightType))
724                 || (isOtherSpeculation(leftType) && isInt32Speculation(rightType))) {
725                 setConstant(node, jsBoolean(false));
726                 break;
727             }
728         }
729         
730         forNode(node).setType(SpecBoolean);
731         
732         // This is overly conservative. But the only thing this prevents is store elimination,
733         // and how likely is it, really, that you'll have redundant stores across a comparison
734         // operation? Comparison operations are typically at the end of basic blocks, so
735         // unless we have global store elimination (super unlikely given how unprofitable that
736         // optimization is to begin with), you aren't going to be wanting to store eliminate
737         // across an equality op.
738         node->setCanExit(true);
739         break;
740     }
741             
742     case CompareStrictEq:
743     case CompareStrictEqConstant: {
744         Node* leftNode = node->child1().node();
745         Node* rightNode = node->child2().node();
746         JSValue left = forNode(leftNode).value();
747         JSValue right = forNode(rightNode).value();
748         if (left && right) {
749             if (left.isNumber() && right.isNumber()) {
750                 setConstant(node, jsBoolean(left.asNumber() == right.asNumber()));
751                 break;
752             }
753             if (left.isString() && right.isString()) {
754                 const StringImpl* a = asString(left)->tryGetValueImpl();
755                 const StringImpl* b = asString(right)->tryGetValueImpl();
756                 if (a && b) {
757                     setConstant(node, jsBoolean(WTF::equal(a, b)));
758                     break;
759                 }
760             }
761         }
762         forNode(node).setType(SpecBoolean);
763         node->setCanExit(true); // This is overly conservative.
764         break;
765     }
766         
767     case StringCharCodeAt:
768         node->setCanExit(true);
769         forNode(node).setType(SpecInt32);
770         break;
771         
772     case StringFromCharCode:
773         forNode(node).setType(SpecString);
774         break;
775
776     case StringCharAt:
777         node->setCanExit(true);
778         forNode(node).set(m_graph, m_graph.m_vm.stringStructure.get());
779         break;
780             
781     case GetByVal: {
782         node->setCanExit(true);
783         switch (node->arrayMode().type()) {
784         case Array::SelectUsingPredictions:
785         case Array::Unprofiled:
786         case Array::Undecided:
787             RELEASE_ASSERT_NOT_REACHED();
788             break;
789         case Array::ForceExit:
790             m_state.setIsValid(false);
791             break;
792         case Array::Generic:
793             clobberWorld(node->codeOrigin, clobberLimit);
794             forNode(node).makeHeapTop();
795             break;
796         case Array::String:
797             if (node->arrayMode().isOutOfBounds()) {
798                 // If the watchpoint was still valid we could totally set this to be
799                 // SpecString | SpecOther. Except that we'd have to be careful. If we
800                 // tested the watchpoint state here then it could change by the time
801                 // we got to the backend. So to do this right, we'd have to get the
802                 // fixup phase to check the watchpoint state and then bake into the
803                 // GetByVal operation the fact that we're using a watchpoint, using
804                 // something like Array::SaneChain (except not quite, because that
805                 // implies an in-bounds access). None of this feels like it's worth it,
806                 // so we're going with TOP for now. The same thing applies to
807                 // clobbering the world.
808                 clobberWorld(node->codeOrigin, clobberLimit);
809                 forNode(node).makeHeapTop();
810             } else
811                 forNode(node).set(m_graph, m_graph.m_vm.stringStructure.get());
812             break;
813         case Array::Arguments:
814             forNode(node).makeHeapTop();
815             break;
816         case Array::Int32:
817             if (node->arrayMode().isOutOfBounds()) {
818                 clobberWorld(node->codeOrigin, clobberLimit);
819                 forNode(node).makeHeapTop();
820             } else
821                 forNode(node).setType(SpecInt32);
822             break;
823         case Array::Double:
824             if (node->arrayMode().isOutOfBounds()) {
825                 clobberWorld(node->codeOrigin, clobberLimit);
826                 forNode(node).makeHeapTop();
827             } else if (node->arrayMode().isSaneChain())
828                 forNode(node).setType(SpecDouble);
829             else
830                 forNode(node).setType(SpecDoubleReal);
831             break;
832         case Array::Contiguous:
833         case Array::ArrayStorage:
834         case Array::SlowPutArrayStorage:
835             if (node->arrayMode().isOutOfBounds())
836                 clobberWorld(node->codeOrigin, clobberLimit);
837             forNode(node).makeHeapTop();
838             break;
839         case Array::Int8Array:
840             forNode(node).setType(SpecInt32);
841             break;
842         case Array::Int16Array:
843             forNode(node).setType(SpecInt32);
844             break;
845         case Array::Int32Array:
846             forNode(node).setType(SpecInt32);
847             break;
848         case Array::Uint8Array:
849             forNode(node).setType(SpecInt32);
850             break;
851         case Array::Uint8ClampedArray:
852             forNode(node).setType(SpecInt32);
853             break;
854         case Array::Uint16Array:
855             forNode(node).setType(SpecInt32);
856             break;
857         case Array::Uint32Array:
858             if (node->shouldSpeculateInt32())
859                 forNode(node).setType(SpecInt32);
860             else if (enableInt52() && node->shouldSpeculateMachineInt())
861                 forNode(node).setType(SpecInt52);
862             else
863                 forNode(node).setType(SpecDouble);
864             break;
865         case Array::Float32Array:
866             forNode(node).setType(SpecDouble);
867             break;
868         case Array::Float64Array:
869             forNode(node).setType(SpecDouble);
870             break;
871         default:
872             RELEASE_ASSERT_NOT_REACHED();
873             break;
874         }
875         break;
876     }
877             
878     case PutByVal:
879     case PutByValAlias: {
880         node->setCanExit(true);
881         switch (node->arrayMode().modeForPut().type()) {
882         case Array::ForceExit:
883             m_state.setIsValid(false);
884             break;
885         case Array::Generic:
886             clobberWorld(node->codeOrigin, clobberLimit);
887             break;
888         case Array::Int32:
889             if (node->arrayMode().isOutOfBounds())
890                 clobberWorld(node->codeOrigin, clobberLimit);
891             break;
892         case Array::Double:
893             if (node->arrayMode().isOutOfBounds())
894                 clobberWorld(node->codeOrigin, clobberLimit);
895             break;
896         case Array::Contiguous:
897         case Array::ArrayStorage:
898             if (node->arrayMode().isOutOfBounds())
899                 clobberWorld(node->codeOrigin, clobberLimit);
900             break;
901         case Array::SlowPutArrayStorage:
902             if (node->arrayMode().mayStoreToHole())
903                 clobberWorld(node->codeOrigin, clobberLimit);
904             break;
905         default:
906             break;
907         }
908         break;
909     }
910             
911     case ArrayPush:
912         node->setCanExit(true);
913         clobberWorld(node->codeOrigin, clobberLimit);
914         forNode(node).setType(SpecBytecodeNumber);
915         break;
916             
917     case ArrayPop:
918         node->setCanExit(true);
919         clobberWorld(node->codeOrigin, clobberLimit);
920         forNode(node).makeHeapTop();
921         break;
922             
923     case RegExpExec:
924         forNode(node).makeHeapTop();
925         break;
926
927     case RegExpTest:
928         forNode(node).setType(SpecBoolean);
929         break;
930             
931     case Jump:
932         break;
933             
934     case Branch: {
935         Node* child = node->child1().node();
936         BooleanResult result = booleanResult(node, forNode(child));
937         if (result == DefinitelyTrue) {
938             m_state.setBranchDirection(TakeTrue);
939             break;
940         }
941         if (result == DefinitelyFalse) {
942             m_state.setBranchDirection(TakeFalse);
943             break;
944         }
945         // FIXME: The above handles the trivial cases of sparse conditional
946         // constant propagation, but we can do better:
947         // We can specialize the source variable's value on each direction of
948         // the branch.
949         node->setCanExit(true); // This is overly conservative.
950         m_state.setBranchDirection(TakeBoth);
951         break;
952     }
953         
954     case Switch: {
955         // Nothing to do for now.
956         // FIXME: Do sparse conditional things.
957         break;
958     }
959             
960     case Return:
961         m_state.setIsValid(false);
962         break;
963         
964     case Throw:
965     case ThrowReferenceError:
966         m_state.setIsValid(false);
967         node->setCanExit(true);
968         break;
969             
970     case ToPrimitive: {
971         JSValue childConst = forNode(node->child1()).value();
972         if (childConst && childConst.isNumber()) {
973             setConstant(node, childConst);
974             break;
975         }
976         
977         ASSERT(node->child1().useKind() == UntypedUse);
978         
979         AbstractValue& source = forNode(node->child1());
980         AbstractValue& destination = forNode(node);
981         
982         // NB. The more canonical way of writing this would have been:
983         //
984         // destination = source;
985         // if (destination.m_type & !(SpecFullNumber | SpecString | SpecBoolean)) {
986         //     destination.filter(SpecFullNumber | SpecString | SpecBoolean);
987         //     AbstractValue string;
988         //     string.set(vm->stringStructure);
989         //     destination.merge(string);
990         // }
991         //
992         // The reason why this would, in most other cases, have been better is that
993         // then destination would preserve any non-SpeculatedType knowledge of source.
994         // As it stands, the code below forgets any non-SpeculatedType knowledge that
995         // source would have had. Fortunately, though, for things like strings and
996         // numbers and booleans, we don't care about the non-SpeculatedType knowedge:
997         // the structure won't tell us anything we don't already know, and neither
998         // will ArrayModes. And if the source was a meaningful constant then we
999         // would have handled that above. Unfortunately, this does mean that
1000         // ToPrimitive will currently forget string constants. But that's not a big
1001         // deal since we don't do any optimization on those currently.
1002         
1003         clobberWorld(node->codeOrigin, clobberLimit);
1004         
1005         SpeculatedType type = source.m_type;
1006         if (type & ~(SpecFullNumber | SpecString | SpecBoolean))
1007             type = (SpecHeapTop & ~SpecCell) | SpecString;
1008
1009         destination.setType(type);
1010         if (destination.isClear())
1011             m_state.setIsValid(false);
1012         break;
1013     }
1014         
1015     case ToString: {
1016         switch (node->child1().useKind()) {
1017         case StringObjectUse:
1018             // This also filters that the StringObject has the primordial StringObject
1019             // structure.
1020             filter(
1021                 node->child1(),
1022                 m_graph.globalObjectFor(node->codeOrigin)->stringObjectStructure());
1023             node->setCanExit(true); // We could be more precise but it's likely not worth it.
1024             break;
1025         case StringOrStringObjectUse:
1026             node->setCanExit(true); // We could be more precise but it's likely not worth it.
1027             break;
1028         case CellUse:
1029         case UntypedUse:
1030             clobberWorld(node->codeOrigin, clobberLimit);
1031             break;
1032         default:
1033             RELEASE_ASSERT_NOT_REACHED();
1034             break;
1035         }
1036         forNode(node).set(m_graph, m_graph.m_vm.stringStructure.get());
1037         break;
1038     }
1039         
1040     case NewStringObject: {
1041         ASSERT(node->structure()->classInfo() == StringObject::info());
1042         forNode(node).set(m_graph, node->structure());
1043         break;
1044     }
1045             
1046     case NewArray:
1047         node->setCanExit(true);
1048         forNode(node).set(
1049             m_graph,
1050             m_graph.globalObjectFor(node->codeOrigin)->arrayStructureForIndexingTypeDuringAllocation(node->indexingType()));
1051         m_state.setHaveStructures(true);
1052         break;
1053         
1054     case NewArrayBuffer:
1055         node->setCanExit(true);
1056         forNode(node).set(
1057             m_graph,
1058             m_graph.globalObjectFor(node->codeOrigin)->arrayStructureForIndexingTypeDuringAllocation(node->indexingType()));
1059         m_state.setHaveStructures(true);
1060         break;
1061
1062     case NewArrayWithSize:
1063         node->setCanExit(true);
1064         forNode(node).setType(SpecArray);
1065         m_state.setHaveStructures(true);
1066         break;
1067         
1068     case NewTypedArray:
1069         switch (node->child1().useKind()) {
1070         case Int32Use:
1071             break;
1072         case UntypedUse:
1073             clobberWorld(node->codeOrigin, clobberLimit);
1074             break;
1075         default:
1076             RELEASE_ASSERT_NOT_REACHED();
1077             break;
1078         }
1079         forNode(node).set(
1080             m_graph,
1081             m_graph.globalObjectFor(node->codeOrigin)->typedArrayStructure(
1082                 node->typedArrayType()));
1083         m_state.setHaveStructures(true);
1084         break;
1085             
1086     case NewRegexp:
1087         forNode(node).set(m_graph, m_graph.globalObjectFor(node->codeOrigin)->regExpStructure());
1088         m_state.setHaveStructures(true);
1089         break;
1090             
1091     case ToThis: {
1092         AbstractValue& source = forNode(node->child1());
1093         AbstractValue& destination = forNode(node);
1094             
1095         if (m_graph.executableFor(node->codeOrigin)->isStrictMode())
1096             destination.makeHeapTop();
1097         else {
1098             destination = source;
1099             destination.merge(SpecObject);
1100         }
1101         break;
1102     }
1103
1104     case CreateThis: {
1105         forNode(node).setType(SpecFinalObject);
1106         break;
1107     }
1108         
1109     case AllocationProfileWatchpoint:
1110         node->setCanExit(true);
1111         break;
1112
1113     case NewObject:
1114         forNode(node).set(m_graph, node->structure());
1115         m_state.setHaveStructures(true);
1116         break;
1117         
1118     case CreateActivation:
1119         forNode(node).set(
1120             m_graph, m_codeBlock->globalObjectFor(node->codeOrigin)->activationStructure());
1121         m_state.setHaveStructures(true);
1122         break;
1123     
1124     case CreateArguments:
1125         forNode(node).setType(SpecArguments);
1126         break;
1127         
1128     case TearOffActivation:
1129     case TearOffArguments:
1130         // Does nothing that is user-visible.
1131         break;
1132
1133     case CheckArgumentsNotCreated:
1134         if (isEmptySpeculation(
1135                 m_state.variables().operand(
1136                     m_graph.argumentsRegisterFor(node->codeOrigin)).m_type))
1137             m_state.setFoundConstants(true);
1138         else
1139             node->setCanExit(true);
1140         break;
1141         
1142     case GetMyArgumentsLength:
1143         // We know that this executable does not escape its arguments, so we can optimize
1144         // the arguments a bit. Note that this is not sufficient to force constant folding
1145         // of GetMyArgumentsLength, because GetMyArgumentsLength is a clobbering operation.
1146         // We perform further optimizations on this later on.
1147         if (node->codeOrigin.inlineCallFrame) {
1148             forNode(node).set(
1149                 m_graph, jsNumber(node->codeOrigin.inlineCallFrame->arguments.size() - 1));
1150         } else
1151             forNode(node).setType(SpecInt32);
1152         node->setCanExit(
1153             !isEmptySpeculation(
1154                 m_state.variables().operand(
1155                     m_graph.argumentsRegisterFor(node->codeOrigin)).m_type));
1156         break;
1157         
1158     case GetMyArgumentsLengthSafe:
1159         // This potentially clobbers all structures if the arguments object had a getter
1160         // installed on the length property.
1161         clobberWorld(node->codeOrigin, clobberLimit);
1162         // We currently make no guarantee about what this returns because it does not
1163         // speculate that the length property is actually a length.
1164         forNode(node).makeHeapTop();
1165         break;
1166         
1167     case GetMyArgumentByVal:
1168         node->setCanExit(true);
1169         // We know that this executable does not escape its arguments, so we can optimize
1170         // the arguments a bit. Note that this ends up being further optimized by the
1171         // ArgumentsSimplificationPhase.
1172         forNode(node).makeHeapTop();
1173         break;
1174         
1175     case GetMyArgumentByValSafe:
1176         node->setCanExit(true);
1177         // This potentially clobbers all structures if the property we're accessing has
1178         // a getter. We don't speculate against this.
1179         clobberWorld(node->codeOrigin, clobberLimit);
1180         // And the result is unknown.
1181         forNode(node).makeHeapTop();
1182         break;
1183         
1184     case NewFunction: {
1185         AbstractValue& value = forNode(node);
1186         value = forNode(node->child1());
1187         
1188         if (!(value.m_type & SpecEmpty)) {
1189             m_state.setFoundConstants(true);
1190             break;
1191         }
1192
1193         value.setType((value.m_type & ~SpecEmpty) | SpecFunction);
1194         break;
1195     }
1196
1197     case NewFunctionExpression:
1198     case NewFunctionNoCheck:
1199         forNode(node).set(
1200             m_graph, m_codeBlock->globalObjectFor(node->codeOrigin)->functionStructure());
1201         break;
1202         
1203     case GetCallee:
1204         forNode(node).setType(SpecFunction);
1205         break;
1206         
1207     case SetCallee:
1208     case SetMyScope:
1209         break;
1210             
1211     case GetScope: // FIXME: We could get rid of these if we know that the JSFunction is a constant. https://bugs.webkit.org/show_bug.cgi?id=106202
1212     case GetMyScope:
1213     case SkipTopScope:
1214         forNode(node).setType(SpecObjectOther);
1215         break;
1216
1217     case SkipScope: {
1218         JSValue child = forNode(node->child1()).value();
1219         if (child) {
1220             setConstant(node, JSValue(jsCast<JSScope*>(child.asCell())->next()));
1221             break;
1222         }
1223         forNode(node).setType(SpecObjectOther);
1224         break;
1225     }
1226
1227     case GetClosureRegisters:
1228         forNode(node).clear(); // The result is not a JS value.
1229         break;
1230
1231     case GetClosureVar:
1232         forNode(node).makeHeapTop();
1233         break;
1234             
1235     case PutClosureVar:
1236         clobberCapturedVars(node->codeOrigin);
1237         break;
1238             
1239     case GetById:
1240     case GetByIdFlush:
1241         node->setCanExit(true);
1242         if (!node->prediction()) {
1243             m_state.setIsValid(false);
1244             break;
1245         }
1246         if (isCellSpeculation(node->child1()->prediction())) {
1247             if (Structure* structure = forNode(node->child1()).bestProvenStructure()) {
1248                 GetByIdStatus status = GetByIdStatus::computeFor(
1249                     m_graph.m_vm, structure,
1250                     m_graph.identifiers()[node->identifierNumber()]);
1251                 if (status.isSimple()) {
1252                     // Assert things that we can't handle and that the computeFor() method
1253                     // above won't be able to return.
1254                     ASSERT(status.structureSet().size() == 1);
1255                     ASSERT(!status.chain());
1256                     
1257                     if (status.specificValue())
1258                         setConstant(node, status.specificValue());
1259                     else
1260                         forNode(node).makeHeapTop();
1261                     filter(node->child1(), status.structureSet());
1262                     
1263                     m_state.setFoundConstants(true);
1264                     break;
1265                 }
1266             }
1267         }
1268         clobberWorld(node->codeOrigin, clobberLimit);
1269         forNode(node).makeHeapTop();
1270         break;
1271             
1272     case GetArrayLength:
1273         node->setCanExit(true); // Lies, but it's true for the common case of JSArray, so it's good enough.
1274         forNode(node).setType(SpecInt32);
1275         break;
1276         
1277     case CheckExecutable: {
1278         // FIXME: We could track executables in AbstractValue, which would allow us to get rid of these checks
1279         // more thoroughly. https://bugs.webkit.org/show_bug.cgi?id=106200
1280         // FIXME: We could eliminate these entirely if we know the exact value that flows into this.
1281         // https://bugs.webkit.org/show_bug.cgi?id=106201
1282         node->setCanExit(true);
1283         break;
1284     }
1285
1286     case CheckStructure: {
1287         // FIXME: We should be able to propagate the structure sets of constants (i.e. prototypes).
1288         AbstractValue& value = forNode(node->child1());
1289         ASSERT(!(value.m_type & ~SpecCell)); // Edge filtering should have already ensured this.
1290
1291         StructureSet& set = node->structureSet();
1292
1293         if (value.m_currentKnownStructure.isSubsetOf(set)) {
1294             m_state.setFoundConstants(true);
1295             break;
1296         }
1297
1298         node->setCanExit(true);
1299         m_state.setHaveStructures(true);
1300
1301         // If this structure check is attempting to prove knowledge already held in
1302         // the futurePossibleStructure set then the constant folding phase should
1303         // turn this into a watchpoint instead.
1304         if (value.m_futurePossibleStructure.isSubsetOf(set)
1305             && value.m_futurePossibleStructure.hasSingleton()) {
1306             m_state.setFoundConstants(true);
1307             filter(value, value.m_futurePossibleStructure.singleton());
1308             break;
1309         }
1310
1311         filter(value, set);
1312         break;
1313     }
1314         
1315     case StructureTransitionWatchpoint: {
1316         AbstractValue& value = forNode(node->child1());
1317
1318         filter(value, node->structure());
1319         m_state.setHaveStructures(true);
1320         node->setCanExit(true);
1321         break;
1322     }
1323             
1324     case PutStructure:
1325     case PhantomPutStructure:
1326         if (!forNode(node->child1()).m_currentKnownStructure.isClear()) {
1327             clobberStructures(clobberLimit);
1328             forNode(node->child1()).set(m_graph, node->structureTransitionData().newStructure);
1329             m_state.setHaveStructures(true);
1330         }
1331         break;
1332     case GetButterfly:
1333     case AllocatePropertyStorage:
1334     case ReallocatePropertyStorage:
1335         forNode(node).clear(); // The result is not a JS value.
1336         break;
1337     case CheckArray: {
1338         if (node->arrayMode().alreadyChecked(m_graph, node, forNode(node->child1()))) {
1339             m_state.setFoundConstants(true);
1340             break;
1341         }
1342         node->setCanExit(true); // Lies, but this is followed by operations (like GetByVal) that always exit, so there is no point in us trying to be clever here.
1343         switch (node->arrayMode().type()) {
1344         case Array::String:
1345             filter(node->child1(), SpecString);
1346             break;
1347         case Array::Int32:
1348         case Array::Double:
1349         case Array::Contiguous:
1350         case Array::ArrayStorage:
1351         case Array::SlowPutArrayStorage:
1352             break;
1353         case Array::Arguments:
1354             filter(node->child1(), SpecArguments);
1355             break;
1356         case Array::Int8Array:
1357             filter(node->child1(), SpecInt8Array);
1358             break;
1359         case Array::Int16Array:
1360             filter(node->child1(), SpecInt16Array);
1361             break;
1362         case Array::Int32Array:
1363             filter(node->child1(), SpecInt32Array);
1364             break;
1365         case Array::Uint8Array:
1366             filter(node->child1(), SpecUint8Array);
1367             break;
1368         case Array::Uint8ClampedArray:
1369             filter(node->child1(), SpecUint8ClampedArray);
1370             break;
1371         case Array::Uint16Array:
1372             filter(node->child1(), SpecUint16Array);
1373             break;
1374         case Array::Uint32Array:
1375             filter(node->child1(), SpecUint32Array);
1376             break;
1377         case Array::Float32Array:
1378             filter(node->child1(), SpecFloat32Array);
1379             break;
1380         case Array::Float64Array:
1381             filter(node->child1(), SpecFloat64Array);
1382             break;
1383         default:
1384             RELEASE_ASSERT_NOT_REACHED();
1385             break;
1386         }
1387         filterArrayModes(node->child1(), node->arrayMode().arrayModesThatPassFiltering());
1388         m_state.setHaveStructures(true);
1389         break;
1390     }
1391     case Arrayify: {
1392         if (node->arrayMode().alreadyChecked(m_graph, node, forNode(node->child1()))) {
1393             m_state.setFoundConstants(true);
1394             break;
1395         }
1396         ASSERT(node->arrayMode().conversion() == Array::Convert
1397             || node->arrayMode().conversion() == Array::RageConvert);
1398         node->setCanExit(true);
1399         clobberStructures(clobberLimit);
1400         filterArrayModes(node->child1(), node->arrayMode().arrayModesThatPassFiltering());
1401         m_state.setHaveStructures(true);
1402         break;
1403     }
1404     case ArrayifyToStructure: {
1405         AbstractValue& value = forNode(node->child1());
1406         StructureSet set = node->structure();
1407         if (value.m_futurePossibleStructure.isSubsetOf(set)
1408             || value.m_currentKnownStructure.isSubsetOf(set))
1409             m_state.setFoundConstants(true);
1410         node->setCanExit(true);
1411         clobberStructures(clobberLimit);
1412         filter(value, set);
1413         m_state.setHaveStructures(true);
1414         break;
1415     }
1416     case GetIndexedPropertyStorage: {
1417         forNode(node).clear();
1418         break; 
1419     }
1420         
1421     case GetTypedArrayByteOffset: {
1422         forNode(node).setType(SpecInt32);
1423         break;
1424     }
1425         
1426     case GetByOffset: {
1427         forNode(node).makeHeapTop();
1428         break;
1429     }
1430             
1431     case PutByOffset: {
1432         break;
1433     }
1434             
1435     case CheckFunction: {
1436         JSValue value = forNode(node->child1()).value();
1437         if (value == node->function()) {
1438             m_state.setFoundConstants(true);
1439             ASSERT(value);
1440             break;
1441         }
1442         
1443         node->setCanExit(true); // Lies! We can do better.
1444         filterByValue(node->child1(), node->function());
1445         break;
1446     }
1447         
1448     case PutById:
1449     case PutByIdDirect:
1450         node->setCanExit(true);
1451         if (Structure* structure = forNode(node->child1()).bestProvenStructure()) {
1452             PutByIdStatus status = PutByIdStatus::computeFor(
1453                 m_graph.m_vm,
1454                 m_graph.globalObjectFor(node->codeOrigin),
1455                 structure,
1456                 m_graph.identifiers()[node->identifierNumber()],
1457                 node->op() == PutByIdDirect);
1458             if (status.isSimpleReplace()) {
1459                 filter(node->child1(), structure);
1460                 m_state.setFoundConstants(true);
1461                 break;
1462             }
1463             if (status.isSimpleTransition()) {
1464                 clobberStructures(clobberLimit);
1465                 forNode(node->child1()).set(m_graph, status.newStructure());
1466                 m_state.setHaveStructures(true);
1467                 m_state.setFoundConstants(true);
1468                 break;
1469             }
1470         }
1471         clobberWorld(node->codeOrigin, clobberLimit);
1472         break;
1473         
1474     case In:
1475         // FIXME: We can determine when the property definitely exists based on abstract
1476         // value information.
1477         clobberWorld(node->codeOrigin, clobberLimit);
1478         forNode(node).setType(SpecBoolean);
1479         break;
1480             
1481     case GetGlobalVar:
1482         forNode(node).makeHeapTop();
1483         break;
1484         
1485     case GlobalVarWatchpoint:
1486     case VarInjectionWatchpoint:
1487         node->setCanExit(true);
1488         break;
1489             
1490     case PutGlobalVar:
1491         break;
1492             
1493     case CheckHasInstance:
1494         node->setCanExit(true);
1495         // Sadly, we don't propagate the fact that we've done CheckHasInstance
1496         break;
1497             
1498     case InstanceOf:
1499         node->setCanExit(true);
1500         // Again, sadly, we don't propagate the fact that we've done InstanceOf
1501         forNode(node).setType(SpecBoolean);
1502         break;
1503             
1504     case Phi:
1505         RELEASE_ASSERT(m_graph.m_form == SSA);
1506         // The state of this node would have already been decided.
1507         break;
1508         
1509     case Upsilon: {
1510         m_state.createValueForNode(node->phi());
1511         AbstractValue& value = forNode(node->child1());
1512         forNode(node) = value;
1513         forNode(node->phi()) = value;
1514         break;
1515     }
1516         
1517     case Flush:
1518     case PhantomLocal:
1519     case Breakpoint:
1520         break;
1521             
1522     case Call:
1523     case Construct:
1524         node->setCanExit(true);
1525         clobberWorld(node->codeOrigin, clobberLimit);
1526         forNode(node).makeHeapTop();
1527         break;
1528
1529     case ForceOSRExit:
1530         node->setCanExit(true);
1531         m_state.setIsValid(false);
1532         break;
1533             
1534     case CheckWatchdogTimer:
1535         node->setCanExit(true);
1536         break;
1537             
1538     case Phantom:
1539     case InlineStart:
1540     case CountExecution:
1541     case CheckTierUpInLoop:
1542     case CheckTierUpAtReturn:
1543         break;
1544
1545     case CheckTierUpAndOSREnter:
1546     case LoopHint:
1547         // We pretend that it can exit because it may want to get all state.
1548         node->setCanExit(true);
1549         break;
1550
1551     case Unreachable:
1552         RELEASE_ASSERT_NOT_REACHED();
1553         break;
1554
1555     case LastNodeType:
1556         RELEASE_ASSERT_NOT_REACHED();
1557         break;
1558     }
1559     
1560     return m_state.isValid();
1561 }
1562
1563 template<typename AbstractStateType>
1564 bool AbstractInterpreter<AbstractStateType>::executeEffects(unsigned indexInBlock)
1565 {
1566     return executeEffects(indexInBlock, m_state.block()->at(indexInBlock));
1567 }
1568
1569 template<typename AbstractStateType>
1570 bool AbstractInterpreter<AbstractStateType>::execute(unsigned indexInBlock)
1571 {
1572     Node* node = m_state.block()->at(indexInBlock);
1573     if (!startExecuting(node))
1574         return true;
1575     
1576     executeEdges(node);
1577     return executeEffects(indexInBlock, node);
1578 }
1579
1580 template<typename AbstractStateType>
1581 bool AbstractInterpreter<AbstractStateType>::execute(Node* node)
1582 {
1583     if (!startExecuting(node))
1584         return true;
1585     
1586     executeEdges(node);
1587     return executeEffects(UINT_MAX, node);
1588 }
1589
1590 template<typename AbstractStateType>
1591 void AbstractInterpreter<AbstractStateType>::clobberWorld(
1592     const CodeOrigin& codeOrigin, unsigned clobberLimit)
1593 {
1594     clobberCapturedVars(codeOrigin);
1595     clobberStructures(clobberLimit);
1596 }
1597
1598 template<typename AbstractStateType>
1599 void AbstractInterpreter<AbstractStateType>::clobberCapturedVars(const CodeOrigin& codeOrigin)
1600 {
1601     if (codeOrigin.inlineCallFrame) {
1602         const BitVector& capturedVars = codeOrigin.inlineCallFrame->capturedVars;
1603         for (size_t i = capturedVars.size(); i--;) {
1604             if (!capturedVars.quickGet(i))
1605                 continue;
1606             m_state.variables().local(i).makeHeapTop();
1607         }
1608     } else {
1609         for (size_t i = m_codeBlock->m_numVars; i--;) {
1610             if (m_codeBlock->isCaptured(localToOperand(i)))
1611                 m_state.variables().local(i).makeHeapTop();
1612         }
1613     }
1614
1615     for (size_t i = m_state.variables().numberOfArguments(); i--;) {
1616         if (m_codeBlock->isCaptured(argumentToOperand(i)))
1617             m_state.variables().argument(i).makeHeapTop();
1618     }
1619 }
1620
1621 template<typename AbstractStateType>
1622 void AbstractInterpreter<AbstractStateType>::clobberStructures(unsigned clobberLimit)
1623 {
1624     if (!m_state.haveStructures())
1625         return;
1626     if (clobberLimit >= m_state.block()->size())
1627         clobberLimit = m_state.block()->size();
1628     else
1629         clobberLimit++;
1630     ASSERT(clobberLimit <= m_state.block()->size());
1631     for (size_t i = clobberLimit; i--;)
1632         forNode(m_state.block()->at(i)).clobberStructures();
1633     if (m_graph.m_form == SSA) {
1634         HashSet<Node*>::iterator iter = m_state.block()->ssa->liveAtHead.begin();
1635         HashSet<Node*>::iterator end = m_state.block()->ssa->liveAtHead.end();
1636         for (; iter != end; ++iter)
1637             forNode(*iter).clobberStructures();
1638     }
1639     for (size_t i = m_state.variables().numberOfArguments(); i--;)
1640         m_state.variables().argument(i).clobberStructures();
1641     for (size_t i = m_state.variables().numberOfLocals(); i--;)
1642         m_state.variables().local(i).clobberStructures();
1643     m_state.setHaveStructures(true);
1644     m_state.setDidClobber(true);
1645 }
1646
1647 template<typename AbstractStateType>
1648 void AbstractInterpreter<AbstractStateType>::dump(PrintStream& out)
1649 {
1650     CommaPrinter comma(" ");
1651     if (m_graph.m_form == SSA) {
1652         HashSet<Node*>::iterator iter = m_state.block()->ssa->liveAtHead.begin();
1653         HashSet<Node*>::iterator end = m_state.block()->ssa->liveAtHead.end();
1654         for (; iter != end; ++iter) {
1655             Node* node = *iter;
1656             AbstractValue& value = forNode(node);
1657             if (value.isClear())
1658                 continue;
1659             out.print(comma, node, ":", value);
1660         }
1661     }
1662     for (size_t i = 0; i < m_state.block()->size(); ++i) {
1663         Node* node = m_state.block()->at(i);
1664         AbstractValue& value = forNode(node);
1665         if (value.isClear())
1666             continue;
1667         out.print(comma, node, ":", value);
1668     }
1669 }
1670
1671 template<typename AbstractStateType>
1672 FiltrationResult AbstractInterpreter<AbstractStateType>::filter(
1673     AbstractValue& value, const StructureSet& set)
1674 {
1675     if (value.filter(m_graph, set) == FiltrationOK)
1676         return FiltrationOK;
1677     m_state.setIsValid(false);
1678     return Contradiction;
1679 }
1680
1681 template<typename AbstractStateType>
1682 FiltrationResult AbstractInterpreter<AbstractStateType>::filterArrayModes(
1683     AbstractValue& value, ArrayModes arrayModes)
1684 {
1685     if (value.filterArrayModes(arrayModes) == FiltrationOK)
1686         return FiltrationOK;
1687     m_state.setIsValid(false);
1688     return Contradiction;
1689 }
1690
1691 template<typename AbstractStateType>
1692 FiltrationResult AbstractInterpreter<AbstractStateType>::filter(
1693     AbstractValue& value, SpeculatedType type)
1694 {
1695     if (value.filter(type) == FiltrationOK)
1696         return FiltrationOK;
1697     m_state.setIsValid(false);
1698     return Contradiction;
1699 }
1700
1701 template<typename AbstractStateType>
1702 FiltrationResult AbstractInterpreter<AbstractStateType>::filterByValue(
1703     AbstractValue& abstractValue, JSValue concreteValue)
1704 {
1705     if (abstractValue.filterByValue(concreteValue) == FiltrationOK)
1706         return FiltrationOK;
1707     m_state.setIsValid(false);
1708     return Contradiction;
1709 }
1710
1711 } } // namespace JSC::DFG
1712
1713 #endif // ENABLE(DFG_JIT)
1714
1715 #endif // DFGAbstractInterpreterInlines_h
1716