| OLD | NEW | 
|---|
| 1 // Copyright 2009 the V8 project authors. All rights reserved. | 1 // Copyright 2009 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 424 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 435       if (!result_saved) __ push(eax); | 435       if (!result_saved) __ push(eax); | 
| 436       break; | 436       break; | 
| 437   } | 437   } | 
| 438 } | 438 } | 
| 439 | 439 | 
| 440 | 440 | 
| 441 void FastCodeGenerator::VisitAssignment(Assignment* expr) { | 441 void FastCodeGenerator::VisitAssignment(Assignment* expr) { | 
| 442   Comment cmnt(masm_, "[ Assignment"); | 442   Comment cmnt(masm_, "[ Assignment"); | 
| 443   ASSERT(expr->op() == Token::ASSIGN || expr->op() == Token::INIT_VAR); | 443   ASSERT(expr->op() == Token::ASSIGN || expr->op() == Token::INIT_VAR); | 
| 444 | 444 | 
| 445   // Left-hand side can only be a global or a (parameter or local) slot. | 445   // Record the source position for the assignment. | 
|  | 446   SetSourcePosition(expr->position()); | 
|  | 447 | 
|  | 448   // Left-hand side can only be a property, a global or | 
|  | 449   // a (parameter or local) slot. | 
| 446   Variable* var = expr->target()->AsVariableProxy()->AsVariable(); | 450   Variable* var = expr->target()->AsVariableProxy()->AsVariable(); | 
| 447   ASSERT(var != NULL); |  | 
| 448   ASSERT(var->is_global() || var->slot() != NULL); |  | 
| 449 |  | 
| 450   Expression* rhs = expr->value(); | 451   Expression* rhs = expr->value(); | 
| 451   if (var->is_global()) { | 452   if (var == NULL) { | 
|  | 453     // Assignment to a property. | 
|  | 454     ASSERT(expr->target()->AsProperty() != NULL); | 
|  | 455     Property* prop = expr->target()->AsProperty(); | 
|  | 456     Visit(prop->obj()); | 
|  | 457     Literal* literal_key = prop->key()->AsLiteral(); | 
|  | 458     uint32_t dummy; | 
|  | 459     if (literal_key != NULL && | 
|  | 460         literal_key->handle()->IsSymbol() && | 
|  | 461         !String::cast(*(literal_key->handle()))->AsArrayIndex(&dummy)) { | 
|  | 462       // NAMED property assignment | 
|  | 463       Visit(rhs); | 
|  | 464       Move(eax, rhs->location()); | 
|  | 465       __ mov(ecx, Immediate(literal_key->handle())); | 
|  | 466       Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); | 
|  | 467       __ call(ic, RelocInfo::CODE_TARGET); | 
|  | 468       __ nop(); | 
|  | 469     } else { | 
|  | 470       // KEYED property assignment | 
|  | 471       Visit(prop->key()); | 
|  | 472       Visit(rhs); | 
|  | 473       Move(eax, rhs->location()); | 
|  | 474       Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize)); | 
|  | 475       __ call(ic, RelocInfo::CODE_TARGET); | 
|  | 476       __ nop(); | 
|  | 477       // Drop key from the stack | 
|  | 478       __ add(Operand(esp), Immediate(kPointerSize)); | 
|  | 479     } | 
|  | 480     // Overwrite the receiver on the stack with the result if needed. | 
|  | 481     DropAndMove(expr->location(), eax); | 
|  | 482   } else if (var->is_global()) { | 
| 452     // Assignment to a global variable, use inline caching.  Right-hand-side | 483     // Assignment to a global variable, use inline caching.  Right-hand-side | 
| 453     // value is passed in eax, variable name in ecx, and the global object | 484     // value is passed in eax, variable name in ecx, and the global object | 
| 454     // on the stack. | 485     // on the stack. | 
| 455 | 486 | 
| 456     // Code for the right-hand-side expression depends on its type. | 487     // Code for the right-hand-side expression depends on its type. | 
| 457     if (rhs->AsLiteral() != NULL) { | 488     if (rhs->AsLiteral() != NULL) { | 
| 458       __ mov(eax, rhs->AsLiteral()->handle()); | 489       __ mov(eax, rhs->AsLiteral()->handle()); | 
| 459     } else { | 490     } else { | 
| 460       ASSERT(rhs->location().is_value()); | 491       ASSERT(rhs->location().is_value()); | 
| 461       Visit(rhs); | 492       Visit(rhs); | 
| 462       __ pop(eax); | 493       __ pop(eax); | 
| 463     } | 494     } | 
| 464     __ mov(ecx, var->name()); | 495     __ mov(ecx, var->name()); | 
| 465     __ push(CodeGenerator::GlobalObject()); | 496     __ push(CodeGenerator::GlobalObject()); | 
| 466     Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); | 497     Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); | 
| 467     __ call(ic, RelocInfo::CODE_TARGET); | 498     __ call(ic, RelocInfo::CODE_TARGET); | 
| 468     // Overwrite the global object on the stack with the result if needed. | 499     // Overwrite the global object on the stack with the result if needed. | 
| 469     DropAndMove(expr->location(), eax); | 500     DropAndMove(expr->location(), eax); | 
| 470   } else { | 501   } else { | 
| 471     // Local or parameter assignment. | 502     // Local or parameter assignment. | 
|  | 503     ASSERT(var->slot() != NULL); | 
| 472 | 504 | 
| 473     // Code for the right-hand side expression depends on its type. | 505     // Code for the right-hand side expression depends on its type. | 
| 474     if (rhs->AsLiteral() != NULL) { | 506     if (rhs->AsLiteral() != NULL) { | 
| 475       // Two cases: 'temp <- (var = constant)', or 'var = constant' with a | 507       // Two cases: 'temp <- (var = constant)', or 'var = constant' with a | 
| 476       // discarded result.  Always perform the assignment. | 508       // discarded result.  Always perform the assignment. | 
| 477       __ mov(eax, rhs->AsLiteral()->handle()); | 509       __ mov(eax, rhs->AsLiteral()->handle()); | 
| 478       __ mov(Operand(ebp, SlotOffset(var->slot())), eax); | 510       __ mov(Operand(ebp, SlotOffset(var->slot())), eax); | 
| 479       Move(expr->location(), eax); | 511       Move(expr->location(), eax); | 
| 480     } else { | 512     } else { | 
| 481       ASSERT(rhs->location().is_value()); | 513       ASSERT(rhs->location().is_value()); | 
| (...skipping 20 matching lines...) Expand all  Loading... | 
| 502 void FastCodeGenerator::VisitProperty(Property* expr) { | 534 void FastCodeGenerator::VisitProperty(Property* expr) { | 
| 503   Comment cmnt(masm_, "[ Property"); | 535   Comment cmnt(masm_, "[ Property"); | 
| 504   Expression* key = expr->key(); | 536   Expression* key = expr->key(); | 
| 505   uint32_t dummy; | 537   uint32_t dummy; | 
| 506 | 538 | 
| 507   // Record the source position for the property load. | 539   // Record the source position for the property load. | 
| 508   SetSourcePosition(expr->position()); | 540   SetSourcePosition(expr->position()); | 
| 509 | 541 | 
| 510   // Evaluate receiver. | 542   // Evaluate receiver. | 
| 511   Visit(expr->obj()); | 543   Visit(expr->obj()); | 
| 512 |  | 
| 513   if (key->AsLiteral() != NULL && key->AsLiteral()->handle()->IsSymbol() && | 544   if (key->AsLiteral() != NULL && key->AsLiteral()->handle()->IsSymbol() && | 
| 514       !String::cast(*(key->AsLiteral()->handle()))->AsArrayIndex(&dummy)) { | 545       !String::cast(*(key->AsLiteral()->handle()))->AsArrayIndex(&dummy)) { | 
| 515     // Do a NAMED property load. | 546     // Do a NAMED property load. | 
| 516     // The IC expects the property name in ecx and the receiver on the stack. | 547     // The IC expects the property name in ecx and the receiver on the stack. | 
| 517     __ mov(ecx, Immediate(key->AsLiteral()->handle())); | 548     __ mov(ecx, Immediate(key->AsLiteral()->handle())); | 
| 518     Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); | 549     Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); | 
| 519     __ call(ic, RelocInfo::CODE_TARGET); | 550     __ call(ic, RelocInfo::CODE_TARGET); | 
| 520     // By emitting a nop we make sure that we do not have a test eax | 551     // By emitting a nop we make sure that we do not have a test eax | 
| 521     // instruction after the call it is treated specially by the LoadIC code. | 552     // instruction after the call it is treated specially by the LoadIC code. | 
| 522     __ nop(); | 553     __ nop(); | 
| 523   } else { | 554   } else { | 
| 524     // Do a KEYED property load. | 555     // Do a KEYED property load. | 
| 525     Visit(expr->key()); | 556     Visit(expr->key()); | 
| 526     Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); | 557     Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); | 
| 527     __ call(ic, RelocInfo::CODE_TARGET); | 558     __ call(ic, RelocInfo::CODE_TARGET); | 
| 528     // By emitting a nop we make sure that we do not have a "test eax,..." | 559     // By emitting a nop we make sure that we do not have a "test eax,..." | 
| 529     // instruction after the call it is treated specially by the LoadIC code. | 560     // instruction after the call it is treated specially by the LoadIC code. | 
| 530     __ nop(); | 561     __ nop(); | 
| 531     // Drop key left on the stack by IC. | 562     // Drop key left on the stack by IC. | 
| 532     __ add(Operand(esp), Immediate(kPointerSize)); | 563     __ add(Operand(esp), Immediate(kPointerSize)); | 
| 533   } | 564   } | 
| 534   switch (expr->location().type()) { | 565   DropAndMove(expr->location(), eax); | 
| 535     case Location::kUninitialized: |  | 
| 536       UNREACHABLE(); |  | 
| 537     case Location::kValue: |  | 
| 538       __ mov(Operand(esp, 0), eax); |  | 
| 539       break; |  | 
| 540     case Location::kEffect: |  | 
| 541       __ add(Operand(esp), Immediate(kPointerSize)); |  | 
| 542       break; |  | 
| 543   } |  | 
| 544 } | 566 } | 
| 545 | 567 | 
| 546 | 568 | 
| 547 void FastCodeGenerator::VisitCall(Call* expr) { | 569 void FastCodeGenerator::VisitCall(Call* expr) { | 
| 548   Expression* fun = expr->expression(); | 570   Expression* fun = expr->expression(); | 
| 549   ZoneList<Expression*>* args = expr->arguments(); | 571   ZoneList<Expression*>* args = expr->arguments(); | 
| 550   Variable* var = fun->AsVariableProxy()->AsVariable(); | 572   Variable* var = fun->AsVariableProxy()->AsVariable(); | 
| 551   ASSERT(var != NULL && !var->is_this() && var->is_global()); | 573   ASSERT(var != NULL && !var->is_this() && var->is_global()); | 
| 552   ASSERT(!var->is_possibly_eval()); | 574   ASSERT(!var->is_possibly_eval()); | 
| 553 | 575 | 
| (...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 754   } | 776   } | 
| 755   // Save or discard the right-hand value as needed. | 777   // Save or discard the right-hand value as needed. | 
| 756   Visit(right); | 778   Visit(right); | 
| 757   ASSERT_EQ(destination.type(), right->location().type()); | 779   ASSERT_EQ(destination.type(), right->location().type()); | 
| 758 | 780 | 
| 759   __ bind(&done); | 781   __ bind(&done); | 
| 760 } | 782 } | 
| 761 | 783 | 
| 762 | 784 | 
| 763 } }  // namespace v8::internal | 785 } }  // namespace v8::internal | 
| OLD | NEW | 
|---|