OLD | NEW |
1 // Copyright 2007-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2007-2008 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 4758 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4769 } | 4769 } |
4770 | 4770 |
4771 // Two times compile event and two times break event. | 4771 // Two times compile event and two times break event. |
4772 CHECK_GT(message_handler_hit_count, 4); | 4772 CHECK_GT(message_handler_hit_count, 4); |
4773 | 4773 |
4774 v8::Debug::SetMessageHandler2(NULL); | 4774 v8::Debug::SetMessageHandler2(NULL); |
4775 CheckDebuggerUnloaded(); | 4775 CheckDebuggerUnloaded(); |
4776 } | 4776 } |
4777 | 4777 |
4778 | 4778 |
| 4779 // Debug message handler which issues a debug break when it hits a break event. |
| 4780 static int message_handler_break_hit_count = 0; |
| 4781 static void DebugBreakMessageHandler(const v8::Debug::Message& message) { |
| 4782 // Schedule a debug break for break events. |
| 4783 if (message.IsEvent() && message.GetEvent() == v8::Break) { |
| 4784 message_handler_break_hit_count++; |
| 4785 if (message_handler_break_hit_count == 1) { |
| 4786 v8::Debug::DebugBreak(); |
| 4787 } |
| 4788 } |
| 4789 |
| 4790 // Issue a continue command if this event will not cause the VM to start |
| 4791 // running. |
| 4792 if (!message.WillStartRunning()) { |
| 4793 SendContinueCommand(); |
| 4794 } |
| 4795 } |
| 4796 |
| 4797 |
| 4798 // Test that a debug break can be scheduled while in a message handler. |
| 4799 TEST(DebugBreakInMessageHandler) { |
| 4800 v8::HandleScope scope; |
| 4801 DebugLocalContext env; |
| 4802 |
| 4803 v8::Debug::SetMessageHandler2(DebugBreakMessageHandler); |
| 4804 |
| 4805 // Test functions. |
| 4806 const char* script = "function f() { debugger; } function g() { }"; |
| 4807 CompileRun(script); |
| 4808 v8::Local<v8::Function> f = |
| 4809 v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("f"))); |
| 4810 v8::Local<v8::Function> g = |
| 4811 v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("g"))); |
| 4812 |
| 4813 // Call f then g. The debugger statement in f will casue a break which will |
| 4814 // cause another break. |
| 4815 f->Call(env->Global(), 0, NULL); |
| 4816 CHECK_EQ(2, message_handler_break_hit_count); |
| 4817 // Calling g will not cause any additional breaks. |
| 4818 g->Call(env->Global(), 0, NULL); |
| 4819 CHECK_EQ(2, message_handler_break_hit_count); |
| 4820 } |
| 4821 |
| 4822 |
| 4823 // Debug event handler which gets the function on the top frame and schedules a |
| 4824 // break a number of times. |
| 4825 static void DebugEventDebugBreak( |
| 4826 v8::DebugEvent event, |
| 4827 v8::Handle<v8::Object> exec_state, |
| 4828 v8::Handle<v8::Object> event_data, |
| 4829 v8::Handle<v8::Value> data) { |
| 4830 |
| 4831 if (event == v8::Break) { |
| 4832 break_point_hit_count++; |
| 4833 |
| 4834 // Get the name of the top frame function. |
| 4835 if (!frame_function_name.IsEmpty()) { |
| 4836 // Get the name of the function. |
| 4837 const int argc = 1; |
| 4838 v8::Handle<v8::Value> argv[argc] = { exec_state }; |
| 4839 v8::Handle<v8::Value> result = frame_function_name->Call(exec_state, |
| 4840 argc, argv); |
| 4841 if (result->IsUndefined()) { |
| 4842 last_function_hit[0] = '\0'; |
| 4843 } else { |
| 4844 CHECK(result->IsString()); |
| 4845 v8::Handle<v8::String> function_name(result->ToString()); |
| 4846 function_name->WriteAscii(last_function_hit); |
| 4847 } |
| 4848 } |
| 4849 |
| 4850 // Keep forcing breaks. |
| 4851 if (break_point_hit_count < 20) { |
| 4852 v8::Debug::DebugBreak(); |
| 4853 } |
| 4854 } |
| 4855 } |
| 4856 |
| 4857 |
| 4858 TEST(RegExpDebugBreak) { |
| 4859 v8::HandleScope scope; |
| 4860 DebugLocalContext env; |
| 4861 |
| 4862 i::FLAG_regexp_native = true; |
| 4863 |
| 4864 // Create a function for checking the function when hitting a break point. |
| 4865 frame_function_name = CompileFunction(&env, |
| 4866 frame_function_name_source, |
| 4867 "frame_function_name"); |
| 4868 |
| 4869 // Test RegExp which matches white spaces and comments at the begining of a |
| 4870 // source line. |
| 4871 const char* script = |
| 4872 "var sourceLineBeginningSkip = /^(?:[ \\v\\h]*(?:\\/\\*.*?\\*\\/)*)*/;\n" |
| 4873 "function f(s) { return s.match(sourceLineBeginningSkip)[0].length; }"; |
| 4874 |
| 4875 v8::Local<v8::Function> f = CompileFunction(script, "f"); |
| 4876 const int argc = 1; |
| 4877 v8::Handle<v8::Value> argv[argc] = { v8::String::New(" /* xxx */ a=0;") }; |
| 4878 v8::Local<v8::Value> result = f->Call(env->Global(), argc, argv); |
| 4879 CHECK_EQ(12, result->Int32Value()); |
| 4880 |
| 4881 v8::Debug::SetDebugEventListener(DebugEventDebugBreak); |
| 4882 v8::Debug::DebugBreak(); |
| 4883 result = f->Call(env->Global(), argc, argv); |
| 4884 |
| 4885 CHECK_EQ(20, break_point_hit_count); |
| 4886 CHECK_EQ("exec", last_function_hit); |
| 4887 } |
| 4888 |
| 4889 |
4779 // Common part of EvalContextData and NestedBreakEventContextData tests. | 4890 // Common part of EvalContextData and NestedBreakEventContextData tests. |
4780 static void ExecuteScriptForContextCheck() { | 4891 static void ExecuteScriptForContextCheck() { |
4781 // Create a context. | 4892 // Create a context. |
4782 v8::Persistent<v8::Context> context_1; | 4893 v8::Persistent<v8::Context> context_1; |
4783 v8::Handle<v8::ObjectTemplate> global_template = | 4894 v8::Handle<v8::ObjectTemplate> global_template = |
4784 v8::Handle<v8::ObjectTemplate>(); | 4895 v8::Handle<v8::ObjectTemplate>(); |
4785 v8::Handle<v8::Value> global_object = v8::Handle<v8::Value>(); | 4896 v8::Handle<v8::Value> global_object = v8::Handle<v8::Value>(); |
4786 context_1 = v8::Context::New(NULL, global_template, global_object); | 4897 context_1 = v8::Context::New(NULL, global_template, global_object); |
4787 | 4898 |
4788 // Default data value is undefined. | 4899 // Default data value is undefined. |
(...skipping 278 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5067 v8::Local<v8::Function> f = | 5178 v8::Local<v8::Function> f = |
5068 v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("f"))); | 5179 v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("f"))); |
5069 f->Call(env->Global(), 0, NULL); | 5180 f->Call(env->Global(), 0, NULL); |
5070 | 5181 |
5071 // Setting message handler to NULL should cause debugger unload. | 5182 // Setting message handler to NULL should cause debugger unload. |
5072 v8::Debug::SetMessageHandler2(NULL); | 5183 v8::Debug::SetMessageHandler2(NULL); |
5073 CheckDebuggerUnloaded(); | 5184 CheckDebuggerUnloaded(); |
5074 | 5185 |
5075 CHECK_EQ(1, exception_event_count); | 5186 CHECK_EQ(1, exception_event_count); |
5076 } | 5187 } |
OLD | NEW |