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