void StoreStubCompiler::GenerateStoreViaSetter(
MacroAssembler* masm,
+ Handle<HeapType> type,
Handle<JSFunction> setter) {
// ----------- S t a t e -------------
// -- r0 : value
// -----------------------------------
{
FrameScope scope(masm, StackFrame::INTERNAL);
+ Register receiver = r1;
+ Register value = r0;
// Save value register, so we can restore it later.
- __ push(r0);
+ __ push(value);
if (!setter.is_null()) {
// Call the JavaScript setter with receiver and value on the stack.
- __ Push(r1, r0);
+ if (IC::TypeToMap(*type, masm->isolate())->IsJSGlobalObjectMap()) {
+ // Swap in the global receiver.
+ __ ldr(receiver,
+ FieldMemOperand(
+ receiver, JSGlobalObject::kGlobalReceiverOffset));
+ }
+ __ Push(receiver, value);
ParameterCount actual(1);
ParameterCount expected(setter);
__ InvokeFunction(setter, expected, actual,
void LoadStubCompiler::GenerateLoadViaGetter(MacroAssembler* masm,
+ Handle<HeapType> type,
Register receiver,
Handle<JSFunction> getter) {
// ----------- S t a t e -------------
if (!getter.is_null()) {
// Call the JavaScript getter with the receiver on the stack.
+ if (IC::TypeToMap(*type, masm->isolate())->IsJSGlobalObjectMap()) {
+ // Swap in the global receiver.
+ __ ldr(receiver,
+ FieldMemOperand(
+ receiver, JSGlobalObject::kGlobalReceiverOffset));
+ }
__ push(receiver);
ParameterCount actual(0);
ParameterCount expected(getter);
static void Generate_LoadIC_Getter_ForDeopt(MacroAssembler* masm) {
LoadStubCompiler::GenerateLoadViaGetter(
- masm, LoadStubCompiler::registers()[0], Handle<JSFunction>());
+ masm, Handle<HeapType>::null(),
+ LoadStubCompiler::registers()[0], Handle<JSFunction>());
}
static void Generate_StoreIC_Setter_ForDeopt(MacroAssembler* masm) {
- StoreStubCompiler::GenerateStoreViaSetter(masm, Handle<JSFunction>());
+ StoreStubCompiler::GenerateStoreViaSetter(
+ masm, Handle<HeapType>::null(), Handle<JSFunction>());
}
void StoreStubCompiler::GenerateStoreViaSetter(
MacroAssembler* masm,
+ Handle<HeapType> type,
Handle<JSFunction> setter) {
// ----------- S t a t e -------------
// -- eax : value
// -----------------------------------
{
FrameScope scope(masm, StackFrame::INTERNAL);
+ Register receiver = edx;
+ Register value = eax;
// Save value register, so we can restore it later.
- __ push(eax);
+ __ push(value);
if (!setter.is_null()) {
// Call the JavaScript setter with receiver and value on the stack.
- __ push(edx);
- __ push(eax);
+ if (IC::TypeToMap(*type, masm->isolate())->IsJSGlobalObjectMap()) {
+ // Swap in the global receiver.
+ __ mov(receiver,
+ FieldOperand(receiver, JSGlobalObject::kGlobalReceiverOffset));
+ }
+ __ push(receiver);
+ __ push(value);
ParameterCount actual(1);
ParameterCount expected(setter);
__ InvokeFunction(setter, expected, actual,
void LoadStubCompiler::GenerateLoadViaGetter(MacroAssembler* masm,
+ Handle<HeapType> type,
Register receiver,
Handle<JSFunction> getter) {
{
if (!getter.is_null()) {
// Call the JavaScript getter with the receiver on the stack.
+ if (IC::TypeToMap(*type, masm->isolate())->IsJSGlobalObjectMap()) {
+ // Swap in the global receiver.
+ __ mov(receiver,
+ FieldOperand(receiver, JSGlobalObject::kGlobalReceiverOffset));
+ }
__ push(receiver);
ParameterCount actual(0);
ParameterCount expected(getter);
Handle<Name> name,
Handle<JSFunction> getter) {
HandlerFrontend(type, receiver(), holder, name);
- GenerateLoadViaGetter(masm(), receiver(), getter);
+ GenerateLoadViaGetter(masm(), type, receiver(), getter);
// Return the generated code.
return GetCode(kind(), Code::FAST, name);
Handle<JSObject> holder,
Handle<Name> name,
Handle<JSFunction> setter) {
- HandlerFrontend(IC::CurrentTypeOf(object, isolate()),
- receiver(), holder, name);
- GenerateStoreViaSetter(masm(), setter);
+ Handle<HeapType> type = IC::CurrentTypeOf(object, isolate());
+ HandlerFrontend(type, receiver(), holder, name);
+ GenerateStoreViaSetter(masm(), type, setter);
return GetCode(kind(), Code::FAST, name);
}
Handle<JSFunction> getter);
static void GenerateLoadViaGetter(MacroAssembler* masm,
+ Handle<HeapType> type,
Register receiver,
Handle<JSFunction> getter);
const CallOptimization& call_optimization);
static void GenerateStoreViaSetter(MacroAssembler* masm,
+ Handle<HeapType> type,
Handle<JSFunction> setter);
Handle<Code> CompileStoreViaSetter(Handle<JSObject> object,
void StoreStubCompiler::GenerateStoreViaSetter(
MacroAssembler* masm,
+ Handle<HeapType> type,
Handle<JSFunction> setter) {
// ----------- S t a t e -------------
// -- rax : value
// -----------------------------------
{
FrameScope scope(masm, StackFrame::INTERNAL);
+ Register receiver = rdx;
+ Register value = rax;
// Save value register, so we can restore it later.
- __ push(rax);
+ __ push(value);
if (!setter.is_null()) {
// Call the JavaScript setter with receiver and value on the stack.
- __ push(rdx);
- __ push(rax);
+ if (IC::TypeToMap(*type, masm->isolate())->IsJSGlobalObjectMap()) {
+ // Swap in the global receiver.
+ __ movp(receiver,
+ FieldOperand(receiver, JSGlobalObject::kGlobalReceiverOffset));
+ }
+ __ push(receiver);
+ __ push(value);
ParameterCount actual(1);
ParameterCount expected(setter);
__ InvokeFunction(setter, expected, actual,
void LoadStubCompiler::GenerateLoadViaGetter(MacroAssembler* masm,
+ Handle<HeapType> type,
Register receiver,
Handle<JSFunction> getter) {
// ----------- S t a t e -------------
if (!getter.is_null()) {
// Call the JavaScript getter with the receiver on the stack.
+ if (IC::TypeToMap(*type, masm->isolate())->IsJSGlobalObjectMap()) {
+ // Swap in the global receiver.
+ __ movp(receiver,
+ FieldOperand(receiver, JSGlobalObject::kGlobalReceiverOffset));
+ }
__ push(receiver);
ParameterCount actual(0);
ParameterCount expected(getter);
"for (var i = 0; i < 10; i++) o.n;");
CHECK(!try_catch.HasCaught());
}
+
+
+THREADED_TEST(GlobalObjectAccessor) {
+ LocalContext env;
+ v8::Isolate* isolate = env->GetIsolate();
+ v8::HandleScope scope(isolate);
+ CompileRun(
+ "var set_value = 1;"
+ "Object.defineProperty(this.__proto__, 'x', {"
+ " get : function() { return this; },"
+ " set : function() { set_value = this; }"
+ "});"
+ "function getter() { return x; }"
+ "function setter() { x = 1; }"
+ "for (var i = 0; i < 4; i++) { getter(); setter(); }");
+ CHECK(v8::Utils::OpenHandle(*CompileRun("getter()"))->IsJSGlobalProxy());
+ CHECK(v8::Utils::OpenHandle(*CompileRun("set_value"))->IsJSGlobalProxy());
+}