5a63b42be03e0fbe90d0d35f4aeaea16e6bc3ffc
[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)->globalExec()))
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             setConstant(node, jsDoubleNumber(operationMathPow(childX.asNumber(), childY.asNumber())));
943             break;
944         }
945
946         if (node->binaryUseKind() == BigIntUse)
947             setTypeForNode(node, SpecBigInt);
948         else {
949             clobberWorld();
950             setTypeForNode(node, SpecBytecodeNumber | SpecBigInt);
951         }
952         break;
953     }
954
955     case ValueMul: {
956         if (node->binaryUseKind() == BigIntUse)
957             setTypeForNode(node, SpecBigInt);
958         else {
959             clobberWorld();
960             setTypeForNode(node, SpecBytecodeNumber | SpecBigInt);
961         }
962         break;
963     }
964
965     case ArithMul: {
966         JSValue left = forNode(node->child1()).value();
967         JSValue right = forNode(node->child2()).value();
968         switch (node->binaryUseKind()) {
969         case Int32Use:
970             if (left && right && left.isInt32() && right.isInt32()) {
971                 if (!shouldCheckOverflow(node->arithMode())) {
972                     setConstant(node, jsNumber(left.asInt32() * right.asInt32()));
973                     break;
974                 }
975                 double doubleResult = left.asNumber() * right.asNumber();
976                 if (!shouldCheckNegativeZero(node->arithMode()))
977                     doubleResult += 0; // Sanitizes zero.
978                 JSValue valueResult = jsNumber(doubleResult);
979                 if (valueResult.isInt32()) {
980                     setConstant(node, valueResult);
981                     break;
982                 }
983             }
984             setNonCellTypeForNode(node, SpecInt32Only);
985             break;
986         case Int52RepUse:
987             if (left && right && left.isAnyInt() && right.isAnyInt()) {
988                 double doubleResult = left.asNumber() * right.asNumber();
989                 if (!shouldCheckNegativeZero(node->arithMode()))
990                     doubleResult += 0;
991                 JSValue valueResult = jsNumber(doubleResult);
992                 if (valueResult.isAnyInt()) {
993                     setConstant(node, valueResult);
994                     break;
995                 }
996             }
997             setNonCellTypeForNode(node, SpecInt52Any);
998             break;
999         case DoubleRepUse:
1000             if (left && right && left.isNumber() && right.isNumber()) {
1001                 setConstant(node, jsDoubleNumber(left.asNumber() * right.asNumber()));
1002                 break;
1003             }
1004             setNonCellTypeForNode(node, 
1005                 typeOfDoubleProduct(
1006                     forNode(node->child1()).m_type, forNode(node->child2()).m_type));
1007             break;
1008         default:
1009             RELEASE_ASSERT_NOT_REACHED();
1010             break;
1011         }
1012         break;
1013     }
1014         
1015     case ValueMod:
1016     case ValueDiv: {
1017         if (handleConstantDivOp(node))
1018             break;
1019
1020         if (node->binaryUseKind() == BigIntUse)
1021             setTypeForNode(node, SpecBigInt);
1022         else {
1023             clobberWorld();
1024             setTypeForNode(node, SpecBytecodeNumber | SpecBigInt);
1025         }
1026         break;
1027     }
1028
1029     case ArithMod:
1030     case ArithDiv: {
1031         if (handleConstantDivOp(node))
1032             break;
1033
1034         switch (node->binaryUseKind()) {
1035         case Int32Use:
1036             setNonCellTypeForNode(node, SpecInt32Only);
1037             break;
1038         case DoubleRepUse:
1039             if (node->op() == ArithDiv) {
1040                 setNonCellTypeForNode(node, 
1041                     typeOfDoubleQuotient(
1042                         forNode(node->child1()).m_type, forNode(node->child2()).m_type));
1043             } else {
1044                 setNonCellTypeForNode(node, 
1045                     typeOfDoubleBinaryOp(
1046                         forNode(node->child1()).m_type, forNode(node->child2()).m_type));
1047             }
1048             
1049             break;
1050         default:
1051             RELEASE_ASSERT_NOT_REACHED();
1052             break;
1053         }
1054         break;
1055     }
1056
1057     case ArithMin: {
1058         JSValue left = forNode(node->child1()).value();
1059         JSValue right = forNode(node->child2()).value();
1060         switch (node->binaryUseKind()) {
1061         case Int32Use:
1062             if (left && right && left.isInt32() && right.isInt32()) {
1063                 setConstant(node, jsNumber(std::min(left.asInt32(), right.asInt32())));
1064                 break;
1065             }
1066             setNonCellTypeForNode(node, SpecInt32Only);
1067             break;
1068         case DoubleRepUse:
1069             if (left && right && left.isNumber() && right.isNumber()) {
1070                 double a = left.asNumber();
1071                 double b = right.asNumber();
1072                 setConstant(node, jsDoubleNumber(a < b ? a : (b <= a ? b : a + b)));
1073                 break;
1074             }
1075             setNonCellTypeForNode(node, 
1076                 typeOfDoubleMinMax(
1077                     forNode(node->child1()).m_type, forNode(node->child2()).m_type));
1078             break;
1079         default:
1080             RELEASE_ASSERT_NOT_REACHED();
1081             break;
1082         }
1083         break;
1084     }
1085             
1086     case ArithMax: {
1087         JSValue left = forNode(node->child1()).value();
1088         JSValue right = forNode(node->child2()).value();
1089         switch (node->binaryUseKind()) {
1090         case Int32Use:
1091             if (left && right && left.isInt32() && right.isInt32()) {
1092                 setConstant(node, jsNumber(std::max(left.asInt32(), right.asInt32())));
1093                 break;
1094             }
1095             setNonCellTypeForNode(node, SpecInt32Only);
1096             break;
1097         case DoubleRepUse:
1098             if (left && right && left.isNumber() && right.isNumber()) {
1099                 double a = left.asNumber();
1100                 double b = right.asNumber();
1101                 setConstant(node, jsDoubleNumber(a > b ? a : (b >= a ? b : a + b)));
1102                 break;
1103             }
1104             setNonCellTypeForNode(node, 
1105                 typeOfDoubleMinMax(
1106                     forNode(node->child1()).m_type, forNode(node->child2()).m_type));
1107             break;
1108         default:
1109             RELEASE_ASSERT_NOT_REACHED();
1110             break;
1111         }
1112         break;
1113     }
1114             
1115     case ArithAbs: {
1116         JSValue child = forNode(node->child1()).value();
1117         switch (node->child1().useKind()) {
1118         case Int32Use:
1119             if (Optional<double> number = child.toNumberFromPrimitive()) {
1120                 JSValue result = jsNumber(fabs(*number));
1121                 if (result.isInt32()) {
1122                     setConstant(node, result);
1123                     break;
1124                 }
1125             }
1126             setNonCellTypeForNode(node, SpecInt32Only);
1127             break;
1128         case DoubleRepUse:
1129             if (Optional<double> number = child.toNumberFromPrimitive()) {
1130                 setConstant(node, jsDoubleNumber(fabs(*number)));
1131                 break;
1132             }
1133             setNonCellTypeForNode(node, typeOfDoubleAbs(forNode(node->child1()).m_type));
1134             break;
1135         default:
1136             DFG_ASSERT(m_graph, node, node->child1().useKind() == UntypedUse, node->child1().useKind());
1137             clobberWorld();
1138             setNonCellTypeForNode(node, SpecBytecodeNumber);
1139             break;
1140         }
1141         break;
1142     }
1143
1144     case ArithPow: {
1145         JSValue childY = forNode(node->child2()).value();
1146         if (childY && childY.isNumber()) {
1147             if (!childY.asNumber()) {
1148                 setConstant(node, jsDoubleNumber(1));
1149                 break;
1150             }
1151
1152             JSValue childX = forNode(node->child1()).value();
1153             if (childX && childX.isNumber()) {
1154                 setConstant(node, jsDoubleNumber(operationMathPow(childX.asNumber(), childY.asNumber())));
1155                 break;
1156             }
1157         }
1158         setNonCellTypeForNode(node, typeOfDoublePow(forNode(node->child1()).m_type, forNode(node->child2()).m_type));
1159         break;
1160     }
1161
1162     case ArithRandom: {
1163         setNonCellTypeForNode(node, SpecDoubleReal);
1164         break;
1165     }
1166
1167     case ArithRound:
1168     case ArithFloor:
1169     case ArithCeil:
1170     case ArithTrunc: {
1171         JSValue operand = forNode(node->child1()).value();
1172         if (Optional<double> number = operand.toNumberFromPrimitive()) {
1173             if (node->child1().useKind() != DoubleRepUse)
1174                 didFoldClobberWorld();
1175             
1176             double roundedValue = 0;
1177             if (node->op() == ArithRound)
1178                 roundedValue = jsRound(*number);
1179             else if (node->op() == ArithFloor)
1180                 roundedValue = floor(*number);
1181             else if (node->op() == ArithCeil)
1182                 roundedValue = ceil(*number);
1183             else {
1184                 ASSERT(node->op() == ArithTrunc);
1185                 roundedValue = trunc(*number);
1186             }
1187
1188             if (node->child1().useKind() == UntypedUse) {
1189                 setConstant(node, jsNumber(roundedValue));
1190                 break;
1191             }
1192             if (producesInteger(node->arithRoundingMode())) {
1193                 int32_t roundedValueAsInt32 = static_cast<int32_t>(roundedValue);
1194                 if (roundedValueAsInt32 == roundedValue) {
1195                     if (shouldCheckNegativeZero(node->arithRoundingMode())) {
1196                         if (roundedValueAsInt32 || !std::signbit(roundedValue)) {
1197                             setConstant(node, jsNumber(roundedValueAsInt32));
1198                             break;
1199                         }
1200                     } else {
1201                         setConstant(node, jsNumber(roundedValueAsInt32));
1202                         break;
1203                     }
1204                 }
1205             } else {
1206                 setConstant(node, jsDoubleNumber(roundedValue));
1207                 break;
1208             }
1209         }
1210         if (node->child1().useKind() == DoubleRepUse) {
1211             if (producesInteger(node->arithRoundingMode()))
1212                 setNonCellTypeForNode(node, SpecInt32Only);
1213             else if (node->child1().useKind() == DoubleRepUse)
1214                 setNonCellTypeForNode(node, typeOfDoubleRounding(forNode(node->child1()).m_type));
1215         } else {
1216             DFG_ASSERT(m_graph, node, node->child1().useKind() == UntypedUse, node->child1().useKind());
1217             clobberWorld();
1218             setNonCellTypeForNode(node, SpecBytecodeNumber);
1219         }
1220         break;
1221     }
1222             
1223     case ArithSqrt:
1224         executeDoubleUnaryOpEffects(node, sqrt);
1225         break;
1226
1227     case ArithFRound:
1228         executeDoubleUnaryOpEffects(node, [](double value) -> double { return static_cast<float>(value); });
1229         break;
1230         
1231     case ArithUnary:
1232         executeDoubleUnaryOpEffects(node, arithUnaryFunction(node->arithUnaryType()));
1233         break;
1234             
1235     case LogicalNot: {
1236         switch (booleanResult(node, forNode(node->child1()))) {
1237         case DefinitelyTrue:
1238             setConstant(node, jsBoolean(false));
1239             break;
1240         case DefinitelyFalse:
1241             setConstant(node, jsBoolean(true));
1242             break;
1243         default:
1244             setNonCellTypeForNode(node, SpecBoolean);
1245             break;
1246         }
1247         break;
1248     }
1249
1250     case MapHash: {
1251         if (JSValue key = forNode(node->child1()).value()) {
1252             if (Optional<uint32_t> hash = concurrentJSMapHash(key)) {
1253                 // Although C++ code uses uint32_t for the hash, the closest type in DFG IR is Int32
1254                 // and that's what MapHash returns. So, we have to cast to int32_t to avoid large
1255                 // unsigned values becoming doubles. This casting between signed and unsigned
1256                 // happens in the assembly code we emit when we don't constant fold this node.
1257                 setConstant(node, jsNumber(static_cast<int32_t>(*hash)));
1258                 break;
1259             }
1260         }
1261         setNonCellTypeForNode(node, SpecInt32Only);
1262         break;
1263     }
1264
1265     case NormalizeMapKey: {
1266         if (JSValue key = forNode(node->child1()).value()) {
1267             setConstant(node, *m_graph.freeze(normalizeMapKey(key)));
1268             break;
1269         }
1270
1271         SpeculatedType typeMaybeNormalized = (SpecFullNumber & ~SpecInt32Only);
1272         if (!(forNode(node->child1()).m_type & typeMaybeNormalized)) {
1273             m_state.setFoundConstants(true);
1274             forNode(node) = forNode(node->child1());
1275             break;
1276         }
1277
1278         makeHeapTopForNode(node);
1279         break;
1280     }
1281
1282     case StringValueOf: {
1283         clobberWorld();
1284         setTypeForNode(node, SpecString);
1285         break;
1286     }
1287
1288     case StringSlice: {
1289         setTypeForNode(node, SpecString);
1290         break;
1291     }
1292
1293     case ToLowerCase: {
1294         setTypeForNode(node, SpecString);
1295         break;
1296     }
1297
1298     case LoadKeyFromMapBucket:
1299     case LoadValueFromMapBucket:
1300     case ExtractValueFromWeakMapGet:
1301         makeHeapTopForNode(node);
1302         break;
1303
1304     case GetMapBucket:
1305     case GetMapBucketHead:
1306         if (node->child1().useKind() == MapObjectUse)
1307             setForNode(node, m_vm.hashMapBucketMapStructure.get());
1308         else {
1309             ASSERT(node->child1().useKind() == SetObjectUse);
1310             setForNode(node, m_vm.hashMapBucketSetStructure.get());
1311         }
1312         break;
1313
1314     case GetMapBucketNext:
1315         if (node->bucketOwnerType() == BucketOwnerType::Map)
1316             setForNode(node, m_vm.hashMapBucketMapStructure.get());
1317         else {
1318             ASSERT(node->bucketOwnerType() == BucketOwnerType::Set);
1319             setForNode(node, m_vm.hashMapBucketSetStructure.get());
1320         }
1321         break;
1322
1323     case SetAdd:
1324         setForNode(node, m_vm.hashMapBucketSetStructure.get());
1325         break;
1326
1327     case MapSet:
1328         setForNode(node, m_vm.hashMapBucketMapStructure.get());
1329         break;
1330
1331     case WeakSetAdd:
1332     case WeakMapSet:
1333         break;
1334
1335     case WeakMapGet:
1336         makeBytecodeTopForNode(node);
1337         break;
1338
1339     case IsEmpty:
1340     case IsUndefined:
1341     case IsUndefinedOrNull:
1342     case IsBoolean:
1343     case IsNumber:
1344     case NumberIsInteger:
1345     case IsObject:
1346     case IsObjectOrNull:
1347     case IsFunction:
1348     case IsCellWithType:
1349     case IsTypedArrayView: {
1350         AbstractValue child = forNode(node->child1());
1351         if (child.value()) {
1352             bool constantWasSet = true;
1353             switch (node->op()) {
1354             case IsCellWithType:
1355                 setConstant(node, jsBoolean(child.value().isCell() && child.value().asCell()->type() == node->queriedType()));
1356                 break;
1357             case IsUndefined:
1358                 setConstant(node, jsBoolean(
1359                     child.value().isCell()
1360                     ? child.value().asCell()->structure(m_vm)->masqueradesAsUndefined(m_codeBlock->globalObjectFor(node->origin.semantic))
1361                     : child.value().isUndefined()));
1362                 break;
1363             case IsUndefinedOrNull:
1364                 setConstant(node, jsBoolean(child.value().isUndefinedOrNull()));
1365                 break;
1366             case IsBoolean:
1367                 setConstant(node, jsBoolean(child.value().isBoolean()));
1368                 break;
1369             case IsNumber:
1370                 setConstant(node, jsBoolean(child.value().isNumber()));
1371                 break;
1372             case NumberIsInteger:
1373                 setConstant(node, jsBoolean(NumberConstructor::isIntegerImpl(child.value())));
1374                 break;
1375             case IsObject:
1376                 setConstant(node, jsBoolean(child.value().isObject()));
1377                 break;
1378             case IsObjectOrNull:
1379                 if (child.value().isObject()) {
1380                     JSObject* object = asObject(child.value());
1381                     if (object->type() == JSFunctionType)
1382                         setConstant(node, jsBoolean(false));
1383                     else if (!(object->inlineTypeFlags() & OverridesGetCallData))
1384                         setConstant(node, jsBoolean(!child.value().asCell()->structure(m_vm)->masqueradesAsUndefined(m_codeBlock->globalObjectFor(node->origin.semantic))));
1385                     else {
1386                         // FIXME: This could just call getCallData.
1387                         // https://bugs.webkit.org/show_bug.cgi?id=144457
1388                         constantWasSet = false;
1389                     }
1390                 } else
1391                     setConstant(node, jsBoolean(child.value().isNull()));
1392                 break;
1393             case IsFunction:
1394                 if (child.value().isObject()) {
1395                     JSObject* object = asObject(child.value());
1396                     if (object->type() == JSFunctionType)
1397                         setConstant(node, jsBoolean(true));
1398                     else if (!(object->inlineTypeFlags() & OverridesGetCallData))
1399                         setConstant(node, jsBoolean(false));
1400                     else {
1401                         // FIXME: This could just call getCallData.
1402                         // https://bugs.webkit.org/show_bug.cgi?id=144457
1403                         constantWasSet = false;
1404                     }
1405                 } else
1406                     setConstant(node, jsBoolean(false));
1407                 break;
1408             case IsEmpty:
1409                 setConstant(node, jsBoolean(child.value().isEmpty()));
1410                 break;
1411             case IsTypedArrayView:
1412                 setConstant(node, jsBoolean(child.value().isObject() && isTypedView(child.value().getObject()->classInfo(m_vm)->typedArrayStorageType)));
1413                 break;
1414             default:
1415                 constantWasSet = false;
1416                 break;
1417             }
1418             if (constantWasSet)
1419                 break;
1420         }
1421         
1422         // FIXME: This code should really use AbstractValue::isType() and
1423         // AbstractValue::couldBeType().
1424         // https://bugs.webkit.org/show_bug.cgi?id=146870
1425         
1426         bool constantWasSet = false;
1427         switch (node->op()) {
1428         case IsEmpty: {
1429             if (child.m_type && !(child.m_type & SpecEmpty)) {
1430                 setConstant(node, jsBoolean(false));
1431                 constantWasSet = true;
1432                 break;
1433             }
1434
1435             if (child.m_type && !(child.m_type & ~SpecEmpty)) {
1436                 setConstant(node, jsBoolean(true));
1437                 constantWasSet = true;
1438                 break;
1439             }
1440
1441             break;
1442         }
1443         case IsUndefined:
1444             // FIXME: Use the masquerades-as-undefined watchpoint thingy.
1445             // https://bugs.webkit.org/show_bug.cgi?id=144456
1446             
1447             if (!(child.m_type & (SpecOther | SpecObjectOther))) {
1448                 setConstant(node, jsBoolean(false));
1449                 constantWasSet = true;
1450                 break;
1451             }
1452             
1453             break;
1454         case IsUndefinedOrNull:
1455             if (!(child.m_type & ~SpecOther)) {
1456                 setConstant(node, jsBoolean(true));
1457                 constantWasSet = true;
1458                 break;
1459             }
1460
1461             if (!(child.m_type & SpecOther)) {
1462                 setConstant(node, jsBoolean(false));
1463                 constantWasSet = true;
1464                 break;
1465             }
1466             break;
1467         case IsBoolean:
1468             if (!(child.m_type & ~SpecBoolean)) {
1469                 setConstant(node, jsBoolean(true));
1470                 constantWasSet = true;
1471                 break;
1472             }
1473             
1474             if (!(child.m_type & SpecBoolean)) {
1475                 setConstant(node, jsBoolean(false));
1476                 constantWasSet = true;
1477                 break;
1478             }
1479             
1480             break;
1481         case IsNumber:
1482             if (!(child.m_type & ~SpecFullNumber)) {
1483                 setConstant(node, jsBoolean(true));
1484                 constantWasSet = true;
1485                 break;
1486             }
1487             
1488             if (!(child.m_type & SpecFullNumber)) {
1489                 setConstant(node, jsBoolean(false));
1490                 constantWasSet = true;
1491                 break;
1492             }
1493             
1494             break;
1495
1496         case NumberIsInteger:
1497             if (!(child.m_type & ~SpecInt32Only)) {
1498                 setConstant(node, jsBoolean(true));
1499                 constantWasSet = true;
1500                 break;
1501             }
1502             
1503             if (!(child.m_type & SpecFullNumber)) {
1504                 setConstant(node, jsBoolean(false));
1505                 constantWasSet = true;
1506                 break;
1507             }
1508             
1509             break;
1510
1511         case IsObject:
1512             if (!(child.m_type & ~SpecObject)) {
1513                 setConstant(node, jsBoolean(true));
1514                 constantWasSet = true;
1515                 break;
1516             }
1517             
1518             if (!(child.m_type & SpecObject)) {
1519                 setConstant(node, jsBoolean(false));
1520                 constantWasSet = true;
1521                 break;
1522             }
1523             
1524             break;
1525         case IsObjectOrNull:
1526             // FIXME: Use the masquerades-as-undefined watchpoint thingy.
1527             // https://bugs.webkit.org/show_bug.cgi?id=144456
1528             
1529             // These expressions are complicated to parse. A helpful way to parse this is that
1530             // "!(T & ~S)" means "T is a subset of S". Conversely, "!(T & S)" means "T is a
1531             // disjoint set from S". Things like "T - S" means that, provided that S is a
1532             // subset of T, it's the "set of all things in T but not in S". Things like "T | S"
1533             // mean the "union of T and S".
1534             
1535             // Is the child's type an object that isn't an other-object (i.e. object that could
1536             // have masquaredes-as-undefined traps) and isn't a function?  Then: we should fold
1537             // this to true.
1538             if (!(child.m_type & ~(SpecObject - SpecObjectOther - SpecFunction))) {
1539                 setConstant(node, jsBoolean(true));
1540                 constantWasSet = true;
1541                 break;
1542             }
1543             
1544             // Is the child's type definitely not either of: an object that isn't a function,
1545             // or either undefined or null?  Then: we should fold this to false.  This means
1546             // for example that if it's any non-function object, including those that have
1547             // masquerades-as-undefined traps, then we don't fold. It also means we won't fold
1548             // if it's undefined-or-null, since the type bits don't distinguish between
1549             // undefined (which should fold to false) and null (which should fold to true).
1550             if (!(child.m_type & ((SpecObject - SpecFunction) | SpecOther))) {
1551                 setConstant(node, jsBoolean(false));
1552                 constantWasSet = true;
1553                 break;
1554             }
1555             
1556             break;
1557         case IsFunction:
1558             if (!(child.m_type & ~SpecFunction)) {
1559                 setConstant(node, jsBoolean(true));
1560                 constantWasSet = true;
1561                 break;
1562             }
1563             
1564             if (!(child.m_type & (SpecFunction | SpecObjectOther | SpecProxyObject))) {
1565                 setConstant(node, jsBoolean(false));
1566                 constantWasSet = true;
1567                 break;
1568             }
1569             break;
1570
1571         case IsCellWithType: {
1572             Optional<SpeculatedType> filter = node->speculatedTypeForQuery();
1573             if (!filter) {
1574                 if (!(child.m_type & SpecCell)) {
1575                     setConstant(node, jsBoolean(false));
1576                     constantWasSet = true;
1577                 }
1578                 break;
1579             }
1580             if (!(child.m_type & ~filter.value())) {
1581                 setConstant(node, jsBoolean(true));
1582                 constantWasSet = true;
1583                 break;
1584             }
1585             if (!(child.m_type & filter.value())) {
1586                 setConstant(node, jsBoolean(false));
1587                 constantWasSet = true;
1588                 break;
1589             }
1590             break;
1591         }
1592
1593         case IsTypedArrayView:
1594             if (!(child.m_type & ~SpecTypedArrayView)) {
1595                 setConstant(node, jsBoolean(true));
1596                 constantWasSet = true;
1597                 break;
1598             }
1599             if (!(child.m_type & SpecTypedArrayView)) {
1600                 setConstant(node, jsBoolean(false));
1601                 constantWasSet = true;
1602                 break;
1603             }
1604             break;
1605
1606         default:
1607             break;
1608         }
1609         if (constantWasSet)
1610             break;
1611         
1612         setNonCellTypeForNode(node, SpecBoolean);
1613         break;
1614     }
1615
1616     case TypeOf: {
1617         JSValue child = forNode(node->child1()).value();
1618         AbstractValue& abstractChild = forNode(node->child1());
1619         if (child) {
1620             JSValue typeString = jsTypeStringForValue(m_vm, m_codeBlock->globalObjectFor(node->origin.semantic), child);
1621             setConstant(node, *m_graph.freeze(typeString));
1622             break;
1623         }
1624         
1625         if (isFullNumberSpeculation(abstractChild.m_type)) {
1626             setConstant(node, *m_graph.freeze(m_vm.smallStrings.numberString()));
1627             break;
1628         }
1629         
1630         if (isStringSpeculation(abstractChild.m_type)) {
1631             setConstant(node, *m_graph.freeze(m_vm.smallStrings.stringString()));
1632             break;
1633         }
1634
1635         // FIXME: We could use the masquerades-as-undefined watchpoint here.
1636         // https://bugs.webkit.org/show_bug.cgi?id=144456
1637         if (!(abstractChild.m_type & ~(SpecObject - SpecObjectOther - SpecFunction))) {
1638             setConstant(node, *m_graph.freeze(m_vm.smallStrings.objectString()));
1639             break;
1640         }
1641         
1642         if (isFunctionSpeculation(abstractChild.m_type)) {
1643             setConstant(node, *m_graph.freeze(m_vm.smallStrings.functionString()));
1644             break;
1645         }
1646         
1647         if (isBooleanSpeculation(abstractChild.m_type)) {
1648             setConstant(node, *m_graph.freeze(m_vm.smallStrings.booleanString()));
1649             break;
1650         }
1651
1652         if (isSymbolSpeculation(abstractChild.m_type)) {
1653             setConstant(node, *m_graph.freeze(m_vm.smallStrings.symbolString()));
1654             break;
1655         }
1656
1657         if (isBigIntSpeculation(abstractChild.m_type)) {
1658             setConstant(node, *m_graph.freeze(m_vm.smallStrings.bigintString()));
1659             break;
1660         }
1661
1662         setTypeForNode(node, SpecStringIdent);
1663         break;
1664     }
1665
1666     case CompareBelow:
1667     case CompareBelowEq: {
1668         JSValue leftConst = forNode(node->child1()).value();
1669         JSValue rightConst = forNode(node->child2()).value();
1670         if (leftConst && rightConst) {
1671             if (leftConst.isInt32() && rightConst.isInt32()) {
1672                 uint32_t a = static_cast<uint32_t>(leftConst.asInt32());
1673                 uint32_t b = static_cast<uint32_t>(rightConst.asInt32());
1674                 switch (node->op()) {
1675                 case CompareBelow:
1676                     setConstant(node, jsBoolean(a < b));
1677                     break;
1678                 case CompareBelowEq:
1679                     setConstant(node, jsBoolean(a <= b));
1680                     break;
1681                 default:
1682                     RELEASE_ASSERT_NOT_REACHED();
1683                     break;
1684                 }
1685                 break;
1686             }
1687         }
1688
1689         if (node->child1() == node->child2()) {
1690             switch (node->op()) {
1691             case CompareBelow:
1692                 setConstant(node, jsBoolean(false));
1693                 break;
1694             case CompareBelowEq:
1695                 setConstant(node, jsBoolean(true));
1696                 break;
1697             default:
1698                 DFG_CRASH(m_graph, node, "Unexpected node type");
1699                 break;
1700             }
1701             break;
1702         }
1703         setNonCellTypeForNode(node, SpecBoolean);
1704         break;
1705     }
1706
1707     case CompareLess:
1708     case CompareLessEq:
1709     case CompareGreater:
1710     case CompareGreaterEq:
1711     case CompareEq: {
1712         bool isClobbering = node->isBinaryUseKind(UntypedUse);
1713         
1714         if (isClobbering)
1715             didFoldClobberWorld();
1716         
1717         JSValue leftConst = forNode(node->child1()).value();
1718         JSValue rightConst = forNode(node->child2()).value();
1719         if (leftConst && rightConst) {
1720             if (leftConst.isNumber() && rightConst.isNumber()) {
1721                 double a = leftConst.asNumber();
1722                 double b = rightConst.asNumber();
1723                 switch (node->op()) {
1724                 case CompareLess:
1725                     setConstant(node, jsBoolean(a < b));
1726                     break;
1727                 case CompareLessEq:
1728                     setConstant(node, jsBoolean(a <= b));
1729                     break;
1730                 case CompareGreater:
1731                     setConstant(node, jsBoolean(a > b));
1732                     break;
1733                 case CompareGreaterEq:
1734                     setConstant(node, jsBoolean(a >= b));
1735                     break;
1736                 case CompareEq:
1737                     setConstant(node, jsBoolean(a == b));
1738                     break;
1739                 default:
1740                     RELEASE_ASSERT_NOT_REACHED();
1741                     break;
1742                 }
1743                 break;
1744             }
1745             
1746             if (leftConst.isString() && rightConst.isString()) {
1747                 const StringImpl* a = asString(leftConst)->tryGetValueImpl();
1748                 const StringImpl* b = asString(rightConst)->tryGetValueImpl();
1749                 if (a && b) {
1750                     bool result;
1751                     if (node->op() == CompareEq)
1752                         result = WTF::equal(a, b);
1753                     else if (node->op() == CompareLess)
1754                         result = codePointCompare(a, b) < 0;
1755                     else if (node->op() == CompareLessEq)
1756                         result = codePointCompare(a, b) <= 0;
1757                     else if (node->op() == CompareGreater)
1758                         result = codePointCompare(a, b) > 0;
1759                     else if (node->op() == CompareGreaterEq)
1760                         result = codePointCompare(a, b) >= 0;
1761                     else
1762                         RELEASE_ASSERT_NOT_REACHED();
1763                     setConstant(node, jsBoolean(result));
1764                     break;
1765                 }
1766             }
1767
1768             if (node->op() == CompareEq && leftConst.isSymbol() && rightConst.isSymbol()) {
1769                 setConstant(node, jsBoolean(asSymbol(leftConst) == asSymbol(rightConst)));
1770                 break;
1771             }
1772         }
1773         
1774         if (node->op() == CompareEq) {
1775             SpeculatedType leftType = forNode(node->child1()).m_type;
1776             SpeculatedType rightType = forNode(node->child2()).m_type;
1777             if (!valuesCouldBeEqual(leftType, rightType)) {
1778                 setConstant(node, jsBoolean(false));
1779                 break;
1780             }
1781
1782             if (leftType == SpecOther)
1783                 std::swap(leftType, rightType);
1784             if (rightType == SpecOther) {
1785                 // Undefined and Null are always equal when compared to eachother.
1786                 if (!(leftType & ~SpecOther)) {
1787                     setConstant(node, jsBoolean(true));
1788                     break;
1789                 }
1790
1791                 // Any other type compared to Null or Undefined is always false
1792                 // as long as the MasqueradesAsUndefined watchpoint is valid.
1793                 //
1794                 // MasqueradesAsUndefined only matters for SpecObjectOther, other
1795                 // cases are always "false".
1796                 if (!(leftType & (SpecObjectOther | SpecOther))) {
1797                     setConstant(node, jsBoolean(false));
1798                     break;
1799                 }
1800
1801                 if (!(leftType & SpecOther) && m_graph.masqueradesAsUndefinedWatchpointIsStillValid(node->origin.semantic)) {
1802                     JSGlobalObject* globalObject = m_graph.globalObjectFor(node->origin.semantic);
1803                     m_graph.watchpoints().addLazily(globalObject->masqueradesAsUndefinedWatchpoint());
1804                     setConstant(node, jsBoolean(false));
1805                     break;
1806                 }
1807             }
1808         }
1809         
1810         if (node->child1() == node->child2()) {
1811             if (node->isBinaryUseKind(Int32Use) ||
1812                 node->isBinaryUseKind(Int52RepUse) ||
1813                 node->isBinaryUseKind(StringUse) ||
1814                 node->isBinaryUseKind(BooleanUse) ||
1815                 node->isBinaryUseKind(SymbolUse) ||
1816                 node->isBinaryUseKind(StringIdentUse) ||
1817                 node->isBinaryUseKind(ObjectUse) ||
1818                 node->isBinaryUseKind(ObjectUse, ObjectOrOtherUse) ||
1819                 node->isBinaryUseKind(ObjectOrOtherUse, ObjectUse)) {
1820                 switch (node->op()) {
1821                 case CompareLess:
1822                 case CompareGreater:
1823                     setConstant(node, jsBoolean(false));
1824                     break;
1825                 case CompareLessEq:
1826                 case CompareGreaterEq:
1827                 case CompareEq:
1828                     setConstant(node, jsBoolean(true));
1829                     break;
1830                 default:
1831                     DFG_CRASH(m_graph, node, "Unexpected node type");
1832                     break;
1833                 }
1834                 break;
1835             }
1836         }
1837
1838         if (isClobbering)
1839             clobberWorld();
1840         setNonCellTypeForNode(node, SpecBoolean);
1841         break;
1842     }
1843             
1844     case CompareStrictEq:
1845     case SameValue: {
1846         Node* leftNode = node->child1().node();
1847         Node* rightNode = node->child2().node();
1848         JSValue left = forNode(leftNode).value();
1849         JSValue right = forNode(rightNode).value();
1850         if (left && right) {
1851             if (left.isString() && right.isString()) {
1852                 // We need this case because JSValue::strictEqual is otherwise too racy for
1853                 // string comparisons.
1854                 const StringImpl* a = asString(left)->tryGetValueImpl();
1855                 const StringImpl* b = asString(right)->tryGetValueImpl();
1856                 if (a && b) {
1857                     setConstant(node, jsBoolean(WTF::equal(a, b)));
1858                     break;
1859                 }
1860             } else {
1861                 if (node->op() == CompareStrictEq)
1862                     setConstant(node, jsBoolean(JSValue::strictEqual(nullptr, left, right)));
1863                 else
1864                     setConstant(node, jsBoolean(sameValue(nullptr, left, right)));
1865                 break;
1866             }
1867         }
1868
1869         if (node->isBinaryUseKind(UntypedUse)) {
1870             // FIXME: Revisit this condition when introducing BigInt to JSC.
1871             auto isNonStringCellConstant = [] (JSValue value) {
1872                 return value && value.isCell() && !value.isString();
1873             };
1874
1875             if (isNonStringCellConstant(left) || isNonStringCellConstant(right)) {
1876                 m_state.setFoundConstants(true);
1877                 setNonCellTypeForNode(node, SpecBoolean);
1878                 break;
1879             }
1880         }
1881         
1882         SpeculatedType leftLUB = leastUpperBoundOfStrictlyEquivalentSpeculations(forNode(leftNode).m_type);
1883         SpeculatedType rightLUB = leastUpperBoundOfStrictlyEquivalentSpeculations(forNode(rightNode).m_type);
1884         if (!(leftLUB & rightLUB)) {
1885             setConstant(node, jsBoolean(false));
1886             break;
1887         }
1888         
1889         if (node->child1() == node->child2()) {
1890             if (node->isBinaryUseKind(BooleanUse) ||
1891                 node->isBinaryUseKind(Int32Use) ||
1892                 node->isBinaryUseKind(Int52RepUse) ||
1893                 node->isBinaryUseKind(StringUse) ||
1894                 node->isBinaryUseKind(StringIdentUse) ||
1895                 node->isBinaryUseKind(SymbolUse) ||
1896                 node->isBinaryUseKind(ObjectUse) ||
1897                 node->isBinaryUseKind(MiscUse, UntypedUse) ||
1898                 node->isBinaryUseKind(UntypedUse, MiscUse) ||
1899                 node->isBinaryUseKind(StringIdentUse, NotStringVarUse) ||
1900                 node->isBinaryUseKind(NotStringVarUse, StringIdentUse) ||
1901                 node->isBinaryUseKind(StringUse, UntypedUse) ||
1902                 node->isBinaryUseKind(UntypedUse, StringUse)) {
1903                 setConstant(node, jsBoolean(true));
1904                 break;
1905             }
1906         }
1907
1908         setNonCellTypeForNode(node, SpecBoolean);
1909         break;
1910     }
1911         
1912     case CompareEqPtr: {
1913         Node* childNode = node->child1().node();
1914         JSValue childValue = forNode(childNode).value();
1915         if (childValue) {
1916             setConstant(node, jsBoolean(childValue.isCell() && childValue.asCell() == node->cellOperand()->cell()));
1917             break;
1918         }
1919         
1920         setNonCellTypeForNode(node, SpecBoolean);
1921         break;
1922     }
1923         
1924     case StringCharCodeAt:
1925     case StringCodePointAt:
1926         setNonCellTypeForNode(node, SpecInt32Only);
1927         break;
1928         
1929     case StringFromCharCode:
1930         switch (node->child1().useKind()) {
1931         case Int32Use:
1932             break;
1933         case UntypedUse:
1934             clobberWorld();
1935             break;
1936         default:
1937             DFG_CRASH(m_graph, node, "Bad use kind");
1938             break;
1939         }
1940         setTypeForNode(node, SpecString);
1941         break;
1942
1943     case StringCharAt:
1944         setForNode(node, m_vm.stringStructure.get());
1945         break;
1946             
1947     case GetByVal:
1948     case AtomicsAdd:
1949     case AtomicsAnd:
1950     case AtomicsCompareExchange:
1951     case AtomicsExchange:
1952     case AtomicsLoad:
1953     case AtomicsOr:
1954     case AtomicsStore:
1955     case AtomicsSub:
1956     case AtomicsXor: {
1957         if (node->op() == GetByVal) {
1958             auto foldGetByValOnConstantProperty = [&] (Edge& arrayEdge, Edge& indexEdge) {
1959                 // FIXME: We can expand this for non x86 environments.
1960                 // https://bugs.webkit.org/show_bug.cgi?id=134641
1961                 if (!isX86())
1962                     return false;
1963
1964                 AbstractValue& arrayValue = forNode(arrayEdge);
1965
1966                 // Check the structure set is finite. This means that this constant's structure is watched and guaranteed the one of this set.
1967                 // When the structure is changed, this code should be invalidated. This is important since the following code relies on the
1968                 // constant object's is not changed.
1969                 if (!arrayValue.m_structure.isFinite())
1970                     return false;
1971
1972                 JSValue arrayConstant = arrayValue.value();
1973                 if (!arrayConstant)
1974                     return false;
1975
1976                 JSObject* array = jsDynamicCast<JSObject*>(m_vm, arrayConstant);
1977                 if (!array)
1978                     return false;
1979
1980                 JSValue indexConstant = forNode(indexEdge).value();
1981                 if (!indexConstant || !indexConstant.isInt32() || indexConstant.asInt32() < 0)
1982                     return false;
1983                 uint32_t index = indexConstant.asUInt32();
1984
1985                 // Check that the early StructureID is not nuked, get the butterfly, and check the late StructureID again.
1986                 // And we check the indexing mode of the structure. If the indexing mode is CoW, the butterfly is
1987                 // definitely JSImmutableButterfly.
1988                 StructureID structureIDEarly = array->structureID();
1989                 if (isNuked(structureIDEarly))
1990                     return false;
1991
1992                 if (node->arrayMode().arrayClass() == Array::OriginalCopyOnWriteArray) {
1993
1994                     WTF::loadLoadFence();
1995                     Butterfly* butterfly = array->butterfly();
1996
1997                     WTF::loadLoadFence();
1998                     StructureID structureIDLate = array->structureID();
1999
2000                     if (structureIDEarly != structureIDLate)
2001                         return false;
2002
2003                     Structure* structure = m_vm.getStructure(structureIDLate);
2004                     switch (node->arrayMode().type()) {
2005                     case Array::Int32:
2006                     case Array::Contiguous:
2007                     case Array::Double:
2008                         if (structure->indexingMode() != (toIndexingShape(node->arrayMode().type()) | CopyOnWrite | IsArray))
2009                             return false;
2010                         break;
2011                     default:
2012                         return false;
2013                     }
2014                     ASSERT(isCopyOnWrite(structure->indexingMode()));
2015
2016                     JSImmutableButterfly* immutableButterfly = JSImmutableButterfly::fromButterfly(butterfly);
2017                     if (index < immutableButterfly->length()) {
2018                         JSValue value = immutableButterfly->get(index);
2019                         ASSERT(value);
2020                         if (value.isCell())
2021                             setConstant(node, *m_graph.freeze(value.asCell()));
2022                         else
2023                             setConstant(node, value);
2024                         return true;
2025                     }
2026
2027                     if (node->arrayMode().isOutOfBounds()) {
2028                         JSGlobalObject* globalObject = m_graph.globalObjectFor(node->origin.semantic);
2029                         Structure* arrayPrototypeStructure = globalObject->arrayPrototype()->structure(m_vm);
2030                         Structure* objectPrototypeStructure = globalObject->objectPrototype()->structure(m_vm);
2031                         if (arrayPrototypeStructure->transitionWatchpointSetIsStillValid()
2032                             && objectPrototypeStructure->transitionWatchpointSetIsStillValid()
2033                             && globalObject->arrayPrototypeChainIsSane()) {
2034                             m_graph.registerAndWatchStructureTransition(arrayPrototypeStructure);
2035                             m_graph.registerAndWatchStructureTransition(objectPrototypeStructure);
2036                             // Note that Array::Double and Array::Int32 return JSValue if array mode is OutOfBounds.
2037                             setConstant(node, jsUndefined());
2038                             return true;
2039                         }
2040                     }
2041                     return false;
2042                 }
2043
2044                 if (node->arrayMode().type() == Array::ArrayStorage || node->arrayMode().type() == Array::SlowPutArrayStorage) {
2045                     JSValue value;
2046                     {
2047                         // ArrayStorage's Butterfly can be half-broken state.
2048                         auto locker = holdLock(array->cellLock());
2049
2050                         WTF::loadLoadFence();
2051                         Butterfly* butterfly = array->butterfly();
2052
2053                         WTF::loadLoadFence();
2054                         StructureID structureIDLate = array->structureID();
2055
2056                         if (structureIDEarly != structureIDLate)
2057                             return false;
2058
2059                         Structure* structure = m_vm.getStructure(structureIDLate);
2060                         if (!hasAnyArrayStorage(structure->indexingMode()))
2061                             return false;
2062
2063                         if (structure->typeInfo().interceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero())
2064                             return false;
2065
2066                         ArrayStorage* storage = butterfly->arrayStorage();
2067                         if (index >= storage->length())
2068                             return false;
2069
2070                         if (index < storage->vectorLength())
2071                             return false;
2072
2073                         SparseArrayValueMap* map = storage->m_sparseMap.get();
2074                         if (!map)
2075                             return false;
2076
2077                         value = map->getConcurrently(index);
2078                     }
2079                     if (!value)
2080                         return false;
2081
2082                     if (value.isCell())
2083                         setConstant(node, *m_graph.freeze(value.asCell()));
2084                     else
2085                         setConstant(node, value);
2086                     return true;
2087                 }
2088
2089                 return false;
2090             };
2091
2092             bool didFold = false;
2093             switch (node->arrayMode().type()) {
2094             case Array::Generic:
2095             case Array::Int32:
2096             case Array::Double:
2097             case Array::Contiguous:
2098             case Array::ArrayStorage:
2099             case Array::SlowPutArrayStorage:
2100                 if (foldGetByValOnConstantProperty(m_graph.child(node, 0), m_graph.child(node, 1))) {
2101                     if (!node->arrayMode().isInBounds())
2102                         didFoldClobberWorld();
2103                     didFold = true;
2104                 }
2105                 break;
2106             default:
2107                 break;
2108             }
2109
2110             if (didFold)
2111                 break;
2112         }
2113
2114         if (node->op() != GetByVal) {
2115             unsigned numExtraArgs = numExtraAtomicsArgs(node->op());
2116             Edge storageEdge = m_graph.child(node, 2 + numExtraArgs);
2117             if (!storageEdge)
2118                 clobberWorld();
2119         }
2120         switch (node->arrayMode().type()) {
2121         case Array::SelectUsingPredictions:
2122         case Array::Unprofiled:
2123         case Array::SelectUsingArguments:
2124             RELEASE_ASSERT_NOT_REACHED();
2125             break;
2126         case Array::ForceExit:
2127             m_state.setIsValid(false);
2128             break;
2129         case Array::Undecided: {
2130             JSValue index = forNode(m_graph.child(node, 1)).value();
2131             if (index && index.isInt32() && index.asInt32() >= 0) {
2132                 setConstant(node, jsUndefined());
2133                 break;
2134             }
2135             setNonCellTypeForNode(node, SpecOther);
2136             break;
2137         }
2138         case Array::Generic:
2139             clobberWorld();
2140             makeHeapTopForNode(node);
2141             break;
2142         case Array::String:
2143             if (node->arrayMode().isOutOfBounds()) {
2144                 // If the watchpoint was still valid we could totally set this to be
2145                 // SpecString | SpecOther. Except that we'd have to be careful. If we
2146                 // tested the watchpoint state here then it could change by the time
2147                 // we got to the backend. So to do this right, we'd have to get the
2148                 // fixup phase to check the watchpoint state and then bake into the
2149                 // GetByVal operation the fact that we're using a watchpoint, using
2150                 // something like Array::SaneChain (except not quite, because that
2151                 // implies an in-bounds access). None of this feels like it's worth it,
2152                 // so we're going with TOP for now. The same thing applies to
2153                 // clobbering the world.
2154                 clobberWorld();
2155                 makeHeapTopForNode(node);
2156             } else
2157                 setForNode(node, m_vm.stringStructure.get());
2158             break;
2159         case Array::DirectArguments:
2160         case Array::ScopedArguments:
2161             if (node->arrayMode().isOutOfBounds())
2162                 clobberWorld();
2163             makeHeapTopForNode(node);
2164             break;
2165         case Array::Int32:
2166             if (node->arrayMode().isOutOfBounds()) {
2167                 clobberWorld();
2168                 makeHeapTopForNode(node);
2169             } else
2170                 setNonCellTypeForNode(node, SpecInt32Only);
2171             break;
2172         case Array::Double:
2173             if (node->arrayMode().isOutOfBounds()) {
2174                 clobberWorld();
2175                 makeHeapTopForNode(node);
2176             } else if (node->arrayMode().isSaneChain())
2177                 setNonCellTypeForNode(node, SpecBytecodeDouble);
2178             else
2179                 setNonCellTypeForNode(node, SpecDoubleReal);
2180             break;
2181         case Array::Contiguous:
2182         case Array::ArrayStorage:
2183         case Array::SlowPutArrayStorage:
2184             if (node->arrayMode().isOutOfBounds())
2185                 clobberWorld();
2186             makeHeapTopForNode(node);
2187             break;
2188         case Array::Int8Array:
2189             setNonCellTypeForNode(node, SpecInt32Only);
2190             break;
2191         case Array::Int16Array:
2192             setNonCellTypeForNode(node, SpecInt32Only);
2193             break;
2194         case Array::Int32Array:
2195             setNonCellTypeForNode(node, SpecInt32Only);
2196             break;
2197         case Array::Uint8Array:
2198             setNonCellTypeForNode(node, SpecInt32Only);
2199             break;
2200         case Array::Uint8ClampedArray:
2201             setNonCellTypeForNode(node, SpecInt32Only);
2202             break;
2203         case Array::Uint16Array:
2204             setNonCellTypeForNode(node, SpecInt32Only);
2205             break;
2206         case Array::Uint32Array:
2207             if (node->shouldSpeculateInt32())
2208                 setNonCellTypeForNode(node, SpecInt32Only);
2209             else if (node->shouldSpeculateInt52())
2210                 setNonCellTypeForNode(node, SpecInt52Any);
2211             else
2212                 setNonCellTypeForNode(node, SpecAnyIntAsDouble);
2213             break;
2214         case Array::Float32Array:
2215             setNonCellTypeForNode(node, SpecFullDouble);
2216             break;
2217         case Array::Float64Array:
2218             setNonCellTypeForNode(node, SpecFullDouble);
2219             break;
2220         default:
2221             RELEASE_ASSERT_NOT_REACHED();
2222             break;
2223         }
2224         break;
2225     }
2226             
2227     case PutByValDirect:
2228     case PutByVal:
2229     case PutByValAlias: {
2230         switch (node->arrayMode().modeForPut().type()) {
2231         case Array::ForceExit:
2232             m_state.setIsValid(false);
2233             break;
2234         case Array::Generic:
2235             clobberWorld();
2236             break;
2237         case Array::Int32:
2238             if (node->arrayMode().isOutOfBounds())
2239                 clobberWorld();
2240             break;
2241         case Array::Double:
2242             if (node->arrayMode().isOutOfBounds())
2243                 clobberWorld();
2244             break;
2245         case Array::Contiguous:
2246         case Array::ArrayStorage:
2247             if (node->arrayMode().isOutOfBounds())
2248                 clobberWorld();
2249             break;
2250         case Array::SlowPutArrayStorage:
2251             if (node->arrayMode().mayStoreToHole())
2252                 clobberWorld();
2253             break;
2254         default:
2255             break;
2256         }
2257         break;
2258     }
2259             
2260     case ArrayPush:
2261         clobberWorld();
2262         setNonCellTypeForNode(node, SpecBytecodeNumber);
2263         break;
2264
2265     case ArraySlice: {
2266         JSGlobalObject* globalObject = m_graph.globalObjectFor(node->origin.semantic);
2267
2268         // FIXME: We could do better here if we prove that the
2269         // incoming value has only a single structure.
2270         RegisteredStructureSet structureSet;
2271         structureSet.add(m_graph.registerStructure(globalObject->originalArrayStructureForIndexingType(ArrayWithInt32)));
2272         structureSet.add(m_graph.registerStructure(globalObject->originalArrayStructureForIndexingType(ArrayWithContiguous)));
2273         structureSet.add(m_graph.registerStructure(globalObject->originalArrayStructureForIndexingType(ArrayWithDouble)));
2274
2275         setForNode(node, structureSet);
2276         break;
2277     }
2278
2279     case ArrayIndexOf: {
2280         setNonCellTypeForNode(node, SpecInt32Only);
2281         break;
2282     }
2283             
2284     case ArrayPop:
2285         clobberWorld();
2286         makeHeapTopForNode(node);
2287         break;
2288         
2289     case GetMyArgumentByVal:
2290     case GetMyArgumentByValOutOfBounds: {
2291         JSValue index = forNode(node->child2()).m_value;
2292         InlineCallFrame* inlineCallFrame = node->child1()->origin.semantic.inlineCallFrame();
2293
2294         if (index && index.isUInt32()) {
2295             // This pretends to return TOP for accesses that are actually proven out-of-bounds because
2296             // that's the conservative thing to do. Otherwise we'd need to write more code to mark such
2297             // paths as unreachable, or to return undefined. We could implement that eventually.
2298
2299             Checked<unsigned, RecordOverflow> argumentIndexChecked = index.asUInt32();
2300             argumentIndexChecked += node->numberOfArgumentsToSkip();
2301             unsigned argumentIndex;
2302             if (argumentIndexChecked.safeGet(argumentIndex) != CheckedState::DidOverflow) {
2303                 if (inlineCallFrame) {
2304                     if (argumentIndex < inlineCallFrame->argumentCountIncludingThis - 1) {
2305                         setForNode(node, m_state.operand(
2306                             virtualRegisterForArgument(argumentIndex + 1) + inlineCallFrame->stackOffset));
2307                         m_state.setFoundConstants(true);
2308                         break;
2309                     }
2310                 } else {
2311                     if (argumentIndex < m_state.numberOfArguments() - 1) {
2312                         setForNode(node, m_state.argument(argumentIndex + 1));
2313                         m_state.setFoundConstants(true);
2314                         break;
2315                     }
2316                 }
2317             }
2318         }
2319         
2320         if (inlineCallFrame) {
2321             // We have a bound on the types even though it's random access. Take advantage of this.
2322             
2323             AbstractValue result;
2324             for (unsigned i = 1 + node->numberOfArgumentsToSkip(); i < inlineCallFrame->argumentCountIncludingThis; ++i) {
2325                 result.merge(
2326                     m_state.operand(
2327                         virtualRegisterForArgument(i) + inlineCallFrame->stackOffset));
2328             }
2329             
2330             if (node->op() == GetMyArgumentByValOutOfBounds)
2331                 result.merge(SpecOther);
2332             
2333             if (result.value())
2334                 m_state.setFoundConstants(true);
2335             
2336             setForNode(node, result);
2337             break;
2338         }
2339         
2340         makeHeapTopForNode(node);
2341         break;
2342     }
2343             
2344     case RegExpExec:
2345     case RegExpExecNonGlobalOrSticky:
2346         if (node->op() == RegExpExec) {
2347             // Even if we've proven known input types as RegExpObject and String,
2348             // accessing lastIndex is effectful if it's a global regexp.
2349             clobberWorld();
2350         }
2351
2352         if (JSValue globalObjectValue = forNode(node->child1()).m_value) {
2353             if (JSGlobalObject* globalObject = jsDynamicCast<JSGlobalObject*>(m_vm, globalObjectValue)) {
2354                 if (!globalObject->isHavingABadTime()) {
2355                     m_graph.watchpoints().addLazily(globalObject->havingABadTimeWatchpoint());
2356                     RegisteredStructureSet structureSet;
2357                     structureSet.add(m_graph.registerStructure(globalObject->regExpMatchesArrayStructure()));
2358                     structureSet.add(m_graph.registerStructure(globalObject->regExpMatchesArrayWithGroupsStructure()));
2359                     setForNode(node, structureSet);
2360                     forNode(node).merge(SpecOther);
2361                     break;
2362                 }
2363             }
2364         }
2365         setTypeForNode(node, SpecOther | SpecArray);
2366         break;
2367
2368     case RegExpTest:
2369         // Even if we've proven known input types as RegExpObject and String,
2370         // accessing lastIndex is effectful if it's a global regexp.
2371         clobberWorld();
2372         setNonCellTypeForNode(node, SpecBoolean);
2373         break;
2374
2375     case RegExpMatchFast:
2376         ASSERT(node->child2().useKind() == RegExpObjectUse);
2377         ASSERT(node->child3().useKind() == StringUse || node->child3().useKind() == KnownStringUse);
2378         setTypeForNode(node, SpecOther | SpecArray);
2379         break;
2380
2381     case RegExpMatchFastGlobal:
2382         ASSERT(node->child2().useKind() == StringUse || node->child2().useKind() == KnownStringUse);
2383         setTypeForNode(node, SpecOther | SpecArray);
2384         break;
2385             
2386     case StringReplace:
2387     case StringReplaceRegExp:
2388         if (node->child1().useKind() == StringUse
2389             && node->child2().useKind() == RegExpObjectUse
2390             && node->child3().useKind() == StringUse) {
2391             // This doesn't clobber the world. It just reads and writes regexp state.
2392         } else
2393             clobberWorld();
2394         setForNode(node, m_vm.stringStructure.get());
2395         break;
2396
2397     case Jump:
2398         break;
2399             
2400     case Branch: {
2401         Node* child = node->child1().node();
2402         BooleanResult result = booleanResult(node, forNode(child));
2403         if (result == DefinitelyTrue) {
2404             m_state.setBranchDirection(TakeTrue);
2405             break;
2406         }
2407         if (result == DefinitelyFalse) {
2408             m_state.setBranchDirection(TakeFalse);
2409             break;
2410         }
2411         // FIXME: The above handles the trivial cases of sparse conditional
2412         // constant propagation, but we can do better:
2413         // We can specialize the source variable's value on each direction of
2414         // the branch.
2415         m_state.setBranchDirection(TakeBoth);
2416         break;
2417     }
2418         
2419     case Switch: {
2420         // Nothing to do for now.
2421         // FIXME: Do sparse conditional things.
2422         break;
2423     }
2424
2425     case EntrySwitch:
2426         break;
2427
2428     case Return:
2429         m_state.setIsValid(false);
2430         break;
2431
2432     case Throw:
2433     case ThrowStaticError:
2434     case TailCall:
2435     case DirectTailCall:
2436     case TailCallVarargs:
2437     case TailCallForwardVarargs:
2438         clobberWorld();
2439         m_state.setIsValid(false);
2440         break;
2441         
2442     case ToPrimitive: {
2443         JSValue childConst = forNode(node->child1()).value();
2444         if (childConst && childConst.isNumber()) {
2445             didFoldClobberWorld();
2446             setConstant(node, childConst);
2447             break;
2448         }
2449         
2450         ASSERT(node->child1().useKind() == UntypedUse);
2451         
2452         if (!(forNode(node->child1()).m_type & ~(SpecFullNumber | SpecBoolean | SpecString | SpecSymbol | SpecBigInt))) {
2453             m_state.setFoundConstants(true);
2454             didFoldClobberWorld();
2455             setForNode(node, forNode(node->child1()));
2456             break;
2457         }
2458         
2459         clobberWorld();
2460         
2461         setTypeForNode(node, SpecHeapTop & ~SpecObject);
2462         break;
2463     }
2464
2465     case ToNumber: {
2466         JSValue childConst = forNode(node->child1()).value();
2467         if (childConst && childConst.isNumber()) {
2468             didFoldClobberWorld();
2469             setConstant(node, childConst);
2470             break;
2471         }
2472
2473         ASSERT(node->child1().useKind() == UntypedUse);
2474
2475         if (!(forNode(node->child1()).m_type & ~SpecBytecodeNumber)) {
2476             m_state.setFoundConstants(true);
2477             didFoldClobberWorld();
2478             setForNode(node, forNode(node->child1()));
2479             break;
2480         }
2481
2482         clobberWorld();
2483         setNonCellTypeForNode(node, SpecBytecodeNumber);
2484         break;
2485     }
2486         
2487     case ToString:
2488     case CallStringConstructor: {
2489         switch (node->child1().useKind()) {
2490         case StringObjectUse:
2491         case StringOrStringObjectUse:
2492         case Int32Use:
2493         case Int52RepUse:
2494         case DoubleRepUse:
2495         case NotCellUse:
2496             break;
2497         case CellUse:
2498         case UntypedUse:
2499             clobberWorld();
2500             break;
2501         default:
2502             RELEASE_ASSERT_NOT_REACHED();
2503             break;
2504         }
2505         setForNode(node, m_vm.stringStructure.get());
2506         break;
2507     }
2508
2509     case NumberToStringWithRadix: {
2510         JSValue radixValue = forNode(node->child2()).m_value;
2511         if (radixValue && radixValue.isInt32()) {
2512             int32_t radix = radixValue.asInt32();
2513             if (2 <= radix && radix <= 36) {
2514                 m_state.setFoundConstants(true);
2515                 didFoldClobberWorld();
2516                 setForNode(node, m_graph.m_vm.stringStructure.get());
2517                 break;
2518             }
2519         }
2520         clobberWorld();
2521         setForNode(node, m_graph.m_vm.stringStructure.get());
2522         break;
2523     }
2524
2525     case NumberToStringWithValidRadixConstant: {
2526         setForNode(node, m_graph.m_vm.stringStructure.get());
2527         break;
2528     }
2529         
2530     case NewStringObject: {
2531         ASSERT(node->structure()->classInfo() == StringObject::info());
2532         setForNode(node, node->structure());
2533         break;
2534     }
2535
2536     case NewSymbol: {
2537         setForNode(node, m_vm.symbolStructure.get());
2538         break;
2539     }
2540             
2541     case NewArray:
2542         ASSERT(node->indexingMode() == node->indexingType()); // Copy on write arrays should only be created by NewArrayBuffer.
2543         setForNode(node,
2544             m_graph.globalObjectFor(node->origin.semantic)->arrayStructureForIndexingTypeDuringAllocation(node->indexingType()));
2545         break;
2546
2547     case NewArrayWithSpread:
2548         if (m_graph.isWatchingHavingABadTimeWatchpoint(node)) {
2549             // We've compiled assuming we're not having a bad time, so to be consistent
2550             // with StructureRegisterationPhase we must say we produce an original array
2551             // allocation structure.
2552             setForNode(node, 
2553                 m_graph.globalObjectFor(node->origin.semantic)->originalArrayStructureForIndexingType(ArrayWithContiguous));
2554         } else {
2555             setForNode(node, 
2556                 m_graph.globalObjectFor(node->origin.semantic)->arrayStructureForIndexingTypeDuringAllocation(ArrayWithContiguous));
2557         }
2558
2559         break;
2560
2561     case Spread:
2562         switch (node->child1()->op()) {
2563         case PhantomNewArrayBuffer:
2564         case PhantomCreateRest:
2565             break;
2566         default:
2567             if (!m_graph.canDoFastSpread(node, forNode(node->child1())))
2568                 clobberWorld();
2569             else
2570                 didFoldClobberWorld();
2571             break;
2572         }
2573
2574         setForNode(node, 
2575             m_vm.fixedArrayStructure.get());
2576         break;
2577         
2578     case NewArrayBuffer:
2579         setForNode(node,
2580             m_graph.globalObjectFor(node->origin.semantic)->arrayStructureForIndexingTypeDuringAllocation(node->indexingMode()));
2581         break;
2582
2583     case NewArrayWithSize:
2584         setTypeForNode(node, SpecArray);
2585         break;
2586         
2587     case NewTypedArray:
2588         switch (node->child1().useKind()) {
2589         case Int32Use:
2590             break;
2591         case UntypedUse:
2592             clobberWorld();
2593             break;
2594         default:
2595             RELEASE_ASSERT_NOT_REACHED();
2596             break;
2597         }
2598         setForNode(node, 
2599             m_graph.globalObjectFor(node->origin.semantic)->typedArrayStructureConcurrently(
2600                 node->typedArrayType()));
2601         break;
2602         
2603     case NewRegexp:
2604         setForNode(node, m_graph.globalObjectFor(node->origin.semantic)->regExpStructure());
2605         break;
2606             
2607     case ToThis: {
2608         AbstractValue& source = forNode(node->child1());
2609         AbstractValue& destination = forNode(node);
2610         bool strictMode = m_graph.isStrictModeFor(node->origin.semantic);
2611
2612         ToThisResult result = isToThisAnIdentity(m_vm, strictMode, source);
2613         switch (result) {
2614         case ToThisResult::Identity:
2615             m_state.setFoundConstants(true);
2616             destination = source;
2617             break;
2618         case ToThisResult::Undefined:
2619             setConstant(node, jsUndefined());
2620             break;
2621         case ToThisResult::GlobalThis:
2622             m_state.setFoundConstants(true);
2623             destination.setType(m_graph, SpecObject);
2624             break;
2625         case ToThisResult::Dynamic:
2626             if (strictMode)
2627                 destination.makeHeapTop();
2628             else {
2629                 destination = source;
2630                 destination.merge(SpecObject);
2631             }
2632             break;
2633         }
2634         break;
2635     }
2636
2637     case CreateThis: {
2638         if (JSValue base = forNode(node->child1()).m_value) {
2639             if (auto* function = jsDynamicCast<JSFunction*>(m_vm, base)) {
2640                 if (FunctionRareData* rareData = function->rareData()) {
2641                     if (rareData->allocationProfileWatchpointSet().isStillValid()) {
2642                         if (Structure* structure = rareData->objectAllocationStructure()) {
2643                             m_graph.freeze(rareData);
2644                             m_graph.watchpoints().addLazily(rareData->allocationProfileWatchpointSet());
2645                             m_state.setFoundConstants(true);
2646                             didFoldClobberWorld();
2647                             setForNode(node, structure);
2648                             break;
2649                         }
2650                     }
2651                 }
2652             }
2653         }
2654         clobberWorld();
2655         setTypeForNode(node, SpecFinalObject);
2656         break;
2657     }
2658
2659     case CreatePromise: {
2660         JSGlobalObject* globalObject = m_graph.globalObjectFor(node->origin.semantic);
2661         if (JSValue base = forNode(node->child1()).m_value) {
2662             if (base == (node->isInternalPromise() ? globalObject->internalPromiseConstructor() : globalObject->promiseConstructor())) {
2663                 m_state.setFoundConstants(true);
2664                 didFoldClobberWorld();
2665                 setForNode(node, node->isInternalPromise() ? globalObject->internalPromiseStructure() : globalObject->promiseStructure());
2666                 break;
2667             }
2668             if (auto* function = jsDynamicCast<JSFunction*>(m_graph.m_vm, base)) {
2669                 if (FunctionRareData* rareData = function->rareData()) {
2670                     if (rareData->allocationProfileWatchpointSet().isStillValid()) {
2671                         Structure* structure = rareData->internalFunctionAllocationStructure();
2672                         if (structure
2673                             && structure->classInfo() == (node->isInternalPromise() ? JSInternalPromise::info() : JSPromise::info())
2674                             && structure->globalObject() == globalObject
2675                             && rareData->allocationProfileWatchpointSet().isStillValid()) {
2676                             m_graph.freeze(rareData);
2677                             m_graph.watchpoints().addLazily(rareData->allocationProfileWatchpointSet());
2678                             m_state.setFoundConstants(true);
2679                             didFoldClobberWorld();
2680                             setForNode(node, structure);
2681                             break;
2682                         }
2683                     }
2684                 }
2685             }
2686         }
2687         clobberWorld();
2688         setTypeForNode(node, SpecPromiseObject);
2689         break;
2690     }
2691
2692     case CreateGenerator:
2693     case CreateAsyncGenerator: {
2694         auto tryToFold = [&] (const ClassInfo* classInfo) -> bool {
2695             JSGlobalObject* globalObject = m_graph.globalObjectFor(node->origin.semantic);
2696             if (JSValue base = forNode(node->child1()).m_value) {
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() == classInfo
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                                 return true;
2711                             }
2712                         }
2713                     }
2714                 }
2715             }
2716             return false;
2717         };
2718
2719         bool found = false;
2720         switch (node->op()) {
2721         case CreateGenerator:
2722             found = tryToFold(JSGenerator::info());
2723             break;
2724         case CreateAsyncGenerator:
2725             found = tryToFold(JSAsyncGenerator::info());
2726             break;
2727         default:
2728             RELEASE_ASSERT_NOT_REACHED();
2729             break;
2730         }
2731         if (found)
2732             break;
2733         clobberWorld();
2734         setTypeForNode(node, SpecObjectOther);
2735         break;
2736     }
2737
2738     case NewPromise:
2739         ASSERT(!!node->structure().get());
2740         setForNode(node, node->structure());
2741         break;
2742
2743     case NewGenerator:
2744     case NewAsyncGenerator:
2745         ASSERT(!!node->structure().get());
2746         setForNode(node, node->structure());
2747         break;
2748         
2749     case NewObject:
2750         ASSERT(!!node->structure().get());
2751         setForNode(node, node->structure());
2752         break;
2753
2754     case ObjectCreate: {
2755         if (JSValue base = forNode(node->child1()).m_value) {
2756             JSGlobalObject* globalObject = m_graph.globalObjectFor(node->origin.semantic);
2757             Structure* structure = nullptr;
2758             if (base.isNull())
2759                 structure = globalObject->nullPrototypeObjectStructure();
2760             else if (base.isObject())
2761                 structure = globalObject->vm().structureCache.emptyObjectStructureConcurrently(globalObject, base.getObject(), JSFinalObject::defaultInlineCapacity());
2762             
2763             if (structure) {
2764                 m_state.setFoundConstants(true);
2765                 if (node->child1().useKind() == UntypedUse)
2766                     didFoldClobberWorld();
2767                 setForNode(node, structure);
2768                 break;
2769             }
2770         }
2771         if (node->child1().useKind() == UntypedUse)
2772             clobberWorld();
2773         setTypeForNode(node, SpecFinalObject);
2774         break;
2775     }
2776
2777     case ObjectKeys: {
2778         if (node->child1().useKind() == ObjectUse) {
2779             auto& structureSet = forNode(node->child1()).m_structure;
2780             if (structureSet.isFinite() && structureSet.size() == 1) {
2781                 RegisteredStructure structure = structureSet.onlyStructure();
2782                 if (auto* rareData = structure->rareDataConcurrently()) {
2783                     if (!!rareData->cachedOwnKeysConcurrently()) {
2784                         if (m_graph.isWatchingHavingABadTimeWatchpoint(node)) {
2785                             m_state.setFoundConstants(true);
2786                             didFoldClobberWorld();
2787                             setTypeForNode(node, SpecArray);
2788                             break;
2789                         }
2790                     }
2791                 }
2792             }
2793         }
2794
2795         clobberWorld();
2796         setTypeForNode(node, SpecArray);
2797         break;
2798     }
2799
2800     case ToObject:
2801     case CallObjectConstructor: {
2802         AbstractValue& source = forNode(node->child1());
2803         AbstractValue& destination = forNode(node);
2804
2805         if (!(source.m_type & ~SpecObject)) {
2806             m_state.setFoundConstants(true);
2807             if (node->op() == ToObject)
2808                 didFoldClobberWorld();
2809             destination = source;
2810             break;
2811         }
2812
2813         if (node->op() == ToObject)
2814             clobberWorld();
2815         setTypeForNode(node, SpecObject);
2816         break;
2817     }
2818
2819     case PhantomNewObject:
2820     case PhantomNewFunction:
2821     case PhantomNewGeneratorFunction:
2822     case PhantomNewAsyncGeneratorFunction:
2823     case PhantomNewAsyncFunction:
2824     case PhantomCreateActivation:
2825     case PhantomDirectArguments:
2826     case PhantomClonedArguments:
2827     case PhantomCreateRest:
2828     case PhantomSpread:
2829     case PhantomNewArrayWithSpread:
2830     case PhantomNewArrayBuffer:
2831     case PhantomNewRegexp:
2832     case BottomValue: {
2833         clearForNode(node);
2834         break;
2835     }
2836
2837     case PutHint:
2838         break;
2839         
2840     case MaterializeNewObject: {
2841         setForNode(node, node->structureSet());
2842         break;
2843     }
2844
2845     case PushWithScope:
2846         // We don't use the more precise withScopeStructure() here because it is a LazyProperty and may not yet be allocated.
2847         setTypeForNode(node, SpecObjectOther);
2848         break;
2849
2850     case CreateActivation:
2851     case MaterializeCreateActivation:
2852         setForNode(node, 
2853             m_codeBlock->globalObjectFor(node->origin.semantic)->activationStructure());
2854         break;
2855         
2856     case CreateDirectArguments:
2857         setForNode(node, m_codeBlock->globalObjectFor(node->origin.semantic)->directArgumentsStructure());
2858         break;
2859         
2860     case CreateScopedArguments:
2861         setForNode(node, m_codeBlock->globalObjectFor(node->origin.semantic)->scopedArgumentsStructure());
2862         break;
2863         
2864     case CreateClonedArguments:
2865         if (!m_graph.isWatchingHavingABadTimeWatchpoint(node)) {
2866             setTypeForNode(node, SpecObject);
2867             break;
2868         }
2869         setForNode(node, m_codeBlock->globalObjectFor(node->origin.semantic)->clonedArgumentsStructure());
2870         break;
2871
2872     case NewGeneratorFunction:
2873         setForNode(node, 
2874             m_codeBlock->globalObjectFor(node->origin.semantic)->generatorFunctionStructure());
2875         break;
2876
2877     case NewAsyncGeneratorFunction:
2878         setForNode(node, 
2879             m_codeBlock->globalObjectFor(node->origin.semantic)->asyncGeneratorFunctionStructure());
2880         break;
2881
2882     case NewAsyncFunction:
2883         setForNode(node, 
2884             m_codeBlock->globalObjectFor(node->origin.semantic)->asyncFunctionStructure());
2885         break;
2886
2887     case NewFunction: {
2888         JSGlobalObject* globalObject = m_codeBlock->globalObjectFor(node->origin.semantic);
2889         Structure* structure = JSFunction::selectStructureForNewFuncExp(globalObject, node->castOperand<FunctionExecutable*>());
2890         setForNode(node, structure);
2891         break;
2892     }
2893         
2894     case GetCallee:
2895         if (FunctionExecutable* executable = jsDynamicCast<FunctionExecutable*>(m_vm, m_codeBlock->ownerExecutable())) {
2896             if (JSFunction* function = executable->singleton().inferredValue()) {
2897                 m_graph.watchpoints().addLazily(executable);
2898                 setConstant(node, *m_graph.freeze(function));
2899                 break;
2900             }
2901         }
2902         setTypeForNode(node, SpecFunction | SpecObjectOther);
2903         break;
2904         
2905     case GetArgumentCountIncludingThis:
2906         setTypeForNode(node, SpecInt32Only);
2907         break;
2908
2909     case SetCallee:
2910     case SetArgumentCountIncludingThis:
2911         break;
2912         
2913     case GetRestLength:
2914         setNonCellTypeForNode(node, SpecInt32Only);
2915         break;
2916         
2917     case GetGetter: {
2918         if (JSValue base = forNode(node->child1()).m_value) {
2919             GetterSetter* getterSetter = jsDynamicCast<GetterSetter*>(m_vm, base);
2920             if (getterSetter && !getterSetter->isGetterNull()) {
2921                 setConstant(node, *m_graph.freeze(getterSetter->getterConcurrently()));
2922                 break;
2923             }
2924         }
2925         
2926         setTypeForNode(node, SpecObject);
2927         break;
2928     }
2929         
2930     case GetSetter: {
2931         if (JSValue base = forNode(node->child1()).m_value) {
2932             GetterSetter* getterSetter = jsDynamicCast<GetterSetter*>(m_vm, base);
2933             if (getterSetter && !getterSetter->isSetterNull()) {
2934                 setConstant(node, *m_graph.freeze(getterSetter->setterConcurrently()));
2935                 break;
2936             }
2937         }
2938         
2939         setTypeForNode(node, SpecObject);
2940         break;
2941     }
2942         
2943     case GetScope:
2944         if (JSValue base = forNode(node->child1()).m_value) {
2945             if (JSFunction* function = jsDynamicCast<JSFunction*>(m_vm, base)) {
2946                 setConstant(node, *m_graph.freeze(function->scope()));
2947                 break;
2948             }
2949         }
2950         setTypeForNode(node, SpecObjectOther);
2951         break;
2952
2953     case SkipScope: {
2954         if (JSValue child = forNode(node->child1()).value()) {
2955             if (JSScope* scope = jsDynamicCast<JSScope*>(m_vm, child)) {
2956                 if (JSScope* nextScope = scope->next()) {
2957                     setConstant(node, *m_graph.freeze(JSValue(nextScope)));
2958                     break;
2959                 }
2960             }
2961         }
2962         setTypeForNode(node, SpecObjectOther);
2963         break;
2964     }
2965
2966     case GetGlobalObject: {
2967         JSValue child = forNode(node->child1()).value();
2968         if (child) {
2969             setConstant(node, *m_graph.freeze(JSValue(asObject(child)->globalObject(m_vm))));
2970             break;
2971         }
2972
2973         if (forNode(node->child1()).m_structure.isFinite()) {
2974             JSGlobalObject* globalObject = nullptr;
2975             bool ok = true;
2976             forNode(node->child1()).m_structure.forEach(
2977                 [&] (RegisteredStructure structure) {
2978                     if (!globalObject)
2979                         globalObject = structure->globalObject();
2980                     else if (globalObject != structure->globalObject())
2981                         ok = false;
2982                 });
2983             if (globalObject && ok) {
2984                 setConstant(node, *m_graph.freeze(JSValue(globalObject)));
2985                 break;
2986             }
2987         }
2988
2989         setTypeForNode(node, SpecObjectOther);
2990         break;
2991     }
2992
2993     case GetGlobalThis: {
2994         setTypeForNode(node, SpecObject);
2995         break;
2996     }
2997
2998     case GetClosureVar:
2999         if (JSValue value = m_graph.tryGetConstantClosureVar(forNode(node->child1()), node->scopeOffset())) {
3000             setConstant(node, *m_graph.freeze(value));
3001             break;
3002         }
3003         makeBytecodeTopForNode(node);
3004         break;
3005             
3006     case PutClosureVar:
3007         break;
3008
3009     case GetInternalField:
3010         makeBytecodeTopForNode(node);
3011         break;
3012
3013     case PutInternalField:
3014         break;
3015
3016
3017     case GetRegExpObjectLastIndex:
3018         makeHeapTopForNode(node);
3019         break;
3020
3021     case SetRegExpObjectLastIndex:
3022     case RecordRegExpCachedResult:
3023         break;
3024         
3025     case GetFromArguments:
3026         makeHeapTopForNode(node);
3027         break;
3028         
3029     case PutToArguments:
3030         break;
3031
3032     case GetArgument:
3033         makeHeapTopForNode(node);
3034         break;
3035
3036     case TryGetById:
3037         // FIXME: This should constant fold at least as well as the normal GetById case.
3038         // https://bugs.webkit.org/show_bug.cgi?id=156422
3039         makeHeapTopForNode(node);
3040         break;
3041
3042     case GetByIdDirect:
3043     case GetByIdDirectFlush:
3044     case GetById:
3045     case GetByIdFlush: {
3046         AbstractValue& value = forNode(node->child1());
3047         if (value.m_structure.isFinite()
3048             && (node->child1().useKind() == CellUse || !(value.m_type & ~SpecCell))) {
3049             UniquedStringImpl* uid = m_graph.identifiers()[node->identifierNumber()];
3050             GetByIdStatus status = GetByIdStatus::computeFor(value.m_structure.toStructureSet(), uid);
3051             if (status.isSimple()) {
3052                 // Figure out what the result is going to be - is it TOP, a constant, or maybe
3053                 // something more subtle?
3054                 AbstractValue result;
3055                 for (unsigned i = status.numVariants(); i--;) {
3056                     // This thing won't give us a variant that involves prototypes. If it did, we'd
3057                     // have more work to do here.
3058                     DFG_ASSERT(m_graph, node, status[i].conditionSet().isEmpty());
3059
3060                     result.merge(
3061                         m_graph.inferredValueForProperty(
3062                             value, status[i].offset(), m_state.structureClobberState()));
3063                 }
3064             
3065                 m_state.setFoundConstants(true);
3066                 didFoldClobberWorld();
3067                 forNode(node) = result;
3068                 break;
3069             }
3070         }
3071
3072         clobberWorld();
3073         makeHeapTopForNode(node);
3074         break;
3075     }
3076
3077     case GetByValWithThis:
3078     case GetByIdWithThis:
3079         clobberWorld();
3080         makeHeapTopForNode(node);
3081         break;
3082             
3083     case GetArrayLength: {
3084         JSArrayBufferView* view = m_graph.tryGetFoldableView(
3085             forNode(node->child1()).m_value, node->arrayMode());
3086         if (view) {
3087             setConstant(node, jsNumber(view->length()));
3088             break;
3089         }
3090         setNonCellTypeForNode(node, SpecInt32Only);
3091         break;
3092     }
3093
3094     case GetVectorLength: {
3095         setNonCellTypeForNode(node, SpecInt32Only);
3096         break;
3097     }
3098
3099     case DeleteById:
3100     case DeleteByVal: {
3101         // FIXME: This could decide if the delete will be successful based on the set of structures that
3102         // we get from our base value. https://bugs.webkit.org/show_bug.cgi?id=156611
3103         clobberWorld();
3104         setNonCellTypeForNode(node, SpecBoolean);
3105         break;
3106     }
3107         
3108     case CheckStructure: {
3109         AbstractValue& value = forNode(node->child1());
3110
3111         const RegisteredStructureSet& set = node->structureSet();
3112         
3113         // It's interesting that we could have proven that the object has a larger structure set
3114         // that includes the set we're testing. In that case we could make the structure check
3115         // more efficient. We currently don't.
3116         
3117         if (value.m_structure.isSubsetOf(set))
3118             m_state.setFoundConstants(true);
3119
3120         SpeculatedType admittedTypes = SpecNone;
3121         switch (node->child1().useKind()) {
3122         case CellUse:
3123         case KnownCellUse:
3124             admittedTypes = SpecNone;
3125             break;
3126         case CellOrOtherUse:
3127             admittedTypes = SpecOther;
3128             break;
3129         default:
3130             DFG_CRASH(m_graph, node, "Bad use kind");
3131             break;
3132         }
3133         
3134         filter(value, set, admittedTypes);
3135         break;
3136     }
3137
3138     case CheckStructureOrEmpty: {
3139         AbstractValue& value = forNode(node->child1());
3140
3141         bool mayBeEmpty = value.m_type & SpecEmpty;
3142         if (!mayBeEmpty)
3143             m_state.setFoundConstants(true);
3144
3145         SpeculatedType admittedTypes = mayBeEmpty ? SpecEmpty : SpecNone;
3146         filter(value, node->structureSet(), admittedTypes);
3147         break;
3148     }
3149         
3150     case CheckStructureImmediate: {
3151         // FIXME: This currently can only reason about one structure at a time.
3152         // https://bugs.webkit.org/show_bug.cgi?id=136988
3153         
3154         AbstractValue& value = forNode(node->child1());
3155         const RegisteredStructureSet& set = node->structureSet();
3156         
3157         if (value.value()) {
3158             if (Structure* structure = jsDynamicCast<Structure*>(m_vm, value.value())) {
3159                 if (set.contains(m_graph.registerStructure(structure))) {
3160                     m_state.setFoundConstants(true);
3161                     break;
3162                 }
3163             }
3164             m_state.setIsValid(false);
3165             break;
3166         }
3167         
3168         if (m_phiChildren) {
3169             bool allGood = true;
3170             m_phiChildren->forAllTransitiveIncomingValues(
3171                 node,
3172                 [&] (Node* incoming) {
3173                     if (Structure* structure = incoming->dynamicCastConstant<Structure*>(m_vm)) {
3174                         if (set.contains(m_graph.registerStructure(structure)))
3175                             return;
3176                     }
3177                     allGood = false;
3178                 });
3179             if (allGood) {
3180                 m_state.setFoundConstants(true);
3181                 break;
3182             }
3183         }
3184             
3185         if (RegisteredStructure structure = set.onlyStructure()) {
3186             filterByValue(node->child1(), *m_graph.freeze(structure.get()));
3187             break;
3188         }
3189         
3190         // Aw shucks, we can't do anything!
3191         break;
3192     }
3193         
3194     case PutStructure:
3195         if (!forNode(node->child1()).m_structure.isClear()) {
3196             if (forNode(node->child1()).m_structure.onlyStructure() == node->transition()->next) {
3197                 didFoldClobberStructures();
3198                 m_state.setFoundConstants(true);
3199             } else {
3200                 observeTransition(
3201                     clobberLimit, node->transition()->previous, node->transition()->next);
3202                 forNode(node->child1()).changeStructure(m_graph, node->transition()->next);
3203             }
3204         } else {
3205             // We're going to exit before we get here, but for the sake of validation, we've folded our write to StructureID.
3206             didFoldClobberStructures();
3207         }
3208         break;
3209     case GetButterfly:
3210     case AllocatePropertyStorage:
3211     case ReallocatePropertyStorage:
3212     case NukeStructureAndSetButterfly:
3213         // FIXME: We don't model the fact that the structureID is nuked, simply because currently
3214         // nobody would currently benefit from having that information. But it's a bug nonetheless.
3215         if (node->op() == NukeStructureAndSetButterfly)
3216             didFoldClobberStructures();
3217         clearForNode(node); // The result is not a JS value.
3218         break;
3219     case CheckSubClass: {
3220         JSValue constant = forNode(node->child1()).value();
3221         if (constant) {
3222             if (constant.isCell() && constant.asCell()->inherits(m_vm, node->classInfo())) {
3223                 m_state.setFoundConstants(true);
3224                 ASSERT(constant);
3225                 break;
3226             }
3227         }
3228
3229         AbstractValue& value = forNode(node->child1());
3230
3231         if (value.m_structure.isSubClassOf(node->classInfo()))
3232             m_state.setFoundConstants(true);
3233
3234         filterClassInfo(value, node->classInfo());
3235         break;
3236     }
3237     case CallDOMGetter: {
3238         CallDOMGetterData* callDOMGetterData = node->callDOMGetterData();
3239         DOMJIT::CallDOMGetterSnippet* snippet = callDOMGetterData->snippet;
3240         if (!snippet || snippet->effect.writes)
3241             clobberWorld();
3242         if (callDOMGetterData->domJIT)
3243             setTypeForNode(node, callDOMGetterData->domJIT->resultType());
3244         else
3245             makeBytecodeTopForNode(node);
3246         break;
3247     }
3248     case CallDOM: {
3249         const DOMJIT::Signature* signature = node->signature();
3250         if (signature->effect.writes)
3251             clobberWorld();
3252         setTypeForNode(node, signature->result);
3253         break;
3254     }
3255     case CheckArray: {
3256         if (node->arrayMode().alreadyChecked(m_graph, node, forNode(node->child1()))) {
3257             m_state.setFoundConstants(true);
3258             break;
3259         }
3260         switch (node->arrayMode().type()) {
3261         case Array::String:
3262             filter(node->child1(), SpecString);
3263             break;
3264         case Array::Int32:
3265         case Array::Double:
3266         case Array::Contiguous:
3267         case Array::Undecided:
3268         case Array::ArrayStorage:
3269         case Array::SlowPutArrayStorage:
3270             break;
3271         case Array::DirectArguments:
3272             filter(node->child1(), SpecDirectArguments);
3273             break;
3274         case Array::ScopedArguments:
3275             filter(node->child1(), SpecScopedArguments);
3276             break;
3277         case Array::Int8Array:
3278             filter(node->child1(), SpecInt8Array);
3279             break;
3280         case Array::Int16Array:
3281             filter(node->child1(), SpecInt16Array);
3282             break;
3283         case Array::Int32Array:
3284             filter(node->child1(), SpecInt32Array);
3285             break;
3286         case Array::Uint8Array:
3287             filter(node->child1(), SpecUint8Array);
3288             break;
3289         case Array::Uint8ClampedArray:
3290             filter(node->child1(), SpecUint8ClampedArray);
3291             break;
3292         case Array::Uint16Array:
3293             filter(node->child1(), SpecUint16Array);
3294             break;
3295         case Array::Uint32Array:
3296             filter(node->child1(), SpecUint32Array);
3297             break;
3298         case Array::Float32Array:
3299             filter(node->child1(), SpecFloat32Array);
3300             break;
3301         case Array::Float64Array:
3302             filter(node->child1(), SpecFloat64Array);
3303             break;
3304         case Array::AnyTypedArray:
3305             filter(node->child1(), SpecTypedArrayView);
3306             break;
3307         default:
3308             RELEASE_ASSERT_NOT_REACHED();
3309             break;
3310         }
3311         filterArrayModes(node->child1(), node->arrayMode().arrayModesThatPassFiltering());
3312         break;
3313     }
3314     case Arrayify: {
3315         if (node->arrayMode().alreadyChecked(m_graph, node, forNode(node->child1()))) {
3316             didFoldClobberStructures();
3317             m_state.setFoundConstants(true);
3318             break;
3319         }
3320         ASSERT(node->arrayMode().conversion() == Array::Convert);
3321         clobberStructures();
3322         filterArrayModes(node->child1(), node->arrayMode().arrayModesThatPassFiltering());
3323         break;
3324     }
3325     case ArrayifyToStructure: {
3326         AbstractValue& value = forNode(node->child1());
3327         if (value.m_structure.isSubsetOf(RegisteredStructureSet(node->structure())))
3328             m_state.setFoundConstants(true);
3329         clobberStructures();
3330         
3331         // We have a bunch of options of how to express the abstract set at this point. Let set S
3332         // be the set of structures that the value had before clobbering and assume that all of
3333         // them are watchable. The new value should be the least expressible upper bound of the
3334         // intersection of "values that currently have structure = node->structure()" and "values
3335         // that have structure in S plus any structure transition-reachable from S". Assume that
3336         // node->structure() is not in S but it is transition-reachable from S. Then we would
3337         // like to say that the result is "values that have structure = node->structure() until
3338         // we invalidate", but there is no way to express this using the AbstractValue syntax. So
3339         // we must choose between:
3340         //
3341         // 1) "values that currently have structure = node->structure()". This is a valid
3342         //    superset of the value that we really want, and it's specific enough to satisfy the
3343         //    preconditions of the array access that this is guarding. It's also specific enough
3344         //    to allow relevant optimizations in the case that we didn't have a contradiction
3345         //    like in this example. Notice that in the abscence of any contradiction, this result
3346         //    is precise rather than being a conservative LUB.
3347         //
3348         // 2) "values that currently hava structure in S plus any structure transition-reachable
3349         //    from S". This is also a valid superset of the value that we really want, but it's
3350         //    not specific enough to satisfy the preconditions of the array access that this is
3351         //    guarding - so playing such shenanigans would preclude us from having assertions on
3352         //    the typing preconditions of any array accesses. This would also not be a desirable
3353         //    answer in the absence of a contradiction.
3354         //
3355         // Note that it's tempting to simply say that the resulting value is BOTTOM because of
3356         // the contradiction. That would be wrong, since we haven't hit an invalidation point,
3357         // yet.
3358         forNode(node->child1()).set(m_graph, node->structure());
3359         break;
3360     }
3361     case GetIndexedPropertyStorage: {
3362         JSArrayBufferView* view = m_graph.tryGetFoldableView(
3363             forNode(node->child1()).m_value, node->arrayMode());
3364         if (view)
3365             m_state.setFoundConstants(true);
3366         clearForNode(node);
3367         break;
3368     }
3369     case ConstantStoragePointer: {
3370         clearForNode(node);
3371         break; 
3372     }
3373         
3374     case GetTypedArrayByteOffset: {
3375         JSArrayBufferView* view = m_graph.tryGetFoldableView(forNode(node->child1()).m_value);
3376         if (view) {
3377             Optional<unsigned> byteOffset = view->byteOffsetConcurrently();
3378             if (byteOffset) {
3379                 setConstant(node, jsNumber(*byteOffset));
3380                 break;
3381             }
3382         }
3383         setNonCellTypeForNode(node, SpecInt32Only);
3384         break;
3385     }
3386
3387     case GetPrototypeOf: {
3388         AbstractValue& value = forNode(node->child1());
3389         if ((value.m_type && !(value.m_type & ~SpecObject)) && value.m_structure.isFinite()) {
3390             bool canFold = !value.m_structure.isClear();
3391             JSValue prototype;
3392             value.m_structure.forEach([&] (RegisteredStructure structure) {
3393                 auto getPrototypeMethod = structure->classInfo()->methodTable.getPrototype;
3394                 MethodTable::GetPrototypeFunctionPtr defaultGetPrototype = JSObject::getPrototype;
3395                 if (getPrototypeMethod != defaultGetPrototype) {
3396                     canFold = false;
3397                     return;
3398                 }
3399
3400                 if (structure->hasPolyProto()) {
3401                     canFold = false;
3402                     return;
3403                 }
3404                 if (!prototype)
3405                     prototype = structure->storedPrototype();
3406                 else if (prototype != structure->storedPrototype())
3407                     canFold = false;
3408             });
3409
3410             if (prototype && canFold) {
3411                 switch (node->child1().useKind()) {
3412                 case ArrayUse:
3413                 case FunctionUse:
3414                 case FinalObjectUse:
3415                     break;
3416                 default:
3417                     didFoldClobberWorld();
3418                     break;
3419                 }
3420                 setConstant(node, *m_graph.freeze(prototype));
3421                 break;
3422             }
3423         }
3424
3425         switch (node->child1().useKind()) {
3426         case ArrayUse:
3427         case FunctionUse:
3428         case FinalObjectUse:
3429             break;
3430         default:
3431             clobberWorld();
3432             break;
3433         }
3434         setTypeForNode(node, SpecObject | SpecOther);
3435         break;
3436     }
3437         
3438     case GetByOffset: {
3439         StorageAccessData& data = node->storageAccessData();
3440
3441         // FIXME: The part of this that handles inferred property types relies on AI knowing the structure
3442         // right now. That's probably not optimal. In some cases, we may perform an optimization (usually
3443         // by something other than AI, maybe by CSE for example) that obscures AI's view of the structure
3444         // at the point where GetByOffset runs. Currently, when that happens, we'll have to rely entirely
3445         // on the type that ByteCodeParser was able to prove.
3446         AbstractValue value = m_graph.inferredValueForProperty(
3447             forNode(node->child2()), data.offset, m_state.structureClobberState());
3448
3449         // If we decide that there does not exist any value that this can return, then it's probably
3450         // because the compilation was already invalidated.
3451         if (value.isClear())
3452             m_state.setIsValid(false);
3453
3454         setForNode(node, value);
3455         if (value.m_value)
3456             m_state.setFoundConstants(true);
3457         break;
3458     }
3459         
3460     case GetGetterSetterByOffset: {
3461         StorageAccessData& data = node->storageAccessData();
3462         AbstractValue base = forNode(node->child2());
3463         JSValue result = m_graph.tryGetConstantProperty(base, data.offset);
3464         if (result && jsDynamicCast<GetterSetter*>(m_vm, result)) {
3465             setConstant(node, *m_graph.freeze(result));
3466             break;
3467         }
3468         
3469         if (base.value() && base.value().isObject()) {