Index: src/ia32/macro-assembler-ia32.cc |
diff --git a/src/ia32/macro-assembler-ia32.cc b/src/ia32/macro-assembler-ia32.cc |
index 7b2f6cf9d79c01c444c928456579712409471994..973c4965b25783145834285c51608403fb4582cd 100644 |
--- a/src/ia32/macro-assembler-ia32.cc |
+++ b/src/ia32/macro-assembler-ia32.cc |
@@ -1512,6 +1512,18 @@ MaybeObject* MacroAssembler::TryJumpToExternalReference( |
} |
+void MacroAssembler::SetReceiverType(Register dst, ReceiverType type) { |
Kevin Millikin (Chromium)
2011/05/18 15:57:23
I'm not sure it helps to have the register as an a
Mads Ager (chromium)
2011/05/23 16:31:34
The point was exactly to make it clear at the call
|
+ if (type == IMPLICIT_RECEIVER) { |
+ // Set to some non-zero smi by updating the least significant |
+ // byte. |
+ mov_b(Operand(dst), 1 << kSmiTagSize); |
+ } else { |
+ // Set to smi zero by clearing the register. |
+ xor_(dst, Operand(dst)); |
+ } |
+} |
+ |
+ |
void MacroAssembler::InvokePrologue(const ParameterCount& expected, |
const ParameterCount& actual, |
Handle<Code> code_constant, |
@@ -1519,7 +1531,8 @@ void MacroAssembler::InvokePrologue(const ParameterCount& expected, |
Label* done, |
InvokeFlag flag, |
Label::Distance done_near, |
- const CallWrapper& call_wrapper) { |
+ const CallWrapper& call_wrapper, |
+ ReceiverType receiver_type) { |
bool definitely_matches = false; |
Label invoke; |
if (expected.is_immediate()) { |
@@ -1570,10 +1583,12 @@ void MacroAssembler::InvokePrologue(const ParameterCount& expected, |
if (flag == CALL_FUNCTION) { |
call_wrapper.BeforeCall(CallSize(adaptor, RelocInfo::CODE_TARGET)); |
+ SetReceiverType(ecx, receiver_type); |
call(adaptor, RelocInfo::CODE_TARGET); |
call_wrapper.AfterCall(); |
jmp(done, done_near); |
} else { |
+ SetReceiverType(ecx, receiver_type); |
jmp(adaptor, RelocInfo::CODE_TARGET); |
} |
bind(&invoke); |
@@ -1585,16 +1600,20 @@ void MacroAssembler::InvokeCode(const Operand& code, |
const ParameterCount& expected, |
const ParameterCount& actual, |
InvokeFlag flag, |
- const CallWrapper& call_wrapper) { |
+ const CallWrapper& call_wrapper, |
+ ReceiverType receiver_type) { |
Label done; |
InvokePrologue(expected, actual, Handle<Code>::null(), code, |
- &done, flag, Label::kNear, call_wrapper); |
+ &done, flag, Label::kNear, call_wrapper, |
+ receiver_type); |
if (flag == CALL_FUNCTION) { |
call_wrapper.BeforeCall(CallSize(code)); |
+ SetReceiverType(ecx, receiver_type); |
call(code); |
call_wrapper.AfterCall(); |
} else { |
ASSERT(flag == JUMP_FUNCTION); |
+ SetReceiverType(ecx, receiver_type); |
jmp(code); |
} |
bind(&done); |
@@ -1606,17 +1625,20 @@ void MacroAssembler::InvokeCode(Handle<Code> code, |
const ParameterCount& actual, |
RelocInfo::Mode rmode, |
InvokeFlag flag, |
- const CallWrapper& call_wrapper) { |
+ const CallWrapper& call_wrapper, |
+ ReceiverType receiver_type) { |
Label done; |
Operand dummy(eax); |
InvokePrologue(expected, actual, code, dummy, &done, flag, Label::kNear, |
call_wrapper); |
if (flag == CALL_FUNCTION) { |
call_wrapper.BeforeCall(CallSize(code, rmode)); |
+ SetReceiverType(ecx, receiver_type); |
call(code, rmode); |
call_wrapper.AfterCall(); |
} else { |
ASSERT(flag == JUMP_FUNCTION); |
+ SetReceiverType(ecx, receiver_type); |
jmp(code, rmode); |
} |
bind(&done); |
@@ -1626,7 +1648,8 @@ void MacroAssembler::InvokeCode(Handle<Code> code, |
void MacroAssembler::InvokeFunction(Register fun, |
const ParameterCount& actual, |
InvokeFlag flag, |
- const CallWrapper& call_wrapper) { |
+ const CallWrapper& call_wrapper, |
+ ReceiverType receiver_type) { |
ASSERT(fun.is(edi)); |
mov(edx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset)); |
mov(esi, FieldOperand(edi, JSFunction::kContextOffset)); |
@@ -1635,7 +1658,7 @@ void MacroAssembler::InvokeFunction(Register fun, |
ParameterCount expected(ebx); |
InvokeCode(FieldOperand(edi, JSFunction::kCodeEntryOffset), |
- expected, actual, flag, call_wrapper); |
+ expected, actual, flag, call_wrapper, receiver_type); |
} |