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

Side by Side Diff: src/typing.cc

Issue 18415005: Introduce type Bounds record (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 230 matching lines...) Expand 10 before | Expand all | Expand 10 after
241 } 241 }
242 242
243 243
244 void AstTyper::VisitConditional(Conditional* expr) { 244 void AstTyper::VisitConditional(Conditional* expr) {
245 RECURSE(Visit(expr->condition())); 245 RECURSE(Visit(expr->condition()));
246 RECURSE(Visit(expr->then_expression())); 246 RECURSE(Visit(expr->then_expression()));
247 RECURSE(Visit(expr->else_expression())); 247 RECURSE(Visit(expr->else_expression()));
248 248
249 expr->condition()->RecordToBooleanTypeFeedback(oracle()); 249 expr->condition()->RecordToBooleanTypeFeedback(oracle());
250 250
251 MergeLowerType(expr, Type::Intersect( 251 NarrowType(expr, Bounds::Either(
252 expr->then_expression()->lower_type(), 252 expr->then_expression()->bounds(),
253 expr->else_expression()->lower_type())); 253 expr->else_expression()->bounds(), isolate_));
254 MergeUpperType(expr, Type::Union(
255 expr->then_expression()->upper_type(),
256 expr->else_expression()->upper_type()));
257 } 254 }
258 255
259 256
260 void AstTyper::VisitVariableProxy(VariableProxy* expr) { 257 void AstTyper::VisitVariableProxy(VariableProxy* expr) {
261 // TODO(rossberg): typing of variables 258 // TODO(rossberg): typing of variables
262 } 259 }
263 260
264 261
265 void AstTyper::VisitLiteral(Literal* expr) { 262 void AstTyper::VisitLiteral(Literal* expr) {
266 Type* type = Type::Constant(expr->value(), isolate_); 263 Type* type = Type::Constant(expr->value(), isolate_);
267 MergeLowerType(expr, type); 264 NarrowType(expr, Bounds(type, isolate_));
268 MergeUpperType(expr, type);
269 } 265 }
270 266
271 267
272 void AstTyper::VisitRegExpLiteral(RegExpLiteral* expr) { 268 void AstTyper::VisitRegExpLiteral(RegExpLiteral* expr) {
273 MergeLowerType(expr, Type::RegExp()); 269 NarrowType(expr, Bounds(Type::RegExp(), isolate_));
274 MergeUpperType(expr, Type::RegExp());
275 } 270 }
276 271
277 272
278 void AstTyper::VisitObjectLiteral(ObjectLiteral* expr) { 273 void AstTyper::VisitObjectLiteral(ObjectLiteral* expr) {
279 ZoneList<ObjectLiteral::Property*>* properties = expr->properties(); 274 ZoneList<ObjectLiteral::Property*>* properties = expr->properties();
280 for (int i = 0; i < properties->length(); ++i) { 275 for (int i = 0; i < properties->length(); ++i) {
281 ObjectLiteral::Property* prop = properties->at(i); 276 ObjectLiteral::Property* prop = properties->at(i);
282 RECURSE(Visit(prop->value())); 277 RECURSE(Visit(prop->value()));
283 278
284 if ((prop->kind() == ObjectLiteral::Property::MATERIALIZED_LITERAL && 279 if ((prop->kind() == ObjectLiteral::Property::MATERIALIZED_LITERAL &&
285 !CompileTimeValue::IsCompileTimeValue(prop->value())) || 280 !CompileTimeValue::IsCompileTimeValue(prop->value())) ||
286 prop->kind() == ObjectLiteral::Property::COMPUTED) { 281 prop->kind() == ObjectLiteral::Property::COMPUTED) {
287 if (prop->key()->value()->IsInternalizedString() && prop->emit_store()) { 282 if (prop->key()->value()->IsInternalizedString() && prop->emit_store()) {
288 prop->RecordTypeFeedback(oracle()); 283 prop->RecordTypeFeedback(oracle());
289 } 284 }
290 } 285 }
291 } 286 }
292 287
293 MergeLowerType(expr, Type::Object()); 288 NarrowType(expr, Bounds(Type::Object(), isolate_));
294 MergeUpperType(expr, Type::Object());
295 } 289 }
296 290
297 291
298 void AstTyper::VisitArrayLiteral(ArrayLiteral* expr) { 292 void AstTyper::VisitArrayLiteral(ArrayLiteral* expr) {
299 ZoneList<Expression*>* values = expr->values(); 293 ZoneList<Expression*>* values = expr->values();
300 for (int i = 0; i < values->length(); ++i) { 294 for (int i = 0; i < values->length(); ++i) {
301 Expression* value = values->at(i); 295 Expression* value = values->at(i);
302 RECURSE(Visit(value)); 296 RECURSE(Visit(value));
303 } 297 }
304 298
305 MergeLowerType(expr, Type::Array()); 299 NarrowType(expr, Bounds(Type::Array(), isolate_));
306 MergeUpperType(expr, Type::Array());
307 } 300 }
308 301
309 302
310 void AstTyper::VisitAssignment(Assignment* expr) { 303 void AstTyper::VisitAssignment(Assignment* expr) {
311 // TODO(rossberg): Can we clean this up? 304 // TODO(rossberg): Can we clean this up?
312 if (expr->is_compound()) { 305 if (expr->is_compound()) {
313 RECURSE(Visit(expr->binary_operation())); 306 RECURSE(Visit(expr->binary_operation()));
314 307
315 Expression* target = expr->target(); 308 Expression* target = expr->target();
316 Property* prop = target->AsProperty(); 309 Property* prop = target->AsProperty();
317 if (prop != NULL) { 310 if (prop != NULL) {
318 prop->RecordTypeFeedback(oracle(), zone()); 311 prop->RecordTypeFeedback(oracle(), zone());
319 if (!prop->key()->IsPropertyName()) { // i.e., keyed 312 if (!prop->key()->IsPropertyName()) { // i.e., keyed
320 expr->RecordTypeFeedback(oracle(), zone()); 313 expr->RecordTypeFeedback(oracle(), zone());
321 } 314 }
322 } 315 }
316
317 NarrowType(expr, expr->binary_operation()->bounds());
323 } else { 318 } else {
324 RECURSE(Visit(expr->target())); 319 RECURSE(Visit(expr->target()));
325 RECURSE(Visit(expr->value())); 320 RECURSE(Visit(expr->value()));
326 321
327 if (expr->target()->AsProperty()) { 322 if (expr->target()->AsProperty()) {
328 expr->RecordTypeFeedback(oracle(), zone()); 323 expr->RecordTypeFeedback(oracle(), zone());
329 } 324 }
330 325
331 MergeLowerType(expr, expr->value()->lower_type()); 326 NarrowType(expr, expr->value()->bounds());
332 MergeUpperType(expr, expr->value()->upper_type());
333 } 327 }
334 // TODO(rossberg): handle target variables 328 // TODO(rossberg): handle target variables
335 } 329 }
336 330
337 331
338 void AstTyper::VisitYield(Yield* expr) { 332 void AstTyper::VisitYield(Yield* expr) {
339 RECURSE(Visit(expr->generator_object())); 333 RECURSE(Visit(expr->generator_object()));
340 RECURSE(Visit(expr->expression())); 334 RECURSE(Visit(expr->expression()));
341 335
342 // We don't know anything about the type. 336 // We don't know anything about the type.
343 } 337 }
344 338
345 339
346 void AstTyper::VisitThrow(Throw* expr) { 340 void AstTyper::VisitThrow(Throw* expr) {
347 RECURSE(Visit(expr->exception())); 341 RECURSE(Visit(expr->exception()));
348 342
349 // Lower type is None already. 343 NarrowType(expr, Bounds(Type::None(), isolate_));
350 MergeUpperType(expr, Type::None());
351 } 344 }
352 345
353 346
354 void AstTyper::VisitProperty(Property* expr) { 347 void AstTyper::VisitProperty(Property* expr) {
355 RECURSE(Visit(expr->obj())); 348 RECURSE(Visit(expr->obj()));
356 RECURSE(Visit(expr->key())); 349 RECURSE(Visit(expr->key()));
357 350
358 expr->RecordTypeFeedback(oracle(), zone()); 351 expr->RecordTypeFeedback(oracle(), zone());
359 352
360 // We don't know anything about the type. 353 // We don't know anything about the type.
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
405 398
406 // We don't know anything about the type. 399 // We don't know anything about the type.
407 } 400 }
408 401
409 402
410 void AstTyper::VisitUnaryOperation(UnaryOperation* expr) { 403 void AstTyper::VisitUnaryOperation(UnaryOperation* expr) {
411 RECURSE(Visit(expr->expression())); 404 RECURSE(Visit(expr->expression()));
412 405
413 // Collect type feedback. 406 // Collect type feedback.
414 Handle<Type> op_type = oracle()->UnaryType(expr->UnaryOperationFeedbackId()); 407 Handle<Type> op_type = oracle()->UnaryType(expr->UnaryOperationFeedbackId());
415 MergeLowerType(expr->expression(), op_type); 408 NarrowLowerType(expr->expression(), op_type);
416 if (expr->op() == Token::NOT) { 409 if (expr->op() == Token::NOT) {
417 // TODO(rossberg): only do in test or value context. 410 // TODO(rossberg): only do in test or value context.
418 expr->expression()->RecordToBooleanTypeFeedback(oracle()); 411 expr->expression()->RecordToBooleanTypeFeedback(oracle());
419 } 412 }
420 413
421 switch (expr->op()) { 414 switch (expr->op()) {
422 case Token::NOT: 415 case Token::NOT:
423 case Token::DELETE: 416 case Token::DELETE:
424 MergeLowerType(expr, Type::Boolean()); 417 NarrowType(expr, Bounds(Type::Boolean(), isolate_));
425 MergeUpperType(expr, Type::Boolean());
426 break; 418 break;
427 case Token::VOID: 419 case Token::VOID:
428 MergeLowerType(expr, Type::Undefined()); 420 NarrowType(expr, Bounds(Type::Undefined(), isolate_));
429 MergeUpperType(expr, Type::Undefined());
430 break; 421 break;
431 case Token::ADD: 422 case Token::ADD:
432 case Token::SUB: { 423 case Token::SUB: {
433 MergeLowerType(expr, Type::Smi()); 424 Type* upper = *expr->expression()->bounds().upper;
434 Type* upper = *expr->expression()->upper_type(); 425 if (!upper->Is(Type::Number())) upper = Type::Number();
435 MergeUpperType(expr, upper->Is(Type::Number()) ? upper : Type::Number()); 426 NarrowType(expr, Bounds(Type::Smi(), upper, isolate_));
436 break; 427 break;
437 } 428 }
438 case Token::BIT_NOT: 429 case Token::BIT_NOT:
439 MergeLowerType(expr, Type::Smi()); 430 NarrowType(expr, Bounds(Type::Smi(), Type::Signed32(), isolate_));
440 MergeUpperType(expr, Type::Signed32());
441 break; 431 break;
442 case Token::TYPEOF: 432 case Token::TYPEOF:
443 MergeLowerType(expr, Type::InternalizedString()); 433 NarrowType(expr, Bounds(Type::InternalizedString(), isolate_));
444 MergeUpperType(expr, Type::InternalizedString());
445 break; 434 break;
446 default: 435 default:
447 UNREACHABLE(); 436 UNREACHABLE();
448 } 437 }
449 } 438 }
450 439
451 440
452 void AstTyper::VisitCountOperation(CountOperation* expr) { 441 void AstTyper::VisitCountOperation(CountOperation* expr) {
453 RECURSE(Visit(expr->expression())); 442 RECURSE(Visit(expr->expression()));
454 443
455 expr->RecordTypeFeedback(oracle(), zone()); 444 expr->RecordTypeFeedback(oracle(), zone());
456 Property* prop = expr->expression()->AsProperty(); 445 Property* prop = expr->expression()->AsProperty();
457 if (prop != NULL) { 446 if (prop != NULL) {
458 prop->RecordTypeFeedback(oracle(), zone()); 447 prop->RecordTypeFeedback(oracle(), zone());
459 } 448 }
460 449
461 MergeLowerType(expr, Type::Smi()); 450 NarrowType(expr, Bounds(Type::Smi(), Type::Number(), isolate_));
462 MergeUpperType(expr, Type::Number());
463 } 451 }
464 452
465 453
466 void AstTyper::VisitBinaryOperation(BinaryOperation* expr) { 454 void AstTyper::VisitBinaryOperation(BinaryOperation* expr) {
467 RECURSE(Visit(expr->left())); 455 RECURSE(Visit(expr->left()));
468 RECURSE(Visit(expr->right())); 456 RECURSE(Visit(expr->right()));
469 457
470 // Collect type feedback. 458 // Collect type feedback.
471 Handle<Type> type, left_type, right_type; 459 Handle<Type> type, left_type, right_type;
472 Maybe<int> fixed_right_arg; 460 Maybe<int> fixed_right_arg;
473 oracle()->BinaryType(expr->BinaryOperationFeedbackId(), 461 oracle()->BinaryType(expr->BinaryOperationFeedbackId(),
474 &left_type, &right_type, &type, &fixed_right_arg); 462 &left_type, &right_type, &type, &fixed_right_arg);
475 MergeLowerType(expr, type); 463 NarrowLowerType(expr, type);
476 MergeLowerType(expr->left(), left_type); 464 NarrowLowerType(expr->left(), left_type);
477 MergeLowerType(expr->right(), right_type); 465 NarrowLowerType(expr->right(), right_type);
478 expr->set_fixed_right_arg(fixed_right_arg); 466 expr->set_fixed_right_arg(fixed_right_arg);
479 if (expr->op() == Token::OR || expr->op() == Token::AND) { 467 if (expr->op() == Token::OR || expr->op() == Token::AND) {
480 expr->left()->RecordToBooleanTypeFeedback(oracle()); 468 expr->left()->RecordToBooleanTypeFeedback(oracle());
481 } 469 }
482 470
483 switch (expr->op()) { 471 switch (expr->op()) {
484 case Token::COMMA: 472 case Token::COMMA:
485 MergeLowerType(expr, expr->right()->lower_type()); 473 NarrowType(expr, expr->right()->bounds());
486 MergeUpperType(expr, expr->right()->upper_type());
487 break; 474 break;
488 case Token::OR: 475 case Token::OR:
489 case Token::AND: 476 case Token::AND:
490 MergeLowerType(expr, Type::Intersect( 477 NarrowType(expr, Bounds::Either(
491 expr->left()->lower_type(), expr->right()->lower_type())); 478 expr->left()->bounds(), expr->right()->bounds(), isolate_));
492 MergeUpperType(expr, Type::Union(
493 expr->left()->upper_type(), expr->right()->upper_type()));
494 break; 479 break;
495 case Token::BIT_OR: 480 case Token::BIT_OR:
496 case Token::BIT_AND: { 481 case Token::BIT_AND: {
497 MergeLowerType(expr, Type::Smi()); 482 Type* upper = Type::Union(
498 Type* upper = 483 expr->left()->bounds().upper, expr->right()->bounds().upper);
499 Type::Union(expr->left()->upper_type(), expr->right()->upper_type()); 484 if (!upper->Is(Type::Signed32())) upper = Type::Signed32();
500 MergeUpperType(expr, 485 NarrowType(expr, Bounds(Type::Smi(), upper, isolate_));
501 upper->Is(Type::Signed32()) ? upper : Type::Signed32());
502 break; 486 break;
503 } 487 }
504 case Token::BIT_XOR: 488 case Token::BIT_XOR:
505 case Token::SHL: 489 case Token::SHL:
506 case Token::SAR: 490 case Token::SAR:
507 MergeLowerType(expr, Type::Smi()); 491 NarrowType(expr, Bounds(Type::Smi(), Type::Signed32(), isolate_));
508 MergeUpperType(expr, Type::Signed32());
509 break; 492 break;
510 case Token::SHR: 493 case Token::SHR:
511 MergeLowerType(expr, Type::Smi()); 494 NarrowType(expr, Bounds(Type::Smi(), Type::Unsigned32(), isolate_));
512 MergeUpperType(expr, Type::Unsigned32());
513 break; 495 break;
514 case Token::ADD: { 496 case Token::ADD: {
515 Handle<Type> l = expr->left()->lower_type(); 497 Bounds l = expr->left()->bounds();
516 Handle<Type> r = expr->right()->lower_type(); 498 Bounds r = expr->right()->bounds();
517 MergeLowerType(expr, 499 Type* lower =
518 l->Is(Type::Number()) && r->Is(Type::Number()) ? Type::Smi() : 500 l.lower->Is(Type::Number()) && r.lower->Is(Type::Number()) ?
519 l->Is(Type::String()) || r->Is(Type::String()) ? Type::String() : 501 Type::Smi() :
520 Type::None()); 502 l.lower->Is(Type::String()) || r.lower->Is(Type::String()) ?
521 l = expr->left()->upper_type(); 503 Type::String() : Type::None();
522 r = expr->right()->upper_type(); 504 Type* upper =
523 MergeUpperType(expr, 505 l.upper->Is(Type::Number()) && r.upper->Is(Type::Number()) ?
524 l->Is(Type::Number()) && r->Is(Type::Number()) ? Type::Number() : 506 Type::Number() :
525 l->Is(Type::String()) || r->Is(Type::String()) ? Type::String() : 507 l.upper->Is(Type::String()) || r.upper->Is(Type::String()) ?
526 Type::NumberOrString()); 508 Type::String() : Type::NumberOrString();
509 NarrowType(expr, Bounds(lower, upper, isolate_));
527 break; 510 break;
528 } 511 }
529 case Token::SUB: 512 case Token::SUB:
530 case Token::MUL: 513 case Token::MUL:
531 case Token::DIV: 514 case Token::DIV:
532 case Token::MOD: 515 case Token::MOD:
533 MergeLowerType(expr, Type::Smi()); 516 NarrowType(expr, Bounds(Type::Smi(), Type::Number(), isolate_));
534 MergeUpperType(expr, Type::Number());
535 break; 517 break;
536 default: 518 default:
537 UNREACHABLE(); 519 UNREACHABLE();
538 } 520 }
539 } 521 }
540 522
541 523
542 void AstTyper::VisitCompareOperation(CompareOperation* expr) { 524 void AstTyper::VisitCompareOperation(CompareOperation* expr) {
543 RECURSE(Visit(expr->left())); 525 RECURSE(Visit(expr->left()));
544 RECURSE(Visit(expr->right())); 526 RECURSE(Visit(expr->right()));
545 527
546 // Collect type feedback. 528 // Collect type feedback.
547 Handle<Type> left_type, right_type, combined_type; 529 Handle<Type> left_type, right_type, combined_type;
548 oracle()->CompareType(expr->CompareOperationFeedbackId(), 530 oracle()->CompareType(expr->CompareOperationFeedbackId(),
549 &left_type, &right_type, &combined_type); 531 &left_type, &right_type, &combined_type);
550 MergeLowerType(expr->left(), left_type); 532 NarrowLowerType(expr->left(), left_type);
551 MergeLowerType(expr->right(), right_type); 533 NarrowLowerType(expr->right(), right_type);
552 expr->set_combined_type(combined_type); 534 expr->set_combined_type(combined_type);
553 535
554 MergeLowerType(expr, Type::Boolean()); 536 NarrowType(expr, Bounds(Type::Boolean(), isolate_));
555 MergeUpperType(expr, Type::Boolean());
556 } 537 }
557 538
558 539
559 void AstTyper::VisitThisFunction(ThisFunction* expr) { 540 void AstTyper::VisitThisFunction(ThisFunction* expr) {
560 } 541 }
561 542
562 543
563 void AstTyper::VisitDeclarations(ZoneList<Declaration*>* decls) { 544 void AstTyper::VisitDeclarations(ZoneList<Declaration*>* decls) {
564 for (int i = 0; i < decls->length(); ++i) { 545 for (int i = 0; i < decls->length(); ++i) {
565 Declaration* decl = decls->at(i); 546 Declaration* decl = decls->at(i);
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
608 void AstTyper::VisitModuleUrl(ModuleUrl* module) { 589 void AstTyper::VisitModuleUrl(ModuleUrl* module) {
609 } 590 }
610 591
611 592
612 void AstTyper::VisitModuleStatement(ModuleStatement* stmt) { 593 void AstTyper::VisitModuleStatement(ModuleStatement* stmt) {
613 RECURSE(Visit(stmt->body())); 594 RECURSE(Visit(stmt->body()));
614 } 595 }
615 596
616 597
617 } } // namespace v8::internal 598 } } // 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