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