| Index: test/cctest/test-debug.cc
|
| diff --git a/test/cctest/test-debug.cc b/test/cctest/test-debug.cc
|
| index 1f1ae994edbaaec9f851b3b1f729008533848dbc..353fa671d394c48dc82029d5b0d987543d2146b7 100644
|
| --- a/test/cctest/test-debug.cc
|
| +++ b/test/cctest/test-debug.cc
|
| @@ -7978,3 +7978,81 @@ TEST(NoInterruptsInDebugListener) {
|
| v8::Debug::SetDebugEventListener(env->GetIsolate(), NoInterruptsOnDebugEvent);
|
| CompileRun("void(0);");
|
| }
|
| +
|
| +class TestBreakLocation : public i::BreakLocation {
|
| + public:
|
| + using i::BreakLocation::GetIterator;
|
| + using i::BreakLocation::Iterator;
|
| +};
|
| +
|
| +TEST(BreakLocationIterator) {
|
| + DebugLocalContext env;
|
| + v8::Isolate* isolate = env->GetIsolate();
|
| + i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
|
| + v8::HandleScope scope(isolate);
|
| +
|
| + v8::Local<v8::Value> result = CompileRun(
|
| + "function f() {\n"
|
| + " debugger; \n"
|
| + " f(); \n"
|
| + " debugger; \n"
|
| + "} \n"
|
| + "f");
|
| + Handle<i::Object> function_obj = v8::Utils::OpenHandle(*result);
|
| + Handle<i::JSFunction> function = Handle<i::JSFunction>::cast(function_obj);
|
| + Handle<i::SharedFunctionInfo> shared(function->shared());
|
| +
|
| + EnableDebugger(isolate);
|
| + CHECK(i_isolate->debug()->EnsureDebugInfo(shared, function));
|
| +
|
| + Handle<i::DebugInfo> debug_info(shared->GetDebugInfo());
|
| + int code_size = debug_info->abstract_code()->Size();
|
| +
|
| + bool found_return = false;
|
| + bool found_call = false;
|
| + bool found_debugger = false;
|
| +
|
| + // Test public interface.
|
| + for (int i = 0; i < code_size; i++) {
|
| + i::BreakLocation location = i::BreakLocation::FromCodeOffset(debug_info, i);
|
| + if (location.IsCall()) found_call = true;
|
| + if (location.IsReturn()) found_return = true;
|
| + if (location.IsDebuggerStatement()) found_debugger = true;
|
| + }
|
| + CHECK(found_call);
|
| + CHECK(found_return);
|
| + CHECK(found_debugger);
|
| +
|
| + // Test underlying implementation.
|
| + TestBreakLocation::Iterator* iterator =
|
| + TestBreakLocation::GetIterator(debug_info, i::ALL_BREAK_LOCATIONS);
|
| + CHECK(iterator->GetBreakLocation().IsDebuggerStatement());
|
| + CHECK_EQ(7, iterator->GetBreakLocation().position());
|
| + iterator->Next();
|
| + CHECK(iterator->GetBreakLocation().IsDebugBreakSlot());
|
| + CHECK_EQ(22, iterator->GetBreakLocation().position());
|
| + iterator->Next();
|
| + CHECK(iterator->GetBreakLocation().IsCall());
|
| + CHECK_EQ(22, iterator->GetBreakLocation().position());
|
| + iterator->Next();
|
| + CHECK(iterator->GetBreakLocation().IsDebuggerStatement());
|
| + CHECK_EQ(37, iterator->GetBreakLocation().position());
|
| + iterator->Next();
|
| + CHECK(iterator->GetBreakLocation().IsReturn());
|
| + CHECK_EQ(50, iterator->GetBreakLocation().position());
|
| + iterator->Next();
|
| + CHECK(iterator->Done());
|
| + delete iterator;
|
| +
|
| + iterator = TestBreakLocation::GetIterator(debug_info, i::CALLS_AND_RETURNS);
|
| + CHECK(iterator->GetBreakLocation().IsCall());
|
| + CHECK_EQ(22, iterator->GetBreakLocation().position());
|
| + iterator->Next();
|
| + CHECK(iterator->GetBreakLocation().IsReturn());
|
| + CHECK_EQ(50, iterator->GetBreakLocation().position());
|
| + iterator->Next();
|
| + CHECK(iterator->Done());
|
| + delete iterator;
|
| +
|
| + DisableDebugger(isolate);
|
| +}
|
|
|