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