| Index: src/macro-assembler-arm.cc
|
| ===================================================================
|
| --- src/macro-assembler-arm.cc (revision 542)
|
| +++ src/macro-assembler-arm.cc (working copy)
|
| @@ -593,7 +593,7 @@
|
|
|
| // Only global objects and objects that do not require access
|
| // checks are allowed in stubs.
|
| - ASSERT(object->IsJSGlobalObject() || !object->IsAccessCheckNeeded());
|
| + ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded());
|
|
|
| // Get the map of the current object.
|
| ldr(scratch, FieldMemOperand(reg, HeapObject::kMapOffset));
|
| @@ -605,8 +605,8 @@
|
| // Check access rights to the global object. This has to happen
|
| // after the map check so that we know that the object is
|
| // actually a global object.
|
| - if (object->IsJSGlobalObject()) {
|
| - CheckAccessGlobal(reg, scratch, miss);
|
| + if (object->IsJSGlobalProxy()) {
|
| + CheckAccessGlobalProxy(reg, scratch, miss);
|
| // Restore scratch register to be the map of the object. In the
|
| // new space case below, we load the prototype from the map in
|
| // the scratch register.
|
| @@ -639,38 +639,73 @@
|
| // Perform security check for access to the global object and return
|
| // the holder register.
|
| ASSERT(object == holder);
|
| - ASSERT(object->IsJSGlobalObject() || !object->IsAccessCheckNeeded());
|
| - if (object->IsJSGlobalObject()) {
|
| - CheckAccessGlobal(reg, scratch, miss);
|
| + ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded());
|
| + if (object->IsJSGlobalProxy()) {
|
| + CheckAccessGlobalProxy(reg, scratch, miss);
|
| }
|
| return reg;
|
| }
|
|
|
|
|
| -void MacroAssembler::CheckAccessGlobal(Register holder_reg,
|
| - Register scratch,
|
| - Label* miss) {
|
| +void MacroAssembler::CheckAccessGlobalProxy(Register holder_reg,
|
| + Register scratch,
|
| + Label* miss) {
|
| + Label same_contexts;
|
| +
|
| ASSERT(!holder_reg.is(scratch));
|
| + ASSERT(!holder_reg.is(ip));
|
| + ASSERT(!scratch.is(ip));
|
|
|
| - // Load the security context.
|
| - mov(scratch, Operand(Top::security_context_address()));
|
| - ldr(scratch, MemOperand(scratch));
|
| - // In debug mode, make sure the security context is set.
|
| + // Load current lexical context from the stack frame.
|
| + ldr(scratch, MemOperand(fp, StandardFrameConstants::kContextOffset));
|
| + // In debug mode, make sure the lexical context is set.
|
| if (kDebug) {
|
| cmp(scratch, Operand(0));
|
| - Check(ne, "we should not have an empty security context");
|
| + Check(ne, "we should not have an empty lexical context");
|
| }
|
|
|
| - // Load the global object of the security context.
|
| + // Load the global context of the current context.
|
| int offset = Context::kHeaderSize + Context::GLOBAL_INDEX * kPointerSize;
|
| ldr(scratch, FieldMemOperand(scratch, offset));
|
| + ldr(scratch, FieldMemOperand(scratch, GlobalObject::kGlobalContextOffset));
|
| +
|
| + // Check the context is a global context.
|
| + if (FLAG_debug_code) {
|
| + // Read the first word and compare to the global_context_map.
|
| + ldr(ip, FieldMemOperand(scratch, HeapObject::kMapOffset));
|
| + cmp(ip, Operand(Factory::global_context_map()));
|
| + Check(eq, "JSGlobalObject::global_context should be a global context.");
|
| + }
|
| +
|
| + // Check if both contexts are the same.
|
| + ldr(ip, FieldMemOperand(holder_reg, JSGlobalProxy::kContextOffset));
|
| + cmp(scratch, Operand(ip));
|
| + b(eq, &same_contexts);
|
| +
|
| + // Check the context is a global context.
|
| + if (FLAG_debug_code) {
|
| + cmp(ip, Operand(Factory::null_value()));
|
| + Check(ne, "JSGlobalProxy::context() should not be null.");
|
| +
|
| + ldr(ip, FieldMemOperand(ip, HeapObject::kMapOffset));
|
| + cmp(ip, Operand(Factory::global_context_map()));
|
| + Check(eq, "JSGlobalObject::global_context should be a global context.");
|
| + // Restore ip to holder's context.
|
| + ldr(ip, FieldMemOperand(holder_reg, JSGlobalProxy::kContextOffset));
|
| + }
|
| +
|
| // Check that the security token in the calling global object is
|
| // compatible with the security token in the receiving global
|
| // object.
|
| - ldr(scratch, FieldMemOperand(scratch, JSGlobalObject::kSecurityTokenOffset));
|
| - ldr(ip, FieldMemOperand(holder_reg, JSGlobalObject::kSecurityTokenOffset));
|
| + int token_offset = Context::kHeaderSize +
|
| + Context::SECURITY_TOKEN_INDEX * kPointerSize;
|
| +
|
| + ldr(scratch, FieldMemOperand(scratch, token_offset));
|
| + ldr(ip, FieldMemOperand(ip, token_offset));
|
| cmp(scratch, Operand(ip));
|
| b(ne, miss);
|
| +
|
| + bind(&same_contexts);
|
| }
|
|
|
|
|
|
|