Index: src/isolate.cc |
diff --git a/src/isolate.cc b/src/isolate.cc |
index 076bb89e06aabf616105f590c16672ae898487ec..c9baf756aeec67aba23663d90a85d24a4c8a43ea 100644 |
--- a/src/isolate.cc |
+++ b/src/isolate.cc |
@@ -693,28 +693,41 @@ void Isolate::SetFailedAccessCheckCallback( |
} |
-void Isolate::ReportFailedAccessCheck(JSObject* receiver, v8::AccessType type) { |
+static inline AccessCheckInfo* GetAccessCheckInfo(Isolate* isolate, |
+ Handle<JSObject> receiver) { |
+ JSFunction* constructor = JSFunction::cast(receiver->map()->constructor()); |
+ if (!constructor->shared()->IsApiFunction()) return NULL; |
+ |
+ Object* data_obj = |
+ constructor->shared()->get_api_func_data()->access_check_info(); |
+ if (data_obj == isolate->heap()->undefined_value()) return NULL; |
+ |
+ return AccessCheckInfo::cast(data_obj); |
+} |
+ |
+ |
+void Isolate::ReportFailedAccessCheck(Handle<JSObject> receiver, |
+ v8::AccessType type) { |
if (!thread_local_top()->failed_access_check_callback_) return; |
ASSERT(receiver->IsAccessCheckNeeded()); |
ASSERT(context()); |
// Get the data object from access check info. |
- JSFunction* constructor = JSFunction::cast(receiver->map()->constructor()); |
- if (!constructor->shared()->IsApiFunction()) return; |
- Object* data_obj = |
- constructor->shared()->get_api_func_data()->access_check_info(); |
- if (data_obj == heap_.undefined_value()) return; |
- |
HandleScope scope(this); |
- Handle<JSObject> receiver_handle(receiver); |
- Handle<Object> data(AccessCheckInfo::cast(data_obj)->data(), this); |
- { VMState<EXTERNAL> state(this); |
- thread_local_top()->failed_access_check_callback_( |
- v8::Utils::ToLocal(receiver_handle), |
+ Handle<Object> data; |
+ { DisallowHeapAllocation no_gc; |
+ AccessCheckInfo* access_check_info = GetAccessCheckInfo(this, receiver); |
+ if (!access_check_info) return; |
+ data = handle(access_check_info->data(), this); |
+ } |
+ |
+ // Leaving JavaScript. |
+ VMState<EXTERNAL> state(this); |
+ thread_local_top()->failed_access_check_callback_( |
+ v8::Utils::ToLocal(receiver), |
type, |
v8::Utils::ToLocal(data)); |
- } |
} |
@@ -724,13 +737,14 @@ enum MayAccessDecision { |
static MayAccessDecision MayAccessPreCheck(Isolate* isolate, |
- JSObject* receiver, |
+ Handle<JSObject> receiver, |
v8::AccessType type) { |
+ DisallowHeapAllocation no_gc; |
// During bootstrapping, callback functions are not enabled yet. |
if (isolate->bootstrapper()->IsActive()) return YES; |
if (receiver->IsJSGlobalProxy()) { |
- Object* receiver_context = JSGlobalProxy::cast(receiver)->native_context(); |
+ Object* receiver_context = JSGlobalProxy::cast(*receiver)->native_context(); |
if (!receiver_context->IsContext()) return NO; |
// Get the native context of current top context. |
@@ -748,16 +762,14 @@ static MayAccessDecision MayAccessPreCheck(Isolate* isolate, |
} |
-bool Isolate::MayNamedAccess(JSObject* receiver, Object* key, |
+bool Isolate::MayNamedAccess(Handle<JSObject> receiver, |
+ Handle<Object> key, |
v8::AccessType type) { |
ASSERT(receiver->IsJSGlobalProxy() || receiver->IsAccessCheckNeeded()); |
- // The callers of this method are not expecting a GC. |
- DisallowHeapAllocation no_gc; |
- |
// Skip checks for hidden properties access. Note, we do not |
// require existence of a context in this case. |
- if (key == heap_.hidden_string()) return true; |
+ if (key.is_identical_to(factory()->hidden_string())) return true; |
// Check for compatibility between the security tokens in the |
// current lexical context and the accessed object. |
@@ -766,39 +778,30 @@ bool Isolate::MayNamedAccess(JSObject* receiver, Object* key, |
MayAccessDecision decision = MayAccessPreCheck(this, receiver, type); |
if (decision != UNKNOWN) return decision == YES; |
- // Get named access check callback |
- JSFunction* constructor = JSFunction::cast(receiver->map()->constructor()); |
- if (!constructor->shared()->IsApiFunction()) return false; |
- |
- Object* data_obj = |
- constructor->shared()->get_api_func_data()->access_check_info(); |
- if (data_obj == heap_.undefined_value()) return false; |
- |
- Object* fun_obj = AccessCheckInfo::cast(data_obj)->named_callback(); |
- v8::NamedSecurityCallback callback = |
- v8::ToCData<v8::NamedSecurityCallback>(fun_obj); |
- |
- if (!callback) return false; |
- |
HandleScope scope(this); |
- Handle<JSObject> receiver_handle(receiver, this); |
- Handle<Object> key_handle(key, this); |
- Handle<Object> data(AccessCheckInfo::cast(data_obj)->data(), this); |
- LOG(this, ApiNamedSecurityCheck(key)); |
- bool result = false; |
- { |
- // Leaving JavaScript. |
- VMState<EXTERNAL> state(this); |
- result = callback(v8::Utils::ToLocal(receiver_handle), |
- v8::Utils::ToLocal(key_handle), |
- type, |
- v8::Utils::ToLocal(data)); |
+ Handle<Object> data; |
+ v8::NamedSecurityCallback callback; |
+ { DisallowHeapAllocation no_gc; |
+ AccessCheckInfo* access_check_info = GetAccessCheckInfo(this, receiver); |
+ if (!access_check_info) return false; |
+ Object* fun_obj = access_check_info->named_callback(); |
+ callback = v8::ToCData<v8::NamedSecurityCallback>(fun_obj); |
+ if (!callback) return false; |
+ data = handle(access_check_info->data(), this); |
} |
- return result; |
+ |
+ LOG(this, ApiNamedSecurityCheck(*key)); |
+ |
+ // Leaving JavaScript. |
+ VMState<EXTERNAL> state(this); |
+ return callback(v8::Utils::ToLocal(receiver), |
+ v8::Utils::ToLocal(key), |
+ type, |
+ v8::Utils::ToLocal(data)); |
} |
-bool Isolate::MayIndexedAccess(JSObject* receiver, |
+bool Isolate::MayIndexedAccess(Handle<JSObject> receiver, |
uint32_t index, |
v8::AccessType type) { |
ASSERT(receiver->IsJSGlobalProxy() || receiver->IsAccessCheckNeeded()); |
@@ -809,34 +812,25 @@ bool Isolate::MayIndexedAccess(JSObject* receiver, |
MayAccessDecision decision = MayAccessPreCheck(this, receiver, type); |
if (decision != UNKNOWN) return decision == YES; |
- // Get indexed access check callback |
- JSFunction* constructor = JSFunction::cast(receiver->map()->constructor()); |
- if (!constructor->shared()->IsApiFunction()) return false; |
- |
- Object* data_obj = |
- constructor->shared()->get_api_func_data()->access_check_info(); |
- if (data_obj == heap_.undefined_value()) return false; |
- |
- Object* fun_obj = AccessCheckInfo::cast(data_obj)->indexed_callback(); |
- v8::IndexedSecurityCallback callback = |
- v8::ToCData<v8::IndexedSecurityCallback>(fun_obj); |
- |
- if (!callback) return false; |
- |
HandleScope scope(this); |
- Handle<JSObject> receiver_handle(receiver, this); |
- Handle<Object> data(AccessCheckInfo::cast(data_obj)->data(), this); |
- LOG(this, ApiIndexedSecurityCheck(index)); |
- bool result = false; |
- { |
- // Leaving JavaScript. |
- VMState<EXTERNAL> state(this); |
- result = callback(v8::Utils::ToLocal(receiver_handle), |
- index, |
- type, |
- v8::Utils::ToLocal(data)); |
+ Handle<Object> data; |
+ v8::IndexedSecurityCallback callback; |
+ { DisallowHeapAllocation no_gc; |
+ // Get named access check callback |
+ AccessCheckInfo* access_check_info = GetAccessCheckInfo(this, receiver); |
+ if (!access_check_info) return false; |
+ Object* fun_obj = access_check_info->indexed_callback(); |
+ callback = v8::ToCData<v8::IndexedSecurityCallback>(fun_obj); |
+ if (!callback) return false; |
+ data = handle(access_check_info->data(), this); |
} |
- return result; |
+ |
+ LOG(this, ApiIndexedSecurityCheck(index)); |
+ |
+ // Leaving JavaScript. |
+ VMState<EXTERNAL> state(this); |
+ return callback( |
+ v8::Utils::ToLocal(receiver), index, type, v8::Utils::ToLocal(data)); |
} |