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

Side by Side Diff: src/arm/fast-codegen-arm.cc

Issue 340037: Support for calls on named and keyed properties of the form:... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 11 years, 1 month 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/arm/codegen-arm.cc ('k') | src/compiler.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 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 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
92 } 92 }
93 93
94 { Comment cmnt(masm_, "[ Body"); 94 { Comment cmnt(masm_, "[ Body");
95 VisitStatements(fun->body()); 95 VisitStatements(fun->body());
96 } 96 }
97 97
98 { Comment cmnt(masm_, "[ return <undefined>;"); 98 { Comment cmnt(masm_, "[ return <undefined>;");
99 // Emit a 'return undefined' in case control fell off the end of the 99 // Emit a 'return undefined' in case control fell off the end of the
100 // body. 100 // body.
101 __ LoadRoot(r0, Heap::kUndefinedValueRootIndex); 101 __ LoadRoot(r0, Heap::kUndefinedValueRootIndex);
102 SetReturnPosition(fun); 102 }
103 if (FLAG_trace) { 103 { Comment cmnt(masm_, "Return sequence");
104 // Push the return value on the stack as the parameter. 104 if (return_label_.is_bound()) {
105 // Runtime::TraceExit returns its parameter in r0. 105 __ b(&return_label_);
106 __ push(r0); 106 } else {
107 __ CallRuntime(Runtime::kTraceExit, 1); 107 __ bind(&return_label_);
108 SetReturnPosition(fun);
109 if (FLAG_trace) {
110 // Push the return value on the stack as the parameter.
111 // Runtime::TraceExit returns its parameter in r0.
112 __ push(r0);
113 __ CallRuntime(Runtime::kTraceExit, 1);
114 }
115 __ RecordJSReturn();
116 __ mov(sp, fp);
117 __ ldm(ia_w, sp, fp.bit() | lr.bit());
118 int num_parameters = function_->scope()->num_parameters();
119 __ add(sp, sp, Operand((num_parameters + 1) * kPointerSize));
120 __ Jump(lr);
108 } 121 }
109
110 __ RecordJSReturn();
111 __ mov(sp, fp);
112 __ ldm(ia_w, sp, fp.bit() | lr.bit());
113 int num_parameters = function_->scope()->num_parameters();
114 __ add(sp, sp, Operand((num_parameters + 1) * kPointerSize));
115 __ Jump(lr);
116 } 122 }
117 } 123 }
118 124
119 125
120 void FastCodeGenerator::Move(Expression::Context context, Slot* source) { 126 void FastCodeGenerator::Move(Expression::Context context, Slot* source) {
121 switch (context) { 127 switch (context) {
122 case Expression::kUninitialized: 128 case Expression::kUninitialized:
123 UNREACHABLE(); 129 UNREACHABLE();
124 case Expression::kEffect: 130 case Expression::kEffect:
125 break; 131 break;
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
176 SetStatementPosition(stmt); 182 SetStatementPosition(stmt);
177 Expression* expr = stmt->expression(); 183 Expression* expr = stmt->expression();
178 // Complete the statement based on the type of the subexpression. 184 // Complete the statement based on the type of the subexpression.
179 if (expr->AsLiteral() != NULL) { 185 if (expr->AsLiteral() != NULL) {
180 __ mov(r0, Operand(expr->AsLiteral()->handle())); 186 __ mov(r0, Operand(expr->AsLiteral()->handle()));
181 } else { 187 } else {
182 ASSERT_EQ(Expression::kValue, expr->context()); 188 ASSERT_EQ(Expression::kValue, expr->context());
183 Visit(expr); 189 Visit(expr);
184 __ pop(r0); 190 __ pop(r0);
185 } 191 }
186 192 if (return_label_.is_bound()) {
187 if (FLAG_trace) { 193 __ b(&return_label_);
188 __ push(r0); 194 } else {
189 __ CallRuntime(Runtime::kTraceExit, 1); 195 __ bind(&return_label_);
196 if (FLAG_trace) {
197 __ push(r0);
198 __ CallRuntime(Runtime::kTraceExit, 1);
199 }
200 __ RecordJSReturn();
201 __ mov(sp, fp);
202 __ ldm(ia_w, sp, fp.bit() | lr.bit());
203 int num_parameters = function_->scope()->num_parameters();
204 __ add(sp, sp, Operand((num_parameters + 1) * kPointerSize));
205 __ Jump(lr);
190 } 206 }
191
192 __ RecordJSReturn();
193 __ mov(sp, fp);
194 __ ldm(ia_w, sp, fp.bit() | lr.bit());
195 int num_parameters = function_->scope()->num_parameters();
196 __ add(sp, sp, Operand((num_parameters + 1) * kPointerSize));
197 __ Jump(lr);
198 } 207 }
199 208
200 209
201 void FastCodeGenerator::VisitFunctionLiteral(FunctionLiteral* expr) { 210 void FastCodeGenerator::VisitFunctionLiteral(FunctionLiteral* expr) {
202 Comment cmnt(masm_, "[ FunctionLiteral"); 211 Comment cmnt(masm_, "[ FunctionLiteral");
203 212
204 // Build the function boilerplate and instantiate it. 213 // Build the function boilerplate and instantiate it.
205 Handle<JSFunction> boilerplate = BuildBoilerplate(expr); 214 Handle<JSFunction> boilerplate = BuildBoilerplate(expr);
206 if (HasStackOverflow()) return; 215 if (HasStackOverflow()) return;
207 216
(...skipping 350 matching lines...) Expand 10 before | Expand all | Expand 10 after
558 // Do a KEYED property load. 567 // Do a KEYED property load.
559 Visit(expr->key()); 568 Visit(expr->key());
560 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); 569 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize));
561 __ Call(ic, RelocInfo::CODE_TARGET); 570 __ Call(ic, RelocInfo::CODE_TARGET);
562 // Drop key and receiver left on the stack by IC. 571 // Drop key and receiver left on the stack by IC.
563 __ pop(); 572 __ pop();
564 } 573 }
565 DropAndMove(expr->context(), r0); 574 DropAndMove(expr->context(), r0);
566 } 575 }
567 576
577 void FastCodeGenerator::EmitCallWithIC(Call* expr, RelocInfo::Mode reloc_info) {
578 // Code common for calls using the IC.
579 ZoneList<Expression*>* args = expr->arguments();
580 int arg_count = args->length();
581 for (int i = 0; i < arg_count; i++) {
582 Visit(args->at(i));
583 ASSERT_EQ(Expression::kValue, args->at(i)->context());
584 }
585 // Record source position for debugger.
586 SetSourcePosition(expr->position());
587 // Call the IC initialization code.
588 Handle<Code> ic = CodeGenerator::ComputeCallInitialize(arg_count,
589 NOT_IN_LOOP);
590 __ Call(ic, reloc_info);
591 // Restore context register.
592 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
593 // Discard the function left on TOS.
594 DropAndMove(expr->context(), r0);
595 }
596
597
598 void FastCodeGenerator::EmitCallWithStub(Call* expr) {
599 // Code common for calls using the call stub.
600 ZoneList<Expression*>* args = expr->arguments();
601 int arg_count = args->length();
602 for (int i = 0; i < arg_count; i++) {
603 Visit(args->at(i));
604 }
605 // Record source position for debugger.
606 SetSourcePosition(expr->position());
607 CallFunctionStub stub(arg_count, NOT_IN_LOOP);
608 __ CallStub(&stub);
609 // Restore context register.
610 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
611 // Discard the function left on TOS.
612 DropAndMove(expr->context(), r0);
613 }
614
568 615
569 void FastCodeGenerator::VisitCall(Call* expr) { 616 void FastCodeGenerator::VisitCall(Call* expr) {
570 Comment cmnt(masm_, "[ Call");
571 Expression* fun = expr->expression(); 617 Expression* fun = expr->expression();
572 ZoneList<Expression*>* args = expr->arguments();
573 Variable* var = fun->AsVariableProxy()->AsVariable();
574 ASSERT(var != NULL && !var->is_this() && var->is_global());
575 ASSERT(!var->is_possibly_eval());
576 618
577 __ mov(r1, Operand(var->name())); 619 if (fun->AsProperty() != NULL) {
578 // Push global object as receiver. 620 // Call on a property.
579 __ ldr(r0, CodeGenerator::GlobalObject()); 621 Property* prop = fun->AsProperty();
580 __ stm(db_w, sp, r1.bit() | r0.bit()); 622 Literal* key = prop->key()->AsLiteral();
581 int arg_count = args->length(); 623 if (key != NULL && key->handle()->IsSymbol()) {
582 for (int i = 0; i < arg_count; i++) { 624 // Call on a named property: foo.x(1,2,3)
583 Visit(args->at(i)); 625 __ mov(r0, Operand(key->handle()));
584 ASSERT_EQ(Expression::kValue, args->at(i)->context()); 626 __ push(r0);
627 Visit(prop->obj());
628 // Use call IC.
629 EmitCallWithIC(expr, RelocInfo::CODE_TARGET);
630 } else {
631 // Call on a keyed property : foo[key](1,2,3)
632 // Use a keyed load IC followed by a call IC.
633 Visit(prop->obj());
634 Visit(prop->key());
635 // Record source position of property.
636 SetSourcePosition(prop->position());
637 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize));
638 __ Call(ic, RelocInfo::CODE_TARGET);
639 // Load receiver object into r1.
640 if (prop->is_synthetic()) {
641 __ ldr(r1, CodeGenerator::GlobalObject());
642 } else {
643 __ ldr(r1, MemOperand(sp, kPointerSize));
644 }
645 // Overwrite (object, key) with (function, receiver).
646 __ str(r0, MemOperand(sp, kPointerSize));
647 __ str(r1, MemOperand(sp));
648 EmitCallWithStub(expr);
649 }
650 } else if (fun->AsVariableProxy()->AsVariable() != NULL) {
651 // Call on a global variable
652 Variable* var = fun->AsVariableProxy()->AsVariable();
653 ASSERT(var != NULL && !var->is_this() && var->is_global());
654 ASSERT(!var->is_possibly_eval());
655 __ mov(r1, Operand(var->name()));
656 // Push global object as receiver.
657 __ ldr(r0, CodeGenerator::GlobalObject());
658 __ stm(db_w, sp, r1.bit() | r0.bit());
659 EmitCallWithIC(expr, RelocInfo::CODE_TARGET_CONTEXT);
660 } else {
661 // Calls we cannot handle right now.
662 // Should bailout in the CodeGenSelector.
663 UNREACHABLE();
585 } 664 }
586 // Record source position for debugger
587 SetSourcePosition(expr->position());
588 // Call the IC initialization code.
589 Handle<Code> ic = CodeGenerator::ComputeCallInitialize(arg_count,
590 NOT_IN_LOOP);
591 __ Call(ic, RelocInfo::CODE_TARGET_CONTEXT);
592 // Restore context register.
593 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
594 DropAndMove(expr->context(), r0);
595 } 665 }
596 666
597 667
598 void FastCodeGenerator::VisitCallNew(CallNew* expr) { 668 void FastCodeGenerator::VisitCallNew(CallNew* expr) {
599 Comment cmnt(masm_, "[ CallNew"); 669 Comment cmnt(masm_, "[ CallNew");
600 // According to ECMA-262, section 11.2.2, page 44, the function 670 // According to ECMA-262, section 11.2.2, page 44, the function
601 // expression in new calls must be evaluated before the 671 // expression in new calls must be evaluated before the
602 // arguments. 672 // arguments.
603 // Push function on the stack. 673 // Push function on the stack.
604 Visit(expr->expression()); 674 Visit(expr->expression());
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after
740 // Discard the left-hand value if present on the stack. 810 // Discard the left-hand value if present on the stack.
741 if (context == Expression::kValue) __ pop(); 811 if (context == Expression::kValue) __ pop();
742 // Save or discard the right-hand value as needed. 812 // Save or discard the right-hand value as needed.
743 Visit(right); 813 Visit(right);
744 ASSERT_EQ(context, right->context()); 814 ASSERT_EQ(context, right->context());
745 815
746 __ bind(&done); 816 __ bind(&done);
747 } 817 }
748 818
749 } } // namespace v8::internal 819 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/arm/codegen-arm.cc ('k') | src/compiler.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698