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