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