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