5e51dea89d44aabb5886958b9ce06c24f3779247
[WebKit-https.git] / Source / JavaScriptCore / dfg / DFGAbstractInterpreterInlines.h
1 /*
2  * Copyright (C) 2013, 2014 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 "Operations.h"
34 #include "PutByIdStatus.h"
35 #include "StringObject.h"
36
37 namespace JSC { namespace DFG {
38
39 template<typename AbstractStateType>
40 AbstractInterpreter<AbstractStateType>::AbstractInterpreter(Graph& graph, AbstractStateType& state)
41     : m_codeBlock(graph.m_codeBlock)
42     , m_graph(graph)
43     , m_state(state)
44 {
45 }
46
47 template<typename AbstractStateType>
48 AbstractInterpreter<AbstractStateType>::~AbstractInterpreter()
49 {
50 }
51
52 template<typename AbstractStateType>
53 typename AbstractInterpreter<AbstractStateType>::BooleanResult
54 AbstractInterpreter<AbstractStateType>::booleanResult(
55     Node* node, AbstractValue& value)
56 {
57     JSValue childConst = value.value();
58     if (childConst) {
59         if (childConst.toBoolean(m_codeBlock->globalObjectFor(node->origin.semantic)->globalExec()))
60             return DefinitelyTrue;
61         return DefinitelyFalse;
62     }
63
64     // Next check if we can fold because we know that the source is an object or string and does not equal undefined.
65     if (isCellSpeculation(value.m_type)
66         && value.m_currentKnownStructure.hasSingleton()) {
67         Structure* structure = value.m_currentKnownStructure.singleton();
68         if (!structure->masqueradesAsUndefined(m_codeBlock->globalObjectFor(node->origin.semantic))
69             && structure->typeInfo().type() != StringType)
70             return DefinitelyTrue;
71     }
72     
73     return UnknownBooleanResult;
74 }
75
76 template<typename AbstractStateType>
77 bool AbstractInterpreter<AbstractStateType>::startExecuting(Node* node)
78 {
79     ASSERT(m_state.block());
80     ASSERT(m_state.isValid());
81     
82     m_state.setDidClobber(false);
83     
84     node->setCanExit(false);
85     
86     return node->shouldGenerate();
87 }
88
89 template<typename AbstractStateType>
90 bool AbstractInterpreter<AbstractStateType>::startExecuting(unsigned indexInBlock)
91 {
92     return startExecuting(m_state.block()->at(indexInBlock));
93 }
94
95 template<typename AbstractStateType>
96 void AbstractInterpreter<AbstractStateType>::executeEdges(Node* node)
97 {
98     DFG_NODE_DO_TO_CHILDREN(m_graph, node, filterEdgeByUse);
99 }
100
101 template<typename AbstractStateType>
102 void AbstractInterpreter<AbstractStateType>::executeEdges(unsigned indexInBlock)
103 {
104     executeEdges(m_state.block()->at(indexInBlock));
105 }
106
107 template<typename AbstractStateType>
108 void AbstractInterpreter<AbstractStateType>::verifyEdge(Node*, Edge edge)
109 {
110     RELEASE_ASSERT(!(forNode(edge).m_type & ~typeFilterFor(edge.useKind())));
111 }
112
113 template<typename AbstractStateType>
114 void AbstractInterpreter<AbstractStateType>::verifyEdges(Node* node)
115 {
116     DFG_NODE_DO_TO_CHILDREN(m_graph, node, verifyEdge);
117 }
118
119 template<typename AbstractStateType>
120 bool AbstractInterpreter<AbstractStateType>::executeEffects(unsigned clobberLimit, Node* node)
121 {
122     if (!ASSERT_DISABLED)
123         verifyEdges(node);
124     
125     m_state.createValueForNode(node);
126     
127     switch (node->op()) {
128     case JSConstant:
129     case DoubleConstant:
130     case Int52Constant:
131     case WeakJSConstant:
132     case PhantomArguments: {
133         setBuiltInConstant(node, 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().offset());
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 (!(node->unlinkedLocal().isArgument())
156             && m_graph.m_lazyVars.get(node->unlinkedLocal().toLocal())) {
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         AbstractValue value = m_state.variables().operand(variableAccessData->local().offset());
171         if (!variableAccessData->isCaptured()) {
172             if (value.isClear())
173                 node->setCanExit(true);
174         }
175         if (value.value())
176             m_state.setFoundConstants(true);
177         forNode(node) = value;
178         break;
179     }
180         
181     case GetLocalUnlinked: {
182         AbstractValue value = m_state.variables().operand(node->unlinkedLocal().offset());
183         if (value.value())
184             m_state.setFoundConstants(true);
185         forNode(node) = value;
186         break;
187     }
188         
189     case SetLocal: {
190         m_state.variables().operand(node->local().offset()) = forNode(node->child1());
191         break;
192     }
193         
194     case MovHint: {
195         // Don't need to do anything. A MovHint only informs us about what would have happened
196         // in bytecode, but this code is just concerned with what is actually happening during
197         // DFG execution.
198         break;
199     }
200         
201     case SetArgument:
202         // Assert that the state of arguments has been set.
203         ASSERT(!m_state.block()->valuesAtHead.operand(node->local()).isClear());
204         break;
205             
206     case BitAnd:
207     case BitOr:
208     case BitXor:
209     case BitRShift:
210     case BitLShift:
211     case BitURShift: {
212         JSValue left = forNode(node->child1()).value();
213         JSValue right = forNode(node->child2()).value();
214         if (left && right && left.isInt32() && right.isInt32()) {
215             int32_t a = left.asInt32();
216             int32_t b = right.asInt32();
217             switch (node->op()) {
218             case BitAnd:
219                 setConstant(node, JSValue(a & b));
220                 break;
221             case BitOr:
222                 setConstant(node, JSValue(a | b));
223                 break;
224             case BitXor:
225                 setConstant(node, JSValue(a ^ b));
226                 break;
227             case BitRShift:
228                 setConstant(node, JSValue(a >> static_cast<uint32_t>(b)));
229                 break;
230             case BitLShift:
231                 setConstant(node, JSValue(a << static_cast<uint32_t>(b)));
232                 break;
233             case BitURShift:
234                 setConstant(node, JSValue(static_cast<uint32_t>(a) >> static_cast<uint32_t>(b)));
235                 break;
236             default:
237                 RELEASE_ASSERT_NOT_REACHED();
238                 break;
239             }
240             break;
241         }
242         forNode(node).setType(SpecInt32);
243         break;
244     }
245         
246     case UInt32ToNumber: {
247         JSValue child = forNode(node->child1()).value();
248         if (doesOverflow(node->arithMode())) {
249             if (child && child.isInt32()) {
250                 uint32_t value = child.asInt32();
251                 setConstant(node, jsNumber(value));
252                 break;
253             }
254             forNode(node).setType(SpecInt52AsDouble);
255             break;
256         }
257         if (child && child.isInt32()) {
258             int32_t value = child.asInt32();
259             if (value >= 0) {
260                 setConstant(node, jsNumber(value));
261                 break;
262             }
263         }
264         forNode(node).setType(SpecInt32);
265         node->setCanExit(true);
266         break;
267     }
268         
269     case BooleanToNumber: {
270         JSValue concreteValue = forNode(node->child1()).value();
271         if (concreteValue) {
272             if (concreteValue.isBoolean())
273                 setConstant(node, jsNumber(concreteValue.asBoolean()));
274             else
275                 setConstant(node, concreteValue);
276             break;
277         }
278         AbstractValue& value = forNode(node);
279         value = forNode(node->child1());
280         if (node->child1().useKind() == UntypedUse && !(value.m_type & ~SpecBoolean))
281             m_state.setFoundConstants(true);
282         if (value.m_type & SpecBoolean) {
283             value.merge(SpecInt32);
284             value.filter(~SpecBoolean);
285         }
286         break;
287     }
288             
289     case DoubleAsInt32: {
290         JSValue child = forNode(node->child1()).value();
291         if (child && child.isNumber()) {
292             double asDouble = child.asNumber();
293             int32_t asInt = JSC::toInt32(asDouble);
294             if (bitwise_cast<int64_t>(static_cast<double>(asInt)) == bitwise_cast<int64_t>(asDouble)) {
295                 setConstant(node, JSValue(asInt));
296                 break;
297             }
298         }
299         node->setCanExit(true);
300         forNode(node).setType(SpecInt32);
301         break;
302     }
303             
304     case ValueToInt32: {
305         JSValue child = forNode(node->child1()).value();
306         if (child) {
307             if (child.isNumber()) {
308                 if (child.isInt32())
309                     setConstant(node, child);
310                 else
311                     setConstant(node, JSValue(JSC::toInt32(child.asDouble())));
312                 break;
313             }
314             if (child.isBoolean()) {
315                 setConstant(node, jsNumber(child.asBoolean()));
316                 break;
317             }
318             if (child.isUndefinedOrNull()) {
319                 setConstant(node, jsNumber(0));
320                 break;
321             }
322         }
323         
324         forNode(node).setType(SpecInt32);
325         break;
326     }
327         
328     case DoubleRep: {
329         JSValue child = forNode(node->child1()).value();
330         if (child && child.isNumber()) {
331             setConstant(node, jsDoubleNumber(child.asNumber()));
332             break;
333         }
334         forNode(node).setType(forNode(node->child1()).m_type);
335         forNode(node).fixTypeForRepresentation(node);
336         break;
337     }
338         
339     case Int52Rep: {
340         JSValue child = forNode(node->child1()).value();
341         if (child && child.isMachineInt()) {
342             setConstant(node, child);
343             break;
344         }
345         
346         forNode(node).setType(SpecInt32);
347         break;
348     }
349         
350     case ValueRep: {
351         JSValue value = forNode(node->child1()).value();
352         if (value) {
353             setConstant(node, value);
354             break;
355         }
356         
357         forNode(node).setType(forNode(node->child1()).m_type & ~SpecDoubleImpureNaN);
358         forNode(node).fixTypeForRepresentation(node);
359         break;
360     }
361         
362     case ValueAdd: {
363         ASSERT(node->binaryUseKind() == UntypedUse);
364         clobberWorld(node->origin.semantic, clobberLimit);
365         forNode(node).setType(SpecString | SpecBytecodeNumber);
366         break;
367     }
368         
369     case ArithAdd: {
370         JSValue left = forNode(node->child1()).value();
371         JSValue right = forNode(node->child2()).value();
372         switch (node->binaryUseKind()) {
373         case Int32Use:
374             if (left && right && left.isInt32() && right.isInt32()) {
375                 if (!shouldCheckOverflow(node->arithMode())) {
376                     setConstant(node, jsNumber(left.asInt32() + right.asInt32()));
377                     break;
378                 }
379                 JSValue result = jsNumber(left.asNumber() + right.asNumber());
380                 if (result.isInt32()) {
381                     setConstant(node, result);
382                     break;
383                 }
384             }
385             forNode(node).setType(SpecInt32);
386             if (shouldCheckOverflow(node->arithMode()))
387                 node->setCanExit(true);
388             break;
389         case Int52RepUse:
390             if (left && right && left.isMachineInt() && right.isMachineInt()) {
391                 JSValue result = jsNumber(left.asMachineInt() + right.asMachineInt());
392                 if (result.isMachineInt()) {
393                     setConstant(node, result);
394                     break;
395                 }
396             }
397             forNode(node).setType(SpecMachineInt);
398             if (!forNode(node->child1()).isType(SpecInt32)
399                 || !forNode(node->child2()).isType(SpecInt32))
400                 node->setCanExit(true);
401             break;
402         case DoubleRepUse:
403             if (left && right && left.isNumber() && right.isNumber()) {
404                 setConstant(node, jsDoubleNumber(left.asNumber() + right.asNumber()));
405                 break;
406             }
407             forNode(node).setType(
408                 typeOfDoubleSum(
409                     forNode(node->child1()).m_type, forNode(node->child2()).m_type));
410             break;
411         default:
412             RELEASE_ASSERT_NOT_REACHED();
413             break;
414         }
415         break;
416     }
417         
418     case MakeRope: {
419         node->setCanExit(true);
420         forNode(node).set(m_graph, m_graph.m_vm.stringStructure.get());
421         break;
422     }
423             
424     case ArithSub: {
425         JSValue left = forNode(node->child1()).value();
426         JSValue right = forNode(node->child2()).value();
427         switch (node->binaryUseKind()) {
428         case Int32Use:
429             if (left && right && left.isInt32() && right.isInt32()) {
430                 if (!shouldCheckOverflow(node->arithMode())) {
431                     setConstant(node, jsNumber(left.asInt32() - right.asInt32()));
432                     break;
433                 }
434                 JSValue result = jsNumber(left.asNumber() - right.asNumber());
435                 if (result.isInt32()) {
436                     setConstant(node, result);
437                     break;
438                 }
439             }
440             forNode(node).setType(SpecInt32);
441             if (shouldCheckOverflow(node->arithMode()))
442                 node->setCanExit(true);
443             break;
444         case Int52RepUse:
445             if (left && right && left.isMachineInt() && right.isMachineInt()) {
446                 JSValue result = jsNumber(left.asMachineInt() - right.asMachineInt());
447                 if (result.isMachineInt() || !shouldCheckOverflow(node->arithMode())) {
448                     setConstant(node, result);
449                     break;
450                 }
451             }
452             forNode(node).setType(SpecMachineInt);
453             if (!forNode(node->child1()).isType(SpecInt32)
454                 || !forNode(node->child2()).isType(SpecInt32))
455                 node->setCanExit(true);
456             break;
457         case DoubleRepUse:
458             if (left && right && left.isNumber() && right.isNumber()) {
459                 setConstant(node, jsDoubleNumber(left.asNumber() - right.asNumber()));
460                 break;
461             }
462             forNode(node).setType(
463                 typeOfDoubleDifference(
464                     forNode(node->child1()).m_type, forNode(node->child2()).m_type));
465             break;
466         default:
467             RELEASE_ASSERT_NOT_REACHED();
468             break;
469         }
470         break;
471     }
472         
473     case ArithNegate: {
474         JSValue child = forNode(node->child1()).value();
475         switch (node->child1().useKind()) {
476         case Int32Use:
477             if (child && child.isInt32()) {
478                 if (!shouldCheckOverflow(node->arithMode())) {
479                     setConstant(node, jsNumber(-child.asInt32()));
480                     break;
481                 }
482                 double doubleResult;
483                 if (shouldCheckNegativeZero(node->arithMode()))
484                     doubleResult = -child.asNumber();
485                 else
486                     doubleResult = 0 - child.asNumber();
487                 JSValue valueResult = jsNumber(doubleResult);
488                 if (valueResult.isInt32()) {
489                     setConstant(node, valueResult);
490                     break;
491                 }
492             }
493             forNode(node).setType(SpecInt32);
494             if (shouldCheckOverflow(node->arithMode()))
495                 node->setCanExit(true);
496             break;
497         case Int52RepUse:
498             if (child && child.isMachineInt()) {
499                 double doubleResult;
500                 if (shouldCheckNegativeZero(node->arithMode()))
501                     doubleResult = -child.asNumber();
502                 else
503                     doubleResult = 0 - child.asNumber();
504                 JSValue valueResult = jsNumber(doubleResult);
505                 if (valueResult.isMachineInt()) {
506                     setConstant(node, valueResult);
507                     break;
508                 }
509             }
510             forNode(node).setType(SpecMachineInt);
511             if (m_state.forNode(node->child1()).couldBeType(SpecInt52))
512                 node->setCanExit(true);
513             if (shouldCheckNegativeZero(node->arithMode()))
514                 node->setCanExit(true);
515             break;
516         case DoubleRepUse:
517             if (child && child.isNumber()) {
518                 setConstant(node, jsDoubleNumber(-child.asNumber()));
519                 break;
520             }
521             forNode(node).setType(
522                 typeOfDoubleNegation(
523                     forNode(node->child1()).m_type));
524             break;
525         default:
526             RELEASE_ASSERT_NOT_REACHED();
527             break;
528         }
529         break;
530     }
531         
532     case ArithMul: {
533         JSValue left = forNode(node->child1()).value();
534         JSValue right = forNode(node->child2()).value();
535         switch (node->binaryUseKind()) {
536         case Int32Use:
537             if (left && right && left.isInt32() && right.isInt32()) {
538                 if (!shouldCheckOverflow(node->arithMode())) {
539                     setConstant(node, jsNumber(left.asInt32() * right.asInt32()));
540                     break;
541                 }
542                 double doubleResult = left.asNumber() * right.asNumber();
543                 if (!shouldCheckNegativeZero(node->arithMode()))
544                     doubleResult += 0; // Sanitizes zero.
545                 JSValue valueResult = jsNumber(doubleResult);
546                 if (valueResult.isInt32()) {
547                     setConstant(node, valueResult);
548                     break;
549                 }
550             }
551             forNode(node).setType(SpecInt32);
552             if (shouldCheckOverflow(node->arithMode()))
553                 node->setCanExit(true);
554             break;
555         case Int52RepUse:
556             if (left && right && left.isMachineInt() && right.isMachineInt()) {
557                 double doubleResult = left.asNumber() * right.asNumber();
558                 if (!shouldCheckNegativeZero(node->arithMode()))
559                     doubleResult += 0;
560                 JSValue valueResult = jsNumber(doubleResult);
561                 if (valueResult.isMachineInt()) {
562                     setConstant(node, valueResult);
563                     break;
564                 }
565             }
566             forNode(node).setType(SpecMachineInt);
567             node->setCanExit(true);
568             break;
569         case DoubleRepUse:
570             if (left && right && left.isNumber() && right.isNumber()) {
571                 setConstant(node, jsDoubleNumber(left.asNumber() * right.asNumber()));
572                 break;
573             }
574             forNode(node).setType(
575                 typeOfDoubleProduct(
576                     forNode(node->child1()).m_type, forNode(node->child2()).m_type));
577             break;
578         default:
579             RELEASE_ASSERT_NOT_REACHED();
580             break;
581         }
582         break;
583     }
584         
585     case ArithDiv: {
586         JSValue left = forNode(node->child1()).value();
587         JSValue right = forNode(node->child2()).value();
588         switch (node->binaryUseKind()) {
589         case Int32Use:
590             if (left && right && left.isInt32() && right.isInt32()) {
591                 double doubleResult = left.asNumber() / right.asNumber();
592                 if (!shouldCheckOverflow(node->arithMode()))
593                     doubleResult = toInt32(doubleResult);
594                 else if (!shouldCheckNegativeZero(node->arithMode()))
595                     doubleResult += 0; // Sanitizes zero.
596                 JSValue valueResult = jsNumber(doubleResult);
597                 if (valueResult.isInt32()) {
598                     setConstant(node, valueResult);
599                     break;
600                 }
601             }
602             forNode(node).setType(SpecInt32);
603             node->setCanExit(true);
604             break;
605         case DoubleRepUse:
606             if (left && right && left.isNumber() && right.isNumber()) {
607                 setConstant(node, jsDoubleNumber(left.asNumber() / right.asNumber()));
608                 break;
609             }
610             forNode(node).setType(
611                 typeOfDoubleQuotient(
612                     forNode(node->child1()).m_type, forNode(node->child2()).m_type));
613             break;
614         default:
615             RELEASE_ASSERT_NOT_REACHED();
616             break;
617         }
618         break;
619     }
620
621     case ArithMod: {
622         JSValue left = forNode(node->child1()).value();
623         JSValue right = forNode(node->child2()).value();
624         switch (node->binaryUseKind()) {
625         case Int32Use:
626             if (left && right && left.isInt32() && right.isInt32()) {
627                 double doubleResult = fmod(left.asNumber(), right.asNumber());
628                 if (!shouldCheckOverflow(node->arithMode()))
629                     doubleResult = toInt32(doubleResult);
630                 else if (!shouldCheckNegativeZero(node->arithMode()))
631                     doubleResult += 0; // Sanitizes zero.
632                 JSValue valueResult = jsNumber(doubleResult);
633                 if (valueResult.isInt32()) {
634                     setConstant(node, valueResult);
635                     break;
636                 }
637             }
638             forNode(node).setType(SpecInt32);
639             node->setCanExit(true);
640             break;
641         case DoubleRepUse:
642             if (left && right && left.isNumber() && right.isNumber()) {
643                 setConstant(node, jsDoubleNumber(fmod(left.asNumber(), right.asNumber())));
644                 break;
645             }
646             forNode(node).setType(
647                 typeOfDoubleBinaryOp(
648                     forNode(node->child1()).m_type, forNode(node->child2()).m_type));
649             break;
650         default:
651             RELEASE_ASSERT_NOT_REACHED();
652             break;
653         }
654         break;
655     }
656
657     case ArithMin: {
658         JSValue left = forNode(node->child1()).value();
659         JSValue right = forNode(node->child2()).value();
660         switch (node->binaryUseKind()) {
661         case Int32Use:
662             if (left && right && left.isInt32() && right.isInt32()) {
663                 setConstant(node, jsNumber(std::min(left.asInt32(), right.asInt32())));
664                 break;
665             }
666             forNode(node).setType(SpecInt32);
667             node->setCanExit(true);
668             break;
669         case DoubleRepUse:
670             if (left && right && left.isNumber() && right.isNumber()) {
671                 double a = left.asNumber();
672                 double b = right.asNumber();
673                 setConstant(node, jsDoubleNumber(a < b ? a : (b <= a ? b : a + b)));
674                 break;
675             }
676             forNode(node).setType(
677                 typeOfDoubleMinMax(
678                     forNode(node->child1()).m_type, forNode(node->child2()).m_type));
679             break;
680         default:
681             RELEASE_ASSERT_NOT_REACHED();
682             break;
683         }
684         break;
685     }
686             
687     case ArithMax: {
688         JSValue left = forNode(node->child1()).value();
689         JSValue right = forNode(node->child2()).value();
690         switch (node->binaryUseKind()) {
691         case Int32Use:
692             if (left && right && left.isInt32() && right.isInt32()) {
693                 setConstant(node, jsNumber(std::max(left.asInt32(), right.asInt32())));
694                 break;
695             }
696             forNode(node).setType(SpecInt32);
697             node->setCanExit(true);
698             break;
699         case DoubleRepUse:
700             if (left && right && left.isNumber() && right.isNumber()) {
701                 double a = left.asNumber();
702                 double b = right.asNumber();
703                 setConstant(node, jsDoubleNumber(a > b ? a : (b >= a ? b : a + b)));
704                 break;
705             }
706             forNode(node).setType(
707                 typeOfDoubleMinMax(
708                     forNode(node->child1()).m_type, forNode(node->child2()).m_type));
709             break;
710         default:
711             RELEASE_ASSERT_NOT_REACHED();
712             break;
713         }
714         break;
715     }
716             
717     case ArithAbs: {
718         JSValue child = forNode(node->child1()).value();
719         switch (node->child1().useKind()) {
720         case Int32Use:
721             if (child && child.isInt32()) {
722                 JSValue result = jsNumber(fabs(child.asNumber()));
723                 if (result.isInt32()) {
724                     setConstant(node, result);
725                     break;
726                 }
727             }
728             forNode(node).setType(SpecInt32);
729             node->setCanExit(true);
730             break;
731         case DoubleRepUse:
732             if (child && child.isNumber()) {
733                 setConstant(node, jsDoubleNumber(child.asNumber()));
734                 break;
735             }
736             forNode(node).setType(typeOfDoubleAbs(forNode(node->child1()).m_type));
737             break;
738         default:
739             RELEASE_ASSERT_NOT_REACHED();
740             break;
741         }
742         break;
743     }
744             
745     case ArithSqrt: {
746         JSValue child = forNode(node->child1()).value();
747         if (child && child.isNumber()) {
748             setConstant(node, jsDoubleNumber(sqrt(child.asNumber())));
749             break;
750         }
751         forNode(node).setType(typeOfDoubleUnaryOp(forNode(node->child1()).m_type));
752         break;
753     }
754         
755     case ArithFRound: {
756         JSValue child = forNode(node->child1()).value();
757         if (child && child.isNumber()) {
758             setConstant(node, jsDoubleNumber(static_cast<float>(child.asNumber())));
759             break;
760         }
761         forNode(node).setType(typeOfDoubleFRound(forNode(node->child1()).m_type));
762         break;
763     }
764         
765     case ArithSin: {
766         JSValue child = forNode(node->child1()).value();
767         if (child && child.isNumber()) {
768             setConstant(node, jsDoubleNumber(sin(child.asNumber())));
769             break;
770         }
771         forNode(node).setType(typeOfDoubleUnaryOp(forNode(node->child1()).m_type));
772         break;
773     }
774     
775     case ArithCos: {
776         JSValue child = forNode(node->child1()).value();
777         if (child && child.isNumber()) {
778             setConstant(node, jsDoubleNumber(cos(child.asNumber())));
779             break;
780         }
781         forNode(node).setType(typeOfDoubleUnaryOp(forNode(node->child1()).m_type));
782         break;
783     }
784             
785     case LogicalNot: {
786         switch (booleanResult(node, forNode(node->child1()))) {
787         case DefinitelyTrue:
788             setConstant(node, jsBoolean(false));
789             break;
790         case DefinitelyFalse:
791             setConstant(node, jsBoolean(true));
792             break;
793         default:
794             switch (node->child1().useKind()) {
795             case BooleanUse:
796             case Int32Use:
797             case DoubleRepUse:
798             case UntypedUse:
799             case StringUse:
800                 break;
801             case ObjectOrOtherUse:
802                 node->setCanExit(true);
803                 break;
804             default:
805                 RELEASE_ASSERT_NOT_REACHED();
806                 break;
807             }
808             forNode(node).setType(SpecBoolean);
809             break;
810         }
811         break;
812     }
813         
814     case IsUndefined:
815     case IsBoolean:
816     case IsNumber:
817     case IsString:
818     case IsObject:
819     case IsFunction: {
820         node->setCanExit(
821             node->op() == IsUndefined
822             && m_graph.masqueradesAsUndefinedWatchpointIsStillValid(node->origin.semantic));
823         JSValue child = forNode(node->child1()).value();
824         if (child) {
825             bool constantWasSet = true;
826             switch (node->op()) {
827             case IsUndefined:
828                 setConstant(node, jsBoolean(
829                     child.isCell()
830                     ? child.asCell()->structure()->masqueradesAsUndefined(m_codeBlock->globalObjectFor(node->origin.semantic))
831                     : child.isUndefined()));
832                 break;
833             case IsBoolean:
834                 setConstant(node, jsBoolean(child.isBoolean()));
835                 break;
836             case IsNumber:
837                 setConstant(node, jsBoolean(child.isNumber()));
838                 break;
839             case IsString:
840                 setConstant(node, jsBoolean(isJSString(child)));
841                 break;
842             case IsObject:
843                 if (child.isNull() || !child.isObject()) {
844                     setConstant(node, jsBoolean(child.isNull()));
845                     break;
846                 }
847                 constantWasSet = false;
848                 break;
849             default:
850                 constantWasSet = false;
851                 break;
852             }
853             if (constantWasSet)
854                 break;
855         }
856
857         forNode(node).setType(SpecBoolean);
858         break;
859     }
860
861     case TypeOf: {
862         VM* vm = m_codeBlock->vm();
863         JSValue child = forNode(node->child1()).value();
864         AbstractValue& abstractChild = forNode(node->child1());
865         if (child) {
866             JSValue typeString = jsTypeStringForValue(*vm, m_codeBlock->globalObjectFor(node->origin.semantic), child);
867             setConstant(node, typeString);
868             break;
869         }
870         
871         if (isFullNumberSpeculation(abstractChild.m_type)) {
872             setConstant(node, vm->smallStrings.numberString());
873             break;
874         }
875         
876         if (isStringSpeculation(abstractChild.m_type)) {
877             setConstant(node, vm->smallStrings.stringString());
878             break;
879         }
880         
881         if (isFinalObjectSpeculation(abstractChild.m_type) || isArraySpeculation(abstractChild.m_type) || isArgumentsSpeculation(abstractChild.m_type)) {
882             setConstant(node, vm->smallStrings.objectString());
883             break;
884         }
885         
886         if (isFunctionSpeculation(abstractChild.m_type)) {
887             setConstant(node, vm->smallStrings.functionString());
888             break;
889         }
890         
891         if (isBooleanSpeculation(abstractChild.m_type)) {
892             setConstant(node, vm->smallStrings.booleanString());
893             break;
894         }
895
896         switch (node->child1().useKind()) {
897         case StringUse:
898         case CellUse:
899             node->setCanExit(true);
900             break;
901         case UntypedUse:
902             break;
903         default:
904             RELEASE_ASSERT_NOT_REACHED();
905             break;
906         }
907         forNode(node).set(m_graph, m_graph.m_vm.stringStructure.get());
908         break;
909     }
910             
911     case CompareLess:
912     case CompareLessEq:
913     case CompareGreater:
914     case CompareGreaterEq:
915     case CompareEq:
916     case CompareEqConstant: {
917         JSValue leftConst = forNode(node->child1()).value();
918         JSValue rightConst = forNode(node->child2()).value();
919         if (leftConst && rightConst) {
920             if (leftConst.isNumber() && rightConst.isNumber()) {
921                 double a = leftConst.asNumber();
922                 double b = rightConst.asNumber();
923                 switch (node->op()) {
924                 case CompareLess:
925                     setConstant(node, jsBoolean(a < b));
926                     break;
927                 case CompareLessEq:
928                     setConstant(node, jsBoolean(a <= b));
929                     break;
930                 case CompareGreater:
931                     setConstant(node, jsBoolean(a > b));
932                     break;
933                 case CompareGreaterEq:
934                     setConstant(node, jsBoolean(a >= b));
935                     break;
936                 case CompareEq:
937                     setConstant(node, jsBoolean(a == b));
938                     break;
939                 default:
940                     RELEASE_ASSERT_NOT_REACHED();
941                     break;
942                 }
943                 break;
944             }
945             
946             if (node->op() == CompareEq && leftConst.isString() && rightConst.isString()) {
947                 const StringImpl* a = asString(leftConst)->tryGetValueImpl();
948                 const StringImpl* b = asString(rightConst)->tryGetValueImpl();
949                 if (a && b) {
950                     setConstant(node, jsBoolean(WTF::equal(a, b)));
951                     break;
952                 }
953             }
954         }
955         
956         if (node->op() == CompareEqConstant || node->op() == CompareEq) {
957             SpeculatedType leftType = forNode(node->child1()).m_type;
958             SpeculatedType rightType = forNode(node->child2()).m_type;
959             if (!valuesCouldBeEqual(leftType, rightType)) {
960                 setConstant(node, jsBoolean(false));
961                 break;
962             }
963         }
964         
965         forNode(node).setType(SpecBoolean);
966         
967         // This is overly conservative. But the only thing this prevents is store elimination,
968         // and how likely is it, really, that you'll have redundant stores across a comparison
969         // operation? Comparison operations are typically at the end of basic blocks, so
970         // unless we have global store elimination (super unlikely given how unprofitable that
971         // optimization is to begin with), you aren't going to be wanting to store eliminate
972         // across an equality op.
973         node->setCanExit(true);
974         break;
975     }
976             
977     case CompareStrictEq: {
978         Node* leftNode = node->child1().node();
979         Node* rightNode = node->child2().node();
980         JSValue left = forNode(leftNode).value();
981         JSValue right = forNode(rightNode).value();
982         if (left && right) {
983             if (left.isString() && right.isString()) {
984                 // We need this case because JSValue::strictEqual is otherwise too racy for
985                 // string comparisons.
986                 const StringImpl* a = asString(left)->tryGetValueImpl();
987                 const StringImpl* b = asString(right)->tryGetValueImpl();
988                 if (a && b) {
989                     setConstant(node, jsBoolean(WTF::equal(a, b)));
990                     break;
991                 }
992             } else {
993                 setConstant(node, jsBoolean(JSValue::strictEqual(0, left, right)));
994                 break;
995             }
996         }
997         
998         SpeculatedType leftLUB = leastUpperBoundOfStrictlyEquivalentSpeculations(forNode(leftNode).m_type);
999         SpeculatedType rightLUB = leastUpperBoundOfStrictlyEquivalentSpeculations(forNode(rightNode).m_type);
1000         if (!(leftLUB & rightLUB)) {
1001             setConstant(node, jsBoolean(false));
1002             break;
1003         }
1004         
1005         forNode(node).setType(SpecBoolean);
1006         node->setCanExit(true); // This is overly conservative.
1007         break;
1008     }
1009         
1010     case StringCharCodeAt:
1011         node->setCanExit(true);
1012         forNode(node).setType(SpecInt32);
1013         break;
1014         
1015     case StringFromCharCode:
1016         forNode(node).setType(SpecString);
1017         break;
1018
1019     case StringCharAt:
1020         node->setCanExit(true);
1021         forNode(node).set(m_graph, m_graph.m_vm.stringStructure.get());
1022         break;
1023             
1024     case GetByVal: {
1025         node->setCanExit(true);
1026         switch (node->arrayMode().type()) {
1027         case Array::SelectUsingPredictions:
1028         case Array::Unprofiled:
1029         case Array::Undecided:
1030             RELEASE_ASSERT_NOT_REACHED();
1031             break;
1032         case Array::ForceExit:
1033             m_state.setIsValid(false);
1034             break;
1035         case Array::Generic:
1036             clobberWorld(node->origin.semantic, clobberLimit);
1037             forNode(node).makeHeapTop();
1038             break;
1039         case Array::String:
1040             if (node->arrayMode().isOutOfBounds()) {
1041                 // If the watchpoint was still valid we could totally set this to be
1042                 // SpecString | SpecOther. Except that we'd have to be careful. If we
1043                 // tested the watchpoint state here then it could change by the time
1044                 // we got to the backend. So to do this right, we'd have to get the
1045                 // fixup phase to check the watchpoint state and then bake into the
1046                 // GetByVal operation the fact that we're using a watchpoint, using
1047                 // something like Array::SaneChain (except not quite, because that
1048                 // implies an in-bounds access). None of this feels like it's worth it,
1049                 // so we're going with TOP for now. The same thing applies to
1050                 // clobbering the world.
1051                 clobberWorld(node->origin.semantic, clobberLimit);
1052                 forNode(node).makeHeapTop();
1053             } else
1054                 forNode(node).set(m_graph, m_graph.m_vm.stringStructure.get());
1055             break;
1056         case Array::Arguments:
1057             forNode(node).makeHeapTop();
1058             break;
1059         case Array::Int32:
1060             if (node->arrayMode().isOutOfBounds()) {
1061                 clobberWorld(node->origin.semantic, clobberLimit);
1062                 forNode(node).makeHeapTop();
1063             } else
1064                 forNode(node).setType(SpecInt32);
1065             break;
1066         case Array::Double:
1067             if (node->arrayMode().isOutOfBounds()) {
1068                 clobberWorld(node->origin.semantic, clobberLimit);
1069                 forNode(node).makeHeapTop();
1070             } else if (node->arrayMode().isSaneChain())
1071                 forNode(node).setType(SpecBytecodeDouble);
1072             else
1073                 forNode(node).setType(SpecDoubleReal);
1074             break;
1075         case Array::Contiguous:
1076         case Array::ArrayStorage:
1077         case Array::SlowPutArrayStorage:
1078             if (node->arrayMode().isOutOfBounds())
1079                 clobberWorld(node->origin.semantic, clobberLimit);
1080             forNode(node).makeHeapTop();
1081             break;
1082         case Array::Int8Array:
1083             forNode(node).setType(SpecInt32);
1084             break;
1085         case Array::Int16Array:
1086             forNode(node).setType(SpecInt32);
1087             break;
1088         case Array::Int32Array:
1089             forNode(node).setType(SpecInt32);
1090             break;
1091         case Array::Uint8Array:
1092             forNode(node).setType(SpecInt32);
1093             break;
1094         case Array::Uint8ClampedArray:
1095             forNode(node).setType(SpecInt32);
1096             break;
1097         case Array::Uint16Array:
1098             forNode(node).setType(SpecInt32);
1099             break;
1100         case Array::Uint32Array:
1101             if (node->shouldSpeculateInt32())
1102                 forNode(node).setType(SpecInt32);
1103             else if (enableInt52() && node->shouldSpeculateMachineInt())
1104                 forNode(node).setType(SpecInt52);
1105             else
1106                 forNode(node).setType(SpecInt52AsDouble);
1107             break;
1108         case Array::Float32Array:
1109             forNode(node).setType(SpecFullDouble);
1110             break;
1111         case Array::Float64Array:
1112             forNode(node).setType(SpecFullDouble);
1113             break;
1114         default:
1115             RELEASE_ASSERT_NOT_REACHED();
1116             break;
1117         }
1118         break;
1119     }
1120             
1121     case PutByValDirect:
1122     case PutByVal:
1123     case PutByValAlias: {
1124         node->setCanExit(true);
1125         switch (node->arrayMode().modeForPut().type()) {
1126         case Array::ForceExit:
1127             m_state.setIsValid(false);
1128             break;
1129         case Array::Generic:
1130             clobberWorld(node->origin.semantic, clobberLimit);
1131             break;
1132         case Array::Int32:
1133             if (node->arrayMode().isOutOfBounds())
1134                 clobberWorld(node->origin.semantic, clobberLimit);
1135             break;
1136         case Array::Double:
1137             if (node->arrayMode().isOutOfBounds())
1138                 clobberWorld(node->origin.semantic, clobberLimit);
1139             break;
1140         case Array::Contiguous:
1141         case Array::ArrayStorage:
1142             if (node->arrayMode().isOutOfBounds())
1143                 clobberWorld(node->origin.semantic, clobberLimit);
1144             break;
1145         case Array::SlowPutArrayStorage:
1146             if (node->arrayMode().mayStoreToHole())
1147                 clobberWorld(node->origin.semantic, clobberLimit);
1148             break;
1149         default:
1150             break;
1151         }
1152         break;
1153     }
1154             
1155     case ArrayPush:
1156         node->setCanExit(true);
1157         clobberWorld(node->origin.semantic, clobberLimit);
1158         forNode(node).setType(SpecBytecodeNumber);
1159         break;
1160             
1161     case ArrayPop:
1162         node->setCanExit(true);
1163         clobberWorld(node->origin.semantic, clobberLimit);
1164         forNode(node).makeHeapTop();
1165         break;
1166             
1167     case RegExpExec:
1168         forNode(node).makeHeapTop();
1169         break;
1170
1171     case RegExpTest:
1172         forNode(node).setType(SpecBoolean);
1173         break;
1174             
1175     case Jump:
1176         break;
1177             
1178     case Branch: {
1179         Node* child = node->child1().node();
1180         BooleanResult result = booleanResult(node, forNode(child));
1181         if (result == DefinitelyTrue) {
1182             m_state.setBranchDirection(TakeTrue);
1183             break;
1184         }
1185         if (result == DefinitelyFalse) {
1186             m_state.setBranchDirection(TakeFalse);
1187             break;
1188         }
1189         // FIXME: The above handles the trivial cases of sparse conditional
1190         // constant propagation, but we can do better:
1191         // We can specialize the source variable's value on each direction of
1192         // the branch.
1193         node->setCanExit(true); // This is overly conservative.
1194         m_state.setBranchDirection(TakeBoth);
1195         break;
1196     }
1197         
1198     case Switch: {
1199         // Nothing to do for now.
1200         // FIXME: Do sparse conditional things.
1201         break;
1202     }
1203             
1204     case Return:
1205         m_state.setIsValid(false);
1206         break;
1207         
1208     case Throw:
1209     case ThrowReferenceError:
1210         m_state.setIsValid(false);
1211         node->setCanExit(true);
1212         break;
1213             
1214     case ToPrimitive: {
1215         JSValue childConst = forNode(node->child1()).value();
1216         if (childConst && childConst.isNumber()) {
1217             setConstant(node, childConst);
1218             break;
1219         }
1220         
1221         ASSERT(node->child1().useKind() == UntypedUse);
1222         
1223         if (!forNode(node->child1()).m_type) {
1224             m_state.setIsValid(false);
1225             break;
1226         }
1227         
1228         if (!(forNode(node->child1()).m_type & ~(SpecFullNumber | SpecBoolean | SpecString))) {
1229             m_state.setFoundConstants(true);
1230             forNode(node) = forNode(node->child1());
1231             break;
1232         }
1233         
1234         clobberWorld(node->origin.semantic, clobberLimit);
1235         
1236         forNode(node).setType((SpecHeapTop & ~SpecCell) | SpecString);
1237         break;
1238     }
1239         
1240     case ToString: {
1241         switch (node->child1().useKind()) {
1242         case StringObjectUse:
1243             // This also filters that the StringObject has the primordial StringObject
1244             // structure.
1245             filter(
1246                 node->child1(),
1247                 m_graph.globalObjectFor(node->origin.semantic)->stringObjectStructure());
1248             node->setCanExit(true); // We could be more precise but it's likely not worth it.
1249             break;
1250         case StringOrStringObjectUse:
1251             node->setCanExit(true); // We could be more precise but it's likely not worth it.
1252             break;
1253         case CellUse:
1254         case UntypedUse:
1255             clobberWorld(node->origin.semantic, clobberLimit);
1256             break;
1257         default:
1258             RELEASE_ASSERT_NOT_REACHED();
1259             break;
1260         }
1261         forNode(node).set(m_graph, m_graph.m_vm.stringStructure.get());
1262         break;
1263     }
1264         
1265     case NewStringObject: {
1266         ASSERT(node->structure()->classInfo() == StringObject::info());
1267         forNode(node).set(m_graph, node->structure());
1268         break;
1269     }
1270             
1271     case NewArray:
1272         node->setCanExit(true);
1273         forNode(node).set(
1274             m_graph,
1275             m_graph.globalObjectFor(node->origin.semantic)->arrayStructureForIndexingTypeDuringAllocation(node->indexingType()));
1276         m_state.setHaveStructures(true);
1277         break;
1278         
1279     case NewArrayBuffer:
1280         node->setCanExit(true);
1281         forNode(node).set(
1282             m_graph,
1283             m_graph.globalObjectFor(node->origin.semantic)->arrayStructureForIndexingTypeDuringAllocation(node->indexingType()));
1284         m_state.setHaveStructures(true);
1285         break;
1286
1287     case NewArrayWithSize:
1288         node->setCanExit(true);
1289         forNode(node).setType(SpecArray);
1290         m_state.setHaveStructures(true);
1291         break;
1292         
1293     case NewTypedArray:
1294         switch (node->child1().useKind()) {
1295         case Int32Use:
1296             break;
1297         case UntypedUse:
1298             clobberWorld(node->origin.semantic, clobberLimit);
1299             break;
1300         default:
1301             RELEASE_ASSERT_NOT_REACHED();
1302             break;
1303         }
1304         forNode(node).set(
1305             m_graph,
1306             m_graph.globalObjectFor(node->origin.semantic)->typedArrayStructure(
1307                 node->typedArrayType()));
1308         m_state.setHaveStructures(true);
1309         break;
1310             
1311     case NewRegexp:
1312         forNode(node).set(m_graph, m_graph.globalObjectFor(node->origin.semantic)->regExpStructure());
1313         m_state.setHaveStructures(true);
1314         break;
1315             
1316     case ToThis: {
1317         AbstractValue& source = forNode(node->child1());
1318         AbstractValue& destination = forNode(node);
1319             
1320         if (m_graph.executableFor(node->origin.semantic)->isStrictMode())
1321             destination.makeHeapTop();
1322         else {
1323             destination = source;
1324             destination.merge(SpecObject);
1325         }
1326         break;
1327     }
1328
1329     case CreateThis: {
1330         forNode(node).setType(SpecFinalObject);
1331         break;
1332     }
1333         
1334     case AllocationProfileWatchpoint:
1335         node->setCanExit(true);
1336         break;
1337
1338     case NewObject:
1339         ASSERT(node->structure());
1340         forNode(node).set(m_graph, node->structure());
1341         m_state.setHaveStructures(true);
1342         break;
1343         
1344     case CreateActivation:
1345         forNode(node).set(
1346             m_graph, m_codeBlock->globalObjectFor(node->origin.semantic)->activationStructure());
1347         m_state.setHaveStructures(true);
1348         break;
1349         
1350     case FunctionReentryWatchpoint:
1351     case TypedArrayWatchpoint:
1352         break;
1353     
1354     case CreateArguments:
1355         forNode(node) = forNode(node->child1());
1356         forNode(node).filter(~SpecEmpty);
1357         forNode(node).merge(SpecArguments);
1358         break;
1359         
1360     case TearOffActivation:
1361     case TearOffArguments:
1362         // Does nothing that is user-visible.
1363         break;
1364
1365     case CheckArgumentsNotCreated:
1366         if (isEmptySpeculation(
1367                 m_state.variables().operand(
1368                     m_graph.argumentsRegisterFor(node->origin.semantic).offset()).m_type))
1369             m_state.setFoundConstants(true);
1370         else
1371             node->setCanExit(true);
1372         break;
1373         
1374     case GetMyArgumentsLength:
1375         // We know that this executable does not escape its arguments, so we can optimize
1376         // the arguments a bit. Note that this is not sufficient to force constant folding
1377         // of GetMyArgumentsLength, because GetMyArgumentsLength is a clobbering operation.
1378         // We perform further optimizations on this later on.
1379         if (node->origin.semantic.inlineCallFrame) {
1380             forNode(node).set(
1381                 m_graph, jsNumber(node->origin.semantic.inlineCallFrame->arguments.size() - 1));
1382         } else
1383             forNode(node).setType(SpecInt32);
1384         node->setCanExit(
1385             !isEmptySpeculation(
1386                 m_state.variables().operand(
1387                     m_graph.argumentsRegisterFor(node->origin.semantic)).m_type));
1388         break;
1389         
1390     case GetMyArgumentsLengthSafe:
1391         // This potentially clobbers all structures if the arguments object had a getter
1392         // installed on the length property.
1393         clobberWorld(node->origin.semantic, clobberLimit);
1394         // We currently make no guarantee about what this returns because it does not
1395         // speculate that the length property is actually a length.
1396         forNode(node).makeHeapTop();
1397         break;
1398         
1399     case GetMyArgumentByVal:
1400         node->setCanExit(true);
1401         // We know that this executable does not escape its arguments, so we can optimize
1402         // the arguments a bit. Note that this ends up being further optimized by the
1403         // ArgumentsSimplificationPhase.
1404         forNode(node).makeHeapTop();
1405         break;
1406         
1407     case GetMyArgumentByValSafe:
1408         node->setCanExit(true);
1409         // This potentially clobbers all structures if the property we're accessing has
1410         // a getter. We don't speculate against this.
1411         clobberWorld(node->origin.semantic, clobberLimit);
1412         // And the result is unknown.
1413         forNode(node).makeHeapTop();
1414         break;
1415         
1416     case NewFunction: {
1417         AbstractValue& value = forNode(node);
1418         value = forNode(node->child1());
1419         
1420         if (!(value.m_type & SpecEmpty)) {
1421             m_state.setFoundConstants(true);
1422             break;
1423         }
1424
1425         value.setType((value.m_type & ~SpecEmpty) | SpecFunction);
1426         break;
1427     }
1428
1429     case NewFunctionExpression:
1430     case NewFunctionNoCheck:
1431         forNode(node).set(
1432             m_graph, m_codeBlock->globalObjectFor(node->origin.semantic)->functionStructure());
1433         break;
1434         
1435     case GetCallee:
1436     case GetGetter:
1437     case GetSetter:
1438         forNode(node).setType(SpecFunction);
1439         break;
1440         
1441     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
1442     case GetMyScope:
1443     case SkipTopScope:
1444         forNode(node).setType(SpecObjectOther);
1445         break;
1446
1447     case SkipScope: {
1448         JSValue child = forNode(node->child1()).value();
1449         if (child) {
1450             setConstant(node, JSValue(jsCast<JSScope*>(child.asCell())->next()));
1451             break;
1452         }
1453         forNode(node).setType(SpecObjectOther);
1454         break;
1455     }
1456
1457     case GetClosureRegisters:
1458         forNode(node).clear(); // The result is not a JS value.
1459         break;
1460
1461     case GetClosureVar:
1462         forNode(node).makeHeapTop();
1463         break;
1464             
1465     case PutClosureVar:
1466         clobberCapturedVars(node->origin.semantic);
1467         break;
1468             
1469     case GetById:
1470     case GetByIdFlush:
1471         node->setCanExit(true);
1472         if (!node->prediction()) {
1473             m_state.setIsValid(false);
1474             break;
1475         }
1476         if (isCellSpeculation(node->child1()->prediction())) {
1477             if (Structure* structure = forNode(node->child1()).bestProvenStructure()) {
1478                 GetByIdStatus status = GetByIdStatus::computeFor(
1479                     m_graph.m_vm, structure,
1480                     m_graph.identifiers()[node->identifierNumber()]);
1481                 if (status.isSimple() && status.numVariants() == 1) {
1482                     // Assert things that we can't handle and that the computeFor() method
1483                     // above won't be able to return.
1484                     ASSERT(status[0].structureSet().size() == 1);
1485                     ASSERT(!status[0].chain());
1486                     
1487                     if (status[0].specificValue())
1488                         setConstant(node, status[0].specificValue());
1489                     else
1490                         forNode(node).makeHeapTop();
1491                     filter(node->child1(), status[0].structureSet());
1492                     
1493                     m_state.setFoundConstants(true);
1494                     m_state.setHaveStructures(true);
1495                     break;
1496                 }
1497             }
1498         }
1499         clobberWorld(node->origin.semantic, clobberLimit);
1500         forNode(node).makeHeapTop();
1501         break;
1502             
1503     case GetArrayLength:
1504         node->setCanExit(true); // Lies, but it's true for the common case of JSArray, so it's good enough.
1505         forNode(node).setType(SpecInt32);
1506         break;
1507         
1508     case CheckExecutable: {
1509         // FIXME: We could track executables in AbstractValue, which would allow us to get rid of these checks
1510         // more thoroughly. https://bugs.webkit.org/show_bug.cgi?id=106200
1511         // FIXME: We could eliminate these entirely if we know the exact value that flows into this.
1512         // https://bugs.webkit.org/show_bug.cgi?id=106201
1513         node->setCanExit(true);
1514         break;
1515     }
1516
1517     case CheckStructure: {
1518         // FIXME: We should be able to propagate the structure sets of constants (i.e. prototypes).
1519         AbstractValue& value = forNode(node->child1());
1520         ASSERT(!(value.m_type & ~SpecCell)); // Edge filtering should have already ensured this.
1521
1522         StructureSet& set = node->structureSet();
1523
1524         if (value.m_currentKnownStructure.isSubsetOf(set)) {
1525             m_state.setFoundConstants(true);
1526             break;
1527         }
1528
1529         node->setCanExit(true);
1530         m_state.setHaveStructures(true);
1531
1532         // If this structure check is attempting to prove knowledge already held in
1533         // the futurePossibleStructure set then the constant folding phase should
1534         // turn this into a watchpoint instead.
1535         if (value.m_futurePossibleStructure.isSubsetOf(set)
1536             && value.m_futurePossibleStructure.hasSingleton()) {
1537             m_state.setFoundConstants(true);
1538             filter(value, value.m_futurePossibleStructure.singleton());
1539             break;
1540         }
1541
1542         filter(value, set);
1543         break;
1544     }
1545         
1546     case StructureTransitionWatchpoint: {
1547         AbstractValue& value = forNode(node->child1());
1548
1549         filter(value, node->structure());
1550         m_state.setHaveStructures(true);
1551         node->setCanExit(true);
1552         break;
1553     }
1554             
1555     case PutStructure:
1556     case PhantomPutStructure:
1557         if (!forNode(node->child1()).m_currentKnownStructure.isClear()) {
1558             clobberStructures(clobberLimit);
1559             forNode(node->child1()).set(m_graph, node->structureTransitionData().newStructure);
1560             m_state.setHaveStructures(true);
1561         }
1562         break;
1563     case GetButterfly:
1564     case AllocatePropertyStorage:
1565     case ReallocatePropertyStorage:
1566         forNode(node).clear(); // The result is not a JS value.
1567         break;
1568     case CheckArray: {
1569         if (node->arrayMode().alreadyChecked(m_graph, node, forNode(node->child1()))) {
1570             m_state.setFoundConstants(true);
1571             break;
1572         }
1573         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.
1574         switch (node->arrayMode().type()) {
1575         case Array::String:
1576             filter(node->child1(), SpecString);
1577             break;
1578         case Array::Int32:
1579         case Array::Double:
1580         case Array::Contiguous:
1581         case Array::ArrayStorage:
1582         case Array::SlowPutArrayStorage:
1583             break;
1584         case Array::Arguments:
1585             filter(node->child1(), SpecArguments);
1586             break;
1587         case Array::Int8Array:
1588             filter(node->child1(), SpecInt8Array);
1589             break;
1590         case Array::Int16Array:
1591             filter(node->child1(), SpecInt16Array);
1592             break;
1593         case Array::Int32Array:
1594             filter(node->child1(), SpecInt32Array);
1595             break;
1596         case Array::Uint8Array:
1597             filter(node->child1(), SpecUint8Array);
1598             break;
1599         case Array::Uint8ClampedArray:
1600             filter(node->child1(), SpecUint8ClampedArray);
1601             break;
1602         case Array::Uint16Array:
1603             filter(node->child1(), SpecUint16Array);
1604             break;
1605         case Array::Uint32Array:
1606             filter(node->child1(), SpecUint32Array);
1607             break;
1608         case Array::Float32Array:
1609             filter(node->child1(), SpecFloat32Array);
1610             break;
1611         case Array::Float64Array:
1612             filter(node->child1(), SpecFloat64Array);
1613             break;
1614         default:
1615             RELEASE_ASSERT_NOT_REACHED();
1616             break;
1617         }
1618         filterArrayModes(node->child1(), node->arrayMode().arrayModesThatPassFiltering());
1619         m_state.setHaveStructures(true);
1620         break;
1621     }
1622     case Arrayify: {
1623         if (node->arrayMode().alreadyChecked(m_graph, node, forNode(node->child1()))) {
1624             m_state.setFoundConstants(true);
1625             break;
1626         }
1627         ASSERT(node->arrayMode().conversion() == Array::Convert
1628             || node->arrayMode().conversion() == Array::RageConvert);
1629         node->setCanExit(true);
1630         clobberStructures(clobberLimit);
1631         filterArrayModes(node->child1(), node->arrayMode().arrayModesThatPassFiltering());
1632         m_state.setHaveStructures(true);
1633         break;
1634     }
1635     case ArrayifyToStructure: {
1636         AbstractValue& value = forNode(node->child1());
1637         StructureSet set = node->structure();
1638         if (value.m_futurePossibleStructure.isSubsetOf(set)
1639             || value.m_currentKnownStructure.isSubsetOf(set))
1640             m_state.setFoundConstants(true);
1641         node->setCanExit(true);
1642         clobberStructures(clobberLimit);
1643         filter(value, set);
1644         m_state.setHaveStructures(true);
1645         break;
1646     }
1647     case GetIndexedPropertyStorage:
1648     case ConstantStoragePointer: {
1649         forNode(node).clear();
1650         break; 
1651     }
1652         
1653     case GetTypedArrayByteOffset: {
1654         forNode(node).setType(SpecInt32);
1655         break;
1656     }
1657         
1658     case GetByOffset: {
1659         forNode(node).makeHeapTop();
1660         break;
1661     }
1662         
1663     case GetGetterSetterByOffset: {
1664         forNode(node).set(m_graph, m_graph.m_vm.getterSetterStructure.get());
1665         break;
1666     }
1667         
1668     case MultiGetByOffset: {
1669         AbstractValue& value = forNode(node->child1());
1670         ASSERT(!(value.m_type & ~SpecCell)); // Edge filtering should have already ensured this.
1671
1672         if (Structure* structure = value.bestProvenStructure()) {
1673             bool done = false;
1674             for (unsigned i = node->multiGetByOffsetData().variants.size(); i--;) {
1675                 const GetByIdVariant& variant = node->multiGetByOffsetData().variants[i];
1676                 if (!variant.structureSet().contains(structure))
1677                     continue;
1678                 
1679                 if (variant.chain())
1680                     break;
1681                 
1682                 filter(value, structure);
1683                 forNode(node).makeHeapTop();
1684                 m_state.setFoundConstants(true);
1685                 done = true;
1686                 break;
1687             }
1688             if (done)
1689                 break;
1690         }
1691         
1692         StructureSet set;
1693         for (unsigned i = node->multiGetByOffsetData().variants.size(); i--;)
1694             set.addAll(node->multiGetByOffsetData().variants[i].structureSet());
1695         
1696         filter(node->child1(), set);
1697         forNode(node).makeHeapTop();
1698         break;
1699     }
1700             
1701     case PutByOffset: {
1702         break;
1703     }
1704         
1705     case MultiPutByOffset: {
1706         AbstractValue& value = forNode(node->child1());
1707         ASSERT(!(value.m_type & ~SpecCell)); // Edge filtering should have already ensured this.
1708
1709         if (Structure* structure = value.bestProvenStructure()) {
1710             bool done = false;
1711             for (unsigned i = node->multiPutByOffsetData().variants.size(); i--;) {
1712                 const PutByIdVariant& variant = node->multiPutByOffsetData().variants[i];
1713                 if (variant.oldStructure() != structure)
1714                     continue;
1715                 
1716                 if (variant.kind() == PutByIdVariant::Replace) {
1717                     filter(node->child1(), structure);
1718                     m_state.setFoundConstants(true);
1719                     m_state.setHaveStructures(true);
1720                     done = true;
1721                     break;
1722                 }
1723                 
1724                 ASSERT(variant.kind() == PutByIdVariant::Transition);
1725                 clobberStructures(clobberLimit);
1726                 forNode(node->child1()).set(m_graph, variant.newStructure());
1727                 m_state.setFoundConstants(true);
1728                 m_state.setHaveStructures(true);
1729                 done = true;
1730                 break;
1731             }
1732             if (done)
1733                 break;
1734         }
1735         
1736         clobberStructures(clobberLimit);
1737         
1738         StructureSet newSet;
1739         for (unsigned i = node->multiPutByOffsetData().variants.size(); i--;) {
1740             const PutByIdVariant& variant = node->multiPutByOffsetData().variants[i];
1741             if (variant.kind() == PutByIdVariant::Replace) {
1742                 if (value.m_currentKnownStructure.contains(variant.structure()))
1743                     newSet.addAll(variant.structure());
1744                 continue;
1745             }
1746             ASSERT(variant.kind() == PutByIdVariant::Transition);
1747             if (value.m_currentKnownStructure.contains(variant.oldStructure()))
1748                 newSet.addAll(variant.newStructure());
1749         }
1750         
1751         // Use filter(value, set) as a way of setting the structure set. This works because
1752         // we would have already made the set be TOP before this. Filtering top is another 
1753         // way of setting.
1754         filter(node->child1(), newSet);
1755         break;
1756     }
1757     
1758     case CheckFunction: {
1759         JSValue value = forNode(node->child1()).value();
1760         if (value == node->function()) {
1761             m_state.setFoundConstants(true);
1762             ASSERT(value);
1763             break;
1764         }
1765         
1766         node->setCanExit(true); // Lies! We can do better.
1767         filterByValue(node->child1(), node->function());
1768         break;
1769     }
1770         
1771     case CheckInBounds: {
1772         JSValue left = forNode(node->child1()).value();
1773         JSValue right = forNode(node->child2()).value();
1774         if (left && right && left.isInt32() && right.isInt32()
1775             && static_cast<uint32_t>(left.asInt32()) < static_cast<uint32_t>(right.asInt32())) {
1776             m_state.setFoundConstants(true);
1777             break;
1778         }
1779         
1780         node->setCanExit(true);
1781         break;
1782     }
1783         
1784     case PutById:
1785     case PutByIdFlush:
1786     case PutByIdDirect:
1787         node->setCanExit(true);
1788         if (Structure* structure = forNode(node->child1()).bestProvenStructure()) {
1789             PutByIdStatus status = PutByIdStatus::computeFor(
1790                 m_graph.m_vm,
1791                 m_graph.globalObjectFor(node->origin.semantic),
1792                 structure,
1793                 m_graph.identifiers()[node->identifierNumber()],
1794                 node->op() == PutByIdDirect);
1795             if (status.isSimple() && status.numVariants() == 1) {
1796                 if (status[0].kind() == PutByIdVariant::Replace) {
1797                     filter(node->child1(), structure);
1798                     m_state.setFoundConstants(true);
1799                     m_state.setHaveStructures(true);
1800                     break;
1801                 }
1802                 if (status[0].kind() == PutByIdVariant::Transition) {
1803                     clobberStructures(clobberLimit);
1804                     forNode(node->child1()).set(m_graph, status[0].newStructure());
1805                     m_state.setHaveStructures(true);
1806                     m_state.setFoundConstants(true);
1807                     break;
1808                 }
1809             }
1810         }
1811         clobberWorld(node->origin.semantic, clobberLimit);
1812         break;
1813         
1814     case In:
1815         // FIXME: We can determine when the property definitely exists based on abstract
1816         // value information.
1817         clobberWorld(node->origin.semantic, clobberLimit);
1818         forNode(node).setType(SpecBoolean);
1819         break;
1820             
1821     case GetGlobalVar:
1822         forNode(node).makeHeapTop();
1823         break;
1824         
1825     case VariableWatchpoint:
1826     case VarInjectionWatchpoint:
1827         node->setCanExit(true);
1828         break;
1829             
1830     case PutGlobalVar:
1831     case NotifyWrite:
1832         break;
1833             
1834     case CheckHasInstance:
1835         node->setCanExit(true);
1836         // Sadly, we don't propagate the fact that we've done CheckHasInstance
1837         break;
1838             
1839     case InstanceOf:
1840         node->setCanExit(true);
1841         // Again, sadly, we don't propagate the fact that we've done InstanceOf
1842         forNode(node).setType(SpecBoolean);
1843         break;
1844             
1845     case Phi:
1846         RELEASE_ASSERT(m_graph.m_form == SSA);
1847         // The state of this node would have already been decided.
1848         break;
1849         
1850     case Upsilon: {
1851         m_state.createValueForNode(node->phi());
1852         AbstractValue& value = forNode(node->child1());
1853         forNode(node) = value;
1854         forNode(node->phi()) = value;
1855         break;
1856     }
1857         
1858     case Flush:
1859     case PhantomLocal:
1860         break;
1861             
1862     case Call:
1863     case Construct:
1864         node->setCanExit(true);
1865         clobberWorld(node->origin.semantic, clobberLimit);
1866         forNode(node).makeHeapTop();
1867         break;
1868
1869     case ForceOSRExit:
1870         node->setCanExit(true);
1871         m_state.setIsValid(false);
1872         break;
1873         
1874     case InvalidationPoint:
1875         node->setCanExit(true);
1876         break;
1877
1878     case CheckWatchdogTimer:
1879         node->setCanExit(true);
1880         break;
1881
1882     case Breakpoint:
1883     case ProfileWillCall:
1884     case ProfileDidCall:
1885     case Phantom:
1886     case HardPhantom:
1887     case Check:
1888     case CountExecution:
1889     case CheckTierUpInLoop:
1890     case CheckTierUpAtReturn:
1891         break;
1892
1893     case StoreBarrier: {
1894         filter(node->child1(), SpecCell);
1895         break;
1896     }
1897
1898     case StoreBarrierWithNullCheck: {
1899         break;
1900     }
1901
1902     case CheckTierUpAndOSREnter:
1903     case LoopHint:
1904         // We pretend that it can exit because it may want to get all state.
1905         node->setCanExit(true);
1906         break;
1907
1908     case ZombieHint:
1909     case Unreachable:
1910     case LastNodeType:
1911     case ArithIMul:
1912     case FiatInt52:
1913         RELEASE_ASSERT_NOT_REACHED();
1914         break;
1915     }
1916     
1917     return m_state.isValid();
1918 }
1919
1920 template<typename AbstractStateType>
1921 bool AbstractInterpreter<AbstractStateType>::executeEffects(unsigned indexInBlock)
1922 {
1923     return executeEffects(indexInBlock, m_state.block()->at(indexInBlock));
1924 }
1925
1926 template<typename AbstractStateType>
1927 bool AbstractInterpreter<AbstractStateType>::execute(unsigned indexInBlock)
1928 {
1929     Node* node = m_state.block()->at(indexInBlock);
1930     if (!startExecuting(node))
1931         return true;
1932     
1933     executeEdges(node);
1934     return executeEffects(indexInBlock, node);
1935 }
1936
1937 template<typename AbstractStateType>
1938 bool AbstractInterpreter<AbstractStateType>::execute(Node* node)
1939 {
1940     if (!startExecuting(node))
1941         return true;
1942     
1943     executeEdges(node);
1944     return executeEffects(UINT_MAX, node);
1945 }
1946
1947 template<typename AbstractStateType>
1948 void AbstractInterpreter<AbstractStateType>::clobberWorld(
1949     const CodeOrigin& codeOrigin, unsigned clobberLimit)
1950 {
1951     clobberCapturedVars(codeOrigin);
1952     clobberStructures(clobberLimit);
1953 }
1954
1955 template<typename AbstractStateType>
1956 void AbstractInterpreter<AbstractStateType>::clobberCapturedVars(const CodeOrigin& codeOrigin)
1957 {
1958     if (codeOrigin.inlineCallFrame) {
1959         const BitVector& capturedVars = codeOrigin.inlineCallFrame->capturedVars;
1960         for (size_t i = capturedVars.size(); i--;) {
1961             if (!capturedVars.quickGet(i))
1962                 continue;
1963             m_state.variables().local(i).makeHeapTop();
1964         }
1965     } else {
1966         for (size_t i = m_codeBlock->m_numVars; i--;) {
1967             if (m_codeBlock->isCaptured(virtualRegisterForLocal(i)))
1968                 m_state.variables().local(i).makeHeapTop();
1969         }
1970     }
1971
1972     for (size_t i = m_state.variables().numberOfArguments(); i--;) {
1973         if (m_codeBlock->isCaptured(virtualRegisterForArgument(i)))
1974             m_state.variables().argument(i).makeHeapTop();
1975     }
1976 }
1977
1978 template<typename AbstractStateType>
1979 void AbstractInterpreter<AbstractStateType>::clobberStructures(unsigned clobberLimit)
1980 {
1981     if (!m_state.haveStructures())
1982         return;
1983     if (clobberLimit >= m_state.block()->size())
1984         clobberLimit = m_state.block()->size();
1985     else
1986         clobberLimit++;
1987     ASSERT(clobberLimit <= m_state.block()->size());
1988     for (size_t i = clobberLimit; i--;)
1989         forNode(m_state.block()->at(i)).clobberStructures();
1990     if (m_graph.m_form == SSA) {
1991         HashSet<Node*>::iterator iter = m_state.block()->ssa->liveAtHead.begin();
1992         HashSet<Node*>::iterator end = m_state.block()->ssa->liveAtHead.end();
1993         for (; iter != end; ++iter)
1994             forNode(*iter).clobberStructures();
1995     }
1996     for (size_t i = m_state.variables().numberOfArguments(); i--;)
1997         m_state.variables().argument(i).clobberStructures();
1998     for (size_t i = m_state.variables().numberOfLocals(); i--;)
1999         m_state.variables().local(i).clobberStructures();
2000     m_state.setHaveStructures(true);
2001     m_state.setDidClobber(true);
2002 }
2003
2004 template<typename AbstractStateType>
2005 void AbstractInterpreter<AbstractStateType>::dump(PrintStream& out)
2006 {
2007     CommaPrinter comma(" ");
2008     if (m_graph.m_form == SSA) {
2009         HashSet<Node*>::iterator iter = m_state.block()->ssa->liveAtHead.begin();
2010         HashSet<Node*>::iterator end = m_state.block()->ssa->liveAtHead.end();
2011         for (; iter != end; ++iter) {
2012             Node* node = *iter;
2013             AbstractValue& value = forNode(node);
2014             if (value.isClear())
2015                 continue;
2016             out.print(comma, node, ":", value);
2017         }
2018     }
2019     for (size_t i = 0; i < m_state.block()->size(); ++i) {
2020         Node* node = m_state.block()->at(i);
2021         AbstractValue& value = forNode(node);
2022         if (value.isClear())
2023             continue;
2024         out.print(comma, node, ":", value);
2025     }
2026 }
2027
2028 template<typename AbstractStateType>
2029 FiltrationResult AbstractInterpreter<AbstractStateType>::filter(
2030     AbstractValue& value, const StructureSet& set)
2031 {
2032     if (value.filter(m_graph, set) == FiltrationOK)
2033         return FiltrationOK;
2034     m_state.setIsValid(false);
2035     return Contradiction;
2036 }
2037
2038 template<typename AbstractStateType>
2039 FiltrationResult AbstractInterpreter<AbstractStateType>::filterArrayModes(
2040     AbstractValue& value, ArrayModes arrayModes)
2041 {
2042     if (value.filterArrayModes(arrayModes) == FiltrationOK)
2043         return FiltrationOK;
2044     m_state.setIsValid(false);
2045     return Contradiction;
2046 }
2047
2048 template<typename AbstractStateType>
2049 FiltrationResult AbstractInterpreter<AbstractStateType>::filter(
2050     AbstractValue& value, SpeculatedType type)
2051 {
2052     if (value.filter(type) == FiltrationOK)
2053         return FiltrationOK;
2054     m_state.setIsValid(false);
2055     return Contradiction;
2056 }
2057
2058 template<typename AbstractStateType>
2059 FiltrationResult AbstractInterpreter<AbstractStateType>::filterByValue(
2060     AbstractValue& abstractValue, JSValue concreteValue)
2061 {
2062     if (abstractValue.filterByValue(concreteValue) == FiltrationOK)
2063         return FiltrationOK;
2064     m_state.setIsValid(false);
2065     return Contradiction;
2066 }
2067
2068 } } // namespace JSC::DFG
2069
2070 #endif // ENABLE(DFG_JIT)
2071
2072 #endif // DFGAbstractInterpreterInlines_h
2073