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

Side by Side Diff: src/typing.cc

Issue 18895002: Unrevert^2 "Derive synthetic type bounds for expressions"" (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: 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::Intersect(
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());
289 }
300 } 290 }
301 } 291 }
292
293 MergeLowerType(expr, Type::Object());
294 MergeUpperType(expr, Type::Object());
302 } 295 }
303 296
304 297
305 void AstTyper::VisitArrayLiteral(ArrayLiteral* expr) { 298 void AstTyper::VisitArrayLiteral(ArrayLiteral* expr) {
306 ASSERT(!HasStackOverflow());
307 ZoneList<Expression*>* values = expr->values(); 299 ZoneList<Expression*>* values = expr->values();
308 for (int i = 0; i < values->length(); ++i) { 300 for (int i = 0; i < values->length(); ++i) {
309 Expression* value = values->at(i); 301 Expression* value = values->at(i);
310 CHECK_ALIVE(Visit(value)); 302 RECURSE(Visit(value));
311 } 303 }
304
305 MergeLowerType(expr, Type::Array());
306 MergeUpperType(expr, Type::Array());
312 } 307 }
313 308
314 309
315 void AstTyper::VisitAssignment(Assignment* expr) { 310 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? 311 // TODO(rossberg): Can we clean this up?
321 if (expr->is_compound()) { 312 if (expr->is_compound()) {
322 CHECK_ALIVE(Visit(expr->binary_operation())); 313 RECURSE(Visit(expr->binary_operation()));
323 314
324 Expression* target = expr->target(); 315 Expression* target = expr->target();
325 Property* prop = target->AsProperty(); 316 Property* prop = target->AsProperty();
326 if (prop != NULL) { 317 if (prop != NULL) {
327 prop->RecordTypeFeedback(oracle(), zone()); 318 prop->RecordTypeFeedback(oracle(), zone());
328 if (!prop->key()->IsPropertyName()) // i.e., keyed 319 if (!prop->key()->IsPropertyName()) { // i.e., keyed
329 expr->RecordTypeFeedback(oracle(), zone()); 320 expr->RecordTypeFeedback(oracle(), zone());
321 }
330 } 322 }
331 return; 323 } else {
324 RECURSE(Visit(expr->target()));
325 RECURSE(Visit(expr->value()));
326
327 if (expr->target()->AsProperty()) {
328 expr->RecordTypeFeedback(oracle(), zone());
329 }
330
331 MergeLowerType(expr, expr->value()->lower_type());
332 MergeUpperType(expr, expr->value()->upper_type());
332 } 333 }
333 if (expr->target()->AsProperty()) 334 // TODO(rossberg): handle target variables
334 expr->RecordTypeFeedback(oracle(), zone());
335 } 335 }
336 336
337 337
338 void AstTyper::VisitYield(Yield* expr) { 338 void AstTyper::VisitYield(Yield* expr) {
339 ASSERT(!HasStackOverflow()); 339 RECURSE(Visit(expr->generator_object()));
340 CHECK_ALIVE(Visit(expr->generator_object())); 340 RECURSE(Visit(expr->expression()));
341 CHECK_ALIVE(Visit(expr->expression())); 341
342 // We don't know anything about the type.
342 } 343 }
343 344
344 345
345 void AstTyper::VisitThrow(Throw* expr) { 346 void AstTyper::VisitThrow(Throw* expr) {
346 ASSERT(!HasStackOverflow()); 347 RECURSE(Visit(expr->exception()));
347 CHECK_ALIVE(Visit(expr->exception())); 348
349 // Lower type is None already.
350 MergeUpperType(expr, Type::None());
348 } 351 }
349 352
350 353
351 void AstTyper::VisitProperty(Property* expr) { 354 void AstTyper::VisitProperty(Property* expr) {
352 ASSERT(!HasStackOverflow()); 355 RECURSE(Visit(expr->obj()));
353 CHECK_ALIVE(Visit(expr->obj())); 356 RECURSE(Visit(expr->key()));
354 CHECK_ALIVE(Visit(expr->key()));
355 357
356 expr->RecordTypeFeedback(oracle(), zone()); 358 expr->RecordTypeFeedback(oracle(), zone());
359
360 // We don't know anything about the type.
357 } 361 }
358 362
359 363
360 void AstTyper::VisitCall(Call* expr) { 364 void AstTyper::VisitCall(Call* expr) {
361 ASSERT(!HasStackOverflow()); 365 RECURSE(Visit(expr->expression()));
362 CHECK_ALIVE(Visit(expr->expression()));
363 ZoneList<Expression*>* args = expr->arguments(); 366 ZoneList<Expression*>* args = expr->arguments();
364 for (int i = 0; i < args->length(); ++i) { 367 for (int i = 0; i < args->length(); ++i) {
365 Expression* arg = args->at(i); 368 Expression* arg = args->at(i);
366 CHECK_ALIVE(Visit(arg)); 369 RECURSE(Visit(arg));
367 } 370 }
368 371
369 Expression* callee = expr->expression(); 372 Expression* callee = expr->expression();
370 Property* prop = callee->AsProperty(); 373 Property* prop = callee->AsProperty();
371 if (prop != NULL) { 374 if (prop != NULL) {
372 if (prop->key()->IsPropertyName()) 375 if (prop->key()->IsPropertyName())
373 expr->RecordTypeFeedback(oracle(), CALL_AS_METHOD); 376 expr->RecordTypeFeedback(oracle(), CALL_AS_METHOD);
374 } else { 377 } else {
375 expr->RecordTypeFeedback(oracle(), CALL_AS_FUNCTION); 378 expr->RecordTypeFeedback(oracle(), CALL_AS_FUNCTION);
376 } 379 }
380
381 // We don't know anything about the type.
377 } 382 }
378 383
379 384
380 void AstTyper::VisitCallNew(CallNew* expr) { 385 void AstTyper::VisitCallNew(CallNew* expr) {
381 ASSERT(!HasStackOverflow()); 386 RECURSE(Visit(expr->expression()));
382 CHECK_ALIVE(Visit(expr->expression()));
383 ZoneList<Expression*>* args = expr->arguments(); 387 ZoneList<Expression*>* args = expr->arguments();
384 for (int i = 0; i < args->length(); ++i) { 388 for (int i = 0; i < args->length(); ++i) {
385 Expression* arg = args->at(i); 389 Expression* arg = args->at(i);
386 CHECK_ALIVE(Visit(arg)); 390 RECURSE(Visit(arg));
387 } 391 }
388 392
389 expr->RecordTypeFeedback(oracle()); 393 expr->RecordTypeFeedback(oracle());
394
395 // We don't know anything about the type.
390 } 396 }
391 397
392 398
393 void AstTyper::VisitCallRuntime(CallRuntime* expr) { 399 void AstTyper::VisitCallRuntime(CallRuntime* expr) {
394 ASSERT(!HasStackOverflow());
395 ZoneList<Expression*>* args = expr->arguments(); 400 ZoneList<Expression*>* args = expr->arguments();
396 for (int i = 0; i < args->length(); ++i) { 401 for (int i = 0; i < args->length(); ++i) {
397 Expression* arg = args->at(i); 402 Expression* arg = args->at(i);
398 CHECK_ALIVE(Visit(arg)); 403 RECURSE(Visit(arg));
399 } 404 }
405
406 // We don't know anything about the type.
400 } 407 }
401 408
402 409
403 void AstTyper::VisitUnaryOperation(UnaryOperation* expr) { 410 void AstTyper::VisitUnaryOperation(UnaryOperation* expr) {
404 ASSERT(!HasStackOverflow()); 411 RECURSE(Visit(expr->expression()));
405 CHECK_ALIVE(Visit(expr->expression()));
406 412
407 // Collect type feedback. 413 // Collect type feedback.
408 Handle<Type> op_type = oracle()->UnaryType(expr->UnaryOperationFeedbackId()); 414 Handle<Type> op_type = oracle()->UnaryType(expr->UnaryOperationFeedbackId());
409 MergeLowerType(expr->expression(), op_type); 415 MergeLowerType(expr->expression(), op_type);
410 if (expr->op() == Token::NOT) { 416 if (expr->op() == Token::NOT) {
411 // TODO(rossberg): only do in test or value context. 417 // TODO(rossberg): only do in test or value context.
412 expr->expression()->RecordToBooleanTypeFeedback(oracle()); 418 expr->expression()->RecordToBooleanTypeFeedback(oracle());
413 } 419 }
420
421 switch (expr->op()) {
422 case Token::NOT:
423 case Token::DELETE:
424 MergeLowerType(expr, Type::Boolean());
425 MergeUpperType(expr, Type::Boolean());
426 break;
427 case Token::VOID:
428 MergeLowerType(expr, Type::Undefined());
429 MergeUpperType(expr, Type::Undefined());
430 break;
431 case Token::ADD:
432 case Token::SUB: {
433 MergeLowerType(expr, Type::Smi());
434 Type* upper = *expr->expression()->upper_type();
435 MergeUpperType(expr, upper->Is(Type::Number()) ? upper : Type::Number());
436 break;
437 }
438 case Token::BIT_NOT:
439 MergeLowerType(expr, Type::Smi());
440 MergeUpperType(expr, Type::Signed32());
441 break;
442 case Token::TYPEOF:
443 MergeLowerType(expr, Type::InternalizedString());
444 MergeUpperType(expr, Type::InternalizedString());
445 break;
446 default:
447 UNREACHABLE();
448 }
414 } 449 }
415 450
416 451
417 void AstTyper::VisitCountOperation(CountOperation* expr) { 452 void AstTyper::VisitCountOperation(CountOperation* expr) {
418 ASSERT(!HasStackOverflow()); 453 RECURSE(Visit(expr->expression()));
419 CHECK_ALIVE(Visit(expr->expression()));
420 454
421 expr->RecordTypeFeedback(oracle(), zone()); 455 expr->RecordTypeFeedback(oracle(), zone());
422 Property* prop = expr->expression()->AsProperty(); 456 Property* prop = expr->expression()->AsProperty();
423 if (prop != NULL) { 457 if (prop != NULL) {
424 prop->RecordTypeFeedback(oracle(), zone()); 458 prop->RecordTypeFeedback(oracle(), zone());
425 } 459 }
460
461 MergeLowerType(expr, Type::Smi());
462 MergeUpperType(expr, Type::Number());
426 } 463 }
427 464
428 465
429 void AstTyper::VisitBinaryOperation(BinaryOperation* expr) { 466 void AstTyper::VisitBinaryOperation(BinaryOperation* expr) {
430 ASSERT(!HasStackOverflow()); 467 RECURSE(Visit(expr->left()));
431 CHECK_ALIVE(Visit(expr->left())); 468 RECURSE(Visit(expr->right()));
432 CHECK_ALIVE(Visit(expr->right()));
433 469
434 // Collect type feedback. 470 // Collect type feedback.
435 Handle<Type> type, left_type, right_type; 471 Handle<Type> type, left_type, right_type;
436 Maybe<int> fixed_right_arg; 472 Maybe<int> fixed_right_arg;
437 oracle()->BinaryType(expr->BinaryOperationFeedbackId(), 473 oracle()->BinaryType(expr->BinaryOperationFeedbackId(),
438 &left_type, &right_type, &type, &fixed_right_arg); 474 &left_type, &right_type, &type, &fixed_right_arg);
439 MergeLowerType(expr, type); 475 MergeLowerType(expr, type);
440 MergeLowerType(expr->left(), left_type); 476 MergeLowerType(expr->left(), left_type);
441 MergeLowerType(expr->right(), right_type); 477 MergeLowerType(expr->right(), right_type);
442 expr->set_fixed_right_arg(fixed_right_arg); 478 expr->set_fixed_right_arg(fixed_right_arg);
443 if (expr->op() == Token::OR || expr->op() == Token::AND) { 479 if (expr->op() == Token::OR || expr->op() == Token::AND) {
444 expr->left()->RecordToBooleanTypeFeedback(oracle()); 480 expr->left()->RecordToBooleanTypeFeedback(oracle());
445 } 481 }
482
483 switch (expr->op()) {
484 case Token::COMMA:
485 MergeLowerType(expr, expr->right()->lower_type());
486 MergeUpperType(expr, expr->right()->upper_type());
487 break;
488 case Token::OR:
489 case Token::AND:
490 MergeLowerType(expr, Type::Intersect(
491 expr->left()->lower_type(), expr->right()->lower_type()));
492 MergeUpperType(expr, Type::Union(
493 expr->left()->upper_type(), expr->right()->upper_type()));
494 break;
495 case Token::BIT_OR:
496 case Token::BIT_AND: {
497 MergeLowerType(expr, Type::Smi());
498 Type* upper =
499 Type::Union(expr->left()->upper_type(), expr->right()->upper_type());
500 MergeUpperType(expr,
501 upper->Is(Type::Signed32()) ? upper : Type::Signed32());
502 break;
503 }
504 case Token::BIT_XOR:
505 case Token::SHL:
506 case Token::SAR:
507 MergeLowerType(expr, Type::Smi());
508 MergeUpperType(expr, Type::Signed32());
509 break;
510 case Token::SHR:
511 MergeLowerType(expr, Type::Smi());
512 MergeUpperType(expr, Type::Unsigned32());
513 break;
514 case Token::ADD: {
515 Handle<Type> l = expr->left()->lower_type();
516 Handle<Type> r = expr->right()->lower_type();
517 MergeLowerType(expr,
518 l->Is(Type::Number()) && r->Is(Type::Number()) ? Type::Smi() :
519 l->Is(Type::String()) || r->Is(Type::String()) ? Type::String() :
520 Type::None());
521 l = expr->left()->upper_type();
522 r = expr->right()->upper_type();
523 MergeUpperType(expr,
524 l->Is(Type::Number()) && r->Is(Type::Number()) ? Type::Number() :
525 l->Is(Type::String()) || r->Is(Type::String()) ? Type::String() :
526 Type::NumberOrString());
527 break;
528 }
529 case Token::SUB:
530 case Token::MUL:
531 case Token::DIV:
532 case Token::MOD:
533 MergeLowerType(expr, Type::Smi());
534 MergeUpperType(expr, Type::Number());
535 break;
536 default:
537 UNREACHABLE();
538 }
446 } 539 }
447 540
448 541
449 void AstTyper::VisitCompareOperation(CompareOperation* expr) { 542 void AstTyper::VisitCompareOperation(CompareOperation* expr) {
450 ASSERT(!HasStackOverflow()); 543 RECURSE(Visit(expr->left()));
451 CHECK_ALIVE(Visit(expr->left())); 544 RECURSE(Visit(expr->right()));
452 CHECK_ALIVE(Visit(expr->right()));
453 545
454 // Collect type feedback. 546 // Collect type feedback.
455 Handle<Type> left_type, right_type, combined_type; 547 Handle<Type> left_type, right_type, combined_type;
456 oracle()->CompareType(expr->CompareOperationFeedbackId(), 548 oracle()->CompareType(expr->CompareOperationFeedbackId(),
457 &left_type, &right_type, &combined_type); 549 &left_type, &right_type, &combined_type);
458 MergeLowerType(expr->left(), left_type); 550 MergeLowerType(expr->left(), left_type);
459 MergeLowerType(expr->right(), right_type); 551 MergeLowerType(expr->right(), right_type);
460 expr->set_combined_type(combined_type); 552 expr->set_combined_type(combined_type);
553
554 MergeLowerType(expr, Type::Boolean());
555 MergeUpperType(expr, Type::Boolean());
461 } 556 }
462 557
463 558
464 void AstTyper::VisitThisFunction(ThisFunction* expr) { 559 void AstTyper::VisitThisFunction(ThisFunction* expr) {
465 ASSERT(!HasStackOverflow());
466 } 560 }
467 561
468 562
469 void AstTyper::VisitDeclarations(ZoneList<Declaration*>* decls) { 563 void AstTyper::VisitDeclarations(ZoneList<Declaration*>* decls) {
470 ASSERT(!HasStackOverflow());
471 for (int i = 0; i < decls->length(); ++i) { 564 for (int i = 0; i < decls->length(); ++i) {
472 Declaration* decl = decls->at(i); 565 Declaration* decl = decls->at(i);
473 CHECK_ALIVE(Visit(decl)); 566 RECURSE(Visit(decl));
474 } 567 }
475 } 568 }
476 569
477 570
478 void AstTyper::VisitVariableDeclaration(VariableDeclaration* declaration) { 571 void AstTyper::VisitVariableDeclaration(VariableDeclaration* declaration) {
479 ASSERT(!HasStackOverflow());
480 } 572 }
481 573
482 574
483 void AstTyper::VisitFunctionDeclaration(FunctionDeclaration* declaration) { 575 void AstTyper::VisitFunctionDeclaration(FunctionDeclaration* declaration) {
484 ASSERT(!HasStackOverflow()); 576 RECURSE(Visit(declaration->fun()));
485 CHECK_ALIVE(Visit(declaration->fun()));
486 } 577 }
487 578
488 579
489 void AstTyper::VisitModuleDeclaration(ModuleDeclaration* declaration) { 580 void AstTyper::VisitModuleDeclaration(ModuleDeclaration* declaration) {
490 ASSERT(!HasStackOverflow()); 581 RECURSE(Visit(declaration->module()));
491 CHECK_ALIVE(Visit(declaration->module()));
492 } 582 }
493 583
494 584
495 void AstTyper::VisitImportDeclaration(ImportDeclaration* declaration) { 585 void AstTyper::VisitImportDeclaration(ImportDeclaration* declaration) {
496 ASSERT(!HasStackOverflow()); 586 RECURSE(Visit(declaration->module()));
497 CHECK_ALIVE(Visit(declaration->module()));
498 } 587 }
499 588
500 589
501 void AstTyper::VisitExportDeclaration(ExportDeclaration* declaration) { 590 void AstTyper::VisitExportDeclaration(ExportDeclaration* declaration) {
502 ASSERT(!HasStackOverflow());
503 } 591 }
504 592
505 593
506 void AstTyper::VisitModuleLiteral(ModuleLiteral* module) { 594 void AstTyper::VisitModuleLiteral(ModuleLiteral* module) {
507 ASSERT(!HasStackOverflow()); 595 RECURSE(Visit(module->body()));
508 CHECK_ALIVE(Visit(module->body()));
509 } 596 }
510 597
511 598
512 void AstTyper::VisitModuleVariable(ModuleVariable* module) { 599 void AstTyper::VisitModuleVariable(ModuleVariable* module) {
513 ASSERT(!HasStackOverflow());
514 } 600 }
515 601
516 602
517 void AstTyper::VisitModulePath(ModulePath* module) { 603 void AstTyper::VisitModulePath(ModulePath* module) {
518 ASSERT(!HasStackOverflow()); 604 RECURSE(Visit(module->module()));
519 CHECK_ALIVE(Visit(module->module()));
520 } 605 }
521 606
522 607
523 void AstTyper::VisitModuleUrl(ModuleUrl* module) { 608 void AstTyper::VisitModuleUrl(ModuleUrl* module) {
524 ASSERT(!HasStackOverflow());
525 } 609 }
526 610
527 611
528 void AstTyper::VisitModuleStatement(ModuleStatement* stmt) { 612 void AstTyper::VisitModuleStatement(ModuleStatement* stmt) {
529 ASSERT(!HasStackOverflow()); 613 RECURSE(Visit(stmt->body()));
530 CHECK_ALIVE(Visit(stmt->body()));
531 } 614 }
532 615
533 616
534 } } // namespace v8::internal 617 } } // 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