| Index: test/cctest/test-api.cc
|
| ===================================================================
|
| --- test/cctest/test-api.cc (revision 539)
|
| +++ test/cctest/test-api.cc (working copy)
|
| @@ -987,13 +987,9 @@
|
| }
|
|
|
|
|
| -v8::Handle<Value> pre_post_global;
|
| -
|
| static v8::Handle<Value> PrePropertyHandlerGet(Local<String> key,
|
| const AccessorInfo& info) {
|
| ApiTestFuzzer::Fuzz();
|
| - CHECK(info.This()->Equals(pre_post_global));
|
| - CHECK(info.Holder()->Equals(pre_post_global));
|
| if (v8_str("pre")->Equals(key)) {
|
| return v8_str("PrePropertyHandler: pre");
|
| }
|
| @@ -1018,7 +1014,6 @@
|
| 0,
|
| PrePropertyHandlerHas);
|
| LocalContext env(NULL, desc->InstanceTemplate());
|
| - pre_post_global = env->Global();
|
| Script::Compile(v8_str(
|
| "var pre = 'Object: pre'; var on = 'Object: on';"))->Run();
|
| v8::Handle<Value> result_pre = Script::Compile(v8_str("pre"))->Run();
|
| @@ -1165,12 +1160,11 @@
|
|
|
| THREADED_TEST(InternalFields) {
|
| v8::HandleScope scope;
|
| + LocalContext env;
|
| +
|
| Local<v8::FunctionTemplate> templ = v8::FunctionTemplate::New();
|
| Local<v8::ObjectTemplate> instance_templ = templ->InstanceTemplate();
|
| instance_templ->SetInternalFieldCount(1);
|
| - LocalContext env(0, instance_templ);
|
| - CHECK_EQ(1, env->Global()->InternalFieldCount());
|
| -
|
| Local<v8::Object> obj = templ->GetFunction()->NewInstance();
|
| CHECK_EQ(1, obj->InternalFieldCount());
|
| CHECK(obj->GetInternalField(0)->IsUndefined());
|
| @@ -3061,7 +3055,7 @@
|
| CHECK(spy->IsFunction());
|
|
|
| // Create another function accessing global objects.
|
| - Script::Compile(v8_str("spy2=function(){return new Array();}"))->Run();
|
| + Script::Compile(v8_str("spy2=function(){return new this.Array();}"))->Run();
|
| Local<Value> spy2 = env1->Global()->Get(v8_str("spy2"));
|
| CHECK(spy2->IsFunction());
|
|
|
| @@ -3074,13 +3068,9 @@
|
| CHECK(result->IsFunction());
|
| }
|
|
|
| - // Change env2 to a new domain and invoke spy on env2. It should be blocked
|
| - // by security check.
|
| {
|
| env2->SetSecurityToken(bar);
|
| Context::Scope scope_env2(env2);
|
| - Local<Value> result = Function::Cast(*spy)->Call(env2->Global(), 0, NULL);
|
| - CHECK(result->IsUndefined());
|
|
|
| // Call cross_domain_call, it should throw an exception
|
| v8::TryCatch try_catch;
|
| @@ -3227,11 +3217,75 @@
|
| }
|
|
|
|
|
| +TEST(ContextDetachGlobal) {
|
| + v8::HandleScope handle_scope;
|
| + LocalContext env1;
|
| + v8::Persistent<Context> env2 = Context::New();
|
| +
|
| + Local<v8::Object> global1 = env1->Global();
|
| +
|
| + Local<Value> foo = v8_str("foo");
|
| +
|
| + // Set to the same domain.
|
| + env1->SetSecurityToken(foo);
|
| + env2->SetSecurityToken(foo);
|
| +
|
| + // Enter env2
|
| + env2->Enter();
|
| +
|
| + // Create a function in env1
|
| + Local<v8::Object> global2 = env2->Global();
|
| + global2->Set(v8_str("prop"), v8::Integer::New(1));
|
| + CompileRun("function getProp() {return prop;}");
|
| +
|
| + env1->Global()->Set(v8_str("getProp"),
|
| + global2->Get(v8_str("getProp")));
|
| +
|
| + // Detach env1's global, and reuse the global object of env1
|
| + env2->Exit();
|
| + env2->DetachGlobal();
|
| + // env2 has a new global object.
|
| + CHECK(!env2->Global()->Equals(global2));
|
| +
|
| + v8::Persistent<Context> env3 =
|
| + Context::New(0, v8::Handle<v8::ObjectTemplate>(), global2);
|
| + env3->SetSecurityToken(v8_str("bar"));
|
| + env3->Enter();
|
| +
|
| + Local<v8::Object> global3 = env3->Global();
|
| + CHECK_EQ(global2, global3);
|
| + CHECK(global3->Get(v8_str("prop"))->IsUndefined());
|
| + CHECK(global3->Get(v8_str("getProp"))->IsUndefined());
|
| + global3->Set(v8_str("prop"), v8::Integer::New(-1));
|
| + global3->Set(v8_str("prop2"), v8::Integer::New(2));
|
| + env3->Exit();
|
| +
|
| + // Call getProp in env1, and it should return the value 1
|
| + {
|
| + Local<Value> get_prop = global1->Get(v8_str("getProp"));
|
| + CHECK(get_prop->IsFunction());
|
| + v8::TryCatch try_catch;
|
| + Local<Value> r = Function::Cast(*get_prop)->Call(global1, 0, NULL);
|
| + CHECK(!try_catch.HasCaught());
|
| + CHECK_EQ(1, r->Int32Value());
|
| + }
|
| +
|
| + // Check that env3 is not accessible from env1
|
| + {
|
| + Local<Value> r = global3->Get(v8_str("prop2"));
|
| + CHECK(r->IsUndefined());
|
| + }
|
| +
|
| + env2.Dispose();
|
| + env3.Dispose();
|
| +}
|
| +
|
| +
|
| static bool NamedAccessBlocker(Local<v8::Object> global,
|
| Local<Value> name,
|
| v8::AccessType type,
|
| Local<Value> data) {
|
| - return Context::GetCurrentSecurityContext()->Global()->Equals(global);
|
| + return Context::GetCurrent()->Global()->Equals(global);
|
| }
|
|
|
|
|
| @@ -3239,7 +3293,7 @@
|
| uint32_t key,
|
| v8::AccessType type,
|
| Local<Value> data) {
|
| - return Context::GetCurrentSecurityContext()->Global()->Equals(global);
|
| + return Context::GetCurrent()->Global()->Equals(global);
|
| }
|
|
|
|
|
| @@ -3252,7 +3306,7 @@
|
|
|
| static void EchoSetter(Local<String> name,
|
| Local<Value> value,
|
| - const AccessorInfo& info) {
|
| + const AccessorInfo&) {
|
| if (value->IsNumber())
|
| g_echo_value = value->Int32Value();
|
| }
|
| @@ -3265,9 +3319,8 @@
|
| }
|
|
|
|
|
| -static void UnreachableSetter(Local<String> name,
|
| - Local<Value> value,
|
| - const AccessorInfo& info) {
|
| +static void UnreachableSetter(Local<String>, Local<Value>,
|
| + const AccessorInfo&) {
|
| CHECK(false); // This function should nto be called.
|
| }
|
|
|
| @@ -3546,15 +3599,14 @@
|
| }
|
|
|
|
|
| -static v8::Handle<Value> AccessControlNamedGetter(Local<String> name,
|
| - const AccessorInfo& info) {
|
| +static v8::Handle<Value> AccessControlNamedGetter(
|
| + Local<String>, const AccessorInfo&) {
|
| return v8::Integer::New(42);
|
| }
|
|
|
|
|
| -static v8::Handle<Value> AccessControlNamedSetter(Local<String> key,
|
| - Local<Value> value,
|
| - const AccessorInfo&) {
|
| +static v8::Handle<Value> AccessControlNamedSetter(
|
| + Local<String>, Local<Value> value, const AccessorInfo&) {
|
| return value;
|
| }
|
|
|
| @@ -3566,9 +3618,8 @@
|
| }
|
|
|
|
|
| -static v8::Handle<Value> AccessControlIndexedSetter(uint32_t index,
|
| - Local<Value> value,
|
| - const AccessorInfo&) {
|
| +static v8::Handle<Value> AccessControlIndexedSetter(
|
| + uint32_t, Local<Value> value, const AccessorInfo&) {
|
| return value;
|
| }
|
|
|
| @@ -3727,9 +3778,7 @@
|
| static int shadow_y_getter_call_count;
|
|
|
|
|
| -static void ShadowYSetter(Local<String> name,
|
| - Local<Value> value,
|
| - const AccessorInfo& info) {
|
| +static void ShadowYSetter(Local<String>, Local<Value>, const AccessorInfo&) {
|
| shadow_y_setter_call_count++;
|
| shadow_y = 42;
|
| }
|
| @@ -4145,9 +4194,7 @@
|
|
|
|
|
| static v8::Handle<Value> InterceptorStoreICSetter(
|
| - Local<String> key,
|
| - Local<Value> value,
|
| - const AccessorInfo&) {
|
| + Local<String> key, Local<Value> value, const AccessorInfo&) {
|
| CHECK(v8_str("x")->Equals(key));
|
| CHECK_EQ(42, value->Int32Value());
|
| return value;
|
| @@ -4292,9 +4339,7 @@
|
| static int interceptor_ic_exception_set_count = 0;
|
|
|
| static v8::Handle<Value> InterceptorICExceptionSetter(
|
| - Local<String> key,
|
| - Local<Value> value,
|
| - const AccessorInfo&) {
|
| + Local<String> key, Local<Value> value, const AccessorInfo&) {
|
| ApiTestFuzzer::Fuzz();
|
| if (++interceptor_ic_exception_set_count > 20) {
|
| return v8::ThrowException(v8_num(42));
|
| @@ -4774,6 +4819,10 @@
|
|
|
| v8::V8::Initialize();
|
|
|
| + // TODO(121): when running "cctest test-api", the initial count is 2,
|
| + // after second GC, the counter drops to 1. Needs to figure out why
|
| + // one GC is not enough to collect all garbage.
|
| + GetSurvivingGlobalObjectsCount();
|
| int count = GetSurvivingGlobalObjectsCount();
|
|
|
| for (int i = 0; i < 5; i++) {
|
|
|