blob: cc05a94e852b79e5213242679d5d6ef5792c64af [file] [log] [blame]
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +00001/*
oliver@apple.com55d32d92013-07-25 04:05:03 +00002 * Copyright (C) 2013 Apple Inc. All rights reserved.
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +00003 *
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
oliver@apple.com55d32d92013-07-25 04:05:03 +000026#ifndef DFGAbstractInterpreterInlines_h
27#define DFGAbstractInterpreterInlines_h
28
29#include <wtf/Platform.h>
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +000030
31#if ENABLE(DFG_JIT)
32
oliver@apple.com55d32d92013-07-25 04:05:03 +000033#include "DFGAbstractInterpreter.h"
fpizlo@apple.comc2c67632012-11-17 08:37:14 +000034#include "GetByIdStatus.h"
oliver@apple.come722ad02013-01-09 02:37:29 +000035#include "Operations.h"
fpizlo@apple.comc2c67632012-11-17 08:37:14 +000036#include "PutByIdStatus.h"
fpizlo@apple.com0e6e1542013-03-18 18:09:22 +000037#include "StringObject.h"
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +000038
39namespace JSC { namespace DFG {
40
oliver@apple.com55d32d92013-07-25 04:05:03 +000041template<typename AbstractStateType>
42AbstractInterpreter<AbstractStateType>::AbstractInterpreter(Graph& graph, AbstractStateType& state)
fpizlo@apple.comadf274c2012-02-18 07:56:10 +000043 : m_codeBlock(graph.m_codeBlock)
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +000044 , m_graph(graph)
oliver@apple.com55d32d92013-07-25 04:05:03 +000045 , m_state(state)
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +000046{
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +000047}
48
oliver@apple.com55d32d92013-07-25 04:05:03 +000049template<typename AbstractStateType>
50AbstractInterpreter<AbstractStateType>::~AbstractInterpreter()
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +000051{
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +000052}
53
oliver@apple.com55d32d92013-07-25 04:05:03 +000054template<typename AbstractStateType>
55typename AbstractInterpreter<AbstractStateType>::BooleanResult
56AbstractInterpreter<AbstractStateType>::booleanResult(
57 Node* node, AbstractValue& value)
fpizlo@apple.com367a1102012-11-10 23:33:29 +000058{
59 JSValue childConst = value.value();
60 if (childConst) {
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +000061 if (childConst.toBoolean(m_codeBlock->globalObjectFor(node->codeOrigin)->globalExec()))
fpizlo@apple.com367a1102012-11-10 23:33:29 +000062 return DefinitelyTrue;
63 return DefinitelyFalse;
64 }
65
66 // Next check if we can fold because we know that the source is an object or string and does not equal undefined.
67 if (isCellSpeculation(value.m_type)
68 && value.m_currentKnownStructure.hasSingleton()) {
69 Structure* structure = value.m_currentKnownStructure.singleton();
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +000070 if (!structure->masqueradesAsUndefined(m_codeBlock->globalObjectFor(node->codeOrigin))
fpizlo@apple.com367a1102012-11-10 23:33:29 +000071 && structure->typeInfo().type() != StringType)
72 return DefinitelyTrue;
73 }
74
75 return UnknownBooleanResult;
76}
77
oliver@apple.com55d32d92013-07-25 04:05:03 +000078template<typename AbstractStateType>
79bool AbstractInterpreter<AbstractStateType>::startExecuting(Node* node)
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +000080{
oliver@apple.com55d32d92013-07-25 04:05:03 +000081 ASSERT(m_state.block());
82 ASSERT(m_state.isValid());
fpizlo@apple.comb75911b2012-06-13 20:53:52 +000083
oliver@apple.com55d32d92013-07-25 04:05:03 +000084 m_state.setDidClobber(false);
fpizlo@apple.comb75911b2012-06-13 20:53:52 +000085
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +000086 node->setCanExit(false);
87
oliver@apple.com96feafa2013-07-25 04:04:57 +000088 return node->shouldGenerate();
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +000089}
90
oliver@apple.com55d32d92013-07-25 04:05:03 +000091template<typename AbstractStateType>
92bool AbstractInterpreter<AbstractStateType>::startExecuting(unsigned indexInBlock)
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +000093{
oliver@apple.com55d32d92013-07-25 04:05:03 +000094 return startExecuting(m_state.block()->at(indexInBlock));
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +000095}
96
oliver@apple.com55d32d92013-07-25 04:05:03 +000097template<typename AbstractStateType>
98void AbstractInterpreter<AbstractStateType>::executeEdges(Node* node)
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +000099{
100 DFG_NODE_DO_TO_CHILDREN(m_graph, node, filterEdgeByUse);
101}
102
oliver@apple.com55d32d92013-07-25 04:05:03 +0000103template<typename AbstractStateType>
104void AbstractInterpreter<AbstractStateType>::executeEdges(unsigned indexInBlock)
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000105{
oliver@apple.com55d32d92013-07-25 04:05:03 +0000106 executeEdges(m_state.block()->at(indexInBlock));
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000107}
108
oliver@apple.com55d32d92013-07-25 04:05:03 +0000109template<typename AbstractStateType>
110void AbstractInterpreter<AbstractStateType>::verifyEdge(Node*, Edge edge)
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000111{
112 RELEASE_ASSERT(!(forNode(edge).m_type & ~typeFilterFor(edge.useKind())));
113}
114
oliver@apple.com55d32d92013-07-25 04:05:03 +0000115template<typename AbstractStateType>
116void AbstractInterpreter<AbstractStateType>::verifyEdges(Node* node)
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000117{
118 DFG_NODE_DO_TO_CHILDREN(m_graph, node, verifyEdge);
119}
120
oliver@apple.com55d32d92013-07-25 04:05:03 +0000121template<typename AbstractStateType>
oliver@apple.come17632e2013-07-25 04:05:31 +0000122bool AbstractInterpreter<AbstractStateType>::executeEffects(unsigned clobberLimit, Node* node)
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000123{
124 if (!ASSERT_DISABLED)
125 verifyEdges(node);
126
oliver@apple.com02e7a972013-07-25 04:05:04 +0000127 m_state.createValueForNode(node);
128
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +0000129 switch (node->op()) {
fpizlo@apple.com53aa8dc2011-11-15 21:54:38 +0000130 case JSConstant:
fpizlo@apple.com7e0f6502012-05-25 22:45:57 +0000131 case WeakJSConstant:
132 case PhantomArguments: {
oliver@apple.comfe0cc192013-07-25 03:58:58 +0000133 forNode(node).set(m_graph, m_graph.valueOfJSConstant(node));
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +0000134 break;
135 }
fpizlo@apple.com5d271712012-11-16 06:19:54 +0000136
137 case Identity: {
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +0000138 forNode(node) = forNode(node->child1());
fpizlo@apple.com5d271712012-11-16 06:19:54 +0000139 break;
140 }
oliver@apple.com827d2cf2013-07-25 04:04:45 +0000141
142 case GetArgument: {
143 ASSERT(m_graph.m_form == SSA);
144 VariableAccessData* variable = node->variableAccessData();
msaboff@apple.com62aa8b72013-09-26 22:53:54 +0000145 AbstractValue& value = m_state.variables().operand(variable->local().offset());
fpizlo@apple.comff779d02013-09-10 21:55:45 +0000146 ASSERT(value.isHeapTop());
oliver@apple.com827d2cf2013-07-25 04:04:45 +0000147 FiltrationResult result =
148 value.filter(typeFilterFor(useKindFor(variable->flushFormat())));
149 ASSERT_UNUSED(result, result == FiltrationOK);
150 forNode(node) = value;
151 break;
152 }
fpizlo@apple.com532f1e52013-09-04 06:26:04 +0000153
154 case ExtractOSREntryLocal: {
msaboff@apple.com62aa8b72013-09-26 22:53:54 +0000155 if (!(node->unlinkedLocal().isArgument())
156 && m_graph.m_lazyVars.get(node->unlinkedLocal().toLocal())) {
fpizlo@apple.com532f1e52013-09-04 06:26:04 +0000157 // This is kind of pessimistic - we could know in some cases that the
158 // DFG code at the point of the OSR had already initialized the lazy
159 // variable. But maybe this is fine, since we're inserting OSR
160 // entrypoints very early in the pipeline - so any lazy initializations
161 // ought to be hoisted out anyway.
fpizlo@apple.comff779d02013-09-10 21:55:45 +0000162 forNode(node).makeBytecodeTop();
163 } else
164 forNode(node).makeHeapTop();
fpizlo@apple.com532f1e52013-09-04 06:26:04 +0000165 break;
166 }
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +0000167
168 case GetLocal: {
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +0000169 VariableAccessData* variableAccessData = node->variableAccessData();
fpizlo@apple.comb75911b2012-06-13 20:53:52 +0000170 if (variableAccessData->prediction() == SpecNone) {
oliver@apple.com55d32d92013-07-25 04:05:03 +0000171 m_state.setIsValid(false);
fpizlo@apple.comb75911b2012-06-13 20:53:52 +0000172 break;
173 }
msaboff@apple.com62aa8b72013-09-26 22:53:54 +0000174 AbstractValue value = m_state.variables().operand(variableAccessData->local().offset());
fpizlo@apple.com8e537cd2012-06-01 23:54:36 +0000175 if (!variableAccessData->isCaptured()) {
fpizlo@apple.com91b2c682012-05-24 06:24:36 +0000176 if (value.isClear())
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000177 node->setCanExit(true);
fpizlo@apple.com91b2c682012-05-24 06:24:36 +0000178 }
fpizlo@apple.com8e537cd2012-06-01 23:54:36 +0000179 if (value.value())
oliver@apple.com55d32d92013-07-25 04:05:03 +0000180 m_state.setFoundConstants(true);
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +0000181 forNode(node) = value;
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +0000182 break;
183 }
184
fpizlo@apple.com9b928722012-05-24 00:18:55 +0000185 case GetLocalUnlinked: {
msaboff@apple.com62aa8b72013-09-26 22:53:54 +0000186 AbstractValue value = m_state.variables().operand(node->unlinkedLocal().offset());
fpizlo@apple.com8e537cd2012-06-01 23:54:36 +0000187 if (value.value())
oliver@apple.com55d32d92013-07-25 04:05:03 +0000188 m_state.setFoundConstants(true);
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +0000189 forNode(node) = value;
fpizlo@apple.com9b928722012-05-24 00:18:55 +0000190 break;
191 }
192
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +0000193 case SetLocal: {
msaboff@apple.com62aa8b72013-09-26 22:53:54 +0000194 m_state.variables().operand(node->local().offset()) = forNode(node->child1());
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +0000195 break;
196 }
fpizlo@apple.com06f82b52013-03-06 02:27:16 +0000197
oliver@apple.com827d2cf2013-07-25 04:04:45 +0000198 case MovHint:
fpizlo@apple.com06f82b52013-03-06 02:27:16 +0000199 case MovHintAndCheck: {
200 // Don't need to do anything. A MovHint is effectively a promise that the SetLocal
201 // was dead.
202 break;
203 }
204
fpizlo@apple.com06f82b52013-03-06 02:27:16 +0000205 case ZombieHint: {
206 RELEASE_ASSERT_NOT_REACHED();
207 break;
208 }
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +0000209
210 case SetArgument:
211 // Assert that the state of arguments has been set.
oliver@apple.com55d32d92013-07-25 04:05:03 +0000212 ASSERT(!m_state.block()->valuesAtHead.operand(node->local()).isClear());
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +0000213 break;
214
215 case BitAnd:
216 case BitOr:
217 case BitXor:
218 case BitRShift:
219 case BitLShift:
fpizlo@apple.com3187c922012-05-18 21:47:53 +0000220 case BitURShift: {
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +0000221 JSValue left = forNode(node->child1()).value();
222 JSValue right = forNode(node->child2()).value();
fpizlo@apple.com3187c922012-05-18 21:47:53 +0000223 if (left && right && left.isInt32() && right.isInt32()) {
224 int32_t a = left.asInt32();
225 int32_t b = right.asInt32();
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +0000226 switch (node->op()) {
fpizlo@apple.com3187c922012-05-18 21:47:53 +0000227 case BitAnd:
fpizlo@apple.com49e37d32013-09-11 21:49:47 +0000228 setConstant(node, JSValue(a & b));
fpizlo@apple.com3187c922012-05-18 21:47:53 +0000229 break;
230 case BitOr:
fpizlo@apple.com49e37d32013-09-11 21:49:47 +0000231 setConstant(node, JSValue(a | b));
fpizlo@apple.com3187c922012-05-18 21:47:53 +0000232 break;
233 case BitXor:
fpizlo@apple.com49e37d32013-09-11 21:49:47 +0000234 setConstant(node, JSValue(a ^ b));
fpizlo@apple.com3187c922012-05-18 21:47:53 +0000235 break;
236 case BitRShift:
fpizlo@apple.com49e37d32013-09-11 21:49:47 +0000237 setConstant(node, JSValue(a >> static_cast<uint32_t>(b)));
fpizlo@apple.com3187c922012-05-18 21:47:53 +0000238 break;
239 case BitLShift:
fpizlo@apple.com49e37d32013-09-11 21:49:47 +0000240 setConstant(node, JSValue(a << static_cast<uint32_t>(b)));
fpizlo@apple.com3187c922012-05-18 21:47:53 +0000241 break;
242 case BitURShift:
fpizlo@apple.com49e37d32013-09-11 21:49:47 +0000243 setConstant(node, JSValue(static_cast<uint32_t>(a) >> static_cast<uint32_t>(b)));
fpizlo@apple.com3187c922012-05-18 21:47:53 +0000244 break;
245 default:
oliver@apple.com5598c182013-01-23 22:25:07 +0000246 RELEASE_ASSERT_NOT_REACHED();
fpizlo@apple.comcacd7dc2012-07-09 23:28:53 +0000247 break;
248 }
fpizlo@apple.com49e37d32013-09-11 21:49:47 +0000249 break;
fpizlo@apple.com3187c922012-05-18 21:47:53 +0000250 }
oliver@apple.comfe0cc192013-07-25 03:58:58 +0000251 forNode(node).setType(SpecInt32);
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +0000252 break;
fpizlo@apple.com3187c922012-05-18 21:47:53 +0000253 }
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +0000254
fpizlo@apple.com3187c922012-05-18 21:47:53 +0000255 case UInt32ToNumber: {
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +0000256 JSValue child = forNode(node->child1()).value();
fpizlo@apple.com3187c922012-05-18 21:47:53 +0000257 if (child && child.isNumber()) {
258 ASSERT(child.isInt32());
fpizlo@apple.com49e37d32013-09-11 21:49:47 +0000259 setConstant(node, JSValue(child.asUInt32()));
260 break;
fpizlo@apple.com3187c922012-05-18 21:47:53 +0000261 }
fpizlo@apple.comefacb612013-09-10 22:16:00 +0000262 if (!node->canSpeculateInt32())
oliver@apple.comfe0cc192013-07-25 03:58:58 +0000263 forNode(node).setType(SpecDouble);
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000264 else {
oliver@apple.comfe0cc192013-07-25 03:58:58 +0000265 forNode(node).setType(SpecInt32);
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +0000266 node->setCanExit(true);
fpizlo@apple.com91b2c682012-05-24 06:24:36 +0000267 }
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +0000268 break;
fpizlo@apple.com3187c922012-05-18 21:47:53 +0000269 }
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +0000270
fpizlo@apple.com3187c922012-05-18 21:47:53 +0000271 case DoubleAsInt32: {
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +0000272 JSValue child = forNode(node->child1()).value();
fpizlo@apple.com3187c922012-05-18 21:47:53 +0000273 if (child && child.isNumber()) {
274 double asDouble = child.asNumber();
275 int32_t asInt = JSC::toInt32(asDouble);
fpizlo@apple.com49e37d32013-09-11 21:49:47 +0000276 if (bitwise_cast<int64_t>(static_cast<double>(asInt)) == bitwise_cast<int64_t>(asDouble)) {
277 setConstant(node, JSValue(asInt));
fpizlo@apple.com3187c922012-05-18 21:47:53 +0000278 break;
279 }
280 }
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +0000281 node->setCanExit(true);
oliver@apple.comfe0cc192013-07-25 03:58:58 +0000282 forNode(node).setType(SpecInt32);
fpizlo@apple.com3d223382012-04-24 19:19:35 +0000283 break;
fpizlo@apple.com3187c922012-05-18 21:47:53 +0000284 }
fpizlo@apple.com3d223382012-04-24 19:19:35 +0000285
fpizlo@apple.com3187c922012-05-18 21:47:53 +0000286 case ValueToInt32: {
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +0000287 JSValue child = forNode(node->child1()).value();
commit-queue@webkit.orga4990a52013-10-03 08:43:07 +0000288 if (child) {
289 if (child.isNumber()) {
290 if (child.isInt32())
291 setConstant(node, child);
292 else
293 setConstant(node, JSValue(JSC::toInt32(child.asDouble())));
294 break;
295 }
296 if (child.isBoolean()) {
297 setConstant(node, JSValue(child.asBoolean()));
298 break;
299 }
fpizlo@apple.com3187c922012-05-18 21:47:53 +0000300 }
fpizlo@apple.com9c7addf2012-03-08 10:01:32 +0000301
oliver@apple.comfe0cc192013-07-25 03:58:58 +0000302 forNode(node).setType(SpecInt32);
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +0000303 break;
fpizlo@apple.com3187c922012-05-18 21:47:53 +0000304 }
oliver@apple.com500b53a2013-07-25 04:05:25 +0000305
306 case Int32ToDouble: {
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +0000307 JSValue child = forNode(node->child1()).value();
fpizlo@apple.com49e37d32013-09-11 21:49:47 +0000308 if (child && child.isNumber()) {
309 setConstant(node, JSValue(JSValue::EncodeAsDouble, child.asNumber()));
fpizlo@apple.com3187c922012-05-18 21:47:53 +0000310 break;
311 }
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +0000312 if (isInt32Speculation(forNode(node->child1()).m_type))
oliver@apple.comfe0cc192013-07-25 03:58:58 +0000313 forNode(node).setType(SpecDoubleReal);
fpizlo@apple.com75c91a72012-11-08 22:28:25 +0000314 else
oliver@apple.comfe0cc192013-07-25 03:58:58 +0000315 forNode(node).setType(SpecDouble);
fpizlo@apple.com96cfc6b2012-03-25 23:50:24 +0000316 break;
fpizlo@apple.com3187c922012-05-18 21:47:53 +0000317 }
fpizlo@apple.coma1cc0fd2012-04-24 20:43:01 +0000318
fpizlo@apple.com6921b292013-09-18 17:14:02 +0000319 case Int52ToDouble: {
320 JSValue child = forNode(node->child1()).value();
321 if (child && child.isNumber()) {
322 setConstant(node, child);
323 break;
324 }
325 forNode(node).setType(SpecDouble);
326 break;
327 }
328
329 case Int52ToValue: {
330 JSValue child = forNode(node->child1()).value();
331 if (child && child.isNumber()) {
332 setConstant(node, child);
333 break;
334 }
335 SpeculatedType type = forNode(node->child1()).m_type;
336 if (type & SpecInt52)
337 type = (type | SpecInt32 | SpecInt52AsDouble) & ~SpecInt52;
338 forNode(node).setType(type);
339 break;
340 }
341
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +0000342 case ValueAdd:
343 case ArithAdd: {
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +0000344 JSValue left = forNode(node->child1()).value();
345 JSValue right = forNode(node->child2()).value();
fpizlo@apple.com49e37d32013-09-11 21:49:47 +0000346 if (left && right && left.isNumber() && right.isNumber()) {
347 setConstant(node, JSValue(left.asNumber() + right.asNumber()));
fpizlo@apple.com3187c922012-05-18 21:47:53 +0000348 break;
349 }
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000350 switch (node->binaryUseKind()) {
351 case Int32Use:
oliver@apple.comfe0cc192013-07-25 03:58:58 +0000352 forNode(node).setType(SpecInt32);
fpizlo@apple.comdc36e832013-09-11 03:24:09 +0000353 if (!bytecodeCanTruncateInteger(node->arithNodeFlags()))
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000354 node->setCanExit(true);
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +0000355 break;
fpizlo@apple.com6921b292013-09-18 17:14:02 +0000356 case MachineIntUse:
357 forNode(node).setType(SpecInt52);
358 if (!forNode(node->child1()).isType(SpecInt32)
359 || !forNode(node->child2()).isType(SpecInt32))
360 node->setCanExit(true);
361 break;
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000362 case NumberUse:
fpizlo@apple.com6921b292013-09-18 17:14:02 +0000363 if (isFullRealNumberSpeculation(forNode(node->child1()).m_type)
364 && isFullRealNumberSpeculation(forNode(node->child2()).m_type))
oliver@apple.comfe0cc192013-07-25 03:58:58 +0000365 forNode(node).setType(SpecDoubleReal);
fpizlo@apple.com75c91a72012-11-08 22:28:25 +0000366 else
oliver@apple.comfe0cc192013-07-25 03:58:58 +0000367 forNode(node).setType(SpecDouble);
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +0000368 break;
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000369 default:
370 RELEASE_ASSERT(node->op() == ValueAdd);
oliver@apple.come17632e2013-07-25 04:05:31 +0000371 clobberWorld(node->codeOrigin, clobberLimit);
fpizlo@apple.com6921b292013-09-18 17:14:02 +0000372 forNode(node).setType(SpecString | SpecBytecodeNumber);
fpizlo@apple.comc0d21912012-02-14 21:26:26 +0000373 break;
374 }
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +0000375 break;
376 }
fpizlo@apple.com4463e442013-03-20 20:29:37 +0000377
378 case MakeRope: {
oliver@apple.comfe0cc192013-07-25 03:58:58 +0000379 forNode(node).set(m_graph, m_graph.m_vm.stringStructure.get());
fpizlo@apple.com4463e442013-03-20 20:29:37 +0000380 break;
381 }
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +0000382
fpizlo@apple.com0c31ace2012-02-01 23:08:54 +0000383 case ArithSub: {
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +0000384 JSValue left = forNode(node->child1()).value();
385 JSValue right = forNode(node->child2()).value();
fpizlo@apple.com49e37d32013-09-11 21:49:47 +0000386 if (left && right && left.isNumber() && right.isNumber()) {
387 setConstant(node, JSValue(left.asNumber() - right.asNumber()));
fpizlo@apple.com3187c922012-05-18 21:47:53 +0000388 break;
389 }
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000390 switch (node->binaryUseKind()) {
391 case Int32Use:
oliver@apple.comfe0cc192013-07-25 03:58:58 +0000392 forNode(node).setType(SpecInt32);
fpizlo@apple.comdc36e832013-09-11 03:24:09 +0000393 if (!bytecodeCanTruncateInteger(node->arithNodeFlags()))
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000394 node->setCanExit(true);
395 break;
fpizlo@apple.com6921b292013-09-18 17:14:02 +0000396 case MachineIntUse:
397 forNode(node).setType(SpecInt52);
398 if (!forNode(node->child1()).isType(SpecInt32)
399 || !forNode(node->child2()).isType(SpecInt32))
400 node->setCanExit(true);
401 break;
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000402 case NumberUse:
oliver@apple.comfe0cc192013-07-25 03:58:58 +0000403 forNode(node).setType(SpecDouble);
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000404 break;
405 default:
406 RELEASE_ASSERT_NOT_REACHED();
fpizlo@apple.com0c31ace2012-02-01 23:08:54 +0000407 break;
408 }
fpizlo@apple.com0c31ace2012-02-01 23:08:54 +0000409 break;
410 }
411
barraclough@apple.com8ff7e8c2012-02-28 00:31:28 +0000412 case ArithNegate: {
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +0000413 JSValue child = forNode(node->child1()).value();
fpizlo@apple.com49e37d32013-09-11 21:49:47 +0000414 if (child && child.isNumber()) {
415 setConstant(node, JSValue(-child.asNumber()));
fpizlo@apple.com3187c922012-05-18 21:47:53 +0000416 break;
417 }
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000418 switch (node->child1().useKind()) {
419 case Int32Use:
oliver@apple.comfe0cc192013-07-25 03:58:58 +0000420 forNode(node).setType(SpecInt32);
fpizlo@apple.comdc36e832013-09-11 03:24:09 +0000421 if (!bytecodeCanTruncateInteger(node->arithNodeFlags()))
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000422 node->setCanExit(true);
423 break;
fpizlo@apple.com6921b292013-09-18 17:14:02 +0000424 case MachineIntUse:
425 forNode(node).setType(SpecInt52);
426 if (m_state.forNode(node->child1()).couldBeType(SpecInt52))
427 node->setCanExit(true);
428 if (!bytecodeCanIgnoreNegativeZero(node->arithNodeFlags()))
429 node->setCanExit(true);
430 break;
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000431 case NumberUse:
oliver@apple.comfe0cc192013-07-25 03:58:58 +0000432 forNode(node).setType(SpecDouble);
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000433 break;
434 default:
435 RELEASE_ASSERT_NOT_REACHED();
barraclough@apple.com8ff7e8c2012-02-28 00:31:28 +0000436 break;
437 }
barraclough@apple.com8ff7e8c2012-02-28 00:31:28 +0000438 break;
439 }
440
fpizlo@apple.comfa9f10c2012-05-22 17:18:21 +0000441 case ArithMul: {
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +0000442 JSValue left = forNode(node->child1()).value();
443 JSValue right = forNode(node->child2()).value();
fpizlo@apple.com49e37d32013-09-11 21:49:47 +0000444 if (left && right && left.isNumber() && right.isNumber()) {
445 setConstant(node, JSValue(left.asNumber() * right.asNumber()));
fpizlo@apple.comfa9f10c2012-05-22 17:18:21 +0000446 break;
447 }
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000448 switch (node->binaryUseKind()) {
449 case Int32Use:
oliver@apple.comfe0cc192013-07-25 03:58:58 +0000450 forNode(node).setType(SpecInt32);
fpizlo@apple.comdc36e832013-09-11 03:24:09 +0000451 if (!bytecodeCanTruncateInteger(node->arithNodeFlags())
452 || !bytecodeCanIgnoreNegativeZero(node->arithNodeFlags()))
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000453 node->setCanExit(true);
454 break;
fpizlo@apple.com6921b292013-09-18 17:14:02 +0000455 case MachineIntUse:
456 forNode(node).setType(SpecInt52);
457 node->setCanExit(true);
458 break;
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000459 case NumberUse:
fpizlo@apple.com6921b292013-09-18 17:14:02 +0000460 if (isFullRealNumberSpeculation(forNode(node->child1()).m_type)
461 || isFullRealNumberSpeculation(forNode(node->child2()).m_type))
oliver@apple.comfe0cc192013-07-25 03:58:58 +0000462 forNode(node).setType(SpecDoubleReal);
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000463 else
oliver@apple.comfe0cc192013-07-25 03:58:58 +0000464 forNode(node).setType(SpecDouble);
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000465 break;
466 default:
467 RELEASE_ASSERT_NOT_REACHED();
fpizlo@apple.comfa9f10c2012-05-22 17:18:21 +0000468 break;
469 }
fpizlo@apple.comfa9f10c2012-05-22 17:18:21 +0000470 break;
471 }
oliver@apple.com64367322013-04-26 00:41:38 +0000472
473 case ArithIMul: {
oliver@apple.com67e0f332013-07-25 03:59:00 +0000474 forNode(node).setType(SpecInt32);
oliver@apple.com64367322013-04-26 00:41:38 +0000475 break;
476 }
fpizlo@apple.comfa9f10c2012-05-22 17:18:21 +0000477
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +0000478 case ArithDiv:
479 case ArithMin:
fpizlo@apple.com19a172792012-03-24 20:15:57 +0000480 case ArithMax:
481 case ArithMod: {
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +0000482 JSValue left = forNode(node->child1()).value();
483 JSValue right = forNode(node->child2()).value();
fpizlo@apple.com49e37d32013-09-11 21:49:47 +0000484 if (node->op() == ArithMod && right && right.isNumber() && right.asNumber() == 1) {
485 setConstant(node, JSValue(0));
oliver@apple.comf4443a72013-07-25 04:01:11 +0000486 break;
487 }
fpizlo@apple.com3187c922012-05-18 21:47:53 +0000488 if (left && right && left.isNumber() && right.isNumber()) {
489 double a = left.asNumber();
490 double b = right.asNumber();
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +0000491 switch (node->op()) {
fpizlo@apple.com3187c922012-05-18 21:47:53 +0000492 case ArithDiv:
fpizlo@apple.com49e37d32013-09-11 21:49:47 +0000493 setConstant(node, JSValue(a / b));
fpizlo@apple.com3187c922012-05-18 21:47:53 +0000494 break;
495 case ArithMin:
fpizlo@apple.com49e37d32013-09-11 21:49:47 +0000496 setConstant(node, JSValue(a < b ? a : (b <= a ? b : a + b)));
fpizlo@apple.com3187c922012-05-18 21:47:53 +0000497 break;
498 case ArithMax:
fpizlo@apple.com49e37d32013-09-11 21:49:47 +0000499 setConstant(node, JSValue(a > b ? a : (b >= a ? b : a + b)));
fpizlo@apple.com3187c922012-05-18 21:47:53 +0000500 break;
501 case ArithMod:
fpizlo@apple.com49e37d32013-09-11 21:49:47 +0000502 setConstant(node, JSValue(fmod(a, b)));
fpizlo@apple.com3187c922012-05-18 21:47:53 +0000503 break;
504 default:
oliver@apple.com5598c182013-01-23 22:25:07 +0000505 RELEASE_ASSERT_NOT_REACHED();
fpizlo@apple.com3187c922012-05-18 21:47:53 +0000506 break;
507 }
fpizlo@apple.com49e37d32013-09-11 21:49:47 +0000508 break;
fpizlo@apple.com3187c922012-05-18 21:47:53 +0000509 }
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000510 switch (node->binaryUseKind()) {
511 case Int32Use:
oliver@apple.comfe0cc192013-07-25 03:58:58 +0000512 forNode(node).setType(SpecInt32);
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000513 node->setCanExit(true);
514 break;
515 case NumberUse:
oliver@apple.comfe0cc192013-07-25 03:58:58 +0000516 forNode(node).setType(SpecDouble);
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000517 break;
518 default:
519 RELEASE_ASSERT_NOT_REACHED();
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +0000520 break;
521 }
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +0000522 break;
523 }
524
fpizlo@apple.com3187c922012-05-18 21:47:53 +0000525 case ArithAbs: {
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +0000526 JSValue child = forNode(node->child1()).value();
fpizlo@apple.com49e37d32013-09-11 21:49:47 +0000527 if (child && child.isNumber()) {
528 setConstant(node, JSValue(fabs(child.asNumber())));
fpizlo@apple.com3187c922012-05-18 21:47:53 +0000529 break;
530 }
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000531 switch (node->child1().useKind()) {
532 case Int32Use:
oliver@apple.comfe0cc192013-07-25 03:58:58 +0000533 forNode(node).setType(SpecInt32);
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000534 node->setCanExit(true);
535 break;
536 case NumberUse:
oliver@apple.comfe0cc192013-07-25 03:58:58 +0000537 forNode(node).setType(SpecDouble);
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000538 break;
539 default:
540 RELEASE_ASSERT_NOT_REACHED();
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +0000541 break;
542 }
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +0000543 break;
fpizlo@apple.com3187c922012-05-18 21:47:53 +0000544 }
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +0000545
fpizlo@apple.com3187c922012-05-18 21:47:53 +0000546 case ArithSqrt: {
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +0000547 JSValue child = forNode(node->child1()).value();
fpizlo@apple.com49e37d32013-09-11 21:49:47 +0000548 if (child && child.isNumber()) {
549 setConstant(node, JSValue(sqrt(child.asNumber())));
fpizlo@apple.com3187c922012-05-18 21:47:53 +0000550 break;
551 }
oliver@apple.comfe0cc192013-07-25 03:58:58 +0000552 forNode(node).setType(SpecDouble);
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +0000553 break;
fpizlo@apple.com3187c922012-05-18 21:47:53 +0000554 }
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +0000555
556 case LogicalNot: {
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +0000557 switch (booleanResult(node, forNode(node->child1()))) {
fpizlo@apple.com367a1102012-11-10 23:33:29 +0000558 case DefinitelyTrue:
fpizlo@apple.com49e37d32013-09-11 21:49:47 +0000559 setConstant(node, jsBoolean(false));
fpizlo@apple.com367a1102012-11-10 23:33:29 +0000560 break;
561 case DefinitelyFalse:
fpizlo@apple.com49e37d32013-09-11 21:49:47 +0000562 setConstant(node, jsBoolean(true));
fpizlo@apple.com367a1102012-11-10 23:33:29 +0000563 break;
564 default:
fpizlo@apple.com49e37d32013-09-11 21:49:47 +0000565 switch (node->child1().useKind()) {
566 case BooleanUse:
567 case Int32Use:
568 case NumberUse:
569 case UntypedUse:
570 break;
571 case ObjectOrOtherUse:
572 node->setCanExit(true);
573 break;
574 default:
575 RELEASE_ASSERT_NOT_REACHED();
576 break;
577 }
578 forNode(node).setType(SpecBoolean);
fpizlo@apple.com367a1102012-11-10 23:33:29 +0000579 break;
580 }
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +0000581 break;
582 }
fpizlo@apple.com1d216892012-04-12 00:55:44 +0000583
584 case IsUndefined:
585 case IsBoolean:
586 case IsNumber:
587 case IsString:
588 case IsObject:
589 case IsFunction: {
oliver@apple.com67e0f332013-07-25 03:59:00 +0000590 node->setCanExit(
591 node->op() == IsUndefined
592 && m_graph.masqueradesAsUndefinedWatchpointIsStillValid(node->codeOrigin));
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +0000593 JSValue child = forNode(node->child1()).value();
fpizlo@apple.com3187c922012-05-18 21:47:53 +0000594 if (child) {
fpizlo@apple.com49e37d32013-09-11 21:49:47 +0000595 bool constantWasSet = true;
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +0000596 switch (node->op()) {
fpizlo@apple.com3187c922012-05-18 21:47:53 +0000597 case IsUndefined:
fpizlo@apple.com49e37d32013-09-11 21:49:47 +0000598 setConstant(node, jsBoolean(
oliver@apple.com67e0f332013-07-25 03:59:00 +0000599 child.isCell()
600 ? child.asCell()->structure()->masqueradesAsUndefined(m_codeBlock->globalObjectFor(node->codeOrigin))
601 : child.isUndefined()));
fpizlo@apple.com3187c922012-05-18 21:47:53 +0000602 break;
603 case IsBoolean:
fpizlo@apple.com49e37d32013-09-11 21:49:47 +0000604 setConstant(node, jsBoolean(child.isBoolean()));
fpizlo@apple.com3187c922012-05-18 21:47:53 +0000605 break;
606 case IsNumber:
fpizlo@apple.com49e37d32013-09-11 21:49:47 +0000607 setConstant(node, jsBoolean(child.isNumber()));
fpizlo@apple.com3187c922012-05-18 21:47:53 +0000608 break;
609 case IsString:
fpizlo@apple.com49e37d32013-09-11 21:49:47 +0000610 setConstant(node, jsBoolean(isJSString(child)));
fpizlo@apple.com3187c922012-05-18 21:47:53 +0000611 break;
oliver@apple.come722ad02013-01-09 02:37:29 +0000612 case IsObject:
613 if (child.isNull() || !child.isObject()) {
fpizlo@apple.com49e37d32013-09-11 21:49:47 +0000614 setConstant(node, jsBoolean(child.isNull()));
oliver@apple.come722ad02013-01-09 02:37:29 +0000615 break;
616 }
fpizlo@apple.com49e37d32013-09-11 21:49:47 +0000617 constantWasSet = false;
618 break;
fpizlo@apple.com3187c922012-05-18 21:47:53 +0000619 default:
fpizlo@apple.comcacd7dc2012-07-09 23:28:53 +0000620 constantWasSet = false;
fpizlo@apple.com3187c922012-05-18 21:47:53 +0000621 break;
622 }
fpizlo@apple.com49e37d32013-09-11 21:49:47 +0000623 if (constantWasSet)
fpizlo@apple.com3187c922012-05-18 21:47:53 +0000624 break;
fpizlo@apple.com3187c922012-05-18 21:47:53 +0000625 }
oliver@apple.come722ad02013-01-09 02:37:29 +0000626
oliver@apple.comfe0cc192013-07-25 03:58:58 +0000627 forNode(node).setType(SpecBoolean);
fpizlo@apple.com1d216892012-04-12 00:55:44 +0000628 break;
629 }
oliver@apple.come722ad02013-01-09 02:37:29 +0000630
631 case TypeOf: {
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +0000632 VM* vm = m_codeBlock->vm();
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +0000633 JSValue child = forNode(node->child1()).value();
634 AbstractValue& abstractChild = forNode(node->child1());
oliver@apple.come722ad02013-01-09 02:37:29 +0000635 if (child) {
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +0000636 JSValue typeString = jsTypeStringForValue(*vm, m_codeBlock->globalObjectFor(node->codeOrigin), child);
fpizlo@apple.com49e37d32013-09-11 21:49:47 +0000637 setConstant(node, typeString);
638 break;
639 }
640
fpizlo@apple.com6921b292013-09-18 17:14:02 +0000641 if (isFullNumberSpeculation(abstractChild.m_type)) {
fpizlo@apple.com49e37d32013-09-11 21:49:47 +0000642 setConstant(node, vm->smallStrings.numberString());
643 break;
644 }
645
646 if (isStringSpeculation(abstractChild.m_type)) {
647 setConstant(node, vm->smallStrings.stringString());
648 break;
649 }
650
651 if (isFinalObjectSpeculation(abstractChild.m_type) || isArraySpeculation(abstractChild.m_type) || isArgumentsSpeculation(abstractChild.m_type)) {
652 setConstant(node, vm->smallStrings.objectString());
653 break;
654 }
655
656 if (isFunctionSpeculation(abstractChild.m_type)) {
657 setConstant(node, vm->smallStrings.functionString());
658 break;
659 }
660
661 if (isBooleanSpeculation(abstractChild.m_type)) {
662 setConstant(node, vm->smallStrings.booleanString());
663 break;
fpizlo@apple.comcd81b572013-02-11 21:39:35 +0000664 }
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000665
666 switch (node->child1().useKind()) {
667 case StringUse:
668 case CellUse:
fpizlo@apple.comcd81b572013-02-11 21:39:35 +0000669 node->setCanExit(true);
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000670 break;
671 case UntypedUse:
672 break;
673 default:
674 RELEASE_ASSERT_NOT_REACHED();
675 break;
oliver@apple.come722ad02013-01-09 02:37:29 +0000676 }
oliver@apple.comfe0cc192013-07-25 03:58:58 +0000677 forNode(node).set(m_graph, m_graph.m_vm.stringStructure.get());
oliver@apple.come722ad02013-01-09 02:37:29 +0000678 break;
679 }
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +0000680
681 case CompareLess:
682 case CompareLessEq:
683 case CompareGreater:
684 case CompareGreaterEq:
fpizlo@apple.comb03b1402013-02-11 22:23:08 +0000685 case CompareEq:
686 case CompareEqConstant: {
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +0000687 JSValue leftConst = forNode(node->child1()).value();
688 JSValue rightConst = forNode(node->child2()).value();
oliver@apple.combd15be82013-07-25 04:03:42 +0000689 if (leftConst && rightConst) {
690 if (leftConst.isNumber() && rightConst.isNumber()) {
691 double a = leftConst.asNumber();
692 double b = rightConst.asNumber();
693 switch (node->op()) {
694 case CompareLess:
fpizlo@apple.com49e37d32013-09-11 21:49:47 +0000695 setConstant(node, jsBoolean(a < b));
oliver@apple.combd15be82013-07-25 04:03:42 +0000696 break;
697 case CompareLessEq:
fpizlo@apple.com49e37d32013-09-11 21:49:47 +0000698 setConstant(node, jsBoolean(a <= b));
oliver@apple.combd15be82013-07-25 04:03:42 +0000699 break;
700 case CompareGreater:
fpizlo@apple.com49e37d32013-09-11 21:49:47 +0000701 setConstant(node, jsBoolean(a > b));
oliver@apple.combd15be82013-07-25 04:03:42 +0000702 break;
703 case CompareGreaterEq:
fpizlo@apple.com49e37d32013-09-11 21:49:47 +0000704 setConstant(node, jsBoolean(a >= b));
oliver@apple.combd15be82013-07-25 04:03:42 +0000705 break;
706 case CompareEq:
fpizlo@apple.com49e37d32013-09-11 21:49:47 +0000707 setConstant(node, jsBoolean(a == b));
oliver@apple.combd15be82013-07-25 04:03:42 +0000708 break;
709 default:
710 RELEASE_ASSERT_NOT_REACHED();
fpizlo@apple.com49e37d32013-09-11 21:49:47 +0000711 break;
712 }
713 break;
714 }
715
716 if (node->op() == CompareEq && leftConst.isString() && rightConst.isString()) {
717 const StringImpl* a = asString(leftConst)->tryGetValueImpl();
718 const StringImpl* b = asString(rightConst)->tryGetValueImpl();
719 if (a && b) {
720 setConstant(node, jsBoolean(WTF::equal(a, b)));
oliver@apple.combd15be82013-07-25 04:03:42 +0000721 break;
722 }
723 }
fpizlo@apple.comf884bb72012-11-09 01:57:14 +0000724 }
725
fpizlo@apple.com49e37d32013-09-11 21:49:47 +0000726 if (node->op() == CompareEqConstant || node->op() == CompareEq) {
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +0000727 SpeculatedType leftType = forNode(node->child1()).m_type;
728 SpeculatedType rightType = forNode(node->child2()).m_type;
fpizlo@apple.comf884bb72012-11-09 01:57:14 +0000729 if ((isInt32Speculation(leftType) && isOtherSpeculation(rightType))
fpizlo@apple.com49e37d32013-09-11 21:49:47 +0000730 || (isOtherSpeculation(leftType) && isInt32Speculation(rightType))) {
731 setConstant(node, jsBoolean(false));
732 break;
733 }
fpizlo@apple.com3187c922012-05-18 21:47:53 +0000734 }
735
oliver@apple.comfe0cc192013-07-25 03:58:58 +0000736 forNode(node).setType(SpecBoolean);
fpizlo@apple.com8b7cf382012-03-31 02:21:35 +0000737
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000738 // This is overly conservative. But the only thing this prevents is store elimination,
739 // and how likely is it, really, that you'll have redundant stores across a comparison
740 // operation? Comparison operations are typically at the end of basic blocks, so
741 // unless we have global store elimination (super unlikely given how unprofitable that
742 // optimization is to begin with), you aren't going to be wanting to store eliminate
743 // across an equality op.
744 node->setCanExit(true);
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +0000745 break;
746 }
747
fpizlo@apple.comb03b1402013-02-11 22:23:08 +0000748 case CompareStrictEq:
749 case CompareStrictEqConstant: {
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +0000750 Node* leftNode = node->child1().node();
751 Node* rightNode = node->child2().node();
752 JSValue left = forNode(leftNode).value();
753 JSValue right = forNode(rightNode).value();
oliver@apple.combd15be82013-07-25 04:03:42 +0000754 if (left && right) {
fpizlo@apple.com49e37d32013-09-11 21:49:47 +0000755 if (left.isNumber() && right.isNumber()) {
756 setConstant(node, jsBoolean(left.asNumber() == right.asNumber()));
oliver@apple.combd15be82013-07-25 04:03:42 +0000757 break;
758 }
759 if (left.isString() && right.isString()) {
760 const StringImpl* a = asString(left)->tryGetValueImpl();
761 const StringImpl* b = asString(right)->tryGetValueImpl();
fpizlo@apple.com49e37d32013-09-11 21:49:47 +0000762 if (a && b) {
763 setConstant(node, jsBoolean(WTF::equal(a, b)));
oliver@apple.combd15be82013-07-25 04:03:42 +0000764 break;
765 }
766 }
fpizlo@apple.com3187c922012-05-18 21:47:53 +0000767 }
oliver@apple.comfe0cc192013-07-25 03:58:58 +0000768 forNode(node).setType(SpecBoolean);
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000769 node->setCanExit(true); // This is overly conservative.
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +0000770 break;
fpizlo@apple.com3187c922012-05-18 21:47:53 +0000771 }
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +0000772
773 case StringCharCodeAt:
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +0000774 node->setCanExit(true);
oliver@apple.comfe0cc192013-07-25 03:58:58 +0000775 forNode(node).setType(SpecInt32);
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +0000776 break;
777
commit-queue@webkit.orgaa31a5e2013-04-09 06:45:16 +0000778 case StringFromCharCode:
oliver@apple.com67e0f332013-07-25 03:59:00 +0000779 forNode(node).setType(SpecString);
commit-queue@webkit.orgaa31a5e2013-04-09 06:45:16 +0000780 break;
781
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +0000782 case StringCharAt:
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +0000783 node->setCanExit(true);
oliver@apple.comfe0cc192013-07-25 03:58:58 +0000784 forNode(node).set(m_graph, m_graph.m_vm.stringStructure.get());
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +0000785 break;
786
787 case GetByVal: {
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +0000788 node->setCanExit(true);
789 switch (node->arrayMode().type()) {
fpizlo@apple.coma0ec0592012-10-22 23:52:15 +0000790 case Array::SelectUsingPredictions:
fpizlo@apple.com97af5762012-09-19 22:36:44 +0000791 case Array::Unprofiled:
fpizlo@apple.com75c91a72012-11-08 22:28:25 +0000792 case Array::Undecided:
oliver@apple.com5598c182013-01-23 22:25:07 +0000793 RELEASE_ASSERT_NOT_REACHED();
fpizlo@apple.com7aed8d82012-08-23 03:38:52 +0000794 break;
795 case Array::ForceExit:
oliver@apple.com55d32d92013-07-25 04:05:03 +0000796 m_state.setIsValid(false);
fpizlo@apple.com6306b5652011-12-23 05:47:17 +0000797 break;
fpizlo@apple.com7aed8d82012-08-23 03:38:52 +0000798 case Array::Generic:
oliver@apple.come17632e2013-07-25 04:05:31 +0000799 clobberWorld(node->codeOrigin, clobberLimit);
fpizlo@apple.comff779d02013-09-10 21:55:45 +0000800 forNode(node).makeHeapTop();
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +0000801 break;
fpizlo@apple.com7aed8d82012-08-23 03:38:52 +0000802 case Array::String:
oliver@apple.com211b3be2013-07-25 04:03:39 +0000803 if (node->arrayMode().isOutOfBounds()) {
804 // If the watchpoint was still valid we could totally set this to be
805 // SpecString | SpecOther. Except that we'd have to be careful. If we
806 // tested the watchpoint state here then it could change by the time
807 // we got to the backend. So to do this right, we'd have to get the
808 // fixup phase to check the watchpoint state and then bake into the
809 // GetByVal operation the fact that we're using a watchpoint, using
810 // something like Array::SaneChain (except not quite, because that
811 // implies an in-bounds access). None of this feels like it's worth it,
oliver@apple.come6427742013-07-25 04:05:12 +0000812 // so we're going with TOP for now. The same thing applies to
813 // clobbering the world.
oliver@apple.come17632e2013-07-25 04:05:31 +0000814 clobberWorld(node->codeOrigin, clobberLimit);
fpizlo@apple.comff779d02013-09-10 21:55:45 +0000815 forNode(node).makeHeapTop();
oliver@apple.com211b3be2013-07-25 04:03:39 +0000816 } else
817 forNode(node).set(m_graph, m_graph.m_vm.stringStructure.get());
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +0000818 break;
fpizlo@apple.com7aed8d82012-08-23 03:38:52 +0000819 case Array::Arguments:
fpizlo@apple.comff779d02013-09-10 21:55:45 +0000820 forNode(node).makeHeapTop();
fpizlo@apple.com7aed8d82012-08-23 03:38:52 +0000821 break;
fpizlo@apple.com75c91a72012-11-08 22:28:25 +0000822 case Array::Int32:
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +0000823 if (node->arrayMode().isOutOfBounds()) {
oliver@apple.come17632e2013-07-25 04:05:31 +0000824 clobberWorld(node->codeOrigin, clobberLimit);
fpizlo@apple.comff779d02013-09-10 21:55:45 +0000825 forNode(node).makeHeapTop();
fpizlo@apple.com75c91a72012-11-08 22:28:25 +0000826 } else
oliver@apple.comfe0cc192013-07-25 03:58:58 +0000827 forNode(node).setType(SpecInt32);
fpizlo@apple.com75c91a72012-11-08 22:28:25 +0000828 break;
829 case Array::Double:
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +0000830 if (node->arrayMode().isOutOfBounds()) {
oliver@apple.come17632e2013-07-25 04:05:31 +0000831 clobberWorld(node->codeOrigin, clobberLimit);
fpizlo@apple.comff779d02013-09-10 21:55:45 +0000832 forNode(node).makeHeapTop();
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +0000833 } else if (node->arrayMode().isSaneChain())
oliver@apple.comfe0cc192013-07-25 03:58:58 +0000834 forNode(node).setType(SpecDouble);
fpizlo@apple.com94e84e92012-11-11 02:56:12 +0000835 else
oliver@apple.comfe0cc192013-07-25 03:58:58 +0000836 forNode(node).setType(SpecDoubleReal);
fpizlo@apple.com75c91a72012-11-08 22:28:25 +0000837 break;
fpizlo@apple.com34d1f082012-10-28 06:13:23 +0000838 case Array::Contiguous:
839 case Array::ArrayStorage:
840 case Array::SlowPutArrayStorage:
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +0000841 if (node->arrayMode().isOutOfBounds())
oliver@apple.come17632e2013-07-25 04:05:31 +0000842 clobberWorld(node->codeOrigin, clobberLimit);
fpizlo@apple.comff779d02013-09-10 21:55:45 +0000843 forNode(node).makeHeapTop();
fpizlo@apple.comfa34ff82012-09-05 01:27:50 +0000844 break;
fpizlo@apple.com7aed8d82012-08-23 03:38:52 +0000845 case Array::Int8Array:
oliver@apple.comfe0cc192013-07-25 03:58:58 +0000846 forNode(node).setType(SpecInt32);
oliver@apple.comaeec3d82011-12-02 01:56:53 +0000847 break;
fpizlo@apple.com7aed8d82012-08-23 03:38:52 +0000848 case Array::Int16Array:
oliver@apple.comfe0cc192013-07-25 03:58:58 +0000849 forNode(node).setType(SpecInt32);
oliver@apple.comaeec3d82011-12-02 01:56:53 +0000850 break;
fpizlo@apple.com7aed8d82012-08-23 03:38:52 +0000851 case Array::Int32Array:
oliver@apple.comfe0cc192013-07-25 03:58:58 +0000852 forNode(node).setType(SpecInt32);
oliver@apple.comaeec3d82011-12-02 01:56:53 +0000853 break;
fpizlo@apple.com7aed8d82012-08-23 03:38:52 +0000854 case Array::Uint8Array:
oliver@apple.comfe0cc192013-07-25 03:58:58 +0000855 forNode(node).setType(SpecInt32);
oliver@apple.comaeec3d82011-12-02 01:56:53 +0000856 break;
fpizlo@apple.com7aed8d82012-08-23 03:38:52 +0000857 case Array::Uint8ClampedArray:
oliver@apple.comfe0cc192013-07-25 03:58:58 +0000858 forNode(node).setType(SpecInt32);
caio.oliveira@openbossa.org992fc372012-01-18 01:11:16 +0000859 break;
fpizlo@apple.com7aed8d82012-08-23 03:38:52 +0000860 case Array::Uint16Array:
oliver@apple.comfe0cc192013-07-25 03:58:58 +0000861 forNode(node).setType(SpecInt32);
oliver@apple.comaeec3d82011-12-02 01:56:53 +0000862 break;
fpizlo@apple.com7aed8d82012-08-23 03:38:52 +0000863 case Array::Uint32Array:
fpizlo@apple.comefacb612013-09-10 22:16:00 +0000864 if (node->shouldSpeculateInt32())
oliver@apple.comfe0cc192013-07-25 03:58:58 +0000865 forNode(node).setType(SpecInt32);
fpizlo@apple.com6921b292013-09-18 17:14:02 +0000866 else if (enableInt52() && node->shouldSpeculateMachineInt())
867 forNode(node).setType(SpecInt52);
fpizlo@apple.com691ac792012-03-13 22:59:43 +0000868 else
oliver@apple.comfe0cc192013-07-25 03:58:58 +0000869 forNode(node).setType(SpecDouble);
oliver@apple.comaeec3d82011-12-02 01:56:53 +0000870 break;
fpizlo@apple.com7aed8d82012-08-23 03:38:52 +0000871 case Array::Float32Array:
oliver@apple.comfe0cc192013-07-25 03:58:58 +0000872 forNode(node).setType(SpecDouble);
oliver@apple.com07d75732011-12-03 01:47:27 +0000873 break;
fpizlo@apple.com7aed8d82012-08-23 03:38:52 +0000874 case Array::Float64Array:
oliver@apple.comfe0cc192013-07-25 03:58:58 +0000875 forNode(node).setType(SpecDouble);
oliver@apple.com07d75732011-12-03 01:47:27 +0000876 break;
fpizlo@apple.com0e9910a2012-10-09 23:39:53 +0000877 default:
oliver@apple.com5598c182013-01-23 22:25:07 +0000878 RELEASE_ASSERT_NOT_REACHED();
fpizlo@apple.com0e9910a2012-10-09 23:39:53 +0000879 break;
oliver@apple.com07d75732011-12-03 01:47:27 +0000880 }
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +0000881 break;
882 }
883
884 case PutByVal:
fpizlo@apple.com7aed8d82012-08-23 03:38:52 +0000885 case PutByValAlias: {
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +0000886 node->setCanExit(true);
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +0000887 switch (node->arrayMode().modeForPut().type()) {
fpizlo@apple.com7aed8d82012-08-23 03:38:52 +0000888 case Array::ForceExit:
oliver@apple.com55d32d92013-07-25 04:05:03 +0000889 m_state.setIsValid(false);
fpizlo@apple.com6306b5652011-12-23 05:47:17 +0000890 break;
fpizlo@apple.com7aed8d82012-08-23 03:38:52 +0000891 case Array::Generic:
oliver@apple.come17632e2013-07-25 04:05:31 +0000892 clobberWorld(node->codeOrigin, clobberLimit);
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +0000893 break;
fpizlo@apple.com75c91a72012-11-08 22:28:25 +0000894 case Array::Int32:
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +0000895 if (node->arrayMode().isOutOfBounds())
oliver@apple.come17632e2013-07-25 04:05:31 +0000896 clobberWorld(node->codeOrigin, clobberLimit);
fpizlo@apple.com75c91a72012-11-08 22:28:25 +0000897 break;
898 case Array::Double:
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +0000899 if (node->arrayMode().isOutOfBounds())
oliver@apple.come17632e2013-07-25 04:05:31 +0000900 clobberWorld(node->codeOrigin, clobberLimit);
fpizlo@apple.com75c91a72012-11-08 22:28:25 +0000901 break;
fpizlo@apple.com34d1f082012-10-28 06:13:23 +0000902 case Array::Contiguous:
903 case Array::ArrayStorage:
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +0000904 if (node->arrayMode().isOutOfBounds())
oliver@apple.come17632e2013-07-25 04:05:31 +0000905 clobberWorld(node->codeOrigin, clobberLimit);
fpizlo@apple.com34d1f082012-10-28 06:13:23 +0000906 break;
907 case Array::SlowPutArrayStorage:
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +0000908 if (node->arrayMode().mayStoreToHole())
oliver@apple.come17632e2013-07-25 04:05:31 +0000909 clobberWorld(node->codeOrigin, clobberLimit);
fpizlo@apple.com7aed8d82012-08-23 03:38:52 +0000910 break;
fpizlo@apple.com7aed8d82012-08-23 03:38:52 +0000911 default:
fpizlo@apple.com7aed8d82012-08-23 03:38:52 +0000912 break;
oliver@apple.com07d75732011-12-03 01:47:27 +0000913 }
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +0000914 break;
915 }
916
917 case ArrayPush:
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +0000918 node->setCanExit(true);
oliver@apple.come17632e2013-07-25 04:05:31 +0000919 clobberWorld(node->codeOrigin, clobberLimit);
fpizlo@apple.com6921b292013-09-18 17:14:02 +0000920 forNode(node).setType(SpecBytecodeNumber);
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +0000921 break;
922
923 case ArrayPop:
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +0000924 node->setCanExit(true);
oliver@apple.come17632e2013-07-25 04:05:31 +0000925 clobberWorld(node->codeOrigin, clobberLimit);
fpizlo@apple.comff779d02013-09-10 21:55:45 +0000926 forNode(node).makeHeapTop();
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +0000927 break;
928
barraclough@apple.com077fdd42012-03-18 01:08:16 +0000929 case RegExpExec:
fpizlo@apple.comff779d02013-09-10 21:55:45 +0000930 forNode(node).makeHeapTop();
barraclough@apple.com077fdd42012-03-18 01:08:16 +0000931 break;
msaboff@apple.com3fc51292013-04-25 18:35:04 +0000932
933 case RegExpTest:
oliver@apple.com67e0f332013-07-25 03:59:00 +0000934 forNode(node).setType(SpecBoolean);
msaboff@apple.com3fc51292013-04-25 18:35:04 +0000935 break;
barraclough@apple.com077fdd42012-03-18 01:08:16 +0000936
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +0000937 case Jump:
938 break;
939
940 case Branch: {
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +0000941 Node* child = node->child1().node();
942 BooleanResult result = booleanResult(node, forNode(child));
fpizlo@apple.com367a1102012-11-10 23:33:29 +0000943 if (result == DefinitelyTrue) {
oliver@apple.com55d32d92013-07-25 04:05:03 +0000944 m_state.setBranchDirection(TakeTrue);
fpizlo@apple.com367a1102012-11-10 23:33:29 +0000945 break;
946 }
947 if (result == DefinitelyFalse) {
oliver@apple.com55d32d92013-07-25 04:05:03 +0000948 m_state.setBranchDirection(TakeFalse);
fpizlo@apple.comdb7ba192012-05-24 02:28:52 +0000949 break;
950 }
951 // FIXME: The above handles the trivial cases of sparse conditional
952 // constant propagation, but we can do better:
fpizlo@apple.com367a1102012-11-10 23:33:29 +0000953 // We can specialize the source variable's value on each direction of
954 // the branch.
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000955 node->setCanExit(true); // This is overly conservative.
oliver@apple.com55d32d92013-07-25 04:05:03 +0000956 m_state.setBranchDirection(TakeBoth);
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +0000957 break;
958 }
oliver@apple.com9b7647b2013-07-25 04:03:00 +0000959
960 case Switch: {
961 // Nothing to do for now.
962 // FIXME: Do sparse conditional things.
963 break;
964 }
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +0000965
966 case Return:
oliver@apple.com55d32d92013-07-25 04:05:03 +0000967 m_state.setIsValid(false);
fpizlo@apple.com91b2c682012-05-24 06:24:36 +0000968 break;
969
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +0000970 case Throw:
971 case ThrowReferenceError:
oliver@apple.com55d32d92013-07-25 04:05:03 +0000972 m_state.setIsValid(false);
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +0000973 node->setCanExit(true);
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +0000974 break;
975
976 case ToPrimitive: {
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000977 JSValue childConst = forNode(node->child1()).value();
fpizlo@apple.com49e37d32013-09-11 21:49:47 +0000978 if (childConst && childConst.isNumber()) {
979 setConstant(node, childConst);
fpizlo@apple.com3187c922012-05-18 21:47:53 +0000980 break;
981 }
982
fpizlo@apple.com0e6e1542013-03-18 18:09:22 +0000983 ASSERT(node->child1().useKind() == UntypedUse);
984
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +0000985 AbstractValue& source = forNode(node->child1());
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +0000986 AbstractValue& destination = forNode(node);
987
988 // NB. The more canonical way of writing this would have been:
989 //
990 // destination = source;
fpizlo@apple.com6921b292013-09-18 17:14:02 +0000991 // if (destination.m_type & !(SpecFullNumber | SpecString | SpecBoolean)) {
992 // destination.filter(SpecFullNumber | SpecString | SpecBoolean);
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +0000993 // AbstractValue string;
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +0000994 // string.set(vm->stringStructure);
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +0000995 // destination.merge(string);
996 // }
997 //
998 // The reason why this would, in most other cases, have been better is that
999 // then destination would preserve any non-SpeculatedType knowledge of source.
1000 // As it stands, the code below forgets any non-SpeculatedType knowledge that
1001 // source would have had. Fortunately, though, for things like strings and
1002 // numbers and booleans, we don't care about the non-SpeculatedType knowedge:
1003 // the structure won't tell us anything we don't already know, and neither
1004 // will ArrayModes. And if the source was a meaningful constant then we
1005 // would have handled that above. Unfortunately, this does mean that
1006 // ToPrimitive will currently forget string constants. But that's not a big
1007 // deal since we don't do any optimization on those currently.
1008
oliver@apple.come17632e2013-07-25 04:05:31 +00001009 clobberWorld(node->codeOrigin, clobberLimit);
fpizlo@apple.com0e6e1542013-03-18 18:09:22 +00001010
fpizlo@apple.com62336162012-06-07 01:35:59 +00001011 SpeculatedType type = source.m_type;
fpizlo@apple.com6921b292013-09-18 17:14:02 +00001012 if (type & ~(SpecFullNumber | SpecString | SpecBoolean))
fpizlo@apple.comff779d02013-09-10 21:55:45 +00001013 type = (SpecHeapTop & ~SpecCell) | SpecString;
oliver@apple.comb06642f2013-08-02 22:38:28 +00001014
oliver@apple.comfe0cc192013-07-25 03:58:58 +00001015 destination.setType(type);
oliver@apple.com33913872013-07-25 04:02:13 +00001016 if (destination.isClear())
oliver@apple.com55d32d92013-07-25 04:05:03 +00001017 m_state.setIsValid(false);
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +00001018 break;
1019 }
fpizlo@apple.com0e6e1542013-03-18 18:09:22 +00001020
1021 case ToString: {
1022 switch (node->child1().useKind()) {
1023 case StringObjectUse:
1024 // This also filters that the StringObject has the primordial StringObject
1025 // structure.
oliver@apple.com33913872013-07-25 04:02:13 +00001026 filter(
1027 node->child1(),
oliver@apple.com37bd9382013-07-25 04:02:17 +00001028 m_graph.globalObjectFor(node->codeOrigin)->stringObjectStructure());
fpizlo@apple.com0e6e1542013-03-18 18:09:22 +00001029 node->setCanExit(true); // We could be more precise but it's likely not worth it.
1030 break;
1031 case StringOrStringObjectUse:
1032 node->setCanExit(true); // We could be more precise but it's likely not worth it.
1033 break;
1034 case CellUse:
1035 case UntypedUse:
oliver@apple.come17632e2013-07-25 04:05:31 +00001036 clobberWorld(node->codeOrigin, clobberLimit);
fpizlo@apple.com0e6e1542013-03-18 18:09:22 +00001037 break;
1038 default:
1039 RELEASE_ASSERT_NOT_REACHED();
1040 break;
1041 }
oliver@apple.comfe0cc192013-07-25 03:58:58 +00001042 forNode(node).set(m_graph, m_graph.m_vm.stringStructure.get());
fpizlo@apple.com0e6e1542013-03-18 18:09:22 +00001043 break;
1044 }
1045
1046 case NewStringObject: {
fpizlo@apple.com10ae2d02013-08-14 02:41:47 +00001047 ASSERT(node->structure()->classInfo() == StringObject::info());
oliver@apple.comfe0cc192013-07-25 03:58:58 +00001048 forNode(node).set(m_graph, node->structure());
fpizlo@apple.com0e6e1542013-03-18 18:09:22 +00001049 break;
1050 }
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +00001051
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +00001052 case NewArray:
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +00001053 node->setCanExit(true);
oliver@apple.comfe0cc192013-07-25 03:58:58 +00001054 forNode(node).set(
1055 m_graph,
1056 m_graph.globalObjectFor(node->codeOrigin)->arrayStructureForIndexingTypeDuringAllocation(node->indexingType()));
oliver@apple.com55d32d92013-07-25 04:05:03 +00001057 m_state.setHaveStructures(true);
fpizlo@apple.com6c89cd32012-06-26 19:42:05 +00001058 break;
1059
fpizlo@apple.com1c4a32c2012-09-17 20:56:39 +00001060 case NewArrayBuffer:
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +00001061 node->setCanExit(true);
oliver@apple.comfe0cc192013-07-25 03:58:58 +00001062 forNode(node).set(
1063 m_graph,
1064 m_graph.globalObjectFor(node->codeOrigin)->arrayStructureForIndexingTypeDuringAllocation(node->indexingType()));
oliver@apple.com55d32d92013-07-25 04:05:03 +00001065 m_state.setHaveStructures(true);
fpizlo@apple.com1c4a32c2012-09-17 20:56:39 +00001066 break;
1067
fpizlo@apple.com6c89cd32012-06-26 19:42:05 +00001068 case NewArrayWithSize:
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +00001069 node->setCanExit(true);
oliver@apple.comfe0cc192013-07-25 03:58:58 +00001070 forNode(node).setType(SpecArray);
oliver@apple.com55d32d92013-07-25 04:05:03 +00001071 m_state.setHaveStructures(true);
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +00001072 break;
fpizlo@apple.com372fa822013-08-21 19:43:47 +00001073
1074 case NewTypedArray:
1075 switch (node->child1().useKind()) {
1076 case Int32Use:
1077 break;
1078 case UntypedUse:
1079 clobberWorld(node->codeOrigin, clobberLimit);
1080 break;
1081 default:
1082 RELEASE_ASSERT_NOT_REACHED();
1083 break;
1084 }
1085 forNode(node).set(
1086 m_graph,
1087 m_graph.globalObjectFor(node->codeOrigin)->typedArrayStructure(
1088 node->typedArrayType()));
1089 m_state.setHaveStructures(true);
1090 break;
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +00001091
1092 case NewRegexp:
oliver@apple.comfe0cc192013-07-25 03:58:58 +00001093 forNode(node).set(m_graph, m_graph.globalObjectFor(node->codeOrigin)->regExpStructure());
oliver@apple.com55d32d92013-07-25 04:05:03 +00001094 m_state.setHaveStructures(true);
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +00001095 break;
1096
oliver@apple.come2fe4ce2013-07-25 03:59:41 +00001097 case ToThis: {
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +00001098 AbstractValue& source = forNode(node->child1());
1099 AbstractValue& destination = forNode(node);
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +00001100
fpizlo@apple.com018818d2013-09-13 23:18:19 +00001101 if (m_graph.executableFor(node->codeOrigin)->isStrictMode())
1102 destination.makeHeapTop();
1103 else {
1104 destination = source;
1105 destination.merge(SpecObject);
1106 }
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +00001107 break;
1108 }
barraclough@apple.comcef11dc2012-05-10 18:40:29 +00001109
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +00001110 case CreateThis: {
oliver@apple.comfe0cc192013-07-25 03:58:58 +00001111 forNode(node).setType(SpecFinalObject);
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +00001112 break;
1113 }
fpizlo@apple.comf5db15e2012-11-14 07:22:57 +00001114
ggaren@apple.comc862eac2013-01-29 05:48:01 +00001115 case AllocationProfileWatchpoint:
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +00001116 node->setCanExit(true);
fpizlo@apple.comf5db15e2012-11-14 07:22:57 +00001117 break;
barraclough@apple.comcef11dc2012-05-10 18:40:29 +00001118
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +00001119 case NewObject:
oliver@apple.comfe0cc192013-07-25 03:58:58 +00001120 forNode(node).set(m_graph, node->structure());
oliver@apple.com55d32d92013-07-25 04:05:03 +00001121 m_state.setHaveStructures(true);
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +00001122 break;
fpizlo@apple.com17da7f32012-02-25 23:05:38 +00001123
1124 case CreateActivation:
oliver@apple.comfe0cc192013-07-25 03:58:58 +00001125 forNode(node).set(
1126 m_graph, m_codeBlock->globalObjectFor(node->codeOrigin)->activationStructure());
oliver@apple.com55d32d92013-07-25 04:05:03 +00001127 m_state.setHaveStructures(true);
fpizlo@apple.com17da7f32012-02-25 23:05:38 +00001128 break;
oliver@apple.com83ec76b2013-09-21 00:00:30 +00001129
fpizlo@apple.comf860f9b2012-05-22 20:02:25 +00001130 case CreateArguments:
oliver@apple.com83ec76b2013-09-21 00:00:30 +00001131 forNode(node).setType(SpecArguments);
fpizlo@apple.comf860f9b2012-05-22 20:02:25 +00001132 break;
1133
fpizlo@apple.com17da7f32012-02-25 23:05:38 +00001134 case TearOffActivation:
fpizlo@apple.com15c03c72012-05-23 02:34:13 +00001135 case TearOffArguments:
fpizlo@apple.com17da7f32012-02-25 23:05:38 +00001136 // Does nothing that is user-visible.
1137 break;
fpizlo@apple.com91b2c682012-05-24 06:24:36 +00001138
1139 case CheckArgumentsNotCreated:
fpizlo@apple.com62336162012-06-07 01:35:59 +00001140 if (isEmptySpeculation(
oliver@apple.com55d32d92013-07-25 04:05:03 +00001141 m_state.variables().operand(
msaboff@apple.com62aa8b72013-09-26 22:53:54 +00001142 m_graph.argumentsRegisterFor(node->codeOrigin).offset()).m_type))
oliver@apple.com55d32d92013-07-25 04:05:03 +00001143 m_state.setFoundConstants(true);
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001144 else
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +00001145 node->setCanExit(true);
fpizlo@apple.com91b2c682012-05-24 06:24:36 +00001146 break;
fpizlo@apple.com17da7f32012-02-25 23:05:38 +00001147
fpizlo@apple.com6d4456e2012-05-23 03:48:52 +00001148 case GetMyArgumentsLength:
fpizlo@apple.com9a548f12012-05-24 05:33:09 +00001149 // We know that this executable does not escape its arguments, so we can optimize
1150 // the arguments a bit. Note that this is not sufficient to force constant folding
1151 // of GetMyArgumentsLength, because GetMyArgumentsLength is a clobbering operation.
1152 // We perform further optimizations on this later on.
oliver@apple.comfe0cc192013-07-25 03:58:58 +00001153 if (node->codeOrigin.inlineCallFrame) {
1154 forNode(node).set(
1155 m_graph, jsNumber(node->codeOrigin.inlineCallFrame->arguments.size() - 1));
1156 } else
1157 forNode(node).setType(SpecInt32);
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +00001158 node->setCanExit(
fpizlo@apple.com62336162012-06-07 01:35:59 +00001159 !isEmptySpeculation(
oliver@apple.com55d32d92013-07-25 04:05:03 +00001160 m_state.variables().operand(
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +00001161 m_graph.argumentsRegisterFor(node->codeOrigin)).m_type));
fpizlo@apple.com9a548f12012-05-24 05:33:09 +00001162 break;
1163
1164 case GetMyArgumentsLengthSafe:
fpizlo@apple.com6d4456e2012-05-23 03:48:52 +00001165 // This potentially clobbers all structures if the arguments object had a getter
1166 // installed on the length property.
oliver@apple.come17632e2013-07-25 04:05:31 +00001167 clobberWorld(node->codeOrigin, clobberLimit);
fpizlo@apple.com6d4456e2012-05-23 03:48:52 +00001168 // We currently make no guarantee about what this returns because it does not
1169 // speculate that the length property is actually a length.
fpizlo@apple.comff779d02013-09-10 21:55:45 +00001170 forNode(node).makeHeapTop();
fpizlo@apple.com6d4456e2012-05-23 03:48:52 +00001171 break;
1172
1173 case GetMyArgumentByVal:
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +00001174 node->setCanExit(true);
fpizlo@apple.com9a548f12012-05-24 05:33:09 +00001175 // We know that this executable does not escape its arguments, so we can optimize
1176 // the arguments a bit. Note that this ends up being further optimized by the
1177 // ArgumentsSimplificationPhase.
fpizlo@apple.comff779d02013-09-10 21:55:45 +00001178 forNode(node).makeHeapTop();
fpizlo@apple.com9a548f12012-05-24 05:33:09 +00001179 break;
1180
1181 case GetMyArgumentByValSafe:
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +00001182 node->setCanExit(true);
fpizlo@apple.com6d4456e2012-05-23 03:48:52 +00001183 // This potentially clobbers all structures if the property we're accessing has
1184 // a getter. We don't speculate against this.
oliver@apple.come17632e2013-07-25 04:05:31 +00001185 clobberWorld(node->codeOrigin, clobberLimit);
fpizlo@apple.com6d4456e2012-05-23 03:48:52 +00001186 // And the result is unknown.
fpizlo@apple.comff779d02013-09-10 21:55:45 +00001187 forNode(node).makeHeapTop();
fpizlo@apple.com6d4456e2012-05-23 03:48:52 +00001188 break;
1189
fpizlo@apple.com507dca12013-07-17 23:27:31 +00001190 case NewFunction: {
1191 AbstractValue& value = forNode(node);
1192 value = forNode(node->child1());
1193
1194 if (!(value.m_type & SpecEmpty)) {
oliver@apple.com55d32d92013-07-25 04:05:03 +00001195 m_state.setFoundConstants(true);
fpizlo@apple.com507dca12013-07-17 23:27:31 +00001196 break;
1197 }
1198
oliver@apple.com02039462013-07-25 03:59:29 +00001199 value.setType((value.m_type & ~SpecEmpty) | SpecFunction);
fpizlo@apple.com507dca12013-07-17 23:27:31 +00001200 break;
1201 }
1202
fpizlo@apple.com17da7f32012-02-25 23:05:38 +00001203 case NewFunctionExpression:
1204 case NewFunctionNoCheck:
oliver@apple.comfe0cc192013-07-25 03:58:58 +00001205 forNode(node).set(
1206 m_graph, m_codeBlock->globalObjectFor(node->codeOrigin)->functionStructure());
fpizlo@apple.com17da7f32012-02-25 23:05:38 +00001207 break;
1208
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +00001209 case GetCallee:
oliver@apple.comfe0cc192013-07-25 03:58:58 +00001210 forNode(node).setType(SpecFunction);
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +00001211 break;
fpizlo@apple.com5e2296a2013-01-07 02:24:58 +00001212
fpizlo@apple.com5e2296a2013-01-07 02:24:58 +00001213 case GetScope: // FIXME: We could get rid of these if we know that the JSFunction is a constant. https://bugs.webkit.org/show_bug.cgi?id=106202
fpizlo@apple.com20d46242012-11-30 21:56:24 +00001214 case GetMyScope:
1215 case SkipTopScope:
oliver@apple.comeca9fbe2013-07-28 18:04:18 +00001216 forNode(node).setType(SpecObjectOther);
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +00001217 break;
ggaren@apple.comce086ca2012-09-23 22:48:19 +00001218
fpizlo@apple.coma0bd0582012-12-04 20:25:24 +00001219 case SkipScope: {
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +00001220 JSValue child = forNode(node->child1()).value();
fpizlo@apple.com49e37d32013-09-11 21:49:47 +00001221 if (child) {
1222 setConstant(node, JSValue(jsCast<JSScope*>(child.asCell())->next()));
fpizlo@apple.coma0bd0582012-12-04 20:25:24 +00001223 break;
1224 }
oliver@apple.comeca9fbe2013-07-28 18:04:18 +00001225 forNode(node).setType(SpecObjectOther);
fpizlo@apple.coma0bd0582012-12-04 20:25:24 +00001226 break;
1227 }
1228
oliver@apple.com58c86752013-07-25 04:02:40 +00001229 case GetClosureRegisters:
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +00001230 forNode(node).clear(); // The result is not a JS value.
ggaren@apple.comce086ca2012-09-23 22:48:19 +00001231 break;
1232
oliver@apple.com58c86752013-07-25 04:02:40 +00001233 case GetClosureVar:
fpizlo@apple.comff779d02013-09-10 21:55:45 +00001234 forNode(node).makeHeapTop();
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +00001235 break;
1236
oliver@apple.com58c86752013-07-25 04:02:40 +00001237 case PutClosureVar:
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +00001238 clobberCapturedVars(node->codeOrigin);
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +00001239 break;
1240
1241 case GetById:
fpizlo@apple.comdc03dc52012-01-17 00:53:40 +00001242 case GetByIdFlush:
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +00001243 node->setCanExit(true);
1244 if (!node->prediction()) {
oliver@apple.com55d32d92013-07-25 04:05:03 +00001245 m_state.setIsValid(false);
fpizlo@apple.com49bfe572011-10-31 23:50:57 +00001246 break;
1247 }
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +00001248 if (isCellSpeculation(node->child1()->prediction())) {
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +00001249 if (Structure* structure = forNode(node->child1()).bestProvenStructure()) {
fpizlo@apple.comc2c67632012-11-17 08:37:14 +00001250 GetByIdStatus status = GetByIdStatus::computeFor(
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +00001251 m_graph.m_vm, structure,
oliver@apple.com90fce822013-07-25 04:00:13 +00001252 m_graph.identifiers()[node->identifierNumber()]);
fpizlo@apple.comc2c67632012-11-17 08:37:14 +00001253 if (status.isSimple()) {
1254 // Assert things that we can't handle and that the computeFor() method
1255 // above won't be able to return.
1256 ASSERT(status.structureSet().size() == 1);
oliver@apple.com98fb6bf2013-07-25 03:59:44 +00001257 ASSERT(!status.chain());
fpizlo@apple.comc2c67632012-11-17 08:37:14 +00001258
1259 if (status.specificValue())
fpizlo@apple.com49e37d32013-09-11 21:49:47 +00001260 setConstant(node, status.specificValue());
fpizlo@apple.comc2c67632012-11-17 08:37:14 +00001261 else
fpizlo@apple.comff779d02013-09-10 21:55:45 +00001262 forNode(node).makeHeapTop();
oliver@apple.com37bd9382013-07-25 04:02:17 +00001263 filter(node->child1(), status.structureSet());
fpizlo@apple.comc2c67632012-11-17 08:37:14 +00001264
oliver@apple.com55d32d92013-07-25 04:05:03 +00001265 m_state.setFoundConstants(true);
fpizlo@apple.comc2c67632012-11-17 08:37:14 +00001266 break;
1267 }
1268 }
1269 }
oliver@apple.come17632e2013-07-25 04:05:31 +00001270 clobberWorld(node->codeOrigin, clobberLimit);
fpizlo@apple.comff779d02013-09-10 21:55:45 +00001271 forNode(node).makeHeapTop();
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +00001272 break;
1273
1274 case GetArrayLength:
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +00001275 node->setCanExit(true); // Lies, but it's true for the common case of JSArray, so it's good enough.
oliver@apple.comfe0cc192013-07-25 03:58:58 +00001276 forNode(node).setType(SpecInt32);
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +00001277 break;
fpizlo@apple.com5e2296a2013-01-07 02:24:58 +00001278
1279 case CheckExecutable: {
1280 // FIXME: We could track executables in AbstractValue, which would allow us to get rid of these checks
1281 // more thoroughly. https://bugs.webkit.org/show_bug.cgi?id=106200
1282 // FIXME: We could eliminate these entirely if we know the exact value that flows into this.
1283 // https://bugs.webkit.org/show_bug.cgi?id=106201
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +00001284 node->setCanExit(true);
fpizlo@apple.com5e2296a2013-01-07 02:24:58 +00001285 break;
1286 }
oliver@apple.comf4596ca2011-10-19 21:25:10 +00001287
oliver@apple.com500b53a2013-07-25 04:05:25 +00001288 case CheckStructure: {
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +00001289 // FIXME: We should be able to propagate the structure sets of constants (i.e. prototypes).
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +00001290 AbstractValue& value = forNode(node->child1());
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001291 ASSERT(!(value.m_type & ~SpecCell)); // Edge filtering should have already ensured this.
oliver@apple.com33913872013-07-25 04:02:13 +00001292
1293 StructureSet& set = node->structureSet();
1294
1295 if (value.m_currentKnownStructure.isSubsetOf(set)) {
oliver@apple.com55d32d92013-07-25 04:05:03 +00001296 m_state.setFoundConstants(true);
oliver@apple.com33913872013-07-25 04:02:13 +00001297 break;
1298 }
1299
oliver@apple.com33913872013-07-25 04:02:13 +00001300 node->setCanExit(true);
oliver@apple.com0402d952013-07-25 04:05:07 +00001301 m_state.setHaveStructures(true);
oliver@apple.com33913872013-07-25 04:02:13 +00001302
fpizlo@apple.comeb3323d2012-08-20 06:11:24 +00001303 // If this structure check is attempting to prove knowledge already held in
1304 // the futurePossibleStructure set then the constant folding phase should
1305 // turn this into a watchpoint instead.
fpizlo@apple.com99f37622012-10-29 04:02:08 +00001306 if (value.m_futurePossibleStructure.isSubsetOf(set)
oliver@apple.com33913872013-07-25 04:02:13 +00001307 && value.m_futurePossibleStructure.hasSingleton()) {
oliver@apple.com55d32d92013-07-25 04:05:03 +00001308 m_state.setFoundConstants(true);
oliver@apple.com37bd9382013-07-25 04:02:17 +00001309 filter(value, value.m_futurePossibleStructure.singleton());
oliver@apple.com33913872013-07-25 04:02:13 +00001310 break;
1311 }
1312
oliver@apple.com37bd9382013-07-25 04:02:17 +00001313 filter(value, set);
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +00001314 break;
fpizlo@apple.com91b2c682012-05-24 06:24:36 +00001315 }
fpizlo@apple.com04e41152012-06-15 22:14:53 +00001316
oliver@apple.com500b53a2013-07-25 04:05:25 +00001317 case StructureTransitionWatchpoint: {
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +00001318 AbstractValue& value = forNode(node->child1());
fpizlo@apple.comeb3323d2012-08-20 06:11:24 +00001319
oliver@apple.com37bd9382013-07-25 04:02:17 +00001320 filter(value, node->structure());
oliver@apple.com55d32d92013-07-25 04:05:03 +00001321 m_state.setHaveStructures(true);
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +00001322 node->setCanExit(true);
fpizlo@apple.com04e41152012-06-15 22:14:53 +00001323 break;
1324 }
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +00001325
1326 case PutStructure:
fpizlo@apple.com7e0f6502012-05-25 22:45:57 +00001327 case PhantomPutStructure:
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +00001328 if (!forNode(node->child1()).m_currentKnownStructure.isClear()) {
oliver@apple.come17632e2013-07-25 04:05:31 +00001329 clobberStructures(clobberLimit);
oliver@apple.comfe0cc192013-07-25 03:58:58 +00001330 forNode(node->child1()).set(m_graph, node->structureTransitionData().newStructure);
oliver@apple.com55d32d92013-07-25 04:05:03 +00001331 m_state.setHaveStructures(true);
fpizlo@apple.com6e0a9ed2012-09-16 02:36:22 +00001332 }
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +00001333 break;
fpizlo@apple.comd8dd0532012-09-13 04:18:52 +00001334 case GetButterfly:
fpizlo@apple.com1ffdcff2012-07-19 00:30:34 +00001335 case AllocatePropertyStorage:
1336 case ReallocatePropertyStorage:
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +00001337 forNode(node).clear(); // The result is not a JS value.
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +00001338 break;
fpizlo@apple.com04c19742012-08-26 22:35:26 +00001339 case CheckArray: {
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +00001340 if (node->arrayMode().alreadyChecked(m_graph, node, forNode(node->child1()))) {
oliver@apple.com55d32d92013-07-25 04:05:03 +00001341 m_state.setFoundConstants(true);
fpizlo@apple.com04c19742012-08-26 22:35:26 +00001342 break;
1343 }
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +00001344 node->setCanExit(true); // Lies, but this is followed by operations (like GetByVal) that always exit, so there is no point in us trying to be clever here.
1345 switch (node->arrayMode().type()) {
fpizlo@apple.com7aed8d82012-08-23 03:38:52 +00001346 case Array::String:
oliver@apple.com33913872013-07-25 04:02:13 +00001347 filter(node->child1(), SpecString);
fpizlo@apple.com7aed8d82012-08-23 03:38:52 +00001348 break;
fpizlo@apple.com75c91a72012-11-08 22:28:25 +00001349 case Array::Int32:
1350 case Array::Double:
fpizlo@apple.com34d1f082012-10-28 06:13:23 +00001351 case Array::Contiguous:
1352 case Array::ArrayStorage:
1353 case Array::SlowPutArrayStorage:
fpizlo@apple.com7aed8d82012-08-23 03:38:52 +00001354 break;
fpizlo@apple.com04c19742012-08-26 22:35:26 +00001355 case Array::Arguments:
oliver@apple.com33913872013-07-25 04:02:13 +00001356 filter(node->child1(), SpecArguments);
fpizlo@apple.com04c19742012-08-26 22:35:26 +00001357 break;
fpizlo@apple.com7aed8d82012-08-23 03:38:52 +00001358 case Array::Int8Array:
oliver@apple.com33913872013-07-25 04:02:13 +00001359 filter(node->child1(), SpecInt8Array);
fpizlo@apple.com7aed8d82012-08-23 03:38:52 +00001360 break;
1361 case Array::Int16Array:
oliver@apple.com33913872013-07-25 04:02:13 +00001362 filter(node->child1(), SpecInt16Array);
fpizlo@apple.com7aed8d82012-08-23 03:38:52 +00001363 break;
1364 case Array::Int32Array:
oliver@apple.com33913872013-07-25 04:02:13 +00001365 filter(node->child1(), SpecInt32Array);
fpizlo@apple.com7aed8d82012-08-23 03:38:52 +00001366 break;
1367 case Array::Uint8Array:
oliver@apple.com33913872013-07-25 04:02:13 +00001368 filter(node->child1(), SpecUint8Array);
fpizlo@apple.com7aed8d82012-08-23 03:38:52 +00001369 break;
1370 case Array::Uint8ClampedArray:
oliver@apple.com33913872013-07-25 04:02:13 +00001371 filter(node->child1(), SpecUint8ClampedArray);
fpizlo@apple.com7aed8d82012-08-23 03:38:52 +00001372 break;
1373 case Array::Uint16Array:
oliver@apple.com33913872013-07-25 04:02:13 +00001374 filter(node->child1(), SpecUint16Array);
fpizlo@apple.com7aed8d82012-08-23 03:38:52 +00001375 break;
1376 case Array::Uint32Array:
oliver@apple.com33913872013-07-25 04:02:13 +00001377 filter(node->child1(), SpecUint32Array);
fpizlo@apple.com7aed8d82012-08-23 03:38:52 +00001378 break;
1379 case Array::Float32Array:
oliver@apple.com33913872013-07-25 04:02:13 +00001380 filter(node->child1(), SpecFloat32Array);
fpizlo@apple.com7aed8d82012-08-23 03:38:52 +00001381 break;
1382 case Array::Float64Array:
oliver@apple.com33913872013-07-25 04:02:13 +00001383 filter(node->child1(), SpecFloat64Array);
fpizlo@apple.com7aed8d82012-08-23 03:38:52 +00001384 break;
1385 default:
oliver@apple.com5598c182013-01-23 22:25:07 +00001386 RELEASE_ASSERT_NOT_REACHED();
fpizlo@apple.comf860f9b2012-05-22 20:02:25 +00001387 break;
1388 }
oliver@apple.com52be8f82013-07-25 04:04:33 +00001389 filterArrayModes(node->child1(), node->arrayMode().arrayModesThatPassFiltering());
oliver@apple.com55d32d92013-07-25 04:05:03 +00001390 m_state.setHaveStructures(true);
fpizlo@apple.com04c19742012-08-26 22:35:26 +00001391 break;
1392 }
fpizlo@apple.com497c7512012-09-19 01:20:52 +00001393 case Arrayify: {
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +00001394 if (node->arrayMode().alreadyChecked(m_graph, node, forNode(node->child1()))) {
oliver@apple.com55d32d92013-07-25 04:05:03 +00001395 m_state.setFoundConstants(true);
fpizlo@apple.com372c6d52012-10-20 06:53:04 +00001396 break;
1397 }
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +00001398 ASSERT(node->arrayMode().conversion() == Array::Convert
1399 || node->arrayMode().conversion() == Array::RageConvert);
1400 node->setCanExit(true);
oliver@apple.come17632e2013-07-25 04:05:31 +00001401 clobberStructures(clobberLimit);
oliver@apple.com33913872013-07-25 04:02:13 +00001402 filterArrayModes(node->child1(), node->arrayMode().arrayModesThatPassFiltering());
oliver@apple.com55d32d92013-07-25 04:05:03 +00001403 m_state.setHaveStructures(true);
fpizlo@apple.com497c7512012-09-19 01:20:52 +00001404 break;
1405 }
fpizlo@apple.com99f37622012-10-29 04:02:08 +00001406 case ArrayifyToStructure: {
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +00001407 AbstractValue& value = forNode(node->child1());
1408 StructureSet set = node->structure();
fpizlo@apple.com99f37622012-10-29 04:02:08 +00001409 if (value.m_futurePossibleStructure.isSubsetOf(set)
1410 || value.m_currentKnownStructure.isSubsetOf(set))
oliver@apple.com55d32d92013-07-25 04:05:03 +00001411 m_state.setFoundConstants(true);
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +00001412 node->setCanExit(true);
oliver@apple.come17632e2013-07-25 04:05:31 +00001413 clobberStructures(clobberLimit);
oliver@apple.com37bd9382013-07-25 04:02:17 +00001414 filter(value, set);
oliver@apple.com55d32d92013-07-25 04:05:03 +00001415 m_state.setHaveStructures(true);
fpizlo@apple.com99f37622012-10-29 04:02:08 +00001416 break;
1417 }
fpizlo@apple.com04c19742012-08-26 22:35:26 +00001418 case GetIndexedPropertyStorage: {
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +00001419 forNode(node).clear();
oliver@apple.com43e511c2011-12-09 08:45:46 +00001420 break;
1421 }
fpizlo@apple.com537a4772013-08-19 23:16:01 +00001422
1423 case GetTypedArrayByteOffset: {
1424 forNode(node).setType(SpecInt32);
1425 break;
1426 }
1427
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001428 case GetByOffset: {
fpizlo@apple.comff779d02013-09-10 21:55:45 +00001429 forNode(node).makeHeapTop();
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +00001430 break;
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001431 }
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +00001432
fpizlo@apple.comc2c67632012-11-17 08:37:14 +00001433 case PutByOffset: {
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +00001434 break;
fpizlo@apple.comc2c67632012-11-17 08:37:14 +00001435 }
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +00001436
fpizlo@apple.com18e7bc12012-11-12 22:52:32 +00001437 case CheckFunction: {
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +00001438 JSValue value = forNode(node->child1()).value();
1439 if (value == node->function()) {
oliver@apple.com55d32d92013-07-25 04:05:03 +00001440 m_state.setFoundConstants(true);
fpizlo@apple.com18e7bc12012-11-12 22:52:32 +00001441 ASSERT(value);
fpizlo@apple.com18e7bc12012-11-12 22:52:32 +00001442 break;
1443 }
1444
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +00001445 node->setCanExit(true); // Lies! We can do better.
oliver@apple.com37bd9382013-07-25 04:02:17 +00001446 filterByValue(node->child1(), node->function());
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +00001447 break;
fpizlo@apple.com18e7bc12012-11-12 22:52:32 +00001448 }
fpizlo@apple.comb75911b2012-06-13 20:53:52 +00001449
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +00001450 case PutById:
1451 case PutByIdDirect:
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +00001452 node->setCanExit(true);
1453 if (Structure* structure = forNode(node->child1()).bestProvenStructure()) {
fpizlo@apple.comc2c67632012-11-17 08:37:14 +00001454 PutByIdStatus status = PutByIdStatus::computeFor(
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +00001455 m_graph.m_vm,
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +00001456 m_graph.globalObjectFor(node->codeOrigin),
fpizlo@apple.comc2c67632012-11-17 08:37:14 +00001457 structure,
oliver@apple.com90fce822013-07-25 04:00:13 +00001458 m_graph.identifiers()[node->identifierNumber()],
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +00001459 node->op() == PutByIdDirect);
fpizlo@apple.comc2c67632012-11-17 08:37:14 +00001460 if (status.isSimpleReplace()) {
oliver@apple.com37bd9382013-07-25 04:02:17 +00001461 filter(node->child1(), structure);
oliver@apple.com55d32d92013-07-25 04:05:03 +00001462 m_state.setFoundConstants(true);
fpizlo@apple.comc2c67632012-11-17 08:37:14 +00001463 break;
1464 }
1465 if (status.isSimpleTransition()) {
oliver@apple.come17632e2013-07-25 04:05:31 +00001466 clobberStructures(clobberLimit);
oliver@apple.comfe0cc192013-07-25 03:58:58 +00001467 forNode(node->child1()).set(m_graph, status.newStructure());
oliver@apple.com55d32d92013-07-25 04:05:03 +00001468 m_state.setHaveStructures(true);
1469 m_state.setFoundConstants(true);
fpizlo@apple.comc2c67632012-11-17 08:37:14 +00001470 break;
1471 }
1472 }
oliver@apple.come17632e2013-07-25 04:05:31 +00001473 clobberWorld(node->codeOrigin, clobberLimit);
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +00001474 break;
oliver@apple.comb3e5acb2013-07-25 04:02:53 +00001475
1476 case In:
1477 // FIXME: We can determine when the property definitely exists based on abstract
1478 // value information.
oliver@apple.come17632e2013-07-25 04:05:31 +00001479 clobberWorld(node->codeOrigin, clobberLimit);
oliver@apple.comb3e5acb2013-07-25 04:02:53 +00001480 forNode(node).setType(SpecBoolean);
1481 break;
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +00001482
1483 case GetGlobalVar:
fpizlo@apple.comff779d02013-09-10 21:55:45 +00001484 forNode(node).makeHeapTop();
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +00001485 break;
fpizlo@apple.comb75911b2012-06-13 20:53:52 +00001486
1487 case GlobalVarWatchpoint:
oliver@apple.com58c86752013-07-25 04:02:40 +00001488 case VarInjectionWatchpoint:
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +00001489 node->setCanExit(true);
fpizlo@apple.comb75911b2012-06-13 20:53:52 +00001490 break;
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +00001491
1492 case PutGlobalVar:
1493 break;
1494
1495 case CheckHasInstance:
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +00001496 node->setCanExit(true);
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +00001497 // Sadly, we don't propagate the fact that we've done CheckHasInstance
1498 break;
1499
1500 case InstanceOf:
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +00001501 node->setCanExit(true);
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +00001502 // Again, sadly, we don't propagate the fact that we've done InstanceOf
oliver@apple.comfe0cc192013-07-25 03:58:58 +00001503 forNode(node).setType(SpecBoolean);
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +00001504 break;
1505
1506 case Phi:
oliver@apple.com827d2cf2013-07-25 04:04:45 +00001507 RELEASE_ASSERT(m_graph.m_form == SSA);
1508 // The state of this node would have already been decided.
1509 break;
1510
1511 case Upsilon: {
oliver@apple.com02e7a972013-07-25 04:05:04 +00001512 m_state.createValueForNode(node->phi());
oliver@apple.com827d2cf2013-07-25 04:04:45 +00001513 AbstractValue& value = forNode(node->child1());
1514 forNode(node) = value;
1515 forNode(node->phi()) = value;
1516 break;
1517 }
1518
fpizlo@apple.comd9ded3b2011-10-22 01:22:46 +00001519 case Flush:
fpizlo@apple.com3fa6f5d2013-02-09 19:33:00 +00001520 case PhantomLocal:
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +00001521 case Breakpoint:
1522 break;
1523
1524 case Call:
1525 case Construct:
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +00001526 node->setCanExit(true);
oliver@apple.come17632e2013-07-25 04:05:31 +00001527 clobberWorld(node->codeOrigin, clobberLimit);
fpizlo@apple.comff779d02013-09-10 21:55:45 +00001528 forNode(node).makeHeapTop();
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +00001529 break;
oliver@apple.comc909f5f2012-10-18 23:37:40 +00001530
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +00001531 case ForceOSRExit:
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +00001532 node->setCanExit(true);
oliver@apple.com55d32d92013-07-25 04:05:03 +00001533 m_state.setIsValid(false);
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +00001534 break;
1535
mark.lam@apple.com10d23a12013-04-25 02:59:51 +00001536 case CheckWatchdogTimer:
1537 node->setCanExit(true);
1538 break;
1539
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +00001540 case Phantom:
fpizlo@apple.com116a0892011-11-03 08:06:42 +00001541 case InlineStart:
fpizlo@apple.com4a81fa42012-12-05 01:26:13 +00001542 case CountExecution:
fpizlo@apple.com532f1e52013-09-04 06:26:04 +00001543 case CheckTierUpInLoop:
1544 case CheckTierUpAtReturn:
1545 break;
1546
1547 case CheckTierUpAndOSREnter:
1548 case LoopHint:
1549 // We pretend that it can exit because it may want to get all state.
1550 node->setCanExit(true);
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +00001551 break;
oliver@apple.com1fc04182013-08-19 19:40:13 +00001552
1553 case Unreachable:
1554 RELEASE_ASSERT_NOT_REACHED();
1555 break;
1556
fpizlo@apple.comd7897b12012-03-12 23:15:45 +00001557 case LastNodeType:
oliver@apple.com5598c182013-01-23 22:25:07 +00001558 RELEASE_ASSERT_NOT_REACHED();
fpizlo@apple.comd7897b12012-03-12 23:15:45 +00001559 break;
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +00001560 }
1561
oliver@apple.com55d32d92013-07-25 04:05:03 +00001562 return m_state.isValid();
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +00001563}
1564
oliver@apple.com55d32d92013-07-25 04:05:03 +00001565template<typename AbstractStateType>
1566bool AbstractInterpreter<AbstractStateType>::executeEffects(unsigned indexInBlock)
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001567{
oliver@apple.com55d32d92013-07-25 04:05:03 +00001568 return executeEffects(indexInBlock, m_state.block()->at(indexInBlock));
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001569}
1570
oliver@apple.com55d32d92013-07-25 04:05:03 +00001571template<typename AbstractStateType>
1572bool AbstractInterpreter<AbstractStateType>::execute(unsigned indexInBlock)
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001573{
oliver@apple.com55d32d92013-07-25 04:05:03 +00001574 Node* node = m_state.block()->at(indexInBlock);
oliver@apple.com37bd9382013-07-25 04:02:17 +00001575 if (!startExecuting(node))
fpizlo@apple.com7a1964c2013-02-21 22:59:02 +00001576 return true;
1577
1578 executeEdges(node);
1579 return executeEffects(indexInBlock, node);
1580}
1581
oliver@apple.com55d32d92013-07-25 04:05:03 +00001582template<typename AbstractStateType>
oliver@apple.come17632e2013-07-25 04:05:31 +00001583bool AbstractInterpreter<AbstractStateType>::execute(Node* node)
1584{
1585 if (!startExecuting(node))
1586 return true;
1587
1588 executeEdges(node);
1589 return executeEffects(UINT_MAX, node);
1590}
1591
1592template<typename AbstractStateType>
oliver@apple.com55d32d92013-07-25 04:05:03 +00001593void AbstractInterpreter<AbstractStateType>::clobberWorld(
oliver@apple.come17632e2013-07-25 04:05:31 +00001594 const CodeOrigin& codeOrigin, unsigned clobberLimit)
fpizlo@apple.com75824e82012-05-30 17:02:49 +00001595{
fpizlo@apple.comcaa68812012-08-02 04:32:30 +00001596 clobberCapturedVars(codeOrigin);
oliver@apple.come17632e2013-07-25 04:05:31 +00001597 clobberStructures(clobberLimit);
fpizlo@apple.comcaa68812012-08-02 04:32:30 +00001598}
1599
oliver@apple.com55d32d92013-07-25 04:05:03 +00001600template<typename AbstractStateType>
1601void AbstractInterpreter<AbstractStateType>::clobberCapturedVars(const CodeOrigin& codeOrigin)
fpizlo@apple.comcaa68812012-08-02 04:32:30 +00001602{
fpizlo@apple.com75824e82012-05-30 17:02:49 +00001603 if (codeOrigin.inlineCallFrame) {
1604 const BitVector& capturedVars = codeOrigin.inlineCallFrame->capturedVars;
1605 for (size_t i = capturedVars.size(); i--;) {
1606 if (!capturedVars.quickGet(i))
1607 continue;
fpizlo@apple.comff779d02013-09-10 21:55:45 +00001608 m_state.variables().local(i).makeHeapTop();
fpizlo@apple.com75824e82012-05-30 17:02:49 +00001609 }
1610 } else {
ggaren@apple.com81c360e2012-09-14 02:17:01 +00001611 for (size_t i = m_codeBlock->m_numVars; i--;) {
msaboff@apple.com62aa8b72013-09-26 22:53:54 +00001612 if (m_codeBlock->isCaptured(virtualRegisterForLocal(i)))
fpizlo@apple.comff779d02013-09-10 21:55:45 +00001613 m_state.variables().local(i).makeHeapTop();
ggaren@apple.com81c360e2012-09-14 02:17:01 +00001614 }
fpizlo@apple.com75824e82012-05-30 17:02:49 +00001615 }
ggaren@apple.com81c360e2012-09-14 02:17:01 +00001616
oliver@apple.com55d32d92013-07-25 04:05:03 +00001617 for (size_t i = m_state.variables().numberOfArguments(); i--;) {
msaboff@apple.com62aa8b72013-09-26 22:53:54 +00001618 if (m_codeBlock->isCaptured(virtualRegisterForArgument(i)))
fpizlo@apple.comff779d02013-09-10 21:55:45 +00001619 m_state.variables().argument(i).makeHeapTop();
fpizlo@apple.com75824e82012-05-30 17:02:49 +00001620 }
fpizlo@apple.com75824e82012-05-30 17:02:49 +00001621}
1622
oliver@apple.com55d32d92013-07-25 04:05:03 +00001623template<typename AbstractStateType>
oliver@apple.come17632e2013-07-25 04:05:31 +00001624void AbstractInterpreter<AbstractStateType>::clobberStructures(unsigned clobberLimit)
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +00001625{
oliver@apple.com55d32d92013-07-25 04:05:03 +00001626 if (!m_state.haveStructures())
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +00001627 return;
oliver@apple.come17632e2013-07-25 04:05:31 +00001628 if (clobberLimit >= m_state.block()->size())
1629 clobberLimit = m_state.block()->size();
1630 else
1631 clobberLimit++;
1632 ASSERT(clobberLimit <= m_state.block()->size());
1633 for (size_t i = clobberLimit; i--;)
oliver@apple.com55d32d92013-07-25 04:05:03 +00001634 forNode(m_state.block()->at(i)).clobberStructures();
oliver@apple.com96feafa2013-07-25 04:04:57 +00001635 if (m_graph.m_form == SSA) {
oliver@apple.com55d32d92013-07-25 04:05:03 +00001636 HashSet<Node*>::iterator iter = m_state.block()->ssa->liveAtHead.begin();
1637 HashSet<Node*>::iterator end = m_state.block()->ssa->liveAtHead.end();
oliver@apple.com96feafa2013-07-25 04:04:57 +00001638 for (; iter != end; ++iter)
1639 forNode(*iter).clobberStructures();
1640 }
oliver@apple.com55d32d92013-07-25 04:05:03 +00001641 for (size_t i = m_state.variables().numberOfArguments(); i--;)
1642 m_state.variables().argument(i).clobberStructures();
1643 for (size_t i = m_state.variables().numberOfLocals(); i--;)
1644 m_state.variables().local(i).clobberStructures();
1645 m_state.setHaveStructures(true);
1646 m_state.setDidClobber(true);
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +00001647}
1648
oliver@apple.com55d32d92013-07-25 04:05:03 +00001649template<typename AbstractStateType>
1650void AbstractInterpreter<AbstractStateType>::dump(PrintStream& out)
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +00001651{
oliver@apple.com96feafa2013-07-25 04:04:57 +00001652 CommaPrinter comma(" ");
1653 if (m_graph.m_form == SSA) {
oliver@apple.com55d32d92013-07-25 04:05:03 +00001654 HashSet<Node*>::iterator iter = m_state.block()->ssa->liveAtHead.begin();
1655 HashSet<Node*>::iterator end = m_state.block()->ssa->liveAtHead.end();
oliver@apple.com96feafa2013-07-25 04:04:57 +00001656 for (; iter != end; ++iter) {
1657 Node* node = *iter;
1658 AbstractValue& value = forNode(node);
1659 if (value.isClear())
1660 continue;
1661 out.print(comma, node, ":", value);
1662 }
1663 }
oliver@apple.com55d32d92013-07-25 04:05:03 +00001664 for (size_t i = 0; i < m_state.block()->size(); ++i) {
1665 Node* node = m_state.block()->at(i);
fpizlo@apple.com8ff092f2013-01-29 08:01:03 +00001666 AbstractValue& value = forNode(node);
yuqiang.xian@intel.com861d9182012-03-01 07:39:31 +00001667 if (value.isClear())
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +00001668 continue;
oliver@apple.com96feafa2013-07-25 04:04:57 +00001669 out.print(comma, node, ":", value);
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +00001670 }
1671}
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +00001672
oliver@apple.com55d32d92013-07-25 04:05:03 +00001673template<typename AbstractStateType>
1674FiltrationResult AbstractInterpreter<AbstractStateType>::filter(
1675 AbstractValue& value, const StructureSet& set)
oliver@apple.com33913872013-07-25 04:02:13 +00001676{
1677 if (value.filter(m_graph, set) == FiltrationOK)
1678 return FiltrationOK;
oliver@apple.com55d32d92013-07-25 04:05:03 +00001679 m_state.setIsValid(false);
oliver@apple.com33913872013-07-25 04:02:13 +00001680 return Contradiction;
1681}
oliver@apple.com55d32d92013-07-25 04:05:03 +00001682
1683template<typename AbstractStateType>
1684FiltrationResult AbstractInterpreter<AbstractStateType>::filterArrayModes(
1685 AbstractValue& value, ArrayModes arrayModes)
oliver@apple.com33913872013-07-25 04:02:13 +00001686{
1687 if (value.filterArrayModes(arrayModes) == FiltrationOK)
1688 return FiltrationOK;
oliver@apple.com55d32d92013-07-25 04:05:03 +00001689 m_state.setIsValid(false);
oliver@apple.com33913872013-07-25 04:02:13 +00001690 return Contradiction;
1691}
oliver@apple.com55d32d92013-07-25 04:05:03 +00001692
1693template<typename AbstractStateType>
1694FiltrationResult AbstractInterpreter<AbstractStateType>::filter(
1695 AbstractValue& value, SpeculatedType type)
oliver@apple.com33913872013-07-25 04:02:13 +00001696{
1697 if (value.filter(type) == FiltrationOK)
1698 return FiltrationOK;
oliver@apple.com55d32d92013-07-25 04:05:03 +00001699 m_state.setIsValid(false);
oliver@apple.com33913872013-07-25 04:02:13 +00001700 return Contradiction;
1701}
oliver@apple.com55d32d92013-07-25 04:05:03 +00001702
1703template<typename AbstractStateType>
1704FiltrationResult AbstractInterpreter<AbstractStateType>::filterByValue(
oliver@apple.com37bd9382013-07-25 04:02:17 +00001705 AbstractValue& abstractValue, JSValue concreteValue)
oliver@apple.com33913872013-07-25 04:02:13 +00001706{
1707 if (abstractValue.filterByValue(concreteValue) == FiltrationOK)
1708 return FiltrationOK;
oliver@apple.com55d32d92013-07-25 04:05:03 +00001709 m_state.setIsValid(false);
oliver@apple.com33913872013-07-25 04:02:13 +00001710 return Contradiction;
1711}
1712
fpizlo@apple.com4ffd3952011-10-12 02:05:53 +00001713} } // namespace JSC::DFG
1714
1715#endif // ENABLE(DFG_JIT)
1716
oliver@apple.com55d32d92013-07-25 04:05:03 +00001717#endif // DFGAbstractInterpreterInlines_h
1718