| Index: src/api.cc
|
| ===================================================================
|
| --- src/api.cc (revision 539)
|
| +++ src/api.cc (working copy)
|
| @@ -412,10 +412,6 @@
|
|
|
| thread_local.SaveContext(i::GlobalHandles::Create(i::Top::context()));
|
| i::Top::set_context(*env);
|
| -
|
| - thread_local.SaveSecurityContext(
|
| - i::GlobalHandles::Create(i::Top::security_context()));
|
| - i::Top::set_security_context(*env);
|
| }
|
|
|
|
|
| @@ -427,16 +423,10 @@
|
| return;
|
| }
|
|
|
| - // Content of 'last_context' and 'last_security_context' could be NULL.
|
| + // Content of 'last_context' could be NULL.
|
| i::Handle<i::Object> last_context = thread_local.RestoreContext();
|
| i::Top::set_context(static_cast<i::Context*>(*last_context));
|
| i::GlobalHandles::Destroy(last_context.location());
|
| -
|
| - i::Handle<i::Object> last_security_context =
|
| - thread_local.RestoreSecurityContext();
|
| - i::Top::set_security_context(
|
| - static_cast<i::Context*>(*last_security_context));
|
| - i::GlobalHandles::Destroy(last_security_context.location());
|
| }
|
|
|
|
|
| @@ -908,7 +898,8 @@
|
| void ObjectTemplate::SetAccessCheckCallbacks(
|
| NamedSecurityCallback named_callback,
|
| IndexedSecurityCallback indexed_callback,
|
| - Handle<Value> data) {
|
| + Handle<Value> data,
|
| + bool turned_on_by_default) {
|
| if (IsDeadCheck("v8::ObjectTemplate::SetAccessCheckCallbacks()")) return;
|
| HandleScope scope;
|
| EnsureConstructor(this);
|
| @@ -925,8 +916,8 @@
|
| i::FunctionTemplateInfo* constructor =
|
| i::FunctionTemplateInfo::cast(Utils::OpenHandle(this)->constructor());
|
| i::Handle<i::FunctionTemplateInfo> cons(constructor);
|
| - cons->set_needs_access_check(true);
|
| cons->set_access_check_info(*info);
|
| + cons->set_needs_access_check(turned_on_by_default);
|
| }
|
|
|
|
|
| @@ -1064,9 +1055,9 @@
|
| HandleScope scope;
|
| i::Handle<i::JSFunction> fun = Utils::OpenHandle(this);
|
| EXCEPTION_PREAMBLE();
|
| - i::Handle<i::Object> global(i::Top::context()->global());
|
| + i::Handle<i::Object> receiver(i::Top::context()->global_proxy());
|
| i::Handle<i::Object> result =
|
| - i::Execution::Call(fun, global, 0, NULL, &has_pending_exception);
|
| + i::Execution::Call(fun, receiver, 0, NULL, &has_pending_exception);
|
| EXCEPTION_BAILOUT_CHECK(Local<Value>());
|
| raw_result = *result;
|
| }
|
| @@ -1764,7 +1755,7 @@
|
|
|
|
|
| bool v8::Object::Set(v8::Handle<Value> key, v8::Handle<Value> value,
|
| - v8::PropertyAttribute attribs) {
|
| + v8::PropertyAttribute attribs) {
|
| ON_BAILOUT("v8::Object::Set()", return false);
|
| i::Handle<i::Object> self = Utils::OpenHandle(this);
|
| i::Handle<i::Object> key_obj = Utils::OpenHandle(*key);
|
| @@ -1937,6 +1928,20 @@
|
| }
|
|
|
|
|
| +// Turns on access checks by copying the map and setting the check flag.
|
| +// Because the object gets a new map, existing inline cache caching
|
| +// the old map of this object will fail.
|
| +void v8::Object::TurnOnAccessCheck() {
|
| + ON_BAILOUT("v8::Object::TurnOnAccessCheck()", return);
|
| + i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
|
| +
|
| + i::Handle<i::Map> new_map =
|
| + i::Factory::CopyMapDropTransitions(i::Handle<i::Map>(obj->map()));
|
| + new_map->set_is_access_check_needed();
|
| + obj->set_map(*new_map);
|
| +}
|
| +
|
| +
|
| Local<v8::Object> Function::NewInstance() {
|
| return NewInstance(0, NULL);
|
| }
|
| @@ -2220,20 +2225,54 @@
|
| }
|
|
|
|
|
| -Persistent<Context> v8::Context::New(v8::ExtensionConfiguration* extensions,
|
| - v8::Handle<ObjectTemplate> global_template,
|
| - v8::Handle<Value> global_object) {
|
| +static i::Handle<i::FunctionTemplateInfo>
|
| + EnsureConstructor(i::Handle<i::ObjectTemplateInfo> templ) {
|
| + if (templ->constructor()->IsUndefined()) {
|
| + Local<FunctionTemplate> constructor = FunctionTemplate::New();
|
| + Utils::OpenHandle(*constructor)->set_instance_template(*templ);
|
| + templ->set_constructor(*Utils::OpenHandle(*constructor));
|
| + }
|
| + return i::Handle<i::FunctionTemplateInfo>(
|
| + i::FunctionTemplateInfo::cast(templ->constructor()));
|
| +}
|
| +
|
| +
|
| +Persistent<Context> v8::Context::New(
|
| + v8::ExtensionConfiguration* extensions,
|
| + v8::Handle<ObjectTemplate> global_template,
|
| + v8::Handle<Value> global_object) {
|
| EnsureInitialized("v8::Context::New()");
|
| LOG_API("Context::New");
|
| ON_BAILOUT("v8::Context::New()", return Persistent<Context>());
|
| +
|
| // Make sure that the global_template has a constructor.
|
| - if (!global_template.IsEmpty() &&
|
| - Utils::OpenHandle(*global_template)->constructor()->IsUndefined()) {
|
| - Local<FunctionTemplate> templ = FunctionTemplate::New();
|
| - Utils::OpenHandle(*templ)->set_instance_template(
|
| + if (!global_template.IsEmpty()) {
|
| + i::Handle<i::FunctionTemplateInfo> constructor =
|
| + EnsureConstructor(Utils::OpenHandle(*global_template));
|
| +
|
| + // Create a fresh template for outer global object.
|
| + Local<ObjectTemplate> outer_template = ObjectTemplate::New();
|
| +
|
| + i::Handle<i::FunctionTemplateInfo> outer_constructor =
|
| + EnsureConstructor(Utils::OpenHandle(*outer_template));
|
| +
|
| + // Set the global template to be the prototype template
|
| + // of outer global template.
|
| + outer_constructor->set_prototype_template(
|
| *Utils::OpenHandle(*global_template));
|
| - i::Handle<i::FunctionTemplateInfo> constructor = Utils::OpenHandle(*templ);
|
| - Utils::OpenHandle(*global_template)->set_constructor(*constructor);
|
| +
|
| + // Migrate security handlers from global_template to outer_template.
|
| + if (!constructor->access_check_info()->IsUndefined()) {
|
| + outer_constructor->set_access_check_info(
|
| + constructor->access_check_info());
|
| + outer_constructor->set_needs_access_check(true);
|
| +
|
| + // Remove access check info from global_template.
|
| + constructor->set_needs_access_check(false);
|
| + constructor->set_access_check_info(i::Heap::undefined_value());
|
| + }
|
| +
|
| + global_template = outer_template;
|
| }
|
|
|
| i::Handle<i::Context> env = i::Bootstrapper::CreateEnvironment(
|
| @@ -2248,18 +2287,27 @@
|
|
|
|
|
| void v8::Context::SetSecurityToken(Handle<Value> token) {
|
| + if (IsDeadCheck("v8::Context::SetSecurityToken()")) return;
|
| i::Handle<i::Context> env = Utils::OpenHandle(this);
|
| i::Handle<i::Object> token_handle = Utils::OpenHandle(*token);
|
| - // The global object of an environment is always a real global
|
| - // object with security token and reference to the builtins object.
|
| - i::JSGlobalObject::cast(env->global())->set_security_token(*token_handle);
|
| + env->set_security_token(*token_handle);
|
| }
|
|
|
|
|
| +void v8::Context::UseDefaultSecurityToken() {
|
| + if (IsDeadCheck("v8::Context::UseDefaultSecurityToken()")) return;
|
| + i::Handle<i::Context> env = Utils::OpenHandle(this);
|
| + // The default security token of an environment is the inner global object
|
| + // of the environment. The security tokens of outer and inner global objects
|
| + // are always the same.
|
| + env->set_security_token(env->global());
|
| +}
|
| +
|
| +
|
| Handle<Value> v8::Context::GetSecurityToken() {
|
| + if (IsDeadCheck("v8::Context::GetSecurityToken()")) return Handle<Value>();
|
| i::Handle<i::Context> env = Utils::OpenHandle(this);
|
| - i::Object* security_token =
|
| - i::JSGlobalObject::cast(env->global())->security_token();
|
| + i::Object* security_token = env->security_token();
|
| i::Handle<i::Object> token_handle(security_token);
|
| return Utils::ToLocal(token_handle);
|
| }
|
| @@ -2276,11 +2324,6 @@
|
| }
|
|
|
|
|
| -bool Context::InSecurityContext() {
|
| - return i::Top::security_context() != NULL;
|
| -}
|
| -
|
| -
|
| v8::Local<v8::Context> Context::GetEntered() {
|
| if (IsDeadCheck("v8::Context::GetEntered()")) return Local<Context>();
|
| i::Handle<i::Object> last = thread_local.LastEnteredContext();
|
| @@ -2297,22 +2340,22 @@
|
| }
|
|
|
|
|
| -v8::Local<v8::Context> Context::GetCurrentSecurityContext() {
|
| - if (IsDeadCheck("v8::Context::GetCurrentSecurityContext()")) {
|
| - return Local<Context>();
|
| - }
|
| - i::Handle<i::Context> context(i::Top::security_context());
|
| - return Utils::ToLocal(context);
|
| +v8::Local<v8::Object> Context::Global() {
|
| + if (IsDeadCheck("v8::Context::Global()")) return Local<v8::Object>();
|
| + i::Object** ctx = reinterpret_cast<i::Object**>(this);
|
| + i::Handle<i::Context> context =
|
| + i::Handle<i::Context>::cast(i::Handle<i::Object>(ctx));
|
| + i::Handle<i::Object> global(context->global_proxy());
|
| + return Utils::ToLocal(i::Handle<i::JSObject>::cast(global));
|
| }
|
|
|
|
|
| -v8::Local<v8::Object> Context::Global() {
|
| - if (IsDeadCheck("v8::Context::Global()")) return Local<v8::Object>();
|
| +void Context::DetachGlobal() {
|
| + if (IsDeadCheck("v8::Context::DetachGlobal()")) return;
|
| i::Object** ctx = reinterpret_cast<i::Object**>(this);
|
| i::Handle<i::Context> context =
|
| i::Handle<i::Context>::cast(i::Handle<i::Object>(ctx));
|
| - i::Handle<i::JSObject> global(context->global());
|
| - return Utils::ToLocal(global);
|
| + i::Bootstrapper::DetachGlobal(context);
|
| }
|
|
|
|
|
|
|