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