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