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