Commit 6e29fadb authored by yurys@chromium.org's avatar yurys@chromium.org

When inspecting a function with a native getter return result of execution of...

When inspecting a function with a native getter return result of execution of the getter function in the client context. This is useful for debugging DOM elements.
Review URL: http://codereview.chromium.org/113821

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@2044 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 80fba5a1
......@@ -5486,7 +5486,8 @@ static int LocalPrototypeChainLength(JSObject* obj) {
}
static Object* DebugLookupResultValue(Object* receiver, LookupResult* result,
static Object* DebugLookupResultValue(Object* receiver, String* name,
LookupResult* result,
bool* caught_exception) {
Object* value;
switch (result->type()) {
......@@ -5511,11 +5512,18 @@ static Object* DebugLookupResultValue(Object* receiver, LookupResult* result,
return result->GetConstantFunction();
case CALLBACKS: {
Object* structure = result->GetCallbackObject();
if (structure->IsProxy()) {
AccessorDescriptor* callback =
reinterpret_cast<AccessorDescriptor*>(
Proxy::cast(structure)->proxy());
value = (callback->getter)(receiver, callback->data);
if (structure->IsProxy() || structure->IsAccessorInfo()) {
if (Debug::debugger_entry()) {
// SaveContext scope. It will restore debugger context after the
// getter execution.
SaveContext save;
Top::set_context(*Debug::debugger_entry()->GetContext());
value = receiver->GetPropertyWithCallback(
receiver, structure, name, result->holder());
} else {
value = receiver->GetPropertyWithCallback(
receiver, structure, name, result->holder());
}
if (value->IsException()) {
value = Top::pending_exception();
Top::clear_pending_exception();
......@@ -5596,7 +5604,7 @@ static Object* Runtime_DebugGetPropertyDetails(Arguments args) {
if (result.IsProperty()) {
bool caught_exception = false;
Object* value = DebugLookupResultValue(*obj, &result,
Object* value = DebugLookupResultValue(*obj, *name, &result,
&caught_exception);
if (value->IsFailure()) return value;
Handle<Object> value_handle(value);
......@@ -5632,7 +5640,7 @@ static Object* Runtime_DebugGetProperty(Arguments args) {
LookupResult result;
obj->Lookup(*name, &result);
if (result.IsProperty()) {
return DebugLookupResultValue(*obj, &result, NULL);
return DebugLookupResultValue(*obj, *name, &result, NULL);
}
return Heap::undefined_value();
}
......
......@@ -3313,6 +3313,82 @@ TEST(HiddenPrototypePropertyMirror) {
}
static v8::Handle<v8::Value> ProtperyXNativeGetter(
v8::Local<v8::String> property, const v8::AccessorInfo& info) {
return v8::Integer::New(10);
}
TEST(NativeGetterPropertyMirror) {
// Create a V8 environment with debug access.
v8::HandleScope scope;
DebugLocalContext env;
env.ExposeDebug();
v8::Handle<v8::String> name = v8::String::New("x");
// Create object with named accessor.
v8::Handle<v8::ObjectTemplate> named = v8::ObjectTemplate::New();
named->SetAccessor(name, &ProtperyXNativeGetter, NULL,
v8::Handle<v8::Value>(), v8::DEFAULT, v8::None);
// Create object with named property getter.
env->Global()->Set(v8::String::New("instance"), named->NewInstance());
CHECK_EQ(10, CompileRun("instance.x")->Int32Value());
// Get mirror for the object with property getter.
CompileRun("instance_mirror = debug.MakeMirror(instance);");
CHECK(CompileRun(
"instance_mirror instanceof debug.ObjectMirror")->BooleanValue());
CompileRun("named_names = instance_mirror.propertyNames();");
CHECK_EQ(1, CompileRun("named_names.length")->Int32Value());
CHECK(CompileRun("named_names[0] == 'x'")->BooleanValue());
CHECK(CompileRun(
"instance_mirror.property('x').value().isNumber()")->BooleanValue());
CHECK(CompileRun(
"instance_mirror.property('x').value().value() == 10")->BooleanValue());
}
static v8::Handle<v8::Value> ProtperyXNativeGetterThrowingError(
v8::Local<v8::String> property, const v8::AccessorInfo& info) {
return CompileRun("throw new Error('Error message');");
}
TEST(NativeGetterThrowingErrorPropertyMirror) {
// Create a V8 environment with debug access.
v8::HandleScope scope;
DebugLocalContext env;
env.ExposeDebug();
v8::Handle<v8::String> name = v8::String::New("x");
// Create object with named accessor.
v8::Handle<v8::ObjectTemplate> named = v8::ObjectTemplate::New();
named->SetAccessor(name, &ProtperyXNativeGetterThrowingError, NULL,
v8::Handle<v8::Value>(), v8::DEFAULT, v8::None);
// Create object with named property getter.
env->Global()->Set(v8::String::New("instance"), named->NewInstance());
// Get mirror for the object with property getter.
CompileRun("instance_mirror = debug.MakeMirror(instance);");
CHECK(CompileRun(
"instance_mirror instanceof debug.ObjectMirror")->BooleanValue());
CompileRun("named_names = instance_mirror.propertyNames();");
CHECK_EQ(1, CompileRun("named_names.length")->Int32Value());
CHECK(CompileRun("named_names[0] == 'x'")->BooleanValue());
CHECK(CompileRun(
"instance_mirror.property('x').value().isError()")->BooleanValue());
// Check that the message is that passed to the Error constructor.
CHECK(CompileRun(
"instance_mirror.property('x').value().message() == 'Error message'")->
BooleanValue());
}
// Multithreaded tests of JSON debugger protocol
// Support classes
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment