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); |
} |