Introduce v8::Object::CreationContext method.
That allows to find out a global context in which the object was created. Review URL: http://codereview.chromium.org/6759054 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@7476 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
b8d5fd7d32
commit
56b53dd5dc
@ -1652,6 +1652,11 @@ class Object : public Value {
|
||||
*/
|
||||
V8EXPORT Local<Object> Clone();
|
||||
|
||||
/**
|
||||
* Returns the context in which the object was created.
|
||||
*/
|
||||
V8EXPORT Local<Context> CreationContext();
|
||||
|
||||
/**
|
||||
* Set the backing store of the indexed properties to be managed by the
|
||||
* embedding layer. Access to the indexed properties will follow the rules
|
||||
|
27
src/api.cc
27
src/api.cc
@ -2879,6 +2879,33 @@ Local<v8::Object> v8::Object::Clone() {
|
||||
}
|
||||
|
||||
|
||||
static i::Context* GetCreationContext(i::JSObject* object) {
|
||||
i::Object* constructor = object->map()->constructor();
|
||||
i::JSFunction* function;
|
||||
if (!constructor->IsJSFunction()) {
|
||||
// API functions have null as a constructor,
|
||||
// but any JSFunction knows its context immediately.
|
||||
ASSERT(object->IsJSFunction() &&
|
||||
i::JSFunction::cast(object)->shared()->IsApiFunction());
|
||||
function = i::JSFunction::cast(object);
|
||||
} else {
|
||||
function = i::JSFunction::cast(constructor);
|
||||
}
|
||||
return function->context()->global_context();
|
||||
}
|
||||
|
||||
|
||||
Local<v8::Context> v8::Object::CreationContext() {
|
||||
i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
|
||||
ON_BAILOUT(isolate,
|
||||
"v8::Object::CreationContext()", return Local<v8::Context>());
|
||||
ENTER_V8(isolate);
|
||||
i::Handle<i::JSObject> self = Utils::OpenHandle(this);
|
||||
i::Context* context = GetCreationContext(*self);
|
||||
return Utils::ToLocal(i::Handle<i::Context>(context));
|
||||
}
|
||||
|
||||
|
||||
int v8::Object::GetIdentityHash() {
|
||||
i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
|
||||
ON_BAILOUT(isolate, "v8::Object::GetIdentityHash()", return 0);
|
||||
|
@ -13629,3 +13629,102 @@ TEST(DefinePropertyPostDetach) {
|
||||
context->DetachGlobal();
|
||||
define_property->Call(proxy, 0, NULL);
|
||||
}
|
||||
|
||||
|
||||
static void InstallContextId(v8::Handle<Context> context, int id) {
|
||||
Context::Scope scope(context);
|
||||
CompileRun("Object.prototype").As<Object>()->
|
||||
Set(v8_str("context_id"), v8::Integer::New(id));
|
||||
}
|
||||
|
||||
|
||||
static void CheckContextId(v8::Handle<Object> object, int expected) {
|
||||
CHECK_EQ(expected, object->Get(v8_str("context_id"))->Int32Value());
|
||||
}
|
||||
|
||||
|
||||
THREADED_TEST(CreationContext) {
|
||||
HandleScope handle_scope;
|
||||
Persistent<Context> context1 = Context::New();
|
||||
InstallContextId(context1, 1);
|
||||
Persistent<Context> context2 = Context::New();
|
||||
InstallContextId(context2, 2);
|
||||
Persistent<Context> context3 = Context::New();
|
||||
InstallContextId(context3, 3);
|
||||
|
||||
Local<v8::FunctionTemplate> tmpl = v8::FunctionTemplate::New();
|
||||
|
||||
Local<Object> object1;
|
||||
Local<Function> func1;
|
||||
{
|
||||
Context::Scope scope(context1);
|
||||
object1 = Object::New();
|
||||
func1 = tmpl->GetFunction();
|
||||
}
|
||||
|
||||
Local<Object> object2;
|
||||
Local<Function> func2;
|
||||
{
|
||||
Context::Scope scope(context2);
|
||||
object2 = Object::New();
|
||||
func2 = tmpl->GetFunction();
|
||||
}
|
||||
|
||||
Local<Object> instance1;
|
||||
Local<Object> instance2;
|
||||
|
||||
{
|
||||
Context::Scope scope(context3);
|
||||
instance1 = func1->NewInstance();
|
||||
instance2 = func2->NewInstance();
|
||||
}
|
||||
|
||||
CHECK(object1->CreationContext() == context1);
|
||||
CheckContextId(object1, 1);
|
||||
CHECK(func1->CreationContext() == context1);
|
||||
CheckContextId(func1, 1);
|
||||
CHECK(instance1->CreationContext() == context1);
|
||||
CheckContextId(instance1, 1);
|
||||
CHECK(object2->CreationContext() == context2);
|
||||
CheckContextId(object2, 2);
|
||||
CHECK(func2->CreationContext() == context2);
|
||||
CheckContextId(func2, 2);
|
||||
CHECK(instance2->CreationContext() == context2);
|
||||
CheckContextId(instance2, 2);
|
||||
|
||||
{
|
||||
Context::Scope scope(context1);
|
||||
CHECK(object1->CreationContext() == context1);
|
||||
CheckContextId(object1, 1);
|
||||
CHECK(func1->CreationContext() == context1);
|
||||
CheckContextId(func1, 1);
|
||||
CHECK(instance1->CreationContext() == context1);
|
||||
CheckContextId(instance1, 1);
|
||||
CHECK(object2->CreationContext() == context2);
|
||||
CheckContextId(object2, 2);
|
||||
CHECK(func2->CreationContext() == context2);
|
||||
CheckContextId(func2, 2);
|
||||
CHECK(instance2->CreationContext() == context2);
|
||||
CheckContextId(instance2, 2);
|
||||
}
|
||||
|
||||
{
|
||||
Context::Scope scope(context2);
|
||||
CHECK(object1->CreationContext() == context1);
|
||||
CheckContextId(object1, 1);
|
||||
CHECK(func1->CreationContext() == context1);
|
||||
CheckContextId(func1, 1);
|
||||
CHECK(instance1->CreationContext() == context1);
|
||||
CheckContextId(instance1, 1);
|
||||
CHECK(object2->CreationContext() == context2);
|
||||
CheckContextId(object2, 2);
|
||||
CHECK(func2->CreationContext() == context2);
|
||||
CheckContextId(func2, 2);
|
||||
CHECK(instance2->CreationContext() == context2);
|
||||
CheckContextId(instance2, 2);
|
||||
}
|
||||
|
||||
context1.Dispose();
|
||||
context2.Dispose();
|
||||
context3.Dispose();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user