Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1324)

Unified Diff: src/isolate.cc

Issue 234913003: Allow allocation and GC in access check callbacks. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: added TODOs, addressed comments Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/isolate.h ('k') | src/objects.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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));
}
« no previous file with comments | « src/isolate.h ('k') | src/objects.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698