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