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