Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(297)

Side by Side Diff: src/typing.cc

Issue 17842004: Derive synthetic type bounds for expressions (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Simplify assignment Created 7 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/typing.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 27 matching lines...) Expand all
38 : info_(info), 38 : info_(info),
39 oracle_( 39 oracle_(
40 Handle<Code>(info->closure()->shared()->code()), 40 Handle<Code>(info->closure()->shared()->code()),
41 Handle<Context>(info->closure()->context()->native_context()), 41 Handle<Context>(info->closure()->context()->native_context()),
42 info->isolate(), 42 info->isolate(),
43 info->zone()) { 43 info->zone()) {
44 InitializeAstVisitor(); 44 InitializeAstVisitor();
45 } 45 }
46 46
47 47
48 #define CHECK_ALIVE(call) \ 48 #define RECURSE(call) \
49 do { \ 49 do { \
50 ASSERT(!visitor->HasStackOverflow()); \
50 call; \ 51 call; \
51 if (visitor->HasStackOverflow()) return; \ 52 if (visitor->HasStackOverflow()) return; \
52 } while (false) 53 } while (false)
53 54
54
55 void AstTyper::Run(CompilationInfo* info) { 55 void AstTyper::Run(CompilationInfo* info) {
56 AstTyper* visitor = new(info->zone()) AstTyper(info); 56 AstTyper* visitor = new(info->zone()) AstTyper(info);
57 Scope* scope = info->scope(); 57 Scope* scope = info->scope();
58 58
59 // Handle implicit declaration of the function name in named function 59 // Handle implicit declaration of the function name in named function
60 // expressions before other declarations. 60 // expressions before other declarations.
61 if (scope->is_function_scope() && scope->function() != NULL) { 61 if (scope->is_function_scope() && scope->function() != NULL) {
62 CHECK_ALIVE(visitor->VisitVariableDeclaration(scope->function())); 62 RECURSE(visitor->VisitVariableDeclaration(scope->function()));
63 } 63 }
64 CHECK_ALIVE(visitor->VisitDeclarations(scope->declarations())); 64 RECURSE(visitor->VisitDeclarations(scope->declarations()));
65 CHECK_ALIVE(visitor->VisitStatements(info->function()->body())); 65 RECURSE(visitor->VisitStatements(info->function()->body()));
66 } 66 }
67 67
68 #undef RECURSE
68 69
69 #undef CHECK_ALIVE 70 #define RECURSE(call) \
70 #define CHECK_ALIVE(call) \
71 do { \ 71 do { \
72 ASSERT(!HasStackOverflow()); \
72 call; \ 73 call; \
73 if (HasStackOverflow()) return; \ 74 if (HasStackOverflow()) return; \
74 } while (false) 75 } while (false)
75 76
76 77
77 void AstTyper::VisitStatements(ZoneList<Statement*>* stmts) { 78 void AstTyper::VisitStatements(ZoneList<Statement*>* stmts) {
78 ASSERT(!HasStackOverflow());
79 for (int i = 0; i < stmts->length(); ++i) { 79 for (int i = 0; i < stmts->length(); ++i) {
80 Statement* stmt = stmts->at(i); 80 Statement* stmt = stmts->at(i);
81 CHECK_ALIVE(Visit(stmt)); 81 RECURSE(Visit(stmt));
82 } 82 }
83 } 83 }
84 84
85 85
86 void AstTyper::VisitBlock(Block* stmt) { 86 void AstTyper::VisitBlock(Block* stmt) {
87 ASSERT(!HasStackOverflow()); 87 RECURSE(VisitStatements(stmt->statements()));
88 CHECK_ALIVE(VisitStatements(stmt->statements()));
89 } 88 }
90 89
91 90
92 void AstTyper::VisitExpressionStatement(ExpressionStatement* stmt) { 91 void AstTyper::VisitExpressionStatement(ExpressionStatement* stmt) {
93 ASSERT(!HasStackOverflow()); 92 RECURSE(Visit(stmt->expression()));
94 CHECK_ALIVE(Visit(stmt->expression()));
95 } 93 }
96 94
97 95
98 void AstTyper::VisitEmptyStatement(EmptyStatement* stmt) { 96 void AstTyper::VisitEmptyStatement(EmptyStatement* stmt) {
99 ASSERT(!HasStackOverflow());
100 } 97 }
101 98
102 99
103 void AstTyper::VisitIfStatement(IfStatement* stmt) { 100 void AstTyper::VisitIfStatement(IfStatement* stmt) {
104 ASSERT(!HasStackOverflow()); 101 RECURSE(Visit(stmt->condition()));
105 CHECK_ALIVE(Visit(stmt->condition())); 102 RECURSE(Visit(stmt->then_statement()));
106 CHECK_ALIVE(Visit(stmt->then_statement())); 103 RECURSE(Visit(stmt->else_statement()));
107 CHECK_ALIVE(Visit(stmt->else_statement()));
108 104
109 if (!stmt->condition()->ToBooleanIsTrue() && 105 if (!stmt->condition()->ToBooleanIsTrue() &&
110 !stmt->condition()->ToBooleanIsFalse()) { 106 !stmt->condition()->ToBooleanIsFalse()) {
111 stmt->condition()->RecordToBooleanTypeFeedback(oracle()); 107 stmt->condition()->RecordToBooleanTypeFeedback(oracle());
112 } 108 }
113 } 109 }
114 110
115 111
116 void AstTyper::VisitContinueStatement(ContinueStatement* stmt) { 112 void AstTyper::VisitContinueStatement(ContinueStatement* stmt) {
117 ASSERT(!HasStackOverflow());
118 } 113 }
119 114
120 115
121 void AstTyper::VisitBreakStatement(BreakStatement* stmt) { 116 void AstTyper::VisitBreakStatement(BreakStatement* stmt) {
122 ASSERT(!HasStackOverflow());
123 } 117 }
124 118
125 119
126 void AstTyper::VisitReturnStatement(ReturnStatement* stmt) { 120 void AstTyper::VisitReturnStatement(ReturnStatement* stmt) {
127 ASSERT(!HasStackOverflow()); 121 RECURSE(Visit(stmt->expression()));
128 CHECK_ALIVE(Visit(stmt->expression()));
129 122
130 // TODO(rossberg): we only need this for inlining into test contexts... 123 // TODO(rossberg): we only need this for inlining into test contexts...
131 stmt->expression()->RecordToBooleanTypeFeedback(oracle()); 124 stmt->expression()->RecordToBooleanTypeFeedback(oracle());
132 } 125 }
133 126
134 127
135 void AstTyper::VisitWithStatement(WithStatement* stmt) { 128 void AstTyper::VisitWithStatement(WithStatement* stmt) {
136 ASSERT(!HasStackOverflow()); 129 RECURSE(stmt->expression());
137 CHECK_ALIVE(stmt->expression()); 130 RECURSE(stmt->statement());
138 CHECK_ALIVE(stmt->statement());
139 } 131 }
140 132
141 133
142 void AstTyper::VisitSwitchStatement(SwitchStatement* stmt) { 134 void AstTyper::VisitSwitchStatement(SwitchStatement* stmt) {
143 ASSERT(!HasStackOverflow()); 135 RECURSE(Visit(stmt->tag()));
144 CHECK_ALIVE(Visit(stmt->tag()));
145 ZoneList<CaseClause*>* clauses = stmt->cases(); 136 ZoneList<CaseClause*>* clauses = stmt->cases();
146 SwitchStatement::SwitchType switch_type = stmt->switch_type(); 137 SwitchStatement::SwitchType switch_type = stmt->switch_type();
147 for (int i = 0; i < clauses->length(); ++i) { 138 for (int i = 0; i < clauses->length(); ++i) {
148 CaseClause* clause = clauses->at(i); 139 CaseClause* clause = clauses->at(i);
149 if (!clause->is_default()) { 140 if (!clause->is_default()) {
150 Expression* label = clause->label(); 141 Expression* label = clause->label();
151 CHECK_ALIVE(Visit(label)); 142 RECURSE(Visit(label));
152 143
153 SwitchStatement::SwitchType label_switch_type = 144 SwitchStatement::SwitchType label_switch_type =
154 label->IsSmiLiteral() ? SwitchStatement::SMI_SWITCH : 145 label->IsSmiLiteral() ? SwitchStatement::SMI_SWITCH :
155 label->IsStringLiteral() ? SwitchStatement::STRING_SWITCH : 146 label->IsStringLiteral() ? SwitchStatement::STRING_SWITCH :
156 SwitchStatement::GENERIC_SWITCH; 147 SwitchStatement::GENERIC_SWITCH;
157 if (switch_type == SwitchStatement::UNKNOWN_SWITCH) 148 if (switch_type == SwitchStatement::UNKNOWN_SWITCH)
158 switch_type = label_switch_type; 149 switch_type = label_switch_type;
159 else if (switch_type != label_switch_type) 150 else if (switch_type != label_switch_type)
160 switch_type = SwitchStatement::GENERIC_SWITCH; 151 switch_type = SwitchStatement::GENERIC_SWITCH;
161 } 152 }
162 CHECK_ALIVE(VisitStatements(clause->statements())); 153 RECURSE(VisitStatements(clause->statements()));
163 } 154 }
164 if (switch_type == SwitchStatement::UNKNOWN_SWITCH) 155 if (switch_type == SwitchStatement::UNKNOWN_SWITCH)
165 switch_type = SwitchStatement::GENERIC_SWITCH; 156 switch_type = SwitchStatement::GENERIC_SWITCH;
166 stmt->set_switch_type(switch_type); 157 stmt->set_switch_type(switch_type);
167 158
168 // TODO(rossberg): can we eliminate this special case and extra loop? 159 // TODO(rossberg): can we eliminate this special case and extra loop?
169 if (switch_type == SwitchStatement::SMI_SWITCH) { 160 if (switch_type == SwitchStatement::SMI_SWITCH) {
170 for (int i = 0; i < clauses->length(); ++i) { 161 for (int i = 0; i < clauses->length(); ++i) {
171 CaseClause* clause = clauses->at(i); 162 CaseClause* clause = clauses->at(i);
172 if (!clause->is_default()) 163 if (!clause->is_default())
173 clause->RecordTypeFeedback(oracle()); 164 clause->RecordTypeFeedback(oracle());
174 } 165 }
175 } 166 }
176 } 167 }
177 168
178 169
179 void AstTyper::VisitDoWhileStatement(DoWhileStatement* stmt) { 170 void AstTyper::VisitDoWhileStatement(DoWhileStatement* stmt) {
180 ASSERT(!HasStackOverflow()); 171 RECURSE(Visit(stmt->body()));
181 CHECK_ALIVE(Visit(stmt->body())); 172 RECURSE(Visit(stmt->cond()));
182 CHECK_ALIVE(Visit(stmt->cond()));
183 173
184 if (!stmt->cond()->ToBooleanIsTrue()) { 174 if (!stmt->cond()->ToBooleanIsTrue()) {
185 stmt->cond()->RecordToBooleanTypeFeedback(oracle()); 175 stmt->cond()->RecordToBooleanTypeFeedback(oracle());
186 } 176 }
187 } 177 }
188 178
189 179
190 void AstTyper::VisitWhileStatement(WhileStatement* stmt) { 180 void AstTyper::VisitWhileStatement(WhileStatement* stmt) {
191 ASSERT(!HasStackOverflow()); 181 RECURSE(Visit(stmt->cond()));
192 CHECK_ALIVE(Visit(stmt->cond())); 182 RECURSE(Visit(stmt->body()));
193 CHECK_ALIVE(Visit(stmt->body()));
194 183
195 if (!stmt->cond()->ToBooleanIsTrue()) { 184 if (!stmt->cond()->ToBooleanIsTrue()) {
196 stmt->cond()->RecordToBooleanTypeFeedback(oracle()); 185 stmt->cond()->RecordToBooleanTypeFeedback(oracle());
197 } 186 }
198 } 187 }
199 188
200 189
201 void AstTyper::VisitForStatement(ForStatement* stmt) { 190 void AstTyper::VisitForStatement(ForStatement* stmt) {
202 ASSERT(!HasStackOverflow());
203 if (stmt->init() != NULL) { 191 if (stmt->init() != NULL) {
204 CHECK_ALIVE(Visit(stmt->init())); 192 RECURSE(Visit(stmt->init()));
205 } 193 }
206 if (stmt->cond() != NULL) { 194 if (stmt->cond() != NULL) {
207 CHECK_ALIVE(Visit(stmt->cond())); 195 RECURSE(Visit(stmt->cond()));
208 196
209 stmt->cond()->RecordToBooleanTypeFeedback(oracle()); 197 stmt->cond()->RecordToBooleanTypeFeedback(oracle());
210 } 198 }
211 CHECK_ALIVE(Visit(stmt->body())); 199 RECURSE(Visit(stmt->body()));
212 if (stmt->next() != NULL) { 200 if (stmt->next() != NULL) {
213 CHECK_ALIVE(Visit(stmt->next())); 201 RECURSE(Visit(stmt->next()));
214 } 202 }
215 } 203 }
216 204
217 205
218 void AstTyper::VisitForInStatement(ForInStatement* stmt) { 206 void AstTyper::VisitForInStatement(ForInStatement* stmt) {
219 ASSERT(!HasStackOverflow()); 207 RECURSE(Visit(stmt->enumerable()));
220 CHECK_ALIVE(Visit(stmt->enumerable())); 208 RECURSE(Visit(stmt->body()));
221 CHECK_ALIVE(Visit(stmt->body()));
222 209
223 stmt->RecordTypeFeedback(oracle()); 210 stmt->RecordTypeFeedback(oracle());
224 } 211 }
225 212
226 213
227 void AstTyper::VisitForOfStatement(ForOfStatement* stmt) { 214 void AstTyper::VisitForOfStatement(ForOfStatement* stmt) {
228 ASSERT(!HasStackOverflow()); 215 RECURSE(Visit(stmt->iterable()));
229 CHECK_ALIVE(Visit(stmt->iterable())); 216 RECURSE(Visit(stmt->body()));
230 CHECK_ALIVE(Visit(stmt->body()));
231 } 217 }
232 218
233 219
234 void AstTyper::VisitTryCatchStatement(TryCatchStatement* stmt) { 220 void AstTyper::VisitTryCatchStatement(TryCatchStatement* stmt) {
235 ASSERT(!HasStackOverflow()); 221 RECURSE(Visit(stmt->try_block()));
236 CHECK_ALIVE(Visit(stmt->try_block())); 222 RECURSE(Visit(stmt->catch_block()));
237 CHECK_ALIVE(Visit(stmt->catch_block()));
238 } 223 }
239 224
240 225
241 void AstTyper::VisitTryFinallyStatement(TryFinallyStatement* stmt) { 226 void AstTyper::VisitTryFinallyStatement(TryFinallyStatement* stmt) {
242 ASSERT(!HasStackOverflow()); 227 RECURSE(Visit(stmt->try_block()));
243 CHECK_ALIVE(Visit(stmt->try_block())); 228 RECURSE(Visit(stmt->finally_block()));
244 CHECK_ALIVE(Visit(stmt->finally_block()));
245 } 229 }
246 230
247 231
248 void AstTyper::VisitDebuggerStatement(DebuggerStatement* stmt) { 232 void AstTyper::VisitDebuggerStatement(DebuggerStatement* stmt) {
249 ASSERT(!HasStackOverflow());
250 } 233 }
251 234
252 235
253 void AstTyper::VisitFunctionLiteral(FunctionLiteral* expr) { 236 void AstTyper::VisitFunctionLiteral(FunctionLiteral* expr) {
254 ASSERT(!HasStackOverflow());
255 } 237 }
256 238
257 239
258 void AstTyper::VisitSharedFunctionInfoLiteral(SharedFunctionInfoLiteral* expr) { 240 void AstTyper::VisitSharedFunctionInfoLiteral(SharedFunctionInfoLiteral* expr) {
259 ASSERT(!HasStackOverflow());
260 } 241 }
261 242
262 243
263 void AstTyper::VisitConditional(Conditional* expr) { 244 void AstTyper::VisitConditional(Conditional* expr) {
264 ASSERT(!HasStackOverflow()); 245 RECURSE(Visit(expr->condition()));
265 CHECK_ALIVE(Visit(expr->condition())); 246 RECURSE(Visit(expr->then_expression()));
266 CHECK_ALIVE(Visit(expr->then_expression())); 247 RECURSE(Visit(expr->else_expression()));
267 CHECK_ALIVE(Visit(expr->else_expression()));
268 248
269 expr->condition()->RecordToBooleanTypeFeedback(oracle()); 249 expr->condition()->RecordToBooleanTypeFeedback(oracle());
250
251 MergeLowerType(expr, Type::Union(
Jakob Kummerow 2013/06/26 15:09:23 As discussed offline, inferring the lower bound as
rossberg 2013/06/26 16:18:59 Actually, the correct thing to use here is interse
252 expr->then_expression()->lower_type(),
253 expr->else_expression()->lower_type()));
254 MergeUpperType(expr, Type::Union(
255 expr->then_expression()->upper_type(),
256 expr->else_expression()->upper_type()));
270 } 257 }
271 258
272 259
273 void AstTyper::VisitVariableProxy(VariableProxy* expr) { 260 void AstTyper::VisitVariableProxy(VariableProxy* expr) {
274 ASSERT(!HasStackOverflow()); 261 // TODO(rossberg): typing of variables
275 } 262 }
276 263
277 264
278 void AstTyper::VisitLiteral(Literal* expr) { 265 void AstTyper::VisitLiteral(Literal* expr) {
279 ASSERT(!HasStackOverflow()); 266 Type* type = Type::Constant(expr->value(), isolate_);
267 MergeLowerType(expr, type);
268 MergeUpperType(expr, type);
280 } 269 }
281 270
282 271
283 void AstTyper::VisitRegExpLiteral(RegExpLiteral* expr) { 272 void AstTyper::VisitRegExpLiteral(RegExpLiteral* expr) {
284 ASSERT(!HasStackOverflow()); 273 MergeLowerType(expr, Type::RegExp());
274 MergeUpperType(expr, Type::RegExp());
285 } 275 }
286 276
287 277
288 void AstTyper::VisitObjectLiteral(ObjectLiteral* expr) { 278 void AstTyper::VisitObjectLiteral(ObjectLiteral* expr) {
289 ASSERT(!HasStackOverflow());
290 ZoneList<ObjectLiteral::Property*>* properties = expr->properties(); 279 ZoneList<ObjectLiteral::Property*>* properties = expr->properties();
291 for (int i = 0; i < properties->length(); ++i) { 280 for (int i = 0; i < properties->length(); ++i) {
292 ObjectLiteral::Property* prop = properties->at(i); 281 ObjectLiteral::Property* prop = properties->at(i);
293 CHECK_ALIVE(Visit(prop->value())); 282 RECURSE(Visit(prop->value()));
294 283
295 if ((prop->kind() == ObjectLiteral::Property::MATERIALIZED_LITERAL && 284 if ((prop->kind() == ObjectLiteral::Property::MATERIALIZED_LITERAL &&
296 !CompileTimeValue::IsCompileTimeValue(prop->value())) || 285 !CompileTimeValue::IsCompileTimeValue(prop->value())) ||
297 prop->kind() == ObjectLiteral::Property::COMPUTED) { 286 prop->kind() == ObjectLiteral::Property::COMPUTED) {
298 if (prop->key()->value()->IsInternalizedString() && prop->emit_store()) 287 if (prop->key()->value()->IsInternalizedString() && prop->emit_store())
299 prop->RecordTypeFeedback(oracle()); 288 prop->RecordTypeFeedback(oracle());
300 } 289 }
301 } 290 }
291
292 MergeLowerType(expr, Type::Object());
293 MergeUpperType(expr, Type::Object());
302 } 294 }
303 295
304 296
305 void AstTyper::VisitArrayLiteral(ArrayLiteral* expr) { 297 void AstTyper::VisitArrayLiteral(ArrayLiteral* expr) {
306 ASSERT(!HasStackOverflow());
307 ZoneList<Expression*>* values = expr->values(); 298 ZoneList<Expression*>* values = expr->values();
308 for (int i = 0; i < values->length(); ++i) { 299 for (int i = 0; i < values->length(); ++i) {
309 Expression* value = values->at(i); 300 Expression* value = values->at(i);
310 CHECK_ALIVE(Visit(value)); 301 RECURSE(Visit(value));
311 } 302 }
303
304 MergeLowerType(expr, Type::Array());
305 MergeUpperType(expr, Type::Array());
312 } 306 }
313 307
314 308
315 void AstTyper::VisitAssignment(Assignment* expr) { 309 void AstTyper::VisitAssignment(Assignment* expr) {
316 ASSERT(!HasStackOverflow());
317 CHECK_ALIVE(Visit(expr->target()));
318 CHECK_ALIVE(Visit(expr->value()));
319
320 // TODO(rossberg): Can we clean this up? 310 // TODO(rossberg): Can we clean this up?
321 if (expr->is_compound()) { 311 if (expr->is_compound()) {
322 CHECK_ALIVE(Visit(expr->binary_operation())); 312 RECURSE(Visit(expr->binary_operation()));
323 313
324 Expression* target = expr->target(); 314 Expression* target = expr->target();
325 Property* prop = target->AsProperty(); 315 Property* prop = target->AsProperty();
326 if (prop != NULL) { 316 if (prop != NULL) {
327 prop->RecordTypeFeedback(oracle(), zone()); 317 prop->RecordTypeFeedback(oracle(), zone());
328 if (!prop->key()->IsPropertyName()) // i.e., keyed 318 if (!prop->key()->IsPropertyName()) // i.e., keyed
329 expr->RecordTypeFeedback(oracle(), zone()); 319 expr->RecordTypeFeedback(oracle(), zone());
Jakob Kummerow 2013/06/26 15:09:23 nit: {} while you're here
rossberg 2013/06/26 16:18:59 Done.
330 } 320 }
331 return; 321 } else {
322 RECURSE(Visit(expr->target()));
323 RECURSE(Visit(expr->value()));
324
325 if (expr->target()->AsProperty())
326 expr->RecordTypeFeedback(oracle(), zone());
Jakob Kummerow 2013/06/26 15:09:23 nit: {}
rossberg 2013/06/26 16:18:59 Done.
327
328 MergeLowerType(expr, expr->value()->lower_type());
329 MergeUpperType(expr, expr->value()->upper_type());
332 } 330 }
333 if (expr->target()->AsProperty()) 331 // TODO(rossberg): handle target variables
334 expr->RecordTypeFeedback(oracle(), zone());
335 } 332 }
336 333
337 334
338 void AstTyper::VisitYield(Yield* expr) { 335 void AstTyper::VisitYield(Yield* expr) {
339 ASSERT(!HasStackOverflow()); 336 RECURSE(Visit(expr->generator_object()));
340 CHECK_ALIVE(Visit(expr->generator_object())); 337 RECURSE(Visit(expr->expression()));
341 CHECK_ALIVE(Visit(expr->expression())); 338
339 // We don't know anything about the type.
342 } 340 }
343 341
344 342
345 void AstTyper::VisitThrow(Throw* expr) { 343 void AstTyper::VisitThrow(Throw* expr) {
346 ASSERT(!HasStackOverflow()); 344 RECURSE(Visit(expr->exception()));
347 CHECK_ALIVE(Visit(expr->exception())); 345
346 // Lower type is None already
Jakob Kummerow 2013/06/26 15:09:23 nit: trailing full stop please.
rossberg 2013/06/26 16:18:59 Done.
347 MergeUpperType(expr, Type::None());
348 } 348 }
349 349
350 350
351 void AstTyper::VisitProperty(Property* expr) { 351 void AstTyper::VisitProperty(Property* expr) {
352 ASSERT(!HasStackOverflow()); 352 RECURSE(Visit(expr->obj()));
353 CHECK_ALIVE(Visit(expr->obj())); 353 RECURSE(Visit(expr->key()));
354 CHECK_ALIVE(Visit(expr->key()));
355 354
356 expr->RecordTypeFeedback(oracle(), zone()); 355 expr->RecordTypeFeedback(oracle(), zone());
356
357 // We don't know anything about the type.
357 } 358 }
358 359
359 360
360 void AstTyper::VisitCall(Call* expr) { 361 void AstTyper::VisitCall(Call* expr) {
361 ASSERT(!HasStackOverflow()); 362 RECURSE(Visit(expr->expression()));
362 CHECK_ALIVE(Visit(expr->expression()));
363 ZoneList<Expression*>* args = expr->arguments(); 363 ZoneList<Expression*>* args = expr->arguments();
364 for (int i = 0; i < args->length(); ++i) { 364 for (int i = 0; i < args->length(); ++i) {
365 Expression* arg = args->at(i); 365 Expression* arg = args->at(i);
366 CHECK_ALIVE(Visit(arg)); 366 RECURSE(Visit(arg));
367 } 367 }
368 368
369 Expression* callee = expr->expression(); 369 Expression* callee = expr->expression();
370 Property* prop = callee->AsProperty(); 370 Property* prop = callee->AsProperty();
371 if (prop != NULL) { 371 if (prop != NULL) {
372 if (prop->key()->IsPropertyName()) 372 if (prop->key()->IsPropertyName())
373 expr->RecordTypeFeedback(oracle(), CALL_AS_METHOD); 373 expr->RecordTypeFeedback(oracle(), CALL_AS_METHOD);
374 } else { 374 } else {
375 expr->RecordTypeFeedback(oracle(), CALL_AS_FUNCTION); 375 expr->RecordTypeFeedback(oracle(), CALL_AS_FUNCTION);
376 } 376 }
377
378 // We don't know anything about the type.
377 } 379 }
378 380
379 381
380 void AstTyper::VisitCallNew(CallNew* expr) { 382 void AstTyper::VisitCallNew(CallNew* expr) {
381 ASSERT(!HasStackOverflow()); 383 RECURSE(Visit(expr->expression()));
382 CHECK_ALIVE(Visit(expr->expression()));
383 ZoneList<Expression*>* args = expr->arguments(); 384 ZoneList<Expression*>* args = expr->arguments();
384 for (int i = 0; i < args->length(); ++i) { 385 for (int i = 0; i < args->length(); ++i) {
385 Expression* arg = args->at(i); 386 Expression* arg = args->at(i);
386 CHECK_ALIVE(Visit(arg)); 387 RECURSE(Visit(arg));
387 } 388 }
388 389
389 expr->RecordTypeFeedback(oracle()); 390 expr->RecordTypeFeedback(oracle());
391
392 // We don't know anything about the type.
390 } 393 }
391 394
392 395
393 void AstTyper::VisitCallRuntime(CallRuntime* expr) { 396 void AstTyper::VisitCallRuntime(CallRuntime* expr) {
394 ASSERT(!HasStackOverflow());
395 ZoneList<Expression*>* args = expr->arguments(); 397 ZoneList<Expression*>* args = expr->arguments();
396 for (int i = 0; i < args->length(); ++i) { 398 for (int i = 0; i < args->length(); ++i) {
397 Expression* arg = args->at(i); 399 Expression* arg = args->at(i);
398 CHECK_ALIVE(Visit(arg)); 400 RECURSE(Visit(arg));
399 } 401 }
402
403 // We don't know anything about the type.
400 } 404 }
401 405
402 406
403 void AstTyper::VisitUnaryOperation(UnaryOperation* expr) { 407 void AstTyper::VisitUnaryOperation(UnaryOperation* expr) {
404 ASSERT(!HasStackOverflow()); 408 RECURSE(Visit(expr->expression()));
405 CHECK_ALIVE(Visit(expr->expression()));
406 409
407 // Collect type feedback. 410 // Collect type feedback.
408 Handle<Type> op_type = oracle()->UnaryType(expr->UnaryOperationFeedbackId()); 411 Handle<Type> op_type = oracle()->UnaryType(expr->UnaryOperationFeedbackId());
409 MergeLowerType(expr->expression(), op_type); 412 MergeLowerType(expr->expression(), op_type);
410 if (expr->op() == Token::NOT) { 413 if (expr->op() == Token::NOT) {
Jakob Kummerow 2013/06/26 15:09:23 Combine this with the switch below maybe? If you w
rossberg 2013/06/26 16:18:59 Yeah, I'd like to keep it separate. (And we should
411 // TODO(rossberg): only do in test or value context. 414 // TODO(rossberg): only do in test or value context.
412 expr->expression()->RecordToBooleanTypeFeedback(oracle()); 415 expr->expression()->RecordToBooleanTypeFeedback(oracle());
413 } 416 }
417
418 switch (expr->op()) {
419 case Token::NOT:
420 case Token::DELETE:
421 MergeLowerType(expr, Type::Boolean());
422 MergeUpperType(expr, Type::Boolean());
423 break;
424 case Token::VOID:
425 MergeLowerType(expr, Type::Undefined());
426 MergeUpperType(expr, Type::Undefined());
427 break;
428 case Token::ADD:
429 case Token::SUB:
430 MergeLowerType(expr, Type::Smi());
431 MergeUpperType(expr,
432 BoundedType(Type::Number(), expr->expression()->upper_type()));
433 break;
434 case Token::BIT_NOT:
435 MergeLowerType(expr, Type::Smi());
436 MergeUpperType(expr, Type::Signed32());
437 break;
438 case Token::TYPEOF:
439 MergeLowerType(expr, Type::InternalizedString());
440 MergeUpperType(expr, Type::InternalizedString());
441 break;
442 default:
443 UNREACHABLE();
444 }
414 } 445 }
415 446
416 447
417 void AstTyper::VisitCountOperation(CountOperation* expr) { 448 void AstTyper::VisitCountOperation(CountOperation* expr) {
418 ASSERT(!HasStackOverflow()); 449 RECURSE(Visit(expr->expression()));
419 CHECK_ALIVE(Visit(expr->expression()));
420 450
421 expr->RecordTypeFeedback(oracle(), zone()); 451 expr->RecordTypeFeedback(oracle(), zone());
422 Property* prop = expr->expression()->AsProperty(); 452 Property* prop = expr->expression()->AsProperty();
423 if (prop != NULL) { 453 if (prop != NULL) {
424 prop->RecordTypeFeedback(oracle(), zone()); 454 prop->RecordTypeFeedback(oracle(), zone());
425 } 455 }
456
457 if (expr->is_prefix()) {
Jakob Kummerow 2013/06/26 15:09:23 I don't think we need all this logic here. Regardl
rossberg 2013/06/26 16:18:59 Good catch. Done.
458 switch (expr->op()) {
459 case Token::INC:
460 // No unique lower type (could be Smi or string)
461 MergeUpperType(expr, AdditionType(expr->expression()->upper_type()));
462 break;
463 case Token::DEC:
464 MergeLowerType(expr, Type::Smi());
465 MergeUpperType(expr, Type::Number());
466 break;
467 default:
468 UNREACHABLE();
469 }
470 } else {
471 MergeLowerType(expr, expr->expression()->lower_type());
472 MergeUpperType(expr, expr->expression()->upper_type());
473 }
426 } 474 }
427 475
428 476
429 void AstTyper::VisitBinaryOperation(BinaryOperation* expr) { 477 void AstTyper::VisitBinaryOperation(BinaryOperation* expr) {
430 ASSERT(!HasStackOverflow()); 478 RECURSE(Visit(expr->left()));
431 CHECK_ALIVE(Visit(expr->left())); 479 RECURSE(Visit(expr->right()));
432 CHECK_ALIVE(Visit(expr->right()));
433 480
434 // Collect type feedback. 481 // Collect type feedback.
435 Handle<Type> type, left_type, right_type; 482 Handle<Type> type, left_type, right_type;
436 Maybe<int> fixed_right_arg; 483 Maybe<int> fixed_right_arg;
437 oracle()->BinaryType(expr->BinaryOperationFeedbackId(), 484 oracle()->BinaryType(expr->BinaryOperationFeedbackId(),
438 &left_type, &right_type, &type, &fixed_right_arg); 485 &left_type, &right_type, &type, &fixed_right_arg);
439 MergeLowerType(expr, type); 486 MergeLowerType(expr, type);
440 MergeLowerType(expr->left(), left_type); 487 MergeLowerType(expr->left(), left_type);
441 MergeLowerType(expr->right(), right_type); 488 MergeLowerType(expr->right(), right_type);
442 expr->set_fixed_right_arg(fixed_right_arg); 489 expr->set_fixed_right_arg(fixed_right_arg);
443 if (expr->op() == Token::OR || expr->op() == Token::AND) { 490 if (expr->op() == Token::OR || expr->op() == Token::AND) {
444 expr->left()->RecordToBooleanTypeFeedback(oracle()); 491 expr->left()->RecordToBooleanTypeFeedback(oracle());
445 } 492 }
493
494 switch (expr->op()) {
495 case Token::COMMA:
496 MergeLowerType(expr, expr->right()->lower_type());
497 MergeUpperType(expr, expr->right()->upper_type());
498 break;
499 case Token::OR:
500 case Token::AND:
501 // No lower type
Jakob Kummerow 2013/06/26 15:09:23 nit: trailing full stop please.
rossberg 2013/06/26 16:18:59 Comment is obsolete now.
502 MergeUpperType(expr, Type::Union(
503 expr->left()->upper_type(), expr->right()->upper_type()));
504 break;
505 case Token::BIT_OR:
506 case Token::BIT_AND:
507 MergeLowerType(expr, Type::Smi());
508 MergeUpperType(expr, BoundedType(Type::Signed32(), handle(Type::Union(
509 expr->left()->upper_type(), expr->right()->upper_type()), isolate_)));
510 break;
511 case Token::BIT_XOR:
512 case Token::SHL:
513 case Token::SHR:
Jakob Kummerow 2013/06/26 15:09:23 I think you're mixing up SHR and SAR here.
rossberg 2013/06/26 16:18:59 Done.
514 MergeLowerType(expr, Type::Smi());
515 MergeUpperType(expr, Type::Signed32());
516 break;
517 case Token::SAR:
518 MergeLowerType(expr, Type::Smi());
519 MergeUpperType(expr, Type::Unsigned32());
520 break;
521 case Token::ADD:
522 // No unique lower type (could be Smi or string)
Jakob Kummerow 2013/06/26 15:09:23 nit: trailing full stop please.
rossberg 2013/06/26 16:18:59 Done.
523 MergeUpperType(expr, AdditionType(handle(Type::Union(
524 expr->left()->upper_type(), expr->right()->upper_type()), isolate_)));
525 break;
526 case Token::SUB:
527 case Token::MUL:
528 case Token::DIV:
529 case Token::MOD:
530 MergeLowerType(expr, Type::Smi());
531 MergeUpperType(expr, Type::Number());
532 break;
533 default:
534 UNREACHABLE();
535 }
446 } 536 }
447 537
448 538
449 void AstTyper::VisitCompareOperation(CompareOperation* expr) { 539 void AstTyper::VisitCompareOperation(CompareOperation* expr) {
450 ASSERT(!HasStackOverflow()); 540 RECURSE(Visit(expr->left()));
451 CHECK_ALIVE(Visit(expr->left())); 541 RECURSE(Visit(expr->right()));
452 CHECK_ALIVE(Visit(expr->right()));
453 542
454 // Collect type feedback. 543 // Collect type feedback.
455 Handle<Type> left_type, right_type, combined_type; 544 Handle<Type> left_type, right_type, combined_type;
456 oracle()->CompareType(expr->CompareOperationFeedbackId(), 545 oracle()->CompareType(expr->CompareOperationFeedbackId(),
457 &left_type, &right_type, &combined_type); 546 &left_type, &right_type, &combined_type);
458 MergeLowerType(expr->left(), left_type); 547 MergeLowerType(expr->left(), left_type);
459 MergeLowerType(expr->right(), right_type); 548 MergeLowerType(expr->right(), right_type);
460 expr->set_combined_type(combined_type); 549 expr->set_combined_type(combined_type);
550
551 MergeLowerType(expr, Type::Boolean());
552 MergeUpperType(expr, Type::Boolean());
461 } 553 }
462 554
463 555
464 void AstTyper::VisitThisFunction(ThisFunction* expr) { 556 void AstTyper::VisitThisFunction(ThisFunction* expr) {
465 ASSERT(!HasStackOverflow());
466 } 557 }
467 558
468 559
469 void AstTyper::VisitDeclarations(ZoneList<Declaration*>* decls) { 560 void AstTyper::VisitDeclarations(ZoneList<Declaration*>* decls) {
470 ASSERT(!HasStackOverflow());
471 for (int i = 0; i < decls->length(); ++i) { 561 for (int i = 0; i < decls->length(); ++i) {
472 Declaration* decl = decls->at(i); 562 Declaration* decl = decls->at(i);
473 CHECK_ALIVE(Visit(decl)); 563 RECURSE(Visit(decl));
474 } 564 }
475 } 565 }
476 566
477 567
478 void AstTyper::VisitVariableDeclaration(VariableDeclaration* declaration) { 568 void AstTyper::VisitVariableDeclaration(VariableDeclaration* declaration) {
479 ASSERT(!HasStackOverflow());
480 } 569 }
481 570
482 571
483 void AstTyper::VisitFunctionDeclaration(FunctionDeclaration* declaration) { 572 void AstTyper::VisitFunctionDeclaration(FunctionDeclaration* declaration) {
484 ASSERT(!HasStackOverflow()); 573 RECURSE(Visit(declaration->fun()));
485 CHECK_ALIVE(Visit(declaration->fun()));
486 } 574 }
487 575
488 576
489 void AstTyper::VisitModuleDeclaration(ModuleDeclaration* declaration) { 577 void AstTyper::VisitModuleDeclaration(ModuleDeclaration* declaration) {
490 ASSERT(!HasStackOverflow()); 578 RECURSE(Visit(declaration->module()));
491 CHECK_ALIVE(Visit(declaration->module()));
492 } 579 }
493 580
494 581
495 void AstTyper::VisitImportDeclaration(ImportDeclaration* declaration) { 582 void AstTyper::VisitImportDeclaration(ImportDeclaration* declaration) {
496 ASSERT(!HasStackOverflow()); 583 RECURSE(Visit(declaration->module()));
497 CHECK_ALIVE(Visit(declaration->module()));
498 } 584 }
499 585
500 586
501 void AstTyper::VisitExportDeclaration(ExportDeclaration* declaration) { 587 void AstTyper::VisitExportDeclaration(ExportDeclaration* declaration) {
502 ASSERT(!HasStackOverflow());
503 } 588 }
504 589
505 590
506 void AstTyper::VisitModuleLiteral(ModuleLiteral* module) { 591 void AstTyper::VisitModuleLiteral(ModuleLiteral* module) {
507 ASSERT(!HasStackOverflow()); 592 RECURSE(Visit(module->body()));
508 CHECK_ALIVE(Visit(module->body()));
509 } 593 }
510 594
511 595
512 void AstTyper::VisitModuleVariable(ModuleVariable* module) { 596 void AstTyper::VisitModuleVariable(ModuleVariable* module) {
513 ASSERT(!HasStackOverflow());
514 } 597 }
515 598
516 599
517 void AstTyper::VisitModulePath(ModulePath* module) { 600 void AstTyper::VisitModulePath(ModulePath* module) {
518 ASSERT(!HasStackOverflow()); 601 RECURSE(Visit(module->module()));
519 CHECK_ALIVE(Visit(module->module()));
520 } 602 }
521 603
522 604
523 void AstTyper::VisitModuleUrl(ModuleUrl* module) { 605 void AstTyper::VisitModuleUrl(ModuleUrl* module) {
524 ASSERT(!HasStackOverflow());
525 } 606 }
526 607
527 608
528 void AstTyper::VisitModuleStatement(ModuleStatement* stmt) { 609 void AstTyper::VisitModuleStatement(ModuleStatement* stmt) {
529 ASSERT(!HasStackOverflow()); 610 RECURSE(Visit(stmt->body()));
530 CHECK_ALIVE(Visit(stmt->body()));
531 } 611 }
532 612
533 613
534 } } // namespace v8::internal 614 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/typing.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698