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