Revision: 3315 Author: [email protected] Date: Tue Nov 17 01:53:59 2009 Log: Merge r3310 and r3311 to 1.3 branch.
Skip debugger frames when looking for calling context. BUG=http://code.google.com/p/v8/issues/detail?id=509 TEST=test/cctest/test-debug.cc/CallingContextIsNotDebugContext Review URL: http://codereview.chromium.org/402006 http://code.google.com/p/v8/source/detail?r=3315 Modified: /branches/1.3/src/top.cc /branches/1.3/src/version.cc /branches/1.3/test/cctest/test-debug.cc ======================================= --- /branches/1.3/src/top.cc Fri Oct 16 04:48:38 2009 +++ /branches/1.3/src/top.cc Tue Nov 17 01:53:59 2009 @@ -941,6 +941,19 @@ Handle<Context> Top::GetCallingGlobalContext() { JavaScriptFrameIterator it; +#ifdef ENABLE_DEBUGGER_SUPPORT + if (Debug::InDebugger()) { + while (!it.done()) { + JavaScriptFrame* frame = it.frame(); + Context* context = Context::cast(frame->context()); + if (context->global_context() == *Debug::debug_context()) { + it.Advance(); + } else { + break; + } + } + } +#endif // ENABLE_DEBUGGER_SUPPORT if (it.done()) return Handle<Context>::null(); JavaScriptFrame* frame = it.frame(); Context* context = Context::cast(frame->context()); ======================================= --- /branches/1.3/src/version.cc Fri Nov 13 00:04:17 2009 +++ /branches/1.3/src/version.cc Tue Nov 17 01:53:59 2009 @@ -35,7 +35,7 @@ #define MAJOR_VERSION 1 #define MINOR_VERSION 3 #define BUILD_NUMBER 18 -#define PATCH_LEVEL 8 +#define PATCH_LEVEL 9 #define CANDIDATE_VERSION false // Define SONAME to have the SCons build the put a specific SONAME into the ======================================= --- /branches/1.3/test/cctest/test-debug.cc Wed Nov 11 02:11:16 2009 +++ /branches/1.3/test/cctest/test-debug.cc Tue Nov 17 01:53:59 2009 @@ -5513,3 +5513,86 @@ v8::Handle<v8::Value> result = run_test->Call(env->Global(), 1, &obj); CHECK(result->IsTrue()); } + + +v8::Handle<v8::Context> debugee_context; +v8::Handle<v8::Context> debugger_context; + + +// Property getter that checks that current and calling contexts +// are both the debugee contexts. +static v8::Handle<v8::Value> NamedGetterWithCallingContextCheck( + v8::Local<v8::String> name, + const v8::AccessorInfo& info) { + CHECK_EQ(0, strcmp(*v8::String::AsciiValue(name), "a")); + v8::Handle<v8::Context> current = v8::Context::GetCurrent(); + CHECK(current == debugee_context); + CHECK(current != debugger_context); + v8::Handle<v8::Context> calling = v8::Context::GetCalling(); + CHECK(calling == debugee_context); + CHECK(calling != debugger_context); + return v8::Int32::New(1); +} + + +// Debug event listener that checks if the first argument of a function is +// an object with property 'a' == 1. If the property has custom accessor +// this handler will eventually invoke it. +static void DebugEventGetAtgumentPropertyValue( + v8::DebugEvent event, + v8::Handle<v8::Object> exec_state, + v8::Handle<v8::Object> event_data, + v8::Handle<v8::Value> data) { + if (event == v8::Break) { + break_point_hit_count++; + CHECK(debugger_context == v8::Context::GetCurrent()); + v8::Handle<v8::Function> func(v8::Function::Cast(*CompileRun( + "(function(exec_state) {\n" + " return (exec_state.frame(0).argumentValue(0).property('a').\n" + " value().value() == 1);\n" + "})"))); + const int argc = 1; + v8::Handle<v8::Value> argv[argc] = { exec_state }; + v8::Handle<v8::Value> result = func->Call(exec_state, argc, argv); + CHECK(result->IsTrue()); + } +} + + +TEST(CallingContextIsNotDebugContext) { + // Create and enter a debugee context. + v8::HandleScope scope; + DebugLocalContext env; + env.ExposeDebug(); + + // Save handles to the debugger and debugee contexts to be used in + // NamedGetterWithCallingContextCheck. + debugee_context = v8::Local<v8::Context>(*env); + debugger_context = v8::Utils::ToLocal(Debug::debug_context()); + + // Create object with 'a' property accessor. + v8::Handle<v8::ObjectTemplate> named = v8::ObjectTemplate::New(); + named->SetAccessor(v8::String::New("a"), + NamedGetterWithCallingContextCheck); + env->Global()->Set(v8::String::New("obj"), + named->NewInstance()); + + // Register the debug event listener + v8::Debug::SetDebugEventListener(DebugEventGetAtgumentPropertyValue); + + // Create a function that invokes debugger. + v8::Local<v8::Function> foo = CompileFunction( + &env, + "function bar(x) { debugger; }" + "function foo(){ bar(obj); }", + "foo"); + + break_point_hit_count = 0; + foo->Call(env->Global(), 0, NULL); + CHECK_EQ(1, break_point_hit_count); + + v8::Debug::SetDebugEventListener(NULL); + debugee_context = v8::Handle<v8::Context>(); + debugger_context = v8::Handle<v8::Context>(); + CheckDebuggerUnloaded(); +} --~--~---------~--~----~------------~-------~--~----~ v8-dev mailing list [email protected] http://groups.google.com/group/v8-dev -~----------~----~----~----~------~----~------~--~---
