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

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

Issue 542087: Ensure correct boxing of values when calling functions on them... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 10 years, 11 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
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 1073 matching lines...) Expand 10 before | Expand all | Expand 10 after
1084 smi.Bind(); 1084 smi.Bind();
1085 __ cmp(r1, Operand(r0)); 1085 __ cmp(r1, Operand(r0));
1086 1086
1087 exit.Bind(); 1087 exit.Bind();
1088 cc_reg_ = cc; 1088 cc_reg_ = cc;
1089 } 1089 }
1090 1090
1091 1091
1092 // Call the function on the stack with the given arguments. 1092 // Call the function on the stack with the given arguments.
1093 void CodeGenerator::CallWithArguments(ZoneList<Expression*>* args, 1093 void CodeGenerator::CallWithArguments(ZoneList<Expression*>* args,
1094 int position) { 1094 CallFunctionFlags flags,
1095 int position) {
1095 VirtualFrame::SpilledScope spilled_scope; 1096 VirtualFrame::SpilledScope spilled_scope;
1096 // Push the arguments ("left-to-right") on the stack. 1097 // Push the arguments ("left-to-right") on the stack.
1097 int arg_count = args->length(); 1098 int arg_count = args->length();
1098 for (int i = 0; i < arg_count; i++) { 1099 for (int i = 0; i < arg_count; i++) {
1099 LoadAndSpill(args->at(i)); 1100 LoadAndSpill(args->at(i));
1100 } 1101 }
1101 1102
1102 // Record the position for debugging purposes. 1103 // Record the position for debugging purposes.
1103 CodeForSourcePosition(position); 1104 CodeForSourcePosition(position);
1104 1105
1105 // Use the shared code stub to call the function. 1106 // Use the shared code stub to call the function.
1106 InLoopFlag in_loop = loop_nesting() > 0 ? IN_LOOP : NOT_IN_LOOP; 1107 InLoopFlag in_loop = loop_nesting() > 0 ? IN_LOOP : NOT_IN_LOOP;
1107 CallFunctionStub call_function(arg_count, in_loop); 1108 CallFunctionStub call_function(arg_count, in_loop, flags);
1108 frame_->CallStub(&call_function, arg_count + 1); 1109 frame_->CallStub(&call_function, arg_count + 1);
1109 1110
1110 // Restore context and pop function from the stack. 1111 // Restore context and pop function from the stack.
1111 __ ldr(cp, frame_->Context()); 1112 __ ldr(cp, frame_->Context());
1112 frame_->Drop(); // discard the TOS 1113 frame_->Drop(); // discard the TOS
1113 } 1114 }
1114 1115
1115 1116
1116 void CodeGenerator::Branch(bool if_true, JumpTarget* target) { 1117 void CodeGenerator::Branch(bool if_true, JumpTarget* target) {
1117 VirtualFrame::SpilledScope spilled_scope; 1118 VirtualFrame::SpilledScope spilled_scope;
(...skipping 1874 matching lines...) Expand 10 before | Expand all | Expand 10 after
2992 frame_->CallRuntime(Runtime::kResolvePossiblyDirectEval, 3); 2993 frame_->CallRuntime(Runtime::kResolvePossiblyDirectEval, 3);
2993 2994
2994 // Touch up stack with the right values for the function and the receiver. 2995 // Touch up stack with the right values for the function and the receiver.
2995 __ str(r0, MemOperand(sp, (arg_count + 1) * kPointerSize)); 2996 __ str(r0, MemOperand(sp, (arg_count + 1) * kPointerSize));
2996 __ str(r1, MemOperand(sp, arg_count * kPointerSize)); 2997 __ str(r1, MemOperand(sp, arg_count * kPointerSize));
2997 2998
2998 // Call the function. 2999 // Call the function.
2999 CodeForSourcePosition(node->position()); 3000 CodeForSourcePosition(node->position());
3000 3001
3001 InLoopFlag in_loop = loop_nesting() > 0 ? IN_LOOP : NOT_IN_LOOP; 3002 InLoopFlag in_loop = loop_nesting() > 0 ? IN_LOOP : NOT_IN_LOOP;
3002 CallFunctionStub call_function(arg_count, in_loop); 3003 CallFunctionStub call_function(arg_count, in_loop, RECEIVER_MIGHT_BE_VALUE);
3003 frame_->CallStub(&call_function, arg_count + 1); 3004 frame_->CallStub(&call_function, arg_count + 1);
3004 3005
3005 __ ldr(cp, frame_->Context()); 3006 __ ldr(cp, frame_->Context());
3006 // Remove the function from the stack. 3007 // Remove the function from the stack.
3007 frame_->Drop(); 3008 frame_->Drop();
3008 frame_->EmitPush(r0); 3009 frame_->EmitPush(r0);
3009 3010
3010 } else if (var != NULL && !var->is_this() && var->is_global()) { 3011 } else if (var != NULL && !var->is_this() && var->is_global()) {
3011 // ---------------------------------- 3012 // ----------------------------------
3012 // JavaScript example: 'foo(1, 2, 3)' // foo is global 3013 // JavaScript example: 'foo(1, 2, 3)' // foo is global
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
3049 __ mov(r0, Operand(var->name())); 3050 __ mov(r0, Operand(var->name()));
3050 frame_->EmitPush(r0); 3051 frame_->EmitPush(r0);
3051 frame_->CallRuntime(Runtime::kLoadContextSlot, 2); 3052 frame_->CallRuntime(Runtime::kLoadContextSlot, 2);
3052 // r0: slot value; r1: receiver 3053 // r0: slot value; r1: receiver
3053 3054
3054 // Load the receiver. 3055 // Load the receiver.
3055 frame_->EmitPush(r0); // function 3056 frame_->EmitPush(r0); // function
3056 frame_->EmitPush(r1); // receiver 3057 frame_->EmitPush(r1); // receiver
3057 3058
3058 // Call the function. 3059 // Call the function.
3059 CallWithArguments(args, node->position()); 3060 CallWithArguments(args, NO_CALL_FUNCTION_FLAGS, node->position());
3060 frame_->EmitPush(r0); 3061 frame_->EmitPush(r0);
3061 3062
3062 } else if (property != NULL) { 3063 } else if (property != NULL) {
3063 // Check if the key is a literal string. 3064 // Check if the key is a literal string.
3064 Literal* literal = property->key()->AsLiteral(); 3065 Literal* literal = property->key()->AsLiteral();
3065 3066
3066 if (literal != NULL && literal->handle()->IsSymbol()) { 3067 if (literal != NULL && literal->handle()->IsSymbol()) {
3067 // ------------------------------------------------------------------ 3068 // ------------------------------------------------------------------
3068 // JavaScript example: 'object.foo(1, 2, 3)' or 'map["key"](1, 2, 3)' 3069 // JavaScript example: 'object.foo(1, 2, 3)' or 'map["key"](1, 2, 3)'
3069 // ------------------------------------------------------------------ 3070 // ------------------------------------------------------------------
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
3102 3103
3103 // Pass receiver to called function. 3104 // Pass receiver to called function.
3104 if (property->is_synthetic()) { 3105 if (property->is_synthetic()) {
3105 LoadGlobalReceiver(r0); 3106 LoadGlobalReceiver(r0);
3106 } else { 3107 } else {
3107 __ ldr(r0, frame_->ElementAt(ref.size())); 3108 __ ldr(r0, frame_->ElementAt(ref.size()));
3108 frame_->EmitPush(r0); 3109 frame_->EmitPush(r0);
3109 } 3110 }
3110 3111
3111 // Call the function. 3112 // Call the function.
3112 CallWithArguments(args, node->position()); 3113 CallWithArguments(args, RECEIVER_MIGHT_BE_VALUE, node->position());
3113 frame_->EmitPush(r0); 3114 frame_->EmitPush(r0);
3114 } 3115 }
3115 3116
3116 } else { 3117 } else {
3117 // ---------------------------------- 3118 // ----------------------------------
3118 // JavaScript example: 'foo(1, 2, 3)' // foo is not global 3119 // JavaScript example: 'foo(1, 2, 3)' // foo is not global
3119 // ---------------------------------- 3120 // ----------------------------------
3120 3121
3121 // Load the function. 3122 // Load the function.
3122 LoadAndSpill(function); 3123 LoadAndSpill(function);
3123 3124
3124 // Pass the global proxy as the receiver. 3125 // Pass the global proxy as the receiver.
3125 LoadGlobalReceiver(r0); 3126 LoadGlobalReceiver(r0);
3126 3127
3127 // Call the function. 3128 // Call the function.
3128 CallWithArguments(args, node->position()); 3129 CallWithArguments(args, NO_CALL_FUNCTION_FLAGS, node->position());
3129 frame_->EmitPush(r0); 3130 frame_->EmitPush(r0);
3130 } 3131 }
3131 ASSERT(frame_->height() == original_height + 1); 3132 ASSERT(frame_->height() == original_height + 1);
3132 } 3133 }
3133 3134
3134 3135
3135 void CodeGenerator::VisitCallNew(CallNew* node) { 3136 void CodeGenerator::VisitCallNew(CallNew* node) {
3136 #ifdef DEBUG 3137 #ifdef DEBUG
3137 int original_height = frame_->height(); 3138 int original_height = frame_->height();
3138 #endif 3139 #endif
(...skipping 3455 matching lines...) Expand 10 before | Expand all | Expand 10 after
6594 __ str(r3, MemOperand(sp, 1 * kPointerSize)); 6595 __ str(r3, MemOperand(sp, 1 * kPointerSize));
6595 6596
6596 // Do the runtime call to allocate the arguments object. 6597 // Do the runtime call to allocate the arguments object.
6597 __ bind(&runtime); 6598 __ bind(&runtime);
6598 __ TailCallRuntime(ExternalReference(Runtime::kNewArgumentsFast), 3, 1); 6599 __ TailCallRuntime(ExternalReference(Runtime::kNewArgumentsFast), 3, 1);
6599 } 6600 }
6600 6601
6601 6602
6602 void CallFunctionStub::Generate(MacroAssembler* masm) { 6603 void CallFunctionStub::Generate(MacroAssembler* masm) {
6603 Label slow; 6604 Label slow;
6605
6606 // If the receiver might be a value (string, number or boolean) check for this
6607 // and box it if it is.
6608 if (ReceiverMightBeValue()) {
6609 // Get the receiver from the stack.
6610 // function, receiver [, arguments]
6611 Label receiver_is_value, receiver_is_js_object;
6612 __ ldr(r1, MemOperand(sp, argc_ * kPointerSize));
6613
6614 // Check if receiver is a smi (which is a number value).
6615 __ BranchOnSmi(r1, &receiver_is_value);
6616
6617 // Check if the receiver is a valid JS object.
6618 __ CompareObjectType(r1, r2, r2, FIRST_JS_OBJECT_TYPE);
6619 __ b(ge, &receiver_is_js_object);
6620
6621 // Call the runtime to box the value.
6622 __ bind(&receiver_is_value);
6623 __ EnterInternalFrame();
6624 __ push(r1);
6625 __ InvokeBuiltin(Builtins::TO_OBJECT, CALL_JS);
6626 __ LeaveInternalFrame();
6627 __ str(r0, MemOperand(sp, argc_ * kPointerSize));
6628
6629 __ bind(&receiver_is_js_object);
6630 }
6631
6604 // Get the function to call from the stack. 6632 // Get the function to call from the stack.
6605 // function, receiver [, arguments] 6633 // function, receiver [, arguments]
6606 __ ldr(r1, MemOperand(sp, (argc_ + 1) * kPointerSize)); 6634 __ ldr(r1, MemOperand(sp, (argc_ + 1) * kPointerSize));
6607 6635
6608 // Check that the function is really a JavaScript function. 6636 // Check that the function is really a JavaScript function.
6609 // r1: pushed function (to be verified) 6637 // r1: pushed function (to be verified)
6610 __ BranchOnSmi(r1, &slow); 6638 __ BranchOnSmi(r1, &slow);
6611 // Get the map of the function object. 6639 // Get the map of the function object.
6612 __ CompareObjectType(r1, r2, r2, JS_FUNCTION_TYPE); 6640 __ CompareObjectType(r1, r2, r2, JS_FUNCTION_TYPE);
6613 __ b(ne, &slow); 6641 __ b(ne, &slow);
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
6673 ASSERT((static_cast<unsigned>(cc_) >> 26) < (1 << 16)); 6701 ASSERT((static_cast<unsigned>(cc_) >> 26) < (1 << 16));
6674 int nnn_value = (never_nan_nan_ ? 2 : 0); 6702 int nnn_value = (never_nan_nan_ ? 2 : 0);
6675 if (cc_ != eq) nnn_value = 0; // Avoid duplicate stubs. 6703 if (cc_ != eq) nnn_value = 0; // Avoid duplicate stubs.
6676 return (static_cast<unsigned>(cc_) >> 26) | nnn_value | (strict_ ? 1 : 0); 6704 return (static_cast<unsigned>(cc_) >> 26) | nnn_value | (strict_ ? 1 : 0);
6677 } 6705 }
6678 6706
6679 6707
6680 #undef __ 6708 #undef __
6681 6709
6682 } } // namespace v8::internal 6710 } } // namespace v8::internal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698