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); |
+} |