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

Side by Side Diff: src/ia32/codegen-ia32.cc

Issue 245042: Remove CallEval as a subclass of the Call AST node type. We were not... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 11 years, 2 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/cfg.cc ('k') | src/parser.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2006-2009 the V8 project authors. All rights reserved. 1 // Copyright 2006-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 4413 matching lines...) Expand 10 before | Expand all | Expand 10 after
4424 void CodeGenerator::VisitProperty(Property* node) { 4424 void CodeGenerator::VisitProperty(Property* node) {
4425 Comment cmnt(masm_, "[ Property"); 4425 Comment cmnt(masm_, "[ Property");
4426 Reference property(this, node); 4426 Reference property(this, node);
4427 property.GetValue(typeof_state()); 4427 property.GetValue(typeof_state());
4428 } 4428 }
4429 4429
4430 4430
4431 void CodeGenerator::VisitCall(Call* node) { 4431 void CodeGenerator::VisitCall(Call* node) {
4432 Comment cmnt(masm_, "[ Call"); 4432 Comment cmnt(masm_, "[ Call");
4433 4433
4434 Expression* function = node->expression();
4434 ZoneList<Expression*>* args = node->arguments(); 4435 ZoneList<Expression*>* args = node->arguments();
4435 4436
4436 // Check if the function is a variable or a property. 4437 // Check if the function is a variable or a property.
4437 Expression* function = node->expression();
4438 Variable* var = function->AsVariableProxy()->AsVariable(); 4438 Variable* var = function->AsVariableProxy()->AsVariable();
4439 Property* property = function->AsProperty(); 4439 Property* property = function->AsProperty();
4440 4440
4441 // ------------------------------------------------------------------------ 4441 // ------------------------------------------------------------------------
4442 // Fast-case: Use inline caching. 4442 // Fast-case: Use inline caching.
4443 // --- 4443 // ---
4444 // According to ECMA-262, section 11.2.3, page 44, the function to call 4444 // According to ECMA-262, section 11.2.3, page 44, the function to call
4445 // must be resolved after the arguments have been evaluated. The IC code 4445 // must be resolved after the arguments have been evaluated. The IC code
4446 // automatically handles this by loading the arguments before the function 4446 // automatically handles this by loading the arguments before the function
4447 // is resolved in cache misses (this also holds for megamorphic calls). 4447 // is resolved in cache misses (this also holds for megamorphic calls).
4448 // ------------------------------------------------------------------------ 4448 // ------------------------------------------------------------------------
4449 4449
4450 if (var != NULL && !var->is_this() && var->is_global()) { 4450 if (var != NULL && var->is_possibly_eval()) {
4451 // ----------------------------------
4452 // JavaScript example: 'eval(arg)' // eval is not known to be shadowed
4453 // ----------------------------------
4454
4455 // In a call to eval, we first call %ResolvePossiblyDirectEval to
4456 // resolve the function we need to call and the receiver of the
4457 // call. Then we call the resolved function using the given
4458 // arguments.
4459
4460 // Prepare the stack for the call to the resolved function.
4461 Load(function);
4462
4463 // Allocate a frame slot for the receiver.
4464 frame_->Push(Factory::undefined_value());
4465 int arg_count = args->length();
4466 for (int i = 0; i < arg_count; i++) {
4467 Load(args->at(i));
4468 }
4469
4470 // Prepare the stack for the call to ResolvePossiblyDirectEval.
4471 frame_->PushElementAt(arg_count + 1);
4472 if (arg_count > 0) {
4473 frame_->PushElementAt(arg_count);
4474 } else {
4475 frame_->Push(Factory::undefined_value());
4476 }
4477
4478 // Resolve the call.
4479 Result result =
4480 frame_->CallRuntime(Runtime::kResolvePossiblyDirectEval, 2);
4481
4482 // Touch up the stack with the right values for the function and the
4483 // receiver. Use a scratch register to avoid destroying the result.
4484 Result scratch = allocator_->Allocate();
4485 ASSERT(scratch.is_valid());
4486 __ mov(scratch.reg(), FieldOperand(result.reg(), FixedArray::kHeaderSize));
4487 frame_->SetElementAt(arg_count + 1, &scratch);
4488
4489 // We can reuse the result register now.
4490 frame_->Spill(result.reg());
4491 __ mov(result.reg(),
4492 FieldOperand(result.reg(), FixedArray::kHeaderSize + kPointerSize));
4493 frame_->SetElementAt(arg_count, &result);
4494
4495 // Call the function.
4496 CodeForSourcePosition(node->position());
4497 InLoopFlag in_loop = loop_nesting() > 0 ? IN_LOOP : NOT_IN_LOOP;
4498 CallFunctionStub call_function(arg_count, in_loop);
4499 result = frame_->CallStub(&call_function, arg_count + 1);
4500
4501 // Restore the context and overwrite the function on the stack with
4502 // the result.
4503 frame_->RestoreContextRegister();
4504 frame_->SetElementAt(0, &result);
4505
4506 } else if (var != NULL && !var->is_this() && var->is_global()) {
4451 // ---------------------------------- 4507 // ----------------------------------
4452 // JavaScript example: 'foo(1, 2, 3)' // foo is global 4508 // JavaScript example: 'foo(1, 2, 3)' // foo is global
4453 // ---------------------------------- 4509 // ----------------------------------
4454 4510
4455 // Push the name of the function and the receiver onto the stack. 4511 // Push the name of the function and the receiver onto the stack.
4456 frame_->Push(var->name()); 4512 frame_->Push(var->name());
4457 4513
4458 // Pass the global object as the receiver and let the IC stub 4514 // Pass the global object as the receiver and let the IC stub
4459 // patch the stack to use the global proxy as 'this' in the 4515 // patch the stack to use the global proxy as 'this' in the
4460 // invoked function. 4516 // invoked function.
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after
4609 4665
4610 // Call the construct call builtin that handles allocation and 4666 // Call the construct call builtin that handles allocation and
4611 // constructor invocation. 4667 // constructor invocation.
4612 CodeForSourcePosition(node->position()); 4668 CodeForSourcePosition(node->position());
4613 Result result = frame_->CallConstructor(arg_count); 4669 Result result = frame_->CallConstructor(arg_count);
4614 // Replace the function on the stack with the result. 4670 // Replace the function on the stack with the result.
4615 frame_->SetElementAt(0, &result); 4671 frame_->SetElementAt(0, &result);
4616 } 4672 }
4617 4673
4618 4674
4619 void CodeGenerator::VisitCallEval(CallEval* node) {
4620 Comment cmnt(masm_, "[ CallEval");
4621
4622 // In a call to eval, we first call %ResolvePossiblyDirectEval to resolve
4623 // the function we need to call and the receiver of the call.
4624 // Then we call the resolved function using the given arguments.
4625
4626 ZoneList<Expression*>* args = node->arguments();
4627 Expression* function = node->expression();
4628
4629 // Prepare the stack for the call to the resolved function.
4630 Load(function);
4631
4632 // Allocate a frame slot for the receiver.
4633 frame_->Push(Factory::undefined_value());
4634 int arg_count = args->length();
4635 for (int i = 0; i < arg_count; i++) {
4636 Load(args->at(i));
4637 }
4638
4639 // Prepare the stack for the call to ResolvePossiblyDirectEval.
4640 frame_->PushElementAt(arg_count + 1);
4641 if (arg_count > 0) {
4642 frame_->PushElementAt(arg_count);
4643 } else {
4644 frame_->Push(Factory::undefined_value());
4645 }
4646
4647 // Resolve the call.
4648 Result result =
4649 frame_->CallRuntime(Runtime::kResolvePossiblyDirectEval, 2);
4650
4651 // Touch up the stack with the right values for the function and the
4652 // receiver. Use a scratch register to avoid destroying the result.
4653 Result scratch = allocator_->Allocate();
4654 ASSERT(scratch.is_valid());
4655 __ mov(scratch.reg(), FieldOperand(result.reg(), FixedArray::kHeaderSize));
4656 frame_->SetElementAt(arg_count + 1, &scratch);
4657
4658 // We can reuse the result register now.
4659 frame_->Spill(result.reg());
4660 __ mov(result.reg(),
4661 FieldOperand(result.reg(), FixedArray::kHeaderSize + kPointerSize));
4662 frame_->SetElementAt(arg_count, &result);
4663
4664 // Call the function.
4665 CodeForSourcePosition(node->position());
4666 InLoopFlag in_loop = loop_nesting() > 0 ? IN_LOOP : NOT_IN_LOOP;
4667 CallFunctionStub call_function(arg_count, in_loop);
4668 result = frame_->CallStub(&call_function, arg_count + 1);
4669
4670 // Restore the context and overwrite the function on the stack with
4671 // the result.
4672 frame_->RestoreContextRegister();
4673 frame_->SetElementAt(0, &result);
4674 }
4675
4676
4677 void CodeGenerator::GenerateIsSmi(ZoneList<Expression*>* args) { 4675 void CodeGenerator::GenerateIsSmi(ZoneList<Expression*>* args) {
4678 ASSERT(args->length() == 1); 4676 ASSERT(args->length() == 1);
4679 Load(args->at(0)); 4677 Load(args->at(0));
4680 Result value = frame_->Pop(); 4678 Result value = frame_->Pop();
4681 value.ToRegister(); 4679 value.ToRegister();
4682 ASSERT(value.is_valid()); 4680 ASSERT(value.is_valid());
4683 __ test(value.reg(), Immediate(kSmiTagMask)); 4681 __ test(value.reg(), Immediate(kSmiTagMask));
4684 value.Unuse(); 4682 value.Unuse();
4685 destination()->Split(zero); 4683 destination()->Split(zero);
4686 } 4684 }
(...skipping 3285 matching lines...) Expand 10 before | Expand all | Expand 10 after
7972 7970
7973 int CompareStub::MinorKey() { 7971 int CompareStub::MinorKey() {
7974 // Encode the two parameters in a unique 16 bit value. 7972 // Encode the two parameters in a unique 16 bit value.
7975 ASSERT(static_cast<unsigned>(cc_) < (1 << 15)); 7973 ASSERT(static_cast<unsigned>(cc_) < (1 << 15));
7976 return (static_cast<unsigned>(cc_) << 1) | (strict_ ? 1 : 0); 7974 return (static_cast<unsigned>(cc_) << 1) | (strict_ ? 1 : 0);
7977 } 7975 }
7978 7976
7979 #undef __ 7977 #undef __
7980 7978
7981 } } // namespace v8::internal 7979 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/cfg.cc ('k') | src/parser.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698