Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / v8 / test / cctest / test-debug.cc
1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are
4 // met:
5 //
6 //     * Redistributions of source code must retain the above copyright
7 //       notice, this list of conditions and the following disclaimer.
8 //     * Redistributions in binary form must reproduce the above
9 //       copyright notice, this list of conditions and the following
10 //       disclaimer in the documentation and/or other materials provided
11 //       with the distribution.
12 //     * Neither the name of Google Inc. nor the names of its
13 //       contributors may be used to endorse or promote products derived
14 //       from this software without specific prior written permission.
15 //
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28 #ifdef ENABLE_DEBUGGER_SUPPORT
29
30 #include <stdlib.h>
31
32 #include "v8.h"
33
34 #include "api.h"
35 #include "cctest.h"
36 #include "compilation-cache.h"
37 #include "debug.h"
38 #include "deoptimizer.h"
39 #include "frames.h"
40 #include "platform.h"
41 #include "platform/condition-variable.h"
42 #include "platform/socket.h"
43 #include "stub-cache.h"
44 #include "utils.h"
45
46
47 using ::v8::internal::Mutex;
48 using ::v8::internal::LockGuard;
49 using ::v8::internal::ConditionVariable;
50 using ::v8::internal::Semaphore;
51 using ::v8::internal::EmbeddedVector;
52 using ::v8::internal::Object;
53 using ::v8::internal::OS;
54 using ::v8::internal::Handle;
55 using ::v8::internal::Heap;
56 using ::v8::internal::JSGlobalProxy;
57 using ::v8::internal::Code;
58 using ::v8::internal::Debug;
59 using ::v8::internal::Debugger;
60 using ::v8::internal::CommandMessage;
61 using ::v8::internal::CommandMessageQueue;
62 using ::v8::internal::StackFrame;
63 using ::v8::internal::StepAction;
64 using ::v8::internal::StepIn;  // From StepAction enum
65 using ::v8::internal::StepNext;  // From StepAction enum
66 using ::v8::internal::StepOut;  // From StepAction enum
67 using ::v8::internal::Vector;
68 using ::v8::internal::StrLength;
69
70 // Size of temp buffer for formatting small strings.
71 #define SMALL_STRING_BUFFER_SIZE 80
72
73 // --- H e l p e r   C l a s s e s
74
75
76 // Helper class for creating a V8 enviromnent for running tests
77 class DebugLocalContext {
78  public:
79   inline DebugLocalContext(
80       v8::ExtensionConfiguration* extensions = 0,
81       v8::Handle<v8::ObjectTemplate> global_template =
82           v8::Handle<v8::ObjectTemplate>(),
83       v8::Handle<v8::Value> global_object = v8::Handle<v8::Value>())
84       : scope_(CcTest::isolate()),
85         context_(
86           v8::Context::New(CcTest::isolate(),
87                            extensions,
88                            global_template,
89                            global_object)) {
90     context_->Enter();
91   }
92   inline ~DebugLocalContext() {
93     context_->Exit();
94   }
95   inline v8::Local<v8::Context> context() { return context_; }
96   inline v8::Context* operator->() { return *context_; }
97   inline v8::Context* operator*() { return *context_; }
98   inline v8::Isolate* GetIsolate() { return context_->GetIsolate(); }
99   inline bool IsReady() { return !context_.IsEmpty(); }
100   void ExposeDebug() {
101     v8::internal::Isolate* isolate =
102         reinterpret_cast<v8::internal::Isolate*>(context_->GetIsolate());
103     v8::internal::Factory* factory = isolate->factory();
104     v8::internal::Debug* debug = isolate->debug();
105     // Expose the debug context global object in the global object for testing.
106     debug->Load();
107     debug->debug_context()->set_security_token(
108         v8::Utils::OpenHandle(*context_)->security_token());
109
110     Handle<JSGlobalProxy> global(Handle<JSGlobalProxy>::cast(
111         v8::Utils::OpenHandle(*context_->Global())));
112     Handle<v8::internal::String> debug_string =
113         factory->InternalizeOneByteString(STATIC_ASCII_VECTOR("debug"));
114     v8::internal::Runtime::SetObjectProperty(isolate, global, debug_string,
115         Handle<Object>(debug->debug_context()->global_proxy(), isolate),
116         DONT_ENUM,
117         ::v8::internal::kNonStrictMode);
118   }
119
120  private:
121   v8::HandleScope scope_;
122   v8::Local<v8::Context> context_;
123 };
124
125
126 // --- H e l p e r   F u n c t i o n s
127
128
129 // Compile and run the supplied source and return the fequested function.
130 static v8::Local<v8::Function> CompileFunction(DebugLocalContext* env,
131                                                const char* source,
132                                                const char* function_name) {
133   v8::Script::Compile(v8::String::NewFromUtf8(env->GetIsolate(), source))
134       ->Run();
135   return v8::Local<v8::Function>::Cast((*env)->Global()->Get(
136       v8::String::NewFromUtf8(env->GetIsolate(), function_name)));
137 }
138
139
140 // Compile and run the supplied source and return the requested function.
141 static v8::Local<v8::Function> CompileFunction(v8::Isolate* isolate,
142                                                const char* source,
143                                                const char* function_name) {
144   v8::Script::Compile(v8::String::NewFromUtf8(isolate, source))->Run();
145   v8::Local<v8::Object> global =
146       CcTest::isolate()->GetCurrentContext()->Global();
147   return v8::Local<v8::Function>::Cast(
148       global->Get(v8::String::NewFromUtf8(isolate, function_name)));
149 }
150
151
152 // Is there any debug info for the function?
153 static bool HasDebugInfo(v8::Handle<v8::Function> fun) {
154   Handle<v8::internal::JSFunction> f = v8::Utils::OpenHandle(*fun);
155   Handle<v8::internal::SharedFunctionInfo> shared(f->shared());
156   return Debug::HasDebugInfo(shared);
157 }
158
159
160 // Set a break point in a function and return the associated break point
161 // number.
162 static int SetBreakPoint(Handle<v8::internal::JSFunction> fun, int position) {
163   static int break_point = 0;
164   v8::internal::Isolate* isolate = fun->GetIsolate();
165   v8::internal::Debug* debug = isolate->debug();
166   debug->SetBreakPoint(
167       fun,
168       Handle<Object>(v8::internal::Smi::FromInt(++break_point), isolate),
169       &position);
170   return break_point;
171 }
172
173
174 // Set a break point in a function and return the associated break point
175 // number.
176 static int SetBreakPoint(v8::Handle<v8::Function> fun, int position) {
177   return SetBreakPoint(v8::Utils::OpenHandle(*fun), position);
178 }
179
180
181 // Set a break point in a function using the Debug object and return the
182 // associated break point number.
183 static int SetBreakPointFromJS(v8::Isolate* isolate,
184                                const char* function_name,
185                                int line, int position) {
186   EmbeddedVector<char, SMALL_STRING_BUFFER_SIZE> buffer;
187   OS::SNPrintF(buffer,
188                "debug.Debug.setBreakPoint(%s,%d,%d)",
189                function_name, line, position);
190   buffer[SMALL_STRING_BUFFER_SIZE - 1] = '\0';
191   v8::Handle<v8::String> str = v8::String::NewFromUtf8(isolate, buffer.start());
192   return v8::Script::Compile(str)->Run()->Int32Value();
193 }
194
195
196 // Set a break point in a script identified by id using the global Debug object.
197 static int SetScriptBreakPointByIdFromJS(v8::Isolate* isolate, int script_id,
198                                          int line, int column) {
199   EmbeddedVector<char, SMALL_STRING_BUFFER_SIZE> buffer;
200   if (column >= 0) {
201     // Column specified set script break point on precise location.
202     OS::SNPrintF(buffer,
203                  "debug.Debug.setScriptBreakPointById(%d,%d,%d)",
204                  script_id, line, column);
205   } else {
206     // Column not specified set script break point on line.
207     OS::SNPrintF(buffer,
208                  "debug.Debug.setScriptBreakPointById(%d,%d)",
209                  script_id, line);
210   }
211   buffer[SMALL_STRING_BUFFER_SIZE - 1] = '\0';
212   {
213     v8::TryCatch try_catch;
214     v8::Handle<v8::String> str =
215         v8::String::NewFromUtf8(isolate, buffer.start());
216     v8::Handle<v8::Value> value = v8::Script::Compile(str)->Run();
217     CHECK(!try_catch.HasCaught());
218     return value->Int32Value();
219   }
220 }
221
222
223 // Set a break point in a script identified by name using the global Debug
224 // object.
225 static int SetScriptBreakPointByNameFromJS(v8::Isolate* isolate,
226                                            const char* script_name, int line,
227                                            int column) {
228   EmbeddedVector<char, SMALL_STRING_BUFFER_SIZE> buffer;
229   if (column >= 0) {
230     // Column specified set script break point on precise location.
231     OS::SNPrintF(buffer,
232                  "debug.Debug.setScriptBreakPointByName(\"%s\",%d,%d)",
233                  script_name, line, column);
234   } else {
235     // Column not specified set script break point on line.
236     OS::SNPrintF(buffer,
237                  "debug.Debug.setScriptBreakPointByName(\"%s\",%d)",
238                  script_name, line);
239   }
240   buffer[SMALL_STRING_BUFFER_SIZE - 1] = '\0';
241   {
242     v8::TryCatch try_catch;
243     v8::Handle<v8::String> str =
244         v8::String::NewFromUtf8(isolate, buffer.start());
245     v8::Handle<v8::Value> value = v8::Script::Compile(str)->Run();
246     CHECK(!try_catch.HasCaught());
247     return value->Int32Value();
248   }
249 }
250
251
252 // Clear a break point.
253 static void ClearBreakPoint(int break_point) {
254   v8::internal::Isolate* isolate = CcTest::i_isolate();
255   v8::internal::Debug* debug = isolate->debug();
256   debug->ClearBreakPoint(
257       Handle<Object>(v8::internal::Smi::FromInt(break_point), isolate));
258 }
259
260
261 // Clear a break point using the global Debug object.
262 static void ClearBreakPointFromJS(v8::Isolate* isolate,
263                                   int break_point_number) {
264   EmbeddedVector<char, SMALL_STRING_BUFFER_SIZE> buffer;
265   OS::SNPrintF(buffer,
266                "debug.Debug.clearBreakPoint(%d)",
267                break_point_number);
268   buffer[SMALL_STRING_BUFFER_SIZE - 1] = '\0';
269   v8::Script::Compile(v8::String::NewFromUtf8(isolate, buffer.start()))->Run();
270 }
271
272
273 static void EnableScriptBreakPointFromJS(v8::Isolate* isolate,
274                                          int break_point_number) {
275   EmbeddedVector<char, SMALL_STRING_BUFFER_SIZE> buffer;
276   OS::SNPrintF(buffer,
277                "debug.Debug.enableScriptBreakPoint(%d)",
278                break_point_number);
279   buffer[SMALL_STRING_BUFFER_SIZE - 1] = '\0';
280   v8::Script::Compile(v8::String::NewFromUtf8(isolate, buffer.start()))->Run();
281 }
282
283
284 static void DisableScriptBreakPointFromJS(v8::Isolate* isolate,
285                                           int break_point_number) {
286   EmbeddedVector<char, SMALL_STRING_BUFFER_SIZE> buffer;
287   OS::SNPrintF(buffer,
288                "debug.Debug.disableScriptBreakPoint(%d)",
289                break_point_number);
290   buffer[SMALL_STRING_BUFFER_SIZE - 1] = '\0';
291   v8::Script::Compile(v8::String::NewFromUtf8(isolate, buffer.start()))->Run();
292 }
293
294
295 static void ChangeScriptBreakPointConditionFromJS(v8::Isolate* isolate,
296                                                   int break_point_number,
297                                                   const char* condition) {
298   EmbeddedVector<char, SMALL_STRING_BUFFER_SIZE> buffer;
299   OS::SNPrintF(buffer,
300                "debug.Debug.changeScriptBreakPointCondition(%d, \"%s\")",
301                break_point_number, condition);
302   buffer[SMALL_STRING_BUFFER_SIZE - 1] = '\0';
303   v8::Script::Compile(v8::String::NewFromUtf8(isolate, buffer.start()))->Run();
304 }
305
306
307 static void ChangeScriptBreakPointIgnoreCountFromJS(v8::Isolate* isolate,
308                                                     int break_point_number,
309                                                     int ignoreCount) {
310   EmbeddedVector<char, SMALL_STRING_BUFFER_SIZE> buffer;
311   OS::SNPrintF(buffer,
312                "debug.Debug.changeScriptBreakPointIgnoreCount(%d, %d)",
313                break_point_number, ignoreCount);
314   buffer[SMALL_STRING_BUFFER_SIZE - 1] = '\0';
315   v8::Script::Compile(v8::String::NewFromUtf8(isolate, buffer.start()))->Run();
316 }
317
318
319 // Change break on exception.
320 static void ChangeBreakOnException(bool caught, bool uncaught) {
321   v8::internal::Debug* debug = CcTest::i_isolate()->debug();
322   debug->ChangeBreakOnException(v8::internal::BreakException, caught);
323   debug->ChangeBreakOnException(v8::internal::BreakUncaughtException, uncaught);
324 }
325
326
327 // Change break on exception using the global Debug object.
328 static void ChangeBreakOnExceptionFromJS(v8::Isolate* isolate, bool caught,
329                                          bool uncaught) {
330   if (caught) {
331     v8::Script::Compile(
332         v8::String::NewFromUtf8(isolate, "debug.Debug.setBreakOnException()"))
333         ->Run();
334   } else {
335     v8::Script::Compile(
336         v8::String::NewFromUtf8(isolate, "debug.Debug.clearBreakOnException()"))
337         ->Run();
338   }
339   if (uncaught) {
340     v8::Script::Compile(
341         v8::String::NewFromUtf8(
342             isolate, "debug.Debug.setBreakOnUncaughtException()"))->Run();
343   } else {
344     v8::Script::Compile(
345         v8::String::NewFromUtf8(
346             isolate, "debug.Debug.clearBreakOnUncaughtException()"))->Run();
347   }
348 }
349
350
351 // Prepare to step to next break location.
352 static void PrepareStep(StepAction step_action) {
353   v8::internal::Debug* debug = CcTest::i_isolate()->debug();
354   debug->PrepareStep(step_action, 1, StackFrame::NO_ID);
355 }
356
357
358 // This function is in namespace v8::internal to be friend with class
359 // v8::internal::Debug.
360 namespace v8 {
361 namespace internal {
362
363 // Collect the currently debugged functions.
364 Handle<FixedArray> GetDebuggedFunctions() {
365   Debug* debug = CcTest::i_isolate()->debug();
366
367   v8::internal::DebugInfoListNode* node = debug->debug_info_list_;
368
369   // Find the number of debugged functions.
370   int count = 0;
371   while (node) {
372     count++;
373     node = node->next();
374   }
375
376   // Allocate array for the debugged functions
377   Handle<FixedArray> debugged_functions =
378       CcTest::i_isolate()->factory()->NewFixedArray(count);
379
380   // Run through the debug info objects and collect all functions.
381   count = 0;
382   while (node) {
383     debugged_functions->set(count++, *node->debug_info());
384     node = node->next();
385   }
386
387   return debugged_functions;
388 }
389
390
391 // Check that the debugger has been fully unloaded.
392 void CheckDebuggerUnloaded(bool check_functions) {
393   // Check that the debugger context is cleared and that there is no debug
394   // information stored for the debugger.
395   CHECK(CcTest::i_isolate()->debug()->debug_context().is_null());
396   CHECK_EQ(NULL, CcTest::i_isolate()->debug()->debug_info_list_);
397
398   // Collect garbage to ensure weak handles are cleared.
399   CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags);
400   CcTest::heap()->CollectAllGarbage(Heap::kMakeHeapIterableMask);
401
402   // Iterate the head and check that there are no debugger related objects left.
403   HeapIterator iterator(CcTest::heap());
404   for (HeapObject* obj = iterator.next(); obj != NULL; obj = iterator.next()) {
405     CHECK(!obj->IsDebugInfo());
406     CHECK(!obj->IsBreakPointInfo());
407
408     // If deep check of functions is requested check that no debug break code
409     // is left in all functions.
410     if (check_functions) {
411       if (obj->IsJSFunction()) {
412         JSFunction* fun = JSFunction::cast(obj);
413         for (RelocIterator it(fun->shared()->code()); !it.done(); it.next()) {
414           RelocInfo::Mode rmode = it.rinfo()->rmode();
415           if (RelocInfo::IsCodeTarget(rmode)) {
416             CHECK(!Debug::IsDebugBreak(it.rinfo()->target_address()));
417           } else if (RelocInfo::IsJSReturn(rmode)) {
418             CHECK(!Debug::IsDebugBreakAtReturn(it.rinfo()));
419           }
420         }
421       }
422     }
423   }
424 }
425
426
427 void ForceUnloadDebugger() {
428   CcTest::i_isolate()->debugger()->never_unload_debugger_ = false;
429   CcTest::i_isolate()->debugger()->UnloadDebugger();
430 }
431
432
433 } }  // namespace v8::internal
434
435
436 // Check that the debugger has been fully unloaded.
437 static void CheckDebuggerUnloaded(bool check_functions = false) {
438   // Let debugger to unload itself synchronously
439   v8::Debug::ProcessDebugMessages();
440
441   v8::internal::CheckDebuggerUnloaded(check_functions);
442 }
443
444
445 // Inherit from BreakLocationIterator to get access to protected parts for
446 // testing.
447 class TestBreakLocationIterator: public v8::internal::BreakLocationIterator {
448  public:
449   explicit TestBreakLocationIterator(Handle<v8::internal::DebugInfo> debug_info)
450     : BreakLocationIterator(debug_info, v8::internal::SOURCE_BREAK_LOCATIONS) {}
451   v8::internal::RelocIterator* it() { return reloc_iterator_; }
452   v8::internal::RelocIterator* it_original() {
453     return reloc_iterator_original_;
454   }
455 };
456
457
458 // Compile a function, set a break point and check that the call at the break
459 // location in the code is the expected debug_break function.
460 void CheckDebugBreakFunction(DebugLocalContext* env,
461                              const char* source, const char* name,
462                              int position, v8::internal::RelocInfo::Mode mode,
463                              Code* debug_break) {
464   v8::internal::Debug* debug = CcTest::i_isolate()->debug();
465
466   // Create function and set the break point.
467   Handle<v8::internal::JSFunction> fun = v8::Utils::OpenHandle(
468       *CompileFunction(env, source, name));
469   int bp = SetBreakPoint(fun, position);
470
471   // Check that the debug break function is as expected.
472   Handle<v8::internal::SharedFunctionInfo> shared(fun->shared());
473   CHECK(Debug::HasDebugInfo(shared));
474   TestBreakLocationIterator it1(Debug::GetDebugInfo(shared));
475   it1.FindBreakLocationFromPosition(position, v8::internal::STATEMENT_ALIGNED);
476   v8::internal::RelocInfo::Mode actual_mode = it1.it()->rinfo()->rmode();
477   if (actual_mode == v8::internal::RelocInfo::CODE_TARGET_WITH_ID) {
478     actual_mode = v8::internal::RelocInfo::CODE_TARGET;
479   }
480   CHECK_EQ(mode, actual_mode);
481   if (mode != v8::internal::RelocInfo::JS_RETURN) {
482     CHECK_EQ(debug_break,
483         Code::GetCodeFromTargetAddress(it1.it()->rinfo()->target_address()));
484   } else {
485     CHECK(Debug::IsDebugBreakAtReturn(it1.it()->rinfo()));
486   }
487
488   // Clear the break point and check that the debug break function is no longer
489   // there
490   ClearBreakPoint(bp);
491   CHECK(!debug->HasDebugInfo(shared));
492   CHECK(debug->EnsureDebugInfo(shared, fun));
493   TestBreakLocationIterator it2(Debug::GetDebugInfo(shared));
494   it2.FindBreakLocationFromPosition(position, v8::internal::STATEMENT_ALIGNED);
495   actual_mode = it2.it()->rinfo()->rmode();
496   if (actual_mode == v8::internal::RelocInfo::CODE_TARGET_WITH_ID) {
497     actual_mode = v8::internal::RelocInfo::CODE_TARGET;
498   }
499   CHECK_EQ(mode, actual_mode);
500   if (mode == v8::internal::RelocInfo::JS_RETURN) {
501     CHECK(!Debug::IsDebugBreakAtReturn(it2.it()->rinfo()));
502   }
503 }
504
505
506 // --- D e b u g   E v e n t   H a n d l e r s
507 // ---
508 // --- The different tests uses a number of debug event handlers.
509 // ---
510
511
512 // Source for the JavaScript function which picks out the function
513 // name of a frame.
514 const char* frame_function_name_source =
515     "function frame_function_name(exec_state, frame_number) {"
516     "  return exec_state.frame(frame_number).func().name();"
517     "}";
518 v8::Local<v8::Function> frame_function_name;
519
520
521 // Source for the JavaScript function which pick out the name of the
522 // first argument of a frame.
523 const char* frame_argument_name_source =
524     "function frame_argument_name(exec_state, frame_number) {"
525     "  return exec_state.frame(frame_number).argumentName(0);"
526     "}";
527 v8::Local<v8::Function> frame_argument_name;
528
529
530 // Source for the JavaScript function which pick out the value of the
531 // first argument of a frame.
532 const char* frame_argument_value_source =
533     "function frame_argument_value(exec_state, frame_number) {"
534     "  return exec_state.frame(frame_number).argumentValue(0).value_;"
535     "}";
536 v8::Local<v8::Function> frame_argument_value;
537
538
539 // Source for the JavaScript function which pick out the name of the
540 // first argument of a frame.
541 const char* frame_local_name_source =
542     "function frame_local_name(exec_state, frame_number) {"
543     "  return exec_state.frame(frame_number).localName(0);"
544     "}";
545 v8::Local<v8::Function> frame_local_name;
546
547
548 // Source for the JavaScript function which pick out the value of the
549 // first argument of a frame.
550 const char* frame_local_value_source =
551     "function frame_local_value(exec_state, frame_number) {"
552     "  return exec_state.frame(frame_number).localValue(0).value_;"
553     "}";
554 v8::Local<v8::Function> frame_local_value;
555
556
557 // Source for the JavaScript function which picks out the source line for the
558 // top frame.
559 const char* frame_source_line_source =
560     "function frame_source_line(exec_state) {"
561     "  return exec_state.frame(0).sourceLine();"
562     "}";
563 v8::Local<v8::Function> frame_source_line;
564
565
566 // Source for the JavaScript function which picks out the source column for the
567 // top frame.
568 const char* frame_source_column_source =
569     "function frame_source_column(exec_state) {"
570     "  return exec_state.frame(0).sourceColumn();"
571     "}";
572 v8::Local<v8::Function> frame_source_column;
573
574
575 // Source for the JavaScript function which picks out the script name for the
576 // top frame.
577 const char* frame_script_name_source =
578     "function frame_script_name(exec_state) {"
579     "  return exec_state.frame(0).func().script().name();"
580     "}";
581 v8::Local<v8::Function> frame_script_name;
582
583
584 // Source for the JavaScript function which picks out the script data for the
585 // top frame.
586 const char* frame_script_data_source =
587     "function frame_script_data(exec_state) {"
588     "  return exec_state.frame(0).func().script().data();"
589     "}";
590 v8::Local<v8::Function> frame_script_data;
591
592
593 // Source for the JavaScript function which picks out the script data from
594 // AfterCompile event
595 const char* compiled_script_data_source =
596     "function compiled_script_data(event_data) {"
597     "  return event_data.script().data();"
598     "}";
599 v8::Local<v8::Function> compiled_script_data;
600
601
602 // Source for the JavaScript function which returns the number of frames.
603 static const char* frame_count_source =
604     "function frame_count(exec_state) {"
605     "  return exec_state.frameCount();"
606     "}";
607 v8::Handle<v8::Function> frame_count;
608
609
610 // Global variable to store the last function hit - used by some tests.
611 char last_function_hit[80];
612
613 // Global variable to store the name and data for last script hit - used by some
614 // tests.
615 char last_script_name_hit[80];
616 char last_script_data_hit[80];
617
618 // Global variables to store the last source position - used by some tests.
619 int last_source_line = -1;
620 int last_source_column = -1;
621
622 // Debug event handler which counts the break points which have been hit.
623 int break_point_hit_count = 0;
624 int break_point_hit_count_deoptimize = 0;
625 static void DebugEventBreakPointHitCount(
626     const v8::Debug::EventDetails& event_details) {
627   v8::DebugEvent event = event_details.GetEvent();
628   v8::Handle<v8::Object> exec_state = event_details.GetExecutionState();
629   v8::Handle<v8::Object> event_data = event_details.GetEventData();
630   v8::internal::Isolate* isolate = CcTest::i_isolate();
631   Debug* debug = isolate->debug();
632   // When hitting a debug event listener there must be a break set.
633   CHECK_NE(debug->break_id(), 0);
634
635   // Count the number of breaks.
636   if (event == v8::Break) {
637     break_point_hit_count++;
638     if (!frame_function_name.IsEmpty()) {
639       // Get the name of the function.
640       const int argc = 2;
641       v8::Handle<v8::Value> argv[argc] = {
642         exec_state, v8::Integer::New(CcTest::isolate(), 0)
643       };
644       v8::Handle<v8::Value> result = frame_function_name->Call(exec_state,
645                                                                argc, argv);
646       if (result->IsUndefined()) {
647         last_function_hit[0] = '\0';
648       } else {
649         CHECK(result->IsString());
650         v8::Handle<v8::String> function_name(result->ToString());
651         function_name->WriteUtf8(last_function_hit);
652       }
653     }
654
655     if (!frame_source_line.IsEmpty()) {
656       // Get the source line.
657       const int argc = 1;
658       v8::Handle<v8::Value> argv[argc] = { exec_state };
659       v8::Handle<v8::Value> result = frame_source_line->Call(exec_state,
660                                                              argc, argv);
661       CHECK(result->IsNumber());
662       last_source_line = result->Int32Value();
663     }
664
665     if (!frame_source_column.IsEmpty()) {
666       // Get the source column.
667       const int argc = 1;
668       v8::Handle<v8::Value> argv[argc] = { exec_state };
669       v8::Handle<v8::Value> result = frame_source_column->Call(exec_state,
670                                                                argc, argv);
671       CHECK(result->IsNumber());
672       last_source_column = result->Int32Value();
673     }
674
675     if (!frame_script_name.IsEmpty()) {
676       // Get the script name of the function script.
677       const int argc = 1;
678       v8::Handle<v8::Value> argv[argc] = { exec_state };
679       v8::Handle<v8::Value> result = frame_script_name->Call(exec_state,
680                                                              argc, argv);
681       if (result->IsUndefined()) {
682         last_script_name_hit[0] = '\0';
683       } else {
684         CHECK(result->IsString());
685         v8::Handle<v8::String> script_name(result->ToString());
686         script_name->WriteUtf8(last_script_name_hit);
687       }
688     }
689
690     if (!frame_script_data.IsEmpty()) {
691       // Get the script data of the function script.
692       const int argc = 1;
693       v8::Handle<v8::Value> argv[argc] = { exec_state };
694       v8::Handle<v8::Value> result = frame_script_data->Call(exec_state,
695                                                              argc, argv);
696       if (result->IsUndefined()) {
697         last_script_data_hit[0] = '\0';
698       } else {
699         result = result->ToString();
700         CHECK(result->IsString());
701         v8::Handle<v8::String> script_data(result->ToString());
702         script_data->WriteUtf8(last_script_data_hit);
703       }
704     }
705
706     // Perform a full deoptimization when the specified number of
707     // breaks have been hit.
708     if (break_point_hit_count == break_point_hit_count_deoptimize) {
709       i::Deoptimizer::DeoptimizeAll(isolate);
710     }
711   } else if (event == v8::AfterCompile && !compiled_script_data.IsEmpty()) {
712     const int argc = 1;
713     v8::Handle<v8::Value> argv[argc] = { event_data };
714     v8::Handle<v8::Value> result = compiled_script_data->Call(exec_state,
715                                                               argc, argv);
716     if (result->IsUndefined()) {
717       last_script_data_hit[0] = '\0';
718     } else {
719       result = result->ToString();
720       CHECK(result->IsString());
721       v8::Handle<v8::String> script_data(result->ToString());
722       script_data->WriteUtf8(last_script_data_hit);
723     }
724   }
725 }
726
727
728 // Debug event handler which counts a number of events and collects the stack
729 // height if there is a function compiled for that.
730 int exception_hit_count = 0;
731 int uncaught_exception_hit_count = 0;
732 int last_js_stack_height = -1;
733
734 static void DebugEventCounterClear() {
735   break_point_hit_count = 0;
736   exception_hit_count = 0;
737   uncaught_exception_hit_count = 0;
738 }
739
740 static void DebugEventCounter(
741     const v8::Debug::EventDetails& event_details) {
742   v8::DebugEvent event = event_details.GetEvent();
743   v8::Handle<v8::Object> exec_state = event_details.GetExecutionState();
744   v8::Handle<v8::Object> event_data = event_details.GetEventData();
745   v8::internal::Debug* debug = CcTest::i_isolate()->debug();
746
747   // When hitting a debug event listener there must be a break set.
748   CHECK_NE(debug->break_id(), 0);
749
750   // Count the number of breaks.
751   if (event == v8::Break) {
752     break_point_hit_count++;
753   } else if (event == v8::Exception) {
754     exception_hit_count++;
755
756     // Check whether the exception was uncaught.
757     v8::Local<v8::String> fun_name =
758         v8::String::NewFromUtf8(CcTest::isolate(), "uncaught");
759     v8::Local<v8::Function> fun =
760         v8::Local<v8::Function>::Cast(event_data->Get(fun_name));
761     v8::Local<v8::Value> result = fun->Call(event_data, 0, NULL);
762     if (result->IsTrue()) {
763       uncaught_exception_hit_count++;
764     }
765   }
766
767   // Collect the JavsScript stack height if the function frame_count is
768   // compiled.
769   if (!frame_count.IsEmpty()) {
770     static const int kArgc = 1;
771     v8::Handle<v8::Value> argv[kArgc] = { exec_state };
772     // Using exec_state as receiver is just to have a receiver.
773     v8::Handle<v8::Value> result =  frame_count->Call(exec_state, kArgc, argv);
774     last_js_stack_height = result->Int32Value();
775   }
776 }
777
778
779 // Debug event handler which evaluates a number of expressions when a break
780 // point is hit. Each evaluated expression is compared with an expected value.
781 // For this debug event handler to work the following two global varaibles
782 // must be initialized.
783 //   checks: An array of expressions and expected results
784 //   evaluate_check_function: A JavaScript function (see below)
785
786 // Structure for holding checks to do.
787 struct EvaluateCheck {
788   const char* expr;  // An expression to evaluate when a break point is hit.
789   v8::Handle<v8::Value> expected;  // The expected result.
790 };
791
792
793 // Array of checks to do.
794 struct EvaluateCheck* checks = NULL;
795 // Source for The JavaScript function which can do the evaluation when a break
796 // point is hit.
797 const char* evaluate_check_source =
798     "function evaluate_check(exec_state, expr, expected) {"
799     "  return exec_state.frame(0).evaluate(expr).value() === expected;"
800     "}";
801 v8::Local<v8::Function> evaluate_check_function;
802
803 // The actual debug event described by the longer comment above.
804 static void DebugEventEvaluate(
805     const v8::Debug::EventDetails& event_details) {
806   v8::DebugEvent event = event_details.GetEvent();
807   v8::Handle<v8::Object> exec_state = event_details.GetExecutionState();
808   v8::internal::Debug* debug = CcTest::i_isolate()->debug();
809   // When hitting a debug event listener there must be a break set.
810   CHECK_NE(debug->break_id(), 0);
811
812   if (event == v8::Break) {
813     for (int i = 0; checks[i].expr != NULL; i++) {
814       const int argc = 3;
815       v8::Handle<v8::Value> argv[argc] = {
816           exec_state,
817           v8::String::NewFromUtf8(CcTest::isolate(), checks[i].expr),
818           checks[i].expected};
819       v8::Handle<v8::Value> result =
820           evaluate_check_function->Call(exec_state, argc, argv);
821       if (!result->IsTrue()) {
822         v8::String::Utf8Value utf8(checks[i].expected->ToString());
823         V8_Fatal(__FILE__, __LINE__, "%s != %s", checks[i].expr, *utf8);
824       }
825     }
826   }
827 }
828
829
830 // This debug event listener removes a breakpoint in a function
831 int debug_event_remove_break_point = 0;
832 static void DebugEventRemoveBreakPoint(
833     const v8::Debug::EventDetails& event_details) {
834   v8::DebugEvent event = event_details.GetEvent();
835   v8::Handle<v8::Value> data = event_details.GetCallbackData();
836   v8::internal::Debug* debug = CcTest::i_isolate()->debug();
837   // When hitting a debug event listener there must be a break set.
838   CHECK_NE(debug->break_id(), 0);
839
840   if (event == v8::Break) {
841     break_point_hit_count++;
842     CHECK(data->IsFunction());
843     ClearBreakPoint(debug_event_remove_break_point);
844   }
845 }
846
847
848 // Debug event handler which counts break points hit and performs a step
849 // afterwards.
850 StepAction step_action = StepIn;  // Step action to perform when stepping.
851 static void DebugEventStep(
852     const v8::Debug::EventDetails& event_details) {
853   v8::DebugEvent event = event_details.GetEvent();
854   v8::internal::Debug* debug = CcTest::i_isolate()->debug();
855   // When hitting a debug event listener there must be a break set.
856   CHECK_NE(debug->break_id(), 0);
857
858   if (event == v8::Break) {
859     break_point_hit_count++;
860     PrepareStep(step_action);
861   }
862 }
863
864
865 // Debug event handler which counts break points hit and performs a step
866 // afterwards. For each call the expected function is checked.
867 // For this debug event handler to work the following two global varaibles
868 // must be initialized.
869 //   expected_step_sequence: An array of the expected function call sequence.
870 //   frame_function_name: A JavaScript function (see below).
871
872 // String containing the expected function call sequence. Note: this only works
873 // if functions have name length of one.
874 const char* expected_step_sequence = NULL;
875
876 // The actual debug event described by the longer comment above.
877 static void DebugEventStepSequence(
878     const v8::Debug::EventDetails& event_details) {
879   v8::DebugEvent event = event_details.GetEvent();
880   v8::Handle<v8::Object> exec_state = event_details.GetExecutionState();
881   v8::internal::Debug* debug = CcTest::i_isolate()->debug();
882   // When hitting a debug event listener there must be a break set.
883   CHECK_NE(debug->break_id(), 0);
884
885   if (event == v8::Break || event == v8::Exception) {
886     // Check that the current function is the expected.
887     CHECK(break_point_hit_count <
888           StrLength(expected_step_sequence));
889     const int argc = 2;
890     v8::Handle<v8::Value> argv[argc] = {
891       exec_state, v8::Integer::New(CcTest::isolate(), 0)
892     };
893     v8::Handle<v8::Value> result = frame_function_name->Call(exec_state,
894                                                              argc, argv);
895     CHECK(result->IsString());
896     v8::String::Utf8Value function_name(result->ToString());
897     CHECK_EQ(1, StrLength(*function_name));
898     CHECK_EQ((*function_name)[0],
899               expected_step_sequence[break_point_hit_count]);
900
901     // Perform step.
902     break_point_hit_count++;
903     PrepareStep(step_action);
904   }
905 }
906
907
908 // Debug event handler which performs a garbage collection.
909 static void DebugEventBreakPointCollectGarbage(
910     const v8::Debug::EventDetails& event_details) {
911   v8::DebugEvent event = event_details.GetEvent();
912   v8::internal::Debug* debug = CcTest::i_isolate()->debug();
913   // When hitting a debug event listener there must be a break set.
914   CHECK_NE(debug->break_id(), 0);
915
916   // Perform a garbage collection when break point is hit and continue. Based
917   // on the number of break points hit either scavenge or mark compact
918   // collector is used.
919   if (event == v8::Break) {
920     break_point_hit_count++;
921     if (break_point_hit_count % 2 == 0) {
922       // Scavenge.
923       CcTest::heap()->CollectGarbage(v8::internal::NEW_SPACE);
924     } else {
925       // Mark sweep compact.
926       CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags);
927     }
928   }
929 }
930
931
932 // Debug event handler which re-issues a debug break and calls the garbage
933 // collector to have the heap verified.
934 static void DebugEventBreak(
935     const v8::Debug::EventDetails& event_details) {
936   v8::DebugEvent event = event_details.GetEvent();
937   v8::internal::Debug* debug = CcTest::i_isolate()->debug();
938   // When hitting a debug event listener there must be a break set.
939   CHECK_NE(debug->break_id(), 0);
940
941   if (event == v8::Break) {
942     // Count the number of breaks.
943     break_point_hit_count++;
944
945     // Run the garbage collector to enforce heap verification if option
946     // --verify-heap is set.
947     CcTest::heap()->CollectGarbage(v8::internal::NEW_SPACE);
948
949     // Set the break flag again to come back here as soon as possible.
950     v8::Debug::DebugBreak(CcTest::isolate());
951   }
952 }
953
954
955 // Debug event handler which re-issues a debug break until a limit has been
956 // reached.
957 int max_break_point_hit_count = 0;
958 bool terminate_after_max_break_point_hit = false;
959 static void DebugEventBreakMax(
960     const v8::Debug::EventDetails& event_details) {
961   v8::DebugEvent event = event_details.GetEvent();
962   v8::Handle<v8::Object> exec_state = event_details.GetExecutionState();
963   v8::Isolate* v8_isolate = CcTest::isolate();
964   v8::internal::Isolate* isolate = CcTest::i_isolate();
965   v8::internal::Debug* debug = isolate->debug();
966   // When hitting a debug event listener there must be a break set.
967   CHECK_NE(debug->break_id(), 0);
968
969   if (event == v8::Break) {
970     if (break_point_hit_count < max_break_point_hit_count) {
971       // Count the number of breaks.
972       break_point_hit_count++;
973
974       // Collect the JavsScript stack height if the function frame_count is
975       // compiled.
976       if (!frame_count.IsEmpty()) {
977         static const int kArgc = 1;
978         v8::Handle<v8::Value> argv[kArgc] = { exec_state };
979         // Using exec_state as receiver is just to have a receiver.
980         v8::Handle<v8::Value> result =
981             frame_count->Call(exec_state, kArgc, argv);
982         last_js_stack_height = result->Int32Value();
983       }
984
985       // Set the break flag again to come back here as soon as possible.
986       v8::Debug::DebugBreak(v8_isolate);
987
988     } else if (terminate_after_max_break_point_hit) {
989       // Terminate execution after the last break if requested.
990       v8::V8::TerminateExecution(v8_isolate);
991     }
992
993     // Perform a full deoptimization when the specified number of
994     // breaks have been hit.
995     if (break_point_hit_count == break_point_hit_count_deoptimize) {
996       i::Deoptimizer::DeoptimizeAll(isolate);
997     }
998   }
999 }
1000
1001
1002 // --- M e s s a g e   C a l l b a c k
1003
1004
1005 // Message callback which counts the number of messages.
1006 int message_callback_count = 0;
1007
1008 static void MessageCallbackCountClear() {
1009   message_callback_count = 0;
1010 }
1011
1012 static void MessageCallbackCount(v8::Handle<v8::Message> message,
1013                                  v8::Handle<v8::Value> data) {
1014   message_callback_count++;
1015 }
1016
1017
1018 // --- T h e   A c t u a l   T e s t s
1019
1020
1021 // Test that the debug break function is the expected one for different kinds
1022 // of break locations.
1023 TEST(DebugStub) {
1024   using ::v8::internal::Builtins;
1025   using ::v8::internal::Isolate;
1026   DebugLocalContext env;
1027   v8::HandleScope scope(env->GetIsolate());
1028
1029   CheckDebugBreakFunction(&env,
1030                           "function f1(){}", "f1",
1031                           0,
1032                           v8::internal::RelocInfo::JS_RETURN,
1033                           NULL);
1034   CheckDebugBreakFunction(&env,
1035                           "function f2(){x=1;}", "f2",
1036                           0,
1037                           v8::internal::RelocInfo::CODE_TARGET,
1038                           CcTest::i_isolate()->builtins()->builtin(
1039                               Builtins::kStoreIC_DebugBreak));
1040   CheckDebugBreakFunction(&env,
1041                           "function f3(){var a=x;}", "f3",
1042                           0,
1043                           v8::internal::RelocInfo::CODE_TARGET,
1044                           CcTest::i_isolate()->builtins()->builtin(
1045                               Builtins::kLoadIC_DebugBreak));
1046
1047 // TODO(1240753): Make the test architecture independent or split
1048 // parts of the debugger into architecture dependent files. This
1049 // part currently disabled as it is not portable between IA32/ARM.
1050 // Currently on ICs for keyed store/load on ARM.
1051 #if !defined (__arm__) && !defined(__thumb__)
1052   CheckDebugBreakFunction(
1053       &env,
1054       "function f4(){var index='propertyName'; var a={}; a[index] = 'x';}",
1055       "f4",
1056       0,
1057       v8::internal::RelocInfo::CODE_TARGET,
1058       CcTest::i_isolate()->builtins()->builtin(
1059           Builtins::kKeyedStoreIC_DebugBreak));
1060   CheckDebugBreakFunction(
1061       &env,
1062       "function f5(){var index='propertyName'; var a={}; return a[index];}",
1063       "f5",
1064       0,
1065       v8::internal::RelocInfo::CODE_TARGET,
1066       CcTest::i_isolate()->builtins()->builtin(
1067           Builtins::kKeyedLoadIC_DebugBreak));
1068 #endif
1069
1070   CheckDebugBreakFunction(
1071       &env,
1072       "function f6(a){return a==null;}",
1073       "f6",
1074       0,
1075       v8::internal::RelocInfo::CODE_TARGET,
1076       CcTest::i_isolate()->builtins()->builtin(
1077           Builtins::kCompareNilIC_DebugBreak));
1078
1079   // Check the debug break code stubs for call ICs with different number of
1080   // parameters.
1081   // TODO(verwaest): XXX update test.
1082   // Handle<Code> debug_break_0 = v8::internal::ComputeCallDebugBreak(0);
1083   // Handle<Code> debug_break_1 = v8::internal::ComputeCallDebugBreak(1);
1084   // Handle<Code> debug_break_4 = v8::internal::ComputeCallDebugBreak(4);
1085
1086   // CheckDebugBreakFunction(&env,
1087   //                         "function f4_0(){x();}", "f4_0",
1088   //                         0,
1089   //                         v8::internal::RelocInfo::CODE_TARGET,
1090   //                         *debug_break_0);
1091
1092   // CheckDebugBreakFunction(&env,
1093   //                         "function f4_1(){x(1);}", "f4_1",
1094   //                         0,
1095   //                         v8::internal::RelocInfo::CODE_TARGET,
1096   //                         *debug_break_1);
1097
1098   // CheckDebugBreakFunction(&env,
1099   //                         "function f4_4(){x(1,2,3,4);}", "f4_4",
1100   //                         0,
1101   //                         v8::internal::RelocInfo::CODE_TARGET,
1102   //                         *debug_break_4);
1103 }
1104
1105
1106 // Test that the debug info in the VM is in sync with the functions being
1107 // debugged.
1108 TEST(DebugInfo) {
1109   DebugLocalContext env;
1110   v8::HandleScope scope(env->GetIsolate());
1111   // Create a couple of functions for the test.
1112   v8::Local<v8::Function> foo =
1113       CompileFunction(&env, "function foo(){}", "foo");
1114   v8::Local<v8::Function> bar =
1115       CompileFunction(&env, "function bar(){}", "bar");
1116   // Initially no functions are debugged.
1117   CHECK_EQ(0, v8::internal::GetDebuggedFunctions()->length());
1118   CHECK(!HasDebugInfo(foo));
1119   CHECK(!HasDebugInfo(bar));
1120   // One function (foo) is debugged.
1121   int bp1 = SetBreakPoint(foo, 0);
1122   CHECK_EQ(1, v8::internal::GetDebuggedFunctions()->length());
1123   CHECK(HasDebugInfo(foo));
1124   CHECK(!HasDebugInfo(bar));
1125   // Two functions are debugged.
1126   int bp2 = SetBreakPoint(bar, 0);
1127   CHECK_EQ(2, v8::internal::GetDebuggedFunctions()->length());
1128   CHECK(HasDebugInfo(foo));
1129   CHECK(HasDebugInfo(bar));
1130   // One function (bar) is debugged.
1131   ClearBreakPoint(bp1);
1132   CHECK_EQ(1, v8::internal::GetDebuggedFunctions()->length());
1133   CHECK(!HasDebugInfo(foo));
1134   CHECK(HasDebugInfo(bar));
1135   // No functions are debugged.
1136   ClearBreakPoint(bp2);
1137   CHECK_EQ(0, v8::internal::GetDebuggedFunctions()->length());
1138   CHECK(!HasDebugInfo(foo));
1139   CHECK(!HasDebugInfo(bar));
1140 }
1141
1142
1143 // Test that a break point can be set at an IC store location.
1144 TEST(BreakPointICStore) {
1145   break_point_hit_count = 0;
1146   DebugLocalContext env;
1147   v8::HandleScope scope(env->GetIsolate());
1148
1149   v8::Debug::SetDebugEventListener2(DebugEventBreakPointHitCount);
1150   v8::Script::Compile(v8::String::NewFromUtf8(env->GetIsolate(),
1151                                               "function foo(){bar=0;}"))->Run();
1152   v8::Local<v8::Function> foo = v8::Local<v8::Function>::Cast(
1153       env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "foo")));
1154
1155   // Run without breakpoints.
1156   foo->Call(env->Global(), 0, NULL);
1157   CHECK_EQ(0, break_point_hit_count);
1158
1159   // Run with breakpoint
1160   int bp = SetBreakPoint(foo, 0);
1161   foo->Call(env->Global(), 0, NULL);
1162   CHECK_EQ(1, break_point_hit_count);
1163   foo->Call(env->Global(), 0, NULL);
1164   CHECK_EQ(2, break_point_hit_count);
1165
1166   // Run without breakpoints.
1167   ClearBreakPoint(bp);
1168   foo->Call(env->Global(), 0, NULL);
1169   CHECK_EQ(2, break_point_hit_count);
1170
1171   v8::Debug::SetDebugEventListener2(NULL);
1172   CheckDebuggerUnloaded();
1173 }
1174
1175
1176 // Test that a break point can be set at an IC load location.
1177 TEST(BreakPointICLoad) {
1178   break_point_hit_count = 0;
1179   DebugLocalContext env;
1180   v8::HandleScope scope(env->GetIsolate());
1181   v8::Debug::SetDebugEventListener2(DebugEventBreakPointHitCount);
1182   v8::Script::Compile(v8::String::NewFromUtf8(env->GetIsolate(), "bar=1"))
1183       ->Run();
1184   v8::Script::Compile(
1185       v8::String::NewFromUtf8(env->GetIsolate(), "function foo(){var x=bar;}"))
1186       ->Run();
1187   v8::Local<v8::Function> foo = v8::Local<v8::Function>::Cast(
1188       env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "foo")));
1189
1190   // Run without breakpoints.
1191   foo->Call(env->Global(), 0, NULL);
1192   CHECK_EQ(0, break_point_hit_count);
1193
1194   // Run with breakpoint.
1195   int bp = SetBreakPoint(foo, 0);
1196   foo->Call(env->Global(), 0, NULL);
1197   CHECK_EQ(1, break_point_hit_count);
1198   foo->Call(env->Global(), 0, NULL);
1199   CHECK_EQ(2, break_point_hit_count);
1200
1201   // Run without breakpoints.
1202   ClearBreakPoint(bp);
1203   foo->Call(env->Global(), 0, NULL);
1204   CHECK_EQ(2, break_point_hit_count);
1205
1206   v8::Debug::SetDebugEventListener2(NULL);
1207   CheckDebuggerUnloaded();
1208 }
1209
1210
1211 // Test that a break point can be set at an IC call location.
1212 TEST(BreakPointICCall) {
1213   break_point_hit_count = 0;
1214   DebugLocalContext env;
1215   v8::HandleScope scope(env->GetIsolate());
1216   v8::Debug::SetDebugEventListener2(DebugEventBreakPointHitCount);
1217   v8::Script::Compile(
1218       v8::String::NewFromUtf8(env->GetIsolate(), "function bar(){}"))->Run();
1219   v8::Script::Compile(v8::String::NewFromUtf8(env->GetIsolate(),
1220                                               "function foo(){bar();}"))->Run();
1221   v8::Local<v8::Function> foo = v8::Local<v8::Function>::Cast(
1222       env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "foo")));
1223
1224   // Run without breakpoints.
1225   foo->Call(env->Global(), 0, NULL);
1226   CHECK_EQ(0, break_point_hit_count);
1227
1228   // Run with breakpoint
1229   int bp = SetBreakPoint(foo, 0);
1230   foo->Call(env->Global(), 0, NULL);
1231   CHECK_EQ(1, break_point_hit_count);
1232   foo->Call(env->Global(), 0, NULL);
1233   CHECK_EQ(2, break_point_hit_count);
1234
1235   // Run without breakpoints.
1236   ClearBreakPoint(bp);
1237   foo->Call(env->Global(), 0, NULL);
1238   CHECK_EQ(2, break_point_hit_count);
1239
1240   v8::Debug::SetDebugEventListener2(NULL);
1241   CheckDebuggerUnloaded();
1242 }
1243
1244
1245 // Test that a break point can be set at an IC call location and survive a GC.
1246 TEST(BreakPointICCallWithGC) {
1247   break_point_hit_count = 0;
1248   DebugLocalContext env;
1249   v8::HandleScope scope(env->GetIsolate());
1250   v8::Debug::SetDebugEventListener2(DebugEventBreakPointCollectGarbage);
1251   v8::Script::Compile(
1252       v8::String::NewFromUtf8(env->GetIsolate(), "function bar(){return 1;}"))
1253       ->Run();
1254   v8::Script::Compile(v8::String::NewFromUtf8(env->GetIsolate(),
1255                                               "function foo(){return bar();}"))
1256       ->Run();
1257   v8::Local<v8::Function> foo = v8::Local<v8::Function>::Cast(
1258       env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "foo")));
1259
1260   // Run without breakpoints.
1261   CHECK_EQ(1, foo->Call(env->Global(), 0, NULL)->Int32Value());
1262   CHECK_EQ(0, break_point_hit_count);
1263
1264   // Run with breakpoint.
1265   int bp = SetBreakPoint(foo, 0);
1266   CHECK_EQ(1, foo->Call(env->Global(), 0, NULL)->Int32Value());
1267   CHECK_EQ(1, break_point_hit_count);
1268   CHECK_EQ(1, foo->Call(env->Global(), 0, NULL)->Int32Value());
1269   CHECK_EQ(2, break_point_hit_count);
1270
1271   // Run without breakpoints.
1272   ClearBreakPoint(bp);
1273   foo->Call(env->Global(), 0, NULL);
1274   CHECK_EQ(2, break_point_hit_count);
1275
1276   v8::Debug::SetDebugEventListener2(NULL);
1277   CheckDebuggerUnloaded();
1278 }
1279
1280
1281 // Test that a break point can be set at an IC call location and survive a GC.
1282 TEST(BreakPointConstructCallWithGC) {
1283   break_point_hit_count = 0;
1284   DebugLocalContext env;
1285   v8::HandleScope scope(env->GetIsolate());
1286   v8::Debug::SetDebugEventListener2(DebugEventBreakPointCollectGarbage);
1287   v8::Script::Compile(v8::String::NewFromUtf8(env->GetIsolate(),
1288                                               "function bar(){ this.x = 1;}"))
1289       ->Run();
1290   v8::Script::Compile(
1291       v8::String::NewFromUtf8(env->GetIsolate(),
1292                               "function foo(){return new bar(1).x;}"))->Run();
1293   v8::Local<v8::Function> foo = v8::Local<v8::Function>::Cast(
1294       env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "foo")));
1295
1296   // Run without breakpoints.
1297   CHECK_EQ(1, foo->Call(env->Global(), 0, NULL)->Int32Value());
1298   CHECK_EQ(0, break_point_hit_count);
1299
1300   // Run with breakpoint.
1301   int bp = SetBreakPoint(foo, 0);
1302   CHECK_EQ(1, foo->Call(env->Global(), 0, NULL)->Int32Value());
1303   CHECK_EQ(1, break_point_hit_count);
1304   CHECK_EQ(1, foo->Call(env->Global(), 0, NULL)->Int32Value());
1305   CHECK_EQ(2, break_point_hit_count);
1306
1307   // Run without breakpoints.
1308   ClearBreakPoint(bp);
1309   foo->Call(env->Global(), 0, NULL);
1310   CHECK_EQ(2, break_point_hit_count);
1311
1312   v8::Debug::SetDebugEventListener2(NULL);
1313   CheckDebuggerUnloaded();
1314 }
1315
1316
1317 // Test that a break point can be set at a return store location.
1318 TEST(BreakPointReturn) {
1319   break_point_hit_count = 0;
1320   DebugLocalContext env;
1321   v8::HandleScope scope(env->GetIsolate());
1322
1323   // Create a functions for checking the source line and column when hitting
1324   // a break point.
1325   frame_source_line = CompileFunction(&env,
1326                                       frame_source_line_source,
1327                                       "frame_source_line");
1328   frame_source_column = CompileFunction(&env,
1329                                         frame_source_column_source,
1330                                         "frame_source_column");
1331
1332
1333   v8::Debug::SetDebugEventListener2(DebugEventBreakPointHitCount);
1334   v8::Script::Compile(
1335       v8::String::NewFromUtf8(env->GetIsolate(), "function foo(){}"))->Run();
1336   v8::Local<v8::Function> foo = v8::Local<v8::Function>::Cast(
1337       env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "foo")));
1338
1339   // Run without breakpoints.
1340   foo->Call(env->Global(), 0, NULL);
1341   CHECK_EQ(0, break_point_hit_count);
1342
1343   // Run with breakpoint
1344   int bp = SetBreakPoint(foo, 0);
1345   foo->Call(env->Global(), 0, NULL);
1346   CHECK_EQ(1, break_point_hit_count);
1347   CHECK_EQ(0, last_source_line);
1348   CHECK_EQ(15, last_source_column);
1349   foo->Call(env->Global(), 0, NULL);
1350   CHECK_EQ(2, break_point_hit_count);
1351   CHECK_EQ(0, last_source_line);
1352   CHECK_EQ(15, last_source_column);
1353
1354   // Run without breakpoints.
1355   ClearBreakPoint(bp);
1356   foo->Call(env->Global(), 0, NULL);
1357   CHECK_EQ(2, break_point_hit_count);
1358
1359   v8::Debug::SetDebugEventListener2(NULL);
1360   CheckDebuggerUnloaded();
1361 }
1362
1363
1364 static void CallWithBreakPoints(v8::Local<v8::Object> recv,
1365                                 v8::Local<v8::Function> f,
1366                                 int break_point_count,
1367                                 int call_count) {
1368   break_point_hit_count = 0;
1369   for (int i = 0; i < call_count; i++) {
1370     f->Call(recv, 0, NULL);
1371     CHECK_EQ((i + 1) * break_point_count, break_point_hit_count);
1372   }
1373 }
1374
1375
1376 // Test GC during break point processing.
1377 TEST(GCDuringBreakPointProcessing) {
1378   break_point_hit_count = 0;
1379   DebugLocalContext env;
1380   v8::HandleScope scope(env->GetIsolate());
1381
1382   v8::Debug::SetDebugEventListener2(DebugEventBreakPointCollectGarbage);
1383   v8::Local<v8::Function> foo;
1384
1385   // Test IC store break point with garbage collection.
1386   foo = CompileFunction(&env, "function foo(){bar=0;}", "foo");
1387   SetBreakPoint(foo, 0);
1388   CallWithBreakPoints(env->Global(), foo, 1, 10);
1389
1390   // Test IC load break point with garbage collection.
1391   foo = CompileFunction(&env, "bar=1;function foo(){var x=bar;}", "foo");
1392   SetBreakPoint(foo, 0);
1393   CallWithBreakPoints(env->Global(), foo, 1, 10);
1394
1395   // Test IC call break point with garbage collection.
1396   foo = CompileFunction(&env, "function bar(){};function foo(){bar();}", "foo");
1397   SetBreakPoint(foo, 0);
1398   CallWithBreakPoints(env->Global(), foo, 1, 10);
1399
1400   // Test return break point with garbage collection.
1401   foo = CompileFunction(&env, "function foo(){}", "foo");
1402   SetBreakPoint(foo, 0);
1403   CallWithBreakPoints(env->Global(), foo, 1, 25);
1404
1405   // Test debug break slot break point with garbage collection.
1406   foo = CompileFunction(&env, "function foo(){var a;}", "foo");
1407   SetBreakPoint(foo, 0);
1408   CallWithBreakPoints(env->Global(), foo, 1, 25);
1409
1410   v8::Debug::SetDebugEventListener2(NULL);
1411   CheckDebuggerUnloaded();
1412 }
1413
1414
1415 // Call the function three times with different garbage collections in between
1416 // and make sure that the break point survives.
1417 static void CallAndGC(v8::Local<v8::Object> recv,
1418                       v8::Local<v8::Function> f) {
1419   break_point_hit_count = 0;
1420
1421   for (int i = 0; i < 3; i++) {
1422     // Call function.
1423     f->Call(recv, 0, NULL);
1424     CHECK_EQ(1 + i * 3, break_point_hit_count);
1425
1426     // Scavenge and call function.
1427     CcTest::heap()->CollectGarbage(v8::internal::NEW_SPACE);
1428     f->Call(recv, 0, NULL);
1429     CHECK_EQ(2 + i * 3, break_point_hit_count);
1430
1431     // Mark sweep (and perhaps compact) and call function.
1432     CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags);
1433     f->Call(recv, 0, NULL);
1434     CHECK_EQ(3 + i * 3, break_point_hit_count);
1435   }
1436 }
1437
1438
1439 // Test that a break point can be set at a return store location.
1440 TEST(BreakPointSurviveGC) {
1441   break_point_hit_count = 0;
1442   DebugLocalContext env;
1443   v8::HandleScope scope(env->GetIsolate());
1444
1445   v8::Debug::SetDebugEventListener2(DebugEventBreakPointHitCount);
1446   v8::Local<v8::Function> foo;
1447
1448   // Test IC store break point with garbage collection.
1449   {
1450     CompileFunction(&env, "function foo(){}", "foo");
1451     foo = CompileFunction(&env, "function foo(){bar=0;}", "foo");
1452     SetBreakPoint(foo, 0);
1453   }
1454   CallAndGC(env->Global(), foo);
1455
1456   // Test IC load break point with garbage collection.
1457   {
1458     CompileFunction(&env, "function foo(){}", "foo");
1459     foo = CompileFunction(&env, "bar=1;function foo(){var x=bar;}", "foo");
1460     SetBreakPoint(foo, 0);
1461   }
1462   CallAndGC(env->Global(), foo);
1463
1464   // Test IC call break point with garbage collection.
1465   {
1466     CompileFunction(&env, "function foo(){}", "foo");
1467     foo = CompileFunction(&env,
1468                           "function bar(){};function foo(){bar();}",
1469                           "foo");
1470     SetBreakPoint(foo, 0);
1471   }
1472   CallAndGC(env->Global(), foo);
1473
1474   // Test return break point with garbage collection.
1475   {
1476     CompileFunction(&env, "function foo(){}", "foo");
1477     foo = CompileFunction(&env, "function foo(){}", "foo");
1478     SetBreakPoint(foo, 0);
1479   }
1480   CallAndGC(env->Global(), foo);
1481
1482   // Test non IC break point with garbage collection.
1483   {
1484     CompileFunction(&env, "function foo(){}", "foo");
1485     foo = CompileFunction(&env, "function foo(){var bar=0;}", "foo");
1486     SetBreakPoint(foo, 0);
1487   }
1488   CallAndGC(env->Global(), foo);
1489
1490
1491   v8::Debug::SetDebugEventListener2(NULL);
1492   CheckDebuggerUnloaded();
1493 }
1494
1495
1496 // Test that break points can be set using the global Debug object.
1497 TEST(BreakPointThroughJavaScript) {
1498   break_point_hit_count = 0;
1499   DebugLocalContext env;
1500   v8::HandleScope scope(env->GetIsolate());
1501   env.ExposeDebug();
1502
1503   v8::Debug::SetDebugEventListener2(DebugEventBreakPointHitCount);
1504   v8::Script::Compile(
1505       v8::String::NewFromUtf8(env->GetIsolate(), "function bar(){}"))->Run();
1506   v8::Script::Compile(v8::String::NewFromUtf8(env->GetIsolate(),
1507                                               "function foo(){bar();bar();}"))
1508       ->Run();
1509   //                                               012345678901234567890
1510   //                                                         1         2
1511   // Break points are set at position 3 and 9
1512   v8::Local<v8::Script> foo =
1513       v8::Script::Compile(v8::String::NewFromUtf8(env->GetIsolate(), "foo()"));
1514
1515   // Run without breakpoints.
1516   foo->Run();
1517   CHECK_EQ(0, break_point_hit_count);
1518
1519   // Run with one breakpoint
1520   int bp1 = SetBreakPointFromJS(env->GetIsolate(), "foo", 0, 3);
1521   foo->Run();
1522   CHECK_EQ(1, break_point_hit_count);
1523   foo->Run();
1524   CHECK_EQ(2, break_point_hit_count);
1525
1526   // Run with two breakpoints
1527   int bp2 = SetBreakPointFromJS(env->GetIsolate(), "foo", 0, 9);
1528   foo->Run();
1529   CHECK_EQ(4, break_point_hit_count);
1530   foo->Run();
1531   CHECK_EQ(6, break_point_hit_count);
1532
1533   // Run with one breakpoint
1534   ClearBreakPointFromJS(env->GetIsolate(), bp2);
1535   foo->Run();
1536   CHECK_EQ(7, break_point_hit_count);
1537   foo->Run();
1538   CHECK_EQ(8, break_point_hit_count);
1539
1540   // Run without breakpoints.
1541   ClearBreakPointFromJS(env->GetIsolate(), bp1);
1542   foo->Run();
1543   CHECK_EQ(8, break_point_hit_count);
1544
1545   v8::Debug::SetDebugEventListener2(NULL);
1546   CheckDebuggerUnloaded();
1547
1548   // Make sure that the break point numbers are consecutive.
1549   CHECK_EQ(1, bp1);
1550   CHECK_EQ(2, bp2);
1551 }
1552
1553
1554 // Test that break points on scripts identified by name can be set using the
1555 // global Debug object.
1556 TEST(ScriptBreakPointByNameThroughJavaScript) {
1557   break_point_hit_count = 0;
1558   DebugLocalContext env;
1559   v8::HandleScope scope(env->GetIsolate());
1560   env.ExposeDebug();
1561
1562   v8::Debug::SetDebugEventListener2(DebugEventBreakPointHitCount);
1563
1564   v8::Local<v8::String> script = v8::String::NewFromUtf8(
1565     env->GetIsolate(),
1566     "function f() {\n"
1567     "  function h() {\n"
1568     "    a = 0;  // line 2\n"
1569     "  }\n"
1570     "  b = 1;  // line 4\n"
1571     "  return h();\n"
1572     "}\n"
1573     "\n"
1574     "function g() {\n"
1575     "  function h() {\n"
1576     "    a = 0;\n"
1577     "  }\n"
1578     "  b = 2;  // line 12\n"
1579     "  h();\n"
1580     "  b = 3;  // line 14\n"
1581     "  f();    // line 15\n"
1582     "}");
1583
1584   // Compile the script and get the two functions.
1585   v8::ScriptOrigin origin =
1586       v8::ScriptOrigin(v8::String::NewFromUtf8(env->GetIsolate(), "test"));
1587   v8::Script::Compile(script, &origin)->Run();
1588   v8::Local<v8::Function> f = v8::Local<v8::Function>::Cast(
1589       env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "f")));
1590   v8::Local<v8::Function> g = v8::Local<v8::Function>::Cast(
1591       env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "g")));
1592
1593   // Call f and g without break points.
1594   break_point_hit_count = 0;
1595   f->Call(env->Global(), 0, NULL);
1596   CHECK_EQ(0, break_point_hit_count);
1597   g->Call(env->Global(), 0, NULL);
1598   CHECK_EQ(0, break_point_hit_count);
1599
1600   // Call f and g with break point on line 12.
1601   int sbp1 = SetScriptBreakPointByNameFromJS(env->GetIsolate(), "test", 12, 0);
1602   break_point_hit_count = 0;
1603   f->Call(env->Global(), 0, NULL);
1604   CHECK_EQ(0, break_point_hit_count);
1605   g->Call(env->Global(), 0, NULL);
1606   CHECK_EQ(1, break_point_hit_count);
1607
1608   // Remove the break point again.
1609   break_point_hit_count = 0;
1610   ClearBreakPointFromJS(env->GetIsolate(), sbp1);
1611   f->Call(env->Global(), 0, NULL);
1612   CHECK_EQ(0, break_point_hit_count);
1613   g->Call(env->Global(), 0, NULL);
1614   CHECK_EQ(0, break_point_hit_count);
1615
1616   // Call f and g with break point on line 2.
1617   int sbp2 = SetScriptBreakPointByNameFromJS(env->GetIsolate(), "test", 2, 0);
1618   break_point_hit_count = 0;
1619   f->Call(env->Global(), 0, NULL);
1620   CHECK_EQ(1, break_point_hit_count);
1621   g->Call(env->Global(), 0, NULL);
1622   CHECK_EQ(2, break_point_hit_count);
1623
1624   // Call f and g with break point on line 2, 4, 12, 14 and 15.
1625   int sbp3 = SetScriptBreakPointByNameFromJS(env->GetIsolate(), "test", 4, 0);
1626   int sbp4 = SetScriptBreakPointByNameFromJS(env->GetIsolate(), "test", 12, 0);
1627   int sbp5 = SetScriptBreakPointByNameFromJS(env->GetIsolate(), "test", 14, 0);
1628   int sbp6 = SetScriptBreakPointByNameFromJS(env->GetIsolate(), "test", 15, 0);
1629   break_point_hit_count = 0;
1630   f->Call(env->Global(), 0, NULL);
1631   CHECK_EQ(2, break_point_hit_count);
1632   g->Call(env->Global(), 0, NULL);
1633   CHECK_EQ(7, break_point_hit_count);
1634
1635   // Remove all the break points again.
1636   break_point_hit_count = 0;
1637   ClearBreakPointFromJS(env->GetIsolate(), sbp2);
1638   ClearBreakPointFromJS(env->GetIsolate(), sbp3);
1639   ClearBreakPointFromJS(env->GetIsolate(), sbp4);
1640   ClearBreakPointFromJS(env->GetIsolate(), sbp5);
1641   ClearBreakPointFromJS(env->GetIsolate(), sbp6);
1642   f->Call(env->Global(), 0, NULL);
1643   CHECK_EQ(0, break_point_hit_count);
1644   g->Call(env->Global(), 0, NULL);
1645   CHECK_EQ(0, break_point_hit_count);
1646
1647   v8::Debug::SetDebugEventListener2(NULL);
1648   CheckDebuggerUnloaded();
1649
1650   // Make sure that the break point numbers are consecutive.
1651   CHECK_EQ(1, sbp1);
1652   CHECK_EQ(2, sbp2);
1653   CHECK_EQ(3, sbp3);
1654   CHECK_EQ(4, sbp4);
1655   CHECK_EQ(5, sbp5);
1656   CHECK_EQ(6, sbp6);
1657 }
1658
1659
1660 TEST(ScriptBreakPointByIdThroughJavaScript) {
1661   break_point_hit_count = 0;
1662   DebugLocalContext env;
1663   v8::HandleScope scope(env->GetIsolate());
1664   env.ExposeDebug();
1665
1666   v8::Debug::SetDebugEventListener2(DebugEventBreakPointHitCount);
1667
1668   v8::Local<v8::String> source = v8::String::NewFromUtf8(
1669     env->GetIsolate(),
1670     "function f() {\n"
1671     "  function h() {\n"
1672     "    a = 0;  // line 2\n"
1673     "  }\n"
1674     "  b = 1;  // line 4\n"
1675     "  return h();\n"
1676     "}\n"
1677     "\n"
1678     "function g() {\n"
1679     "  function h() {\n"
1680     "    a = 0;\n"
1681     "  }\n"
1682     "  b = 2;  // line 12\n"
1683     "  h();\n"
1684     "  b = 3;  // line 14\n"
1685     "  f();    // line 15\n"
1686     "}");
1687
1688   // Compile the script and get the two functions.
1689   v8::ScriptOrigin origin =
1690       v8::ScriptOrigin(v8::String::NewFromUtf8(env->GetIsolate(), "test"));
1691   v8::Local<v8::Script> script = v8::Script::Compile(source, &origin);
1692   script->Run();
1693   v8::Local<v8::Function> f = v8::Local<v8::Function>::Cast(
1694       env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "f")));
1695   v8::Local<v8::Function> g = v8::Local<v8::Function>::Cast(
1696       env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "g")));
1697
1698   // Get the script id knowing that internally it is a 32 integer.
1699   int script_id = script->GetId();
1700
1701   // Call f and g without break points.
1702   break_point_hit_count = 0;
1703   f->Call(env->Global(), 0, NULL);
1704   CHECK_EQ(0, break_point_hit_count);
1705   g->Call(env->Global(), 0, NULL);
1706   CHECK_EQ(0, break_point_hit_count);
1707
1708   // Call f and g with break point on line 12.
1709   int sbp1 = SetScriptBreakPointByIdFromJS(env->GetIsolate(), script_id, 12, 0);
1710   break_point_hit_count = 0;
1711   f->Call(env->Global(), 0, NULL);
1712   CHECK_EQ(0, break_point_hit_count);
1713   g->Call(env->Global(), 0, NULL);
1714   CHECK_EQ(1, break_point_hit_count);
1715
1716   // Remove the break point again.
1717   break_point_hit_count = 0;
1718   ClearBreakPointFromJS(env->GetIsolate(), sbp1);
1719   f->Call(env->Global(), 0, NULL);
1720   CHECK_EQ(0, break_point_hit_count);
1721   g->Call(env->Global(), 0, NULL);
1722   CHECK_EQ(0, break_point_hit_count);
1723
1724   // Call f and g with break point on line 2.
1725   int sbp2 = SetScriptBreakPointByIdFromJS(env->GetIsolate(), script_id, 2, 0);
1726   break_point_hit_count = 0;
1727   f->Call(env->Global(), 0, NULL);
1728   CHECK_EQ(1, break_point_hit_count);
1729   g->Call(env->Global(), 0, NULL);
1730   CHECK_EQ(2, break_point_hit_count);
1731
1732   // Call f and g with break point on line 2, 4, 12, 14 and 15.
1733   int sbp3 = SetScriptBreakPointByIdFromJS(env->GetIsolate(), script_id, 4, 0);
1734   int sbp4 = SetScriptBreakPointByIdFromJS(env->GetIsolate(), script_id, 12, 0);
1735   int sbp5 = SetScriptBreakPointByIdFromJS(env->GetIsolate(), script_id, 14, 0);
1736   int sbp6 = SetScriptBreakPointByIdFromJS(env->GetIsolate(), script_id, 15, 0);
1737   break_point_hit_count = 0;
1738   f->Call(env->Global(), 0, NULL);
1739   CHECK_EQ(2, break_point_hit_count);
1740   g->Call(env->Global(), 0, NULL);
1741   CHECK_EQ(7, break_point_hit_count);
1742
1743   // Remove all the break points again.
1744   break_point_hit_count = 0;
1745   ClearBreakPointFromJS(env->GetIsolate(), sbp2);
1746   ClearBreakPointFromJS(env->GetIsolate(), sbp3);
1747   ClearBreakPointFromJS(env->GetIsolate(), sbp4);
1748   ClearBreakPointFromJS(env->GetIsolate(), sbp5);
1749   ClearBreakPointFromJS(env->GetIsolate(), sbp6);
1750   f->Call(env->Global(), 0, NULL);
1751   CHECK_EQ(0, break_point_hit_count);
1752   g->Call(env->Global(), 0, NULL);
1753   CHECK_EQ(0, break_point_hit_count);
1754
1755   v8::Debug::SetDebugEventListener2(NULL);
1756   CheckDebuggerUnloaded();
1757
1758   // Make sure that the break point numbers are consecutive.
1759   CHECK_EQ(1, sbp1);
1760   CHECK_EQ(2, sbp2);
1761   CHECK_EQ(3, sbp3);
1762   CHECK_EQ(4, sbp4);
1763   CHECK_EQ(5, sbp5);
1764   CHECK_EQ(6, sbp6);
1765 }
1766
1767
1768 // Test conditional script break points.
1769 TEST(EnableDisableScriptBreakPoint) {
1770   break_point_hit_count = 0;
1771   DebugLocalContext env;
1772   v8::HandleScope scope(env->GetIsolate());
1773   env.ExposeDebug();
1774
1775   v8::Debug::SetDebugEventListener2(DebugEventBreakPointHitCount);
1776
1777   v8::Local<v8::String> script = v8::String::NewFromUtf8(
1778     env->GetIsolate(),
1779     "function f() {\n"
1780     "  a = 0;  // line 1\n"
1781     "};");
1782
1783   // Compile the script and get function f.
1784   v8::ScriptOrigin origin =
1785       v8::ScriptOrigin(v8::String::NewFromUtf8(env->GetIsolate(), "test"));
1786   v8::Script::Compile(script, &origin)->Run();
1787   v8::Local<v8::Function> f = v8::Local<v8::Function>::Cast(
1788       env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "f")));
1789
1790   // Set script break point on line 1 (in function f).
1791   int sbp = SetScriptBreakPointByNameFromJS(env->GetIsolate(), "test", 1, 0);
1792
1793   // Call f while enabeling and disabling the script break point.
1794   break_point_hit_count = 0;
1795   f->Call(env->Global(), 0, NULL);
1796   CHECK_EQ(1, break_point_hit_count);
1797
1798   DisableScriptBreakPointFromJS(env->GetIsolate(), sbp);
1799   f->Call(env->Global(), 0, NULL);
1800   CHECK_EQ(1, break_point_hit_count);
1801
1802   EnableScriptBreakPointFromJS(env->GetIsolate(), sbp);
1803   f->Call(env->Global(), 0, NULL);
1804   CHECK_EQ(2, break_point_hit_count);
1805
1806   DisableScriptBreakPointFromJS(env->GetIsolate(), sbp);
1807   f->Call(env->Global(), 0, NULL);
1808   CHECK_EQ(2, break_point_hit_count);
1809
1810   // Reload the script and get f again checking that the disabeling survives.
1811   v8::Script::Compile(script, &origin)->Run();
1812   f = v8::Local<v8::Function>::Cast(
1813       env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "f")));
1814   f->Call(env->Global(), 0, NULL);
1815   CHECK_EQ(2, break_point_hit_count);
1816
1817   EnableScriptBreakPointFromJS(env->GetIsolate(), sbp);
1818   f->Call(env->Global(), 0, NULL);
1819   CHECK_EQ(3, break_point_hit_count);
1820
1821   v8::Debug::SetDebugEventListener2(NULL);
1822   CheckDebuggerUnloaded();
1823 }
1824
1825
1826 // Test conditional script break points.
1827 TEST(ConditionalScriptBreakPoint) {
1828   break_point_hit_count = 0;
1829   DebugLocalContext env;
1830   v8::HandleScope scope(env->GetIsolate());
1831   env.ExposeDebug();
1832
1833   v8::Debug::SetDebugEventListener2(DebugEventBreakPointHitCount);
1834
1835   v8::Local<v8::String> script = v8::String::NewFromUtf8(
1836     env->GetIsolate(),
1837     "count = 0;\n"
1838     "function f() {\n"
1839     "  g(count++);  // line 2\n"
1840     "};\n"
1841     "function g(x) {\n"
1842     "  var a=x;  // line 5\n"
1843     "};");
1844
1845   // Compile the script and get function f.
1846   v8::ScriptOrigin origin =
1847       v8::ScriptOrigin(v8::String::NewFromUtf8(env->GetIsolate(), "test"));
1848   v8::Script::Compile(script, &origin)->Run();
1849   v8::Local<v8::Function> f = v8::Local<v8::Function>::Cast(
1850       env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "f")));
1851
1852   // Set script break point on line 5 (in function g).
1853   int sbp1 = SetScriptBreakPointByNameFromJS(env->GetIsolate(), "test", 5, 0);
1854
1855   // Call f with different conditions on the script break point.
1856   break_point_hit_count = 0;
1857   ChangeScriptBreakPointConditionFromJS(env->GetIsolate(), sbp1, "false");
1858   f->Call(env->Global(), 0, NULL);
1859   CHECK_EQ(0, break_point_hit_count);
1860
1861   ChangeScriptBreakPointConditionFromJS(env->GetIsolate(), sbp1, "true");
1862   break_point_hit_count = 0;
1863   f->Call(env->Global(), 0, NULL);
1864   CHECK_EQ(1, break_point_hit_count);
1865
1866   ChangeScriptBreakPointConditionFromJS(env->GetIsolate(), sbp1, "x % 2 == 0");
1867   break_point_hit_count = 0;
1868   for (int i = 0; i < 10; i++) {
1869     f->Call(env->Global(), 0, NULL);
1870   }
1871   CHECK_EQ(5, break_point_hit_count);
1872
1873   // Reload the script and get f again checking that the condition survives.
1874   v8::Script::Compile(script, &origin)->Run();
1875   f = v8::Local<v8::Function>::Cast(
1876       env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "f")));
1877
1878   break_point_hit_count = 0;
1879   for (int i = 0; i < 10; i++) {
1880     f->Call(env->Global(), 0, NULL);
1881   }
1882   CHECK_EQ(5, break_point_hit_count);
1883
1884   v8::Debug::SetDebugEventListener2(NULL);
1885   CheckDebuggerUnloaded();
1886 }
1887
1888
1889 // Test ignore count on script break points.
1890 TEST(ScriptBreakPointIgnoreCount) {
1891   break_point_hit_count = 0;
1892   DebugLocalContext env;
1893   v8::HandleScope scope(env->GetIsolate());
1894   env.ExposeDebug();
1895
1896   v8::Debug::SetDebugEventListener2(DebugEventBreakPointHitCount);
1897
1898   v8::Local<v8::String> script = v8::String::NewFromUtf8(
1899     env->GetIsolate(),
1900     "function f() {\n"
1901     "  a = 0;  // line 1\n"
1902     "};");
1903
1904   // Compile the script and get function f.
1905   v8::ScriptOrigin origin =
1906       v8::ScriptOrigin(v8::String::NewFromUtf8(env->GetIsolate(), "test"));
1907   v8::Script::Compile(script, &origin)->Run();
1908   v8::Local<v8::Function> f = v8::Local<v8::Function>::Cast(
1909       env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "f")));
1910
1911   // Set script break point on line 1 (in function f).
1912   int sbp = SetScriptBreakPointByNameFromJS(env->GetIsolate(), "test", 1, 0);
1913
1914   // Call f with different ignores on the script break point.
1915   break_point_hit_count = 0;
1916   ChangeScriptBreakPointIgnoreCountFromJS(env->GetIsolate(), sbp, 1);
1917   f->Call(env->Global(), 0, NULL);
1918   CHECK_EQ(0, break_point_hit_count);
1919   f->Call(env->Global(), 0, NULL);
1920   CHECK_EQ(1, break_point_hit_count);
1921
1922   ChangeScriptBreakPointIgnoreCountFromJS(env->GetIsolate(), sbp, 5);
1923   break_point_hit_count = 0;
1924   for (int i = 0; i < 10; i++) {
1925     f->Call(env->Global(), 0, NULL);
1926   }
1927   CHECK_EQ(5, break_point_hit_count);
1928
1929   // Reload the script and get f again checking that the ignore survives.
1930   v8::Script::Compile(script, &origin)->Run();
1931   f = v8::Local<v8::Function>::Cast(
1932       env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "f")));
1933
1934   break_point_hit_count = 0;
1935   for (int i = 0; i < 10; i++) {
1936     f->Call(env->Global(), 0, NULL);
1937   }
1938   CHECK_EQ(5, break_point_hit_count);
1939
1940   v8::Debug::SetDebugEventListener2(NULL);
1941   CheckDebuggerUnloaded();
1942 }
1943
1944
1945 // Test that script break points survive when a script is reloaded.
1946 TEST(ScriptBreakPointReload) {
1947   break_point_hit_count = 0;
1948   DebugLocalContext env;
1949   v8::HandleScope scope(env->GetIsolate());
1950   env.ExposeDebug();
1951
1952   v8::Debug::SetDebugEventListener2(DebugEventBreakPointHitCount);
1953
1954   v8::Local<v8::Function> f;
1955   v8::Local<v8::String> script = v8::String::NewFromUtf8(
1956     env->GetIsolate(),
1957     "function f() {\n"
1958     "  function h() {\n"
1959     "    a = 0;  // line 2\n"
1960     "  }\n"
1961     "  b = 1;  // line 4\n"
1962     "  return h();\n"
1963     "}");
1964
1965   v8::ScriptOrigin origin_1 =
1966       v8::ScriptOrigin(v8::String::NewFromUtf8(env->GetIsolate(), "1"));
1967   v8::ScriptOrigin origin_2 =
1968       v8::ScriptOrigin(v8::String::NewFromUtf8(env->GetIsolate(), "2"));
1969
1970   // Set a script break point before the script is loaded.
1971   SetScriptBreakPointByNameFromJS(env->GetIsolate(), "1", 2, 0);
1972
1973   // Compile the script and get the function.
1974   v8::Script::Compile(script, &origin_1)->Run();
1975   f = v8::Local<v8::Function>::Cast(
1976       env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "f")));
1977
1978   // Call f and check that the script break point is active.
1979   break_point_hit_count = 0;
1980   f->Call(env->Global(), 0, NULL);
1981   CHECK_EQ(1, break_point_hit_count);
1982
1983   // Compile the script again with a different script data and get the
1984   // function.
1985   v8::Script::Compile(script, &origin_2)->Run();
1986   f = v8::Local<v8::Function>::Cast(
1987       env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "f")));
1988
1989   // Call f and check that no break points are set.
1990   break_point_hit_count = 0;
1991   f->Call(env->Global(), 0, NULL);
1992   CHECK_EQ(0, break_point_hit_count);
1993
1994   // Compile the script again and get the function.
1995   v8::Script::Compile(script, &origin_1)->Run();
1996   f = v8::Local<v8::Function>::Cast(
1997       env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "f")));
1998
1999   // Call f and check that the script break point is active.
2000   break_point_hit_count = 0;
2001   f->Call(env->Global(), 0, NULL);
2002   CHECK_EQ(1, break_point_hit_count);
2003
2004   v8::Debug::SetDebugEventListener2(NULL);
2005   CheckDebuggerUnloaded();
2006 }
2007
2008
2009 // Test when several scripts has the same script data
2010 TEST(ScriptBreakPointMultiple) {
2011   break_point_hit_count = 0;
2012   DebugLocalContext env;
2013   v8::HandleScope scope(env->GetIsolate());
2014   env.ExposeDebug();
2015
2016   v8::Debug::SetDebugEventListener2(DebugEventBreakPointHitCount);
2017
2018   v8::Local<v8::Function> f;
2019   v8::Local<v8::String> script_f =
2020       v8::String::NewFromUtf8(env->GetIsolate(),
2021                               "function f() {\n"
2022                               "  a = 0;  // line 1\n"
2023                               "}");
2024
2025   v8::Local<v8::Function> g;
2026   v8::Local<v8::String> script_g =
2027       v8::String::NewFromUtf8(env->GetIsolate(),
2028                               "function g() {\n"
2029                               "  b = 0;  // line 1\n"
2030                               "}");
2031
2032   v8::ScriptOrigin origin =
2033       v8::ScriptOrigin(v8::String::NewFromUtf8(env->GetIsolate(), "test"));
2034
2035   // Set a script break point before the scripts are loaded.
2036   int sbp = SetScriptBreakPointByNameFromJS(env->GetIsolate(), "test", 1, 0);
2037
2038   // Compile the scripts with same script data and get the functions.
2039   v8::Script::Compile(script_f, &origin)->Run();
2040   f = v8::Local<v8::Function>::Cast(
2041       env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "f")));
2042   v8::Script::Compile(script_g, &origin)->Run();
2043   g = v8::Local<v8::Function>::Cast(
2044       env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "g")));
2045
2046   // Call f and g and check that the script break point is active.
2047   break_point_hit_count = 0;
2048   f->Call(env->Global(), 0, NULL);
2049   CHECK_EQ(1, break_point_hit_count);
2050   g->Call(env->Global(), 0, NULL);
2051   CHECK_EQ(2, break_point_hit_count);
2052
2053   // Clear the script break point.
2054   ClearBreakPointFromJS(env->GetIsolate(), sbp);
2055
2056   // Call f and g and check that the script break point is no longer active.
2057   break_point_hit_count = 0;
2058   f->Call(env->Global(), 0, NULL);
2059   CHECK_EQ(0, break_point_hit_count);
2060   g->Call(env->Global(), 0, NULL);
2061   CHECK_EQ(0, break_point_hit_count);
2062
2063   // Set script break point with the scripts loaded.
2064   sbp = SetScriptBreakPointByNameFromJS(env->GetIsolate(), "test", 1, 0);
2065
2066   // Call f and g and check that the script break point is active.
2067   break_point_hit_count = 0;
2068   f->Call(env->Global(), 0, NULL);
2069   CHECK_EQ(1, break_point_hit_count);
2070   g->Call(env->Global(), 0, NULL);
2071   CHECK_EQ(2, break_point_hit_count);
2072
2073   v8::Debug::SetDebugEventListener2(NULL);
2074   CheckDebuggerUnloaded();
2075 }
2076
2077
2078 // Test the script origin which has both name and line offset.
2079 TEST(ScriptBreakPointLineOffset) {
2080   break_point_hit_count = 0;
2081   DebugLocalContext env;
2082   v8::HandleScope scope(env->GetIsolate());
2083   env.ExposeDebug();
2084
2085   v8::Debug::SetDebugEventListener2(DebugEventBreakPointHitCount);
2086
2087   v8::Local<v8::Function> f;
2088   v8::Local<v8::String> script = v8::String::NewFromUtf8(
2089       env->GetIsolate(),
2090       "function f() {\n"
2091       "  a = 0;  // line 8 as this script has line offset 7\n"
2092       "  b = 0;  // line 9 as this script has line offset 7\n"
2093       "}");
2094
2095   // Create script origin both name and line offset.
2096   v8::ScriptOrigin origin(
2097       v8::String::NewFromUtf8(env->GetIsolate(), "test.html"),
2098       v8::Integer::New(env->GetIsolate(), 7));
2099
2100   // Set two script break points before the script is loaded.
2101   int sbp1 =
2102       SetScriptBreakPointByNameFromJS(env->GetIsolate(), "test.html", 8, 0);
2103   int sbp2 =
2104       SetScriptBreakPointByNameFromJS(env->GetIsolate(), "test.html", 9, 0);
2105
2106   // Compile the script and get the function.
2107   v8::Script::Compile(script, &origin)->Run();
2108   f = v8::Local<v8::Function>::Cast(
2109       env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "f")));
2110
2111   // Call f and check that the script break point is active.
2112   break_point_hit_count = 0;
2113   f->Call(env->Global(), 0, NULL);
2114   CHECK_EQ(2, break_point_hit_count);
2115
2116   // Clear the script break points.
2117   ClearBreakPointFromJS(env->GetIsolate(), sbp1);
2118   ClearBreakPointFromJS(env->GetIsolate(), sbp2);
2119
2120   // Call f and check that no script break points are active.
2121   break_point_hit_count = 0;
2122   f->Call(env->Global(), 0, NULL);
2123   CHECK_EQ(0, break_point_hit_count);
2124
2125   // Set a script break point with the script loaded.
2126   sbp1 = SetScriptBreakPointByNameFromJS(env->GetIsolate(), "test.html", 9, 0);
2127
2128   // Call f and check that the script break point is active.
2129   break_point_hit_count = 0;
2130   f->Call(env->Global(), 0, NULL);
2131   CHECK_EQ(1, break_point_hit_count);
2132
2133   v8::Debug::SetDebugEventListener2(NULL);
2134   CheckDebuggerUnloaded();
2135 }
2136
2137
2138 // Test script break points set on lines.
2139 TEST(ScriptBreakPointLine) {
2140   DebugLocalContext env;
2141   v8::HandleScope scope(env->GetIsolate());
2142   env.ExposeDebug();
2143
2144   // Create a function for checking the function when hitting a break point.
2145   frame_function_name = CompileFunction(&env,
2146                                         frame_function_name_source,
2147                                         "frame_function_name");
2148
2149   v8::Debug::SetDebugEventListener2(DebugEventBreakPointHitCount);
2150
2151   v8::Local<v8::Function> f;
2152   v8::Local<v8::Function> g;
2153   v8::Local<v8::String> script =
2154       v8::String::NewFromUtf8(env->GetIsolate(),
2155                               "a = 0                      // line 0\n"
2156                               "function f() {\n"
2157                               "  a = 1;                   // line 2\n"
2158                               "}\n"
2159                               " a = 2;                    // line 4\n"
2160                               "  /* xx */ function g() {  // line 5\n"
2161                               "    function h() {         // line 6\n"
2162                               "      a = 3;               // line 7\n"
2163                               "    }\n"
2164                               "    h();                   // line 9\n"
2165                               "    a = 4;                 // line 10\n"
2166                               "  }\n"
2167                               " a=5;                      // line 12");
2168
2169   // Set a couple script break point before the script is loaded.
2170   int sbp1 =
2171       SetScriptBreakPointByNameFromJS(env->GetIsolate(), "test.html", 0, -1);
2172   int sbp2 =
2173       SetScriptBreakPointByNameFromJS(env->GetIsolate(), "test.html", 1, -1);
2174   int sbp3 =
2175       SetScriptBreakPointByNameFromJS(env->GetIsolate(), "test.html", 5, -1);
2176
2177   // Compile the script and get the function.
2178   break_point_hit_count = 0;
2179   v8::ScriptOrigin origin(
2180       v8::String::NewFromUtf8(env->GetIsolate(), "test.html"),
2181       v8::Integer::New(env->GetIsolate(), 0));
2182   v8::Script::Compile(script, &origin)->Run();
2183   f = v8::Local<v8::Function>::Cast(
2184       env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "f")));
2185   g = v8::Local<v8::Function>::Cast(
2186       env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "g")));
2187
2188   // Check that a break point was hit when the script was run.
2189   CHECK_EQ(1, break_point_hit_count);
2190   CHECK_EQ(0, StrLength(last_function_hit));
2191
2192   // Call f and check that the script break point.
2193   f->Call(env->Global(), 0, NULL);
2194   CHECK_EQ(2, break_point_hit_count);
2195   CHECK_EQ("f", last_function_hit);
2196
2197   // Call g and check that the script break point.
2198   g->Call(env->Global(), 0, NULL);
2199   CHECK_EQ(3, break_point_hit_count);
2200   CHECK_EQ("g", last_function_hit);
2201
2202   // Clear the script break point on g and set one on h.
2203   ClearBreakPointFromJS(env->GetIsolate(), sbp3);
2204   int sbp4 =
2205       SetScriptBreakPointByNameFromJS(env->GetIsolate(), "test.html", 6, -1);
2206
2207   // Call g and check that the script break point in h is hit.
2208   g->Call(env->Global(), 0, NULL);
2209   CHECK_EQ(4, break_point_hit_count);
2210   CHECK_EQ("h", last_function_hit);
2211
2212   // Clear break points in f and h. Set a new one in the script between
2213   // functions f and g and test that there is no break points in f and g any
2214   // more.
2215   ClearBreakPointFromJS(env->GetIsolate(), sbp2);
2216   ClearBreakPointFromJS(env->GetIsolate(), sbp4);
2217   int sbp5 =
2218       SetScriptBreakPointByNameFromJS(env->GetIsolate(), "test.html", 4, -1);
2219   break_point_hit_count = 0;
2220   f->Call(env->Global(), 0, NULL);
2221   g->Call(env->Global(), 0, NULL);
2222   CHECK_EQ(0, break_point_hit_count);
2223
2224   // Reload the script which should hit two break points.
2225   break_point_hit_count = 0;
2226   v8::Script::Compile(script, &origin)->Run();
2227   CHECK_EQ(2, break_point_hit_count);
2228   CHECK_EQ(0, StrLength(last_function_hit));
2229
2230   // Set a break point in the code after the last function decleration.
2231   int sbp6 =
2232       SetScriptBreakPointByNameFromJS(env->GetIsolate(), "test.html", 12, -1);
2233
2234   // Reload the script which should hit three break points.
2235   break_point_hit_count = 0;
2236   v8::Script::Compile(script, &origin)->Run();
2237   CHECK_EQ(3, break_point_hit_count);
2238   CHECK_EQ(0, StrLength(last_function_hit));
2239
2240   // Clear the last break points, and reload the script which should not hit any
2241   // break points.
2242   ClearBreakPointFromJS(env->GetIsolate(), sbp1);
2243   ClearBreakPointFromJS(env->GetIsolate(), sbp5);
2244   ClearBreakPointFromJS(env->GetIsolate(), sbp6);
2245   break_point_hit_count = 0;
2246   v8::Script::Compile(script, &origin)->Run();
2247   CHECK_EQ(0, break_point_hit_count);
2248
2249   v8::Debug::SetDebugEventListener2(NULL);
2250   CheckDebuggerUnloaded();
2251 }
2252
2253
2254 // Test top level script break points set on lines.
2255 TEST(ScriptBreakPointLineTopLevel) {
2256   DebugLocalContext env;
2257   v8::HandleScope scope(env->GetIsolate());
2258   env.ExposeDebug();
2259
2260   v8::Debug::SetDebugEventListener2(DebugEventBreakPointHitCount);
2261
2262   v8::Local<v8::String> script =
2263       v8::String::NewFromUtf8(env->GetIsolate(),
2264                               "function f() {\n"
2265                               "  a = 1;                   // line 1\n"
2266                               "}\n"
2267                               "a = 2;                     // line 3\n");
2268   v8::Local<v8::Function> f;
2269   {
2270     v8::HandleScope scope(env->GetIsolate());
2271     v8::Script::Compile(
2272         script, v8::String::NewFromUtf8(env->GetIsolate(), "test.html"))->Run();
2273   }
2274   f = v8::Local<v8::Function>::Cast(
2275       env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "f")));
2276
2277   CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags);
2278
2279   SetScriptBreakPointByNameFromJS(env->GetIsolate(), "test.html", 3, -1);
2280
2281   // Call f and check that there was no break points.
2282   break_point_hit_count = 0;
2283   f->Call(env->Global(), 0, NULL);
2284   CHECK_EQ(0, break_point_hit_count);
2285
2286   // Recompile and run script and check that break point was hit.
2287   break_point_hit_count = 0;
2288   v8::Script::Compile(
2289       script, v8::String::NewFromUtf8(env->GetIsolate(), "test.html"))->Run();
2290   CHECK_EQ(1, break_point_hit_count);
2291
2292   // Call f and check that there are still no break points.
2293   break_point_hit_count = 0;
2294   f = v8::Local<v8::Function>::Cast(
2295       env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "f")));
2296   CHECK_EQ(0, break_point_hit_count);
2297
2298   v8::Debug::SetDebugEventListener2(NULL);
2299   CheckDebuggerUnloaded();
2300 }
2301
2302
2303 // Test that it is possible to add and remove break points in a top level
2304 // function which has no references but has not been collected yet.
2305 TEST(ScriptBreakPointTopLevelCrash) {
2306   DebugLocalContext env;
2307   v8::HandleScope scope(env->GetIsolate());
2308   env.ExposeDebug();
2309
2310   v8::Debug::SetDebugEventListener2(DebugEventBreakPointHitCount);
2311
2312   v8::Local<v8::String> script_source =
2313       v8::String::NewFromUtf8(env->GetIsolate(),
2314                               "function f() {\n"
2315                               "  return 0;\n"
2316                               "}\n"
2317                               "f()");
2318
2319   int sbp1 =
2320       SetScriptBreakPointByNameFromJS(env->GetIsolate(), "test.html", 3, -1);
2321   {
2322     v8::HandleScope scope(env->GetIsolate());
2323     break_point_hit_count = 0;
2324     v8::Script::Compile(script_source,
2325                         v8::String::NewFromUtf8(env->GetIsolate(), "test.html"))
2326         ->Run();
2327     CHECK_EQ(1, break_point_hit_count);
2328   }
2329
2330   int sbp2 =
2331       SetScriptBreakPointByNameFromJS(env->GetIsolate(), "test.html", 3, -1);
2332   ClearBreakPointFromJS(env->GetIsolate(), sbp1);
2333   ClearBreakPointFromJS(env->GetIsolate(), sbp2);
2334
2335   v8::Debug::SetDebugEventListener2(NULL);
2336   CheckDebuggerUnloaded();
2337 }
2338
2339
2340 // Test that it is possible to remove the last break point for a function
2341 // inside the break handling of that break point.
2342 TEST(RemoveBreakPointInBreak) {
2343   DebugLocalContext env;
2344   v8::HandleScope scope(env->GetIsolate());
2345
2346   v8::Local<v8::Function> foo =
2347       CompileFunction(&env, "function foo(){a=1;}", "foo");
2348   debug_event_remove_break_point = SetBreakPoint(foo, 0);
2349
2350   // Register the debug event listener pasing the function
2351   v8::Debug::SetDebugEventListener2(DebugEventRemoveBreakPoint, foo);
2352
2353   break_point_hit_count = 0;
2354   foo->Call(env->Global(), 0, NULL);
2355   CHECK_EQ(1, break_point_hit_count);
2356
2357   break_point_hit_count = 0;
2358   foo->Call(env->Global(), 0, NULL);
2359   CHECK_EQ(0, break_point_hit_count);
2360
2361   v8::Debug::SetDebugEventListener2(NULL);
2362   CheckDebuggerUnloaded();
2363 }
2364
2365
2366 // Test that the debugger statement causes a break.
2367 TEST(DebuggerStatement) {
2368   break_point_hit_count = 0;
2369   DebugLocalContext env;
2370   v8::HandleScope scope(env->GetIsolate());
2371   v8::Debug::SetDebugEventListener2(DebugEventBreakPointHitCount);
2372   v8::Script::Compile(
2373       v8::String::NewFromUtf8(env->GetIsolate(), "function bar(){debugger}"))
2374       ->Run();
2375   v8::Script::Compile(
2376       v8::String::NewFromUtf8(env->GetIsolate(),
2377                               "function foo(){debugger;debugger;}"))->Run();
2378   v8::Local<v8::Function> foo = v8::Local<v8::Function>::Cast(
2379       env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "foo")));
2380   v8::Local<v8::Function> bar = v8::Local<v8::Function>::Cast(
2381       env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "bar")));
2382
2383   // Run function with debugger statement
2384   bar->Call(env->Global(), 0, NULL);
2385   CHECK_EQ(1, break_point_hit_count);
2386
2387   // Run function with two debugger statement
2388   foo->Call(env->Global(), 0, NULL);
2389   CHECK_EQ(3, break_point_hit_count);
2390
2391   v8::Debug::SetDebugEventListener2(NULL);
2392   CheckDebuggerUnloaded();
2393 }
2394
2395
2396 // Test setting a breakpoint on the debugger statement.
2397 TEST(DebuggerStatementBreakpoint) {
2398     break_point_hit_count = 0;
2399     DebugLocalContext env;
2400     v8::HandleScope scope(env->GetIsolate());
2401     v8::Debug::SetDebugEventListener2(DebugEventBreakPointHitCount);
2402     v8::Script::Compile(
2403         v8::String::NewFromUtf8(env->GetIsolate(), "function foo(){debugger;}"))
2404         ->Run();
2405     v8::Local<v8::Function> foo = v8::Local<v8::Function>::Cast(
2406         env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "foo")));
2407
2408     // The debugger statement triggers breakpint hit
2409     foo->Call(env->Global(), 0, NULL);
2410     CHECK_EQ(1, break_point_hit_count);
2411
2412     int bp = SetBreakPoint(foo, 0);
2413
2414     // Set breakpoint does not duplicate hits
2415     foo->Call(env->Global(), 0, NULL);
2416     CHECK_EQ(2, break_point_hit_count);
2417
2418     ClearBreakPoint(bp);
2419     v8::Debug::SetDebugEventListener2(NULL);
2420     CheckDebuggerUnloaded();
2421 }
2422
2423
2424 // Test that the evaluation of expressions when a break point is hit generates
2425 // the correct results.
2426 TEST(DebugEvaluate) {
2427   DebugLocalContext env;
2428   v8::Isolate* isolate = env->GetIsolate();
2429   v8::HandleScope scope(isolate);
2430   env.ExposeDebug();
2431
2432   // Create a function for checking the evaluation when hitting a break point.
2433   evaluate_check_function = CompileFunction(&env,
2434                                             evaluate_check_source,
2435                                             "evaluate_check");
2436   // Register the debug event listener
2437   v8::Debug::SetDebugEventListener2(DebugEventEvaluate);
2438
2439   // Different expected vaules of x and a when in a break point (u = undefined,
2440   // d = Hello, world!).
2441   struct EvaluateCheck checks_uu[] = {
2442     {"x", v8::Undefined(isolate)},
2443     {"a", v8::Undefined(isolate)},
2444     {NULL, v8::Handle<v8::Value>()}
2445   };
2446   struct EvaluateCheck checks_hu[] = {
2447     {"x", v8::String::NewFromUtf8(env->GetIsolate(), "Hello, world!")},
2448     {"a", v8::Undefined(isolate)},
2449     {NULL, v8::Handle<v8::Value>()}
2450   };
2451   struct EvaluateCheck checks_hh[] = {
2452     {"x", v8::String::NewFromUtf8(env->GetIsolate(), "Hello, world!")},
2453     {"a", v8::String::NewFromUtf8(env->GetIsolate(), "Hello, world!")},
2454     {NULL, v8::Handle<v8::Value>()}
2455   };
2456
2457   // Simple test function. The "y=0" is in the function foo to provide a break
2458   // location. For "y=0" the "y" is at position 15 in the barbar function
2459   // therefore setting breakpoint at position 15 will break at "y=0" and
2460   // setting it higher will break after.
2461   v8::Local<v8::Function> foo = CompileFunction(&env,
2462     "function foo(x) {"
2463     "  var a;"
2464     "  y=0;"  // To ensure break location 1.
2465     "  a=x;"
2466     "  y=0;"  // To ensure break location 2.
2467     "}",
2468     "foo");
2469   const int foo_break_position_1 = 15;
2470   const int foo_break_position_2 = 29;
2471
2472   // Arguments with one parameter "Hello, world!"
2473   v8::Handle<v8::Value> argv_foo[1] = {
2474       v8::String::NewFromUtf8(env->GetIsolate(), "Hello, world!")};
2475
2476   // Call foo with breakpoint set before a=x and undefined as parameter.
2477   int bp = SetBreakPoint(foo, foo_break_position_1);
2478   checks = checks_uu;
2479   foo->Call(env->Global(), 0, NULL);
2480
2481   // Call foo with breakpoint set before a=x and parameter "Hello, world!".
2482   checks = checks_hu;
2483   foo->Call(env->Global(), 1, argv_foo);
2484
2485   // Call foo with breakpoint set after a=x and parameter "Hello, world!".
2486   ClearBreakPoint(bp);
2487   SetBreakPoint(foo, foo_break_position_2);
2488   checks = checks_hh;
2489   foo->Call(env->Global(), 1, argv_foo);
2490
2491   // Test function with an inner function. The "y=0" is in function barbar
2492   // to provide a break location. For "y=0" the "y" is at position 8 in the
2493   // barbar function therefore setting breakpoint at position 8 will break at
2494   // "y=0" and setting it higher will break after.
2495   v8::Local<v8::Function> bar = CompileFunction(&env,
2496     "y = 0;"
2497     "x = 'Goodbye, world!';"
2498     "function bar(x, b) {"
2499     "  var a;"
2500     "  function barbar() {"
2501     "    y=0; /* To ensure break location.*/"
2502     "    a=x;"
2503     "  };"
2504     "  debug.Debug.clearAllBreakPoints();"
2505     "  barbar();"
2506     "  y=0;a=x;"
2507     "}",
2508     "bar");
2509   const int barbar_break_position = 8;
2510
2511   // Call bar setting breakpoint before a=x in barbar and undefined as
2512   // parameter.
2513   checks = checks_uu;
2514   v8::Handle<v8::Value> argv_bar_1[2] = {
2515     v8::Undefined(isolate),
2516     v8::Number::New(isolate, barbar_break_position)
2517   };
2518   bar->Call(env->Global(), 2, argv_bar_1);
2519
2520   // Call bar setting breakpoint before a=x in barbar and parameter
2521   // "Hello, world!".
2522   checks = checks_hu;
2523   v8::Handle<v8::Value> argv_bar_2[2] = {
2524     v8::String::NewFromUtf8(env->GetIsolate(), "Hello, world!"),
2525     v8::Number::New(env->GetIsolate(), barbar_break_position)
2526   };
2527   bar->Call(env->Global(), 2, argv_bar_2);
2528
2529   // Call bar setting breakpoint after a=x in barbar and parameter
2530   // "Hello, world!".
2531   checks = checks_hh;
2532   v8::Handle<v8::Value> argv_bar_3[2] = {
2533     v8::String::NewFromUtf8(env->GetIsolate(), "Hello, world!"),
2534     v8::Number::New(env->GetIsolate(), barbar_break_position + 1)
2535   };
2536   bar->Call(env->Global(), 2, argv_bar_3);
2537
2538   v8::Debug::SetDebugEventListener2(NULL);
2539   CheckDebuggerUnloaded();
2540 }
2541
2542
2543 int debugEventCount = 0;
2544 static void CheckDebugEvent(const v8::Debug::EventDetails& eventDetails) {
2545   if (eventDetails.GetEvent() == v8::Break) ++debugEventCount;
2546 }
2547
2548
2549 // Test that the conditional breakpoints work event if code generation from
2550 // strings is prohibited in the debugee context.
2551 TEST(ConditionalBreakpointWithCodeGenerationDisallowed) {
2552   DebugLocalContext env;
2553   v8::HandleScope scope(env->GetIsolate());
2554   env.ExposeDebug();
2555
2556   v8::Debug::SetDebugEventListener2(CheckDebugEvent);
2557
2558   v8::Local<v8::Function> foo = CompileFunction(&env,
2559     "function foo(x) {\n"
2560     "  var s = 'String value2';\n"
2561     "  return s + x;\n"
2562     "}",
2563     "foo");
2564
2565   // Set conditional breakpoint with condition 'true'.
2566   CompileRun("debug.Debug.setBreakPoint(foo, 2, 0, 'true')");
2567
2568   debugEventCount = 0;
2569   env->AllowCodeGenerationFromStrings(false);
2570   foo->Call(env->Global(), 0, NULL);
2571   CHECK_EQ(1, debugEventCount);
2572
2573   v8::Debug::SetDebugEventListener2(NULL);
2574   CheckDebuggerUnloaded();
2575 }
2576
2577
2578 bool checkedDebugEvals = true;
2579 v8::Handle<v8::Function> checkGlobalEvalFunction;
2580 v8::Handle<v8::Function> checkFrameEvalFunction;
2581 static void CheckDebugEval(const v8::Debug::EventDetails& eventDetails) {
2582   if (eventDetails.GetEvent() == v8::Break) {
2583     ++debugEventCount;
2584     v8::HandleScope handleScope(CcTest::isolate());
2585
2586     v8::Handle<v8::Value> args[] = { eventDetails.GetExecutionState() };
2587     CHECK(checkGlobalEvalFunction->Call(
2588         eventDetails.GetEventContext()->Global(), 1, args)->IsTrue());
2589     CHECK(checkFrameEvalFunction->Call(
2590         eventDetails.GetEventContext()->Global(), 1, args)->IsTrue());
2591   }
2592 }
2593
2594
2595 // Test that the evaluation of expressions when a break point is hit generates
2596 // the correct results in case code generation from strings is disallowed in the
2597 // debugee context.
2598 TEST(DebugEvaluateWithCodeGenerationDisallowed) {
2599   DebugLocalContext env;
2600   v8::HandleScope scope(env->GetIsolate());
2601   env.ExposeDebug();
2602
2603   v8::Debug::SetDebugEventListener2(CheckDebugEval);
2604
2605   v8::Local<v8::Function> foo = CompileFunction(&env,
2606     "var global = 'Global';\n"
2607     "function foo(x) {\n"
2608     "  var local = 'Local';\n"
2609     "  debugger;\n"
2610     "  return local + x;\n"
2611     "}",
2612     "foo");
2613   checkGlobalEvalFunction = CompileFunction(&env,
2614     "function checkGlobalEval(exec_state) {\n"
2615     "  return exec_state.evaluateGlobal('global').value() === 'Global';\n"
2616     "}",
2617     "checkGlobalEval");
2618
2619   checkFrameEvalFunction = CompileFunction(&env,
2620     "function checkFrameEval(exec_state) {\n"
2621     "  return exec_state.frame(0).evaluate('local').value() === 'Local';\n"
2622     "}",
2623     "checkFrameEval");
2624   debugEventCount = 0;
2625   env->AllowCodeGenerationFromStrings(false);
2626   foo->Call(env->Global(), 0, NULL);
2627   CHECK_EQ(1, debugEventCount);
2628
2629   checkGlobalEvalFunction.Clear();
2630   checkFrameEvalFunction.Clear();
2631   v8::Debug::SetDebugEventListener2(NULL);
2632   CheckDebuggerUnloaded();
2633 }
2634
2635
2636 // Copies a C string to a 16-bit string.  Does not check for buffer overflow.
2637 // Does not use the V8 engine to convert strings, so it can be used
2638 // in any thread.  Returns the length of the string.
2639 int AsciiToUtf16(const char* input_buffer, uint16_t* output_buffer) {
2640   int i;
2641   for (i = 0; input_buffer[i] != '\0'; ++i) {
2642     // ASCII does not use chars > 127, but be careful anyway.
2643     output_buffer[i] = static_cast<unsigned char>(input_buffer[i]);
2644   }
2645   output_buffer[i] = 0;
2646   return i;
2647 }
2648
2649
2650 // Copies a 16-bit string to a C string by dropping the high byte of
2651 // each character.  Does not check for buffer overflow.
2652 // Can be used in any thread.  Requires string length as an input.
2653 int Utf16ToAscii(const uint16_t* input_buffer, int length,
2654                  char* output_buffer, int output_len = -1) {
2655   if (output_len >= 0) {
2656     if (length > output_len - 1) {
2657       length = output_len - 1;
2658     }
2659   }
2660
2661   for (int i = 0; i < length; ++i) {
2662     output_buffer[i] = static_cast<char>(input_buffer[i]);
2663   }
2664   output_buffer[length] = '\0';
2665   return length;
2666 }
2667
2668
2669 // We match parts of the message to get evaluate result int value.
2670 bool GetEvaluateStringResult(char *message, char* buffer, int buffer_size) {
2671   if (strstr(message, "\"command\":\"evaluate\"") == NULL) {
2672     return false;
2673   }
2674   const char* prefix = "\"text\":\"";
2675   char* pos1 = strstr(message, prefix);
2676   if (pos1 == NULL) {
2677     return false;
2678   }
2679   pos1 += strlen(prefix);
2680   char* pos2 = strchr(pos1, '"');
2681   if (pos2 == NULL) {
2682     return false;
2683   }
2684   Vector<char> buf(buffer, buffer_size);
2685   int len = static_cast<int>(pos2 - pos1);
2686   if (len > buffer_size - 1) {
2687     len = buffer_size - 1;
2688   }
2689   OS::StrNCpy(buf, pos1, len);
2690   buffer[buffer_size - 1] = '\0';
2691   return true;
2692 }
2693
2694
2695 struct EvaluateResult {
2696   static const int kBufferSize = 20;
2697   char buffer[kBufferSize];
2698 };
2699
2700 struct DebugProcessDebugMessagesData {
2701   static const int kArraySize = 5;
2702   int counter;
2703   EvaluateResult results[kArraySize];
2704
2705   void reset() {
2706     counter = 0;
2707   }
2708   EvaluateResult* current() {
2709     return &results[counter % kArraySize];
2710   }
2711   void next() {
2712     counter++;
2713   }
2714 };
2715
2716 DebugProcessDebugMessagesData process_debug_messages_data;
2717
2718 static void DebugProcessDebugMessagesHandler(
2719     const v8::Debug::Message& message) {
2720   v8::Handle<v8::String> json = message.GetJSON();
2721   v8::String::Utf8Value utf8(json);
2722   EvaluateResult* array_item = process_debug_messages_data.current();
2723
2724   bool res = GetEvaluateStringResult(*utf8,
2725                                      array_item->buffer,
2726                                      EvaluateResult::kBufferSize);
2727   if (res) {
2728     process_debug_messages_data.next();
2729   }
2730 }
2731
2732
2733 // Test that the evaluation of expressions works even from ProcessDebugMessages
2734 // i.e. with empty stack.
2735 TEST(DebugEvaluateWithoutStack) {
2736   v8::Debug::SetMessageHandler2(DebugProcessDebugMessagesHandler);
2737
2738   DebugLocalContext env;
2739   v8::HandleScope scope(env->GetIsolate());
2740
2741   const char* source =
2742       "var v1 = 'Pinguin';\n function getAnimal() { return 'Capy' + 'bara'; }";
2743
2744   v8::Script::Compile(v8::String::NewFromUtf8(env->GetIsolate(), source))
2745       ->Run();
2746
2747   v8::Debug::ProcessDebugMessages();
2748
2749   const int kBufferSize = 1000;
2750   uint16_t buffer[kBufferSize];
2751
2752   const char* command_111 = "{\"seq\":111,"
2753       "\"type\":\"request\","
2754       "\"command\":\"evaluate\","
2755       "\"arguments\":{"
2756       "    \"global\":true,"
2757       "    \"expression\":\"v1\",\"disable_break\":true"
2758       "}}";
2759
2760   v8::Isolate* isolate = CcTest::isolate();
2761   v8::Debug::SendCommand(isolate, buffer, AsciiToUtf16(command_111, buffer));
2762
2763   const char* command_112 = "{\"seq\":112,"
2764       "\"type\":\"request\","
2765       "\"command\":\"evaluate\","
2766       "\"arguments\":{"
2767       "    \"global\":true,"
2768       "    \"expression\":\"getAnimal()\",\"disable_break\":true"
2769       "}}";
2770
2771   v8::Debug::SendCommand(isolate, buffer, AsciiToUtf16(command_112, buffer));
2772
2773   const char* command_113 = "{\"seq\":113,"
2774      "\"type\":\"request\","
2775      "\"command\":\"evaluate\","
2776      "\"arguments\":{"
2777      "    \"global\":true,"
2778      "    \"expression\":\"239 + 566\",\"disable_break\":true"
2779      "}}";
2780
2781   v8::Debug::SendCommand(isolate, buffer, AsciiToUtf16(command_113, buffer));
2782
2783   v8::Debug::ProcessDebugMessages();
2784
2785   CHECK_EQ(3, process_debug_messages_data.counter);
2786
2787   CHECK_EQ(strcmp("Pinguin", process_debug_messages_data.results[0].buffer), 0);
2788   CHECK_EQ(strcmp("Capybara", process_debug_messages_data.results[1].buffer),
2789            0);
2790   CHECK_EQ(strcmp("805", process_debug_messages_data.results[2].buffer), 0);
2791
2792   v8::Debug::SetMessageHandler2(NULL);
2793   v8::Debug::SetDebugEventListener2(NULL);
2794   CheckDebuggerUnloaded();
2795 }
2796
2797
2798 // Simple test of the stepping mechanism using only store ICs.
2799 TEST(DebugStepLinear) {
2800   DebugLocalContext env;
2801   v8::HandleScope scope(env->GetIsolate());
2802
2803   // Create a function for testing stepping.
2804   v8::Local<v8::Function> foo = CompileFunction(&env,
2805                                                 "function foo(){a=1;b=1;c=1;}",
2806                                                 "foo");
2807
2808   // Run foo to allow it to get optimized.
2809   CompileRun("a=0; b=0; c=0; foo();");
2810
2811   SetBreakPoint(foo, 3);
2812
2813   // Register a debug event listener which steps and counts.
2814   v8::Debug::SetDebugEventListener2(DebugEventStep);
2815
2816   step_action = StepIn;
2817   break_point_hit_count = 0;
2818   foo->Call(env->Global(), 0, NULL);
2819
2820   // With stepping all break locations are hit.
2821   CHECK_EQ(4, break_point_hit_count);
2822
2823   v8::Debug::SetDebugEventListener2(NULL);
2824   CheckDebuggerUnloaded();
2825
2826   // Register a debug event listener which just counts.
2827   v8::Debug::SetDebugEventListener2(DebugEventBreakPointHitCount);
2828
2829   SetBreakPoint(foo, 3);
2830   break_point_hit_count = 0;
2831   foo->Call(env->Global(), 0, NULL);
2832
2833   // Without stepping only active break points are hit.
2834   CHECK_EQ(1, break_point_hit_count);
2835
2836   v8::Debug::SetDebugEventListener2(NULL);
2837   CheckDebuggerUnloaded();
2838 }
2839
2840
2841 // Test of the stepping mechanism for keyed load in a loop.
2842 TEST(DebugStepKeyedLoadLoop) {
2843   DebugLocalContext env;
2844   v8::HandleScope scope(env->GetIsolate());
2845
2846   // Register a debug event listener which steps and counts.
2847   v8::Debug::SetDebugEventListener2(DebugEventStep);
2848
2849   // Create a function for testing stepping of keyed load. The statement 'y=1'
2850   // is there to have more than one breakable statement in the loop, TODO(315).
2851   v8::Local<v8::Function> foo = CompileFunction(
2852       &env,
2853       "function foo(a) {\n"
2854       "  var x;\n"
2855       "  var len = a.length;\n"
2856       "  for (var i = 0; i < len; i++) {\n"
2857       "    y = 1;\n"
2858       "    x = a[i];\n"
2859       "  }\n"
2860       "}\n"
2861       "y=0\n",
2862       "foo");
2863
2864   // Create array [0,1,2,3,4,5,6,7,8,9]
2865   v8::Local<v8::Array> a = v8::Array::New(env->GetIsolate(), 10);
2866   for (int i = 0; i < 10; i++) {
2867     a->Set(v8::Number::New(env->GetIsolate(), i),
2868            v8::Number::New(env->GetIsolate(), i));
2869   }
2870
2871   // Call function without any break points to ensure inlining is in place.
2872   const int kArgc = 1;
2873   v8::Handle<v8::Value> args[kArgc] = { a };
2874   foo->Call(env->Global(), kArgc, args);
2875
2876   // Set up break point and step through the function.
2877   SetBreakPoint(foo, 3);
2878   step_action = StepNext;
2879   break_point_hit_count = 0;
2880   foo->Call(env->Global(), kArgc, args);
2881
2882   // With stepping all break locations are hit.
2883   CHECK_EQ(35, break_point_hit_count);
2884
2885   v8::Debug::SetDebugEventListener2(NULL);
2886   CheckDebuggerUnloaded();
2887 }
2888
2889
2890 // Test of the stepping mechanism for keyed store in a loop.
2891 TEST(DebugStepKeyedStoreLoop) {
2892   DebugLocalContext env;
2893   v8::HandleScope scope(env->GetIsolate());
2894
2895   // Register a debug event listener which steps and counts.
2896   v8::Debug::SetDebugEventListener2(DebugEventStep);
2897
2898   // Create a function for testing stepping of keyed store. The statement 'y=1'
2899   // is there to have more than one breakable statement in the loop, TODO(315).
2900   v8::Local<v8::Function> foo = CompileFunction(
2901       &env,
2902       "function foo(a) {\n"
2903       "  var len = a.length;\n"
2904       "  for (var i = 0; i < len; i++) {\n"
2905       "    y = 1;\n"
2906       "    a[i] = 42;\n"
2907       "  }\n"
2908       "}\n"
2909       "y=0\n",
2910       "foo");
2911
2912   // Create array [0,1,2,3,4,5,6,7,8,9]
2913   v8::Local<v8::Array> a = v8::Array::New(env->GetIsolate(), 10);
2914   for (int i = 0; i < 10; i++) {
2915     a->Set(v8::Number::New(env->GetIsolate(), i),
2916            v8::Number::New(env->GetIsolate(), i));
2917   }
2918
2919   // Call function without any break points to ensure inlining is in place.
2920   const int kArgc = 1;
2921   v8::Handle<v8::Value> args[kArgc] = { a };
2922   foo->Call(env->Global(), kArgc, args);
2923
2924   // Set up break point and step through the function.
2925   SetBreakPoint(foo, 3);
2926   step_action = StepNext;
2927   break_point_hit_count = 0;
2928   foo->Call(env->Global(), kArgc, args);
2929
2930   // With stepping all break locations are hit.
2931   CHECK_EQ(34, break_point_hit_count);
2932
2933   v8::Debug::SetDebugEventListener2(NULL);
2934   CheckDebuggerUnloaded();
2935 }
2936
2937
2938 // Test of the stepping mechanism for named load in a loop.
2939 TEST(DebugStepNamedLoadLoop) {
2940   DebugLocalContext env;
2941   v8::HandleScope scope(env->GetIsolate());
2942
2943   // Register a debug event listener which steps and counts.
2944   v8::Debug::SetDebugEventListener2(DebugEventStep);
2945
2946   // Create a function for testing stepping of named load.
2947   v8::Local<v8::Function> foo = CompileFunction(
2948       &env,
2949       "function foo() {\n"
2950           "  var a = [];\n"
2951           "  var s = \"\";\n"
2952           "  for (var i = 0; i < 10; i++) {\n"
2953           "    var v = new V(i, i + 1);\n"
2954           "    v.y;\n"
2955           "    a.length;\n"  // Special case: array length.
2956           "    s.length;\n"  // Special case: string length.
2957           "  }\n"
2958           "}\n"
2959           "function V(x, y) {\n"
2960           "  this.x = x;\n"
2961           "  this.y = y;\n"
2962           "}\n",
2963           "foo");
2964
2965   // Call function without any break points to ensure inlining is in place.
2966   foo->Call(env->Global(), 0, NULL);
2967
2968   // Set up break point and step through the function.
2969   SetBreakPoint(foo, 4);
2970   step_action = StepNext;
2971   break_point_hit_count = 0;
2972   foo->Call(env->Global(), 0, NULL);
2973
2974   // With stepping all break locations are hit.
2975   CHECK_EQ(55, break_point_hit_count);
2976
2977   v8::Debug::SetDebugEventListener2(NULL);
2978   CheckDebuggerUnloaded();
2979 }
2980
2981
2982 static void DoDebugStepNamedStoreLoop(int expected) {
2983   DebugLocalContext env;
2984   v8::HandleScope scope(env->GetIsolate());
2985
2986   // Register a debug event listener which steps and counts.
2987   v8::Debug::SetDebugEventListener2(DebugEventStep);
2988
2989   // Create a function for testing stepping of named store.
2990   v8::Local<v8::Function> foo = CompileFunction(
2991       &env,
2992       "function foo() {\n"
2993           "  var a = {a:1};\n"
2994           "  for (var i = 0; i < 10; i++) {\n"
2995           "    a.a = 2\n"
2996           "  }\n"
2997           "}\n",
2998           "foo");
2999
3000   // Call function without any break points to ensure inlining is in place.
3001   foo->Call(env->Global(), 0, NULL);
3002
3003   // Set up break point and step through the function.
3004   SetBreakPoint(foo, 3);
3005   step_action = StepNext;
3006   break_point_hit_count = 0;
3007   foo->Call(env->Global(), 0, NULL);
3008
3009   // With stepping all expected break locations are hit.
3010   CHECK_EQ(expected, break_point_hit_count);
3011
3012   v8::Debug::SetDebugEventListener2(NULL);
3013   CheckDebuggerUnloaded();
3014 }
3015
3016
3017 // Test of the stepping mechanism for named load in a loop.
3018 TEST(DebugStepNamedStoreLoop) {
3019   DoDebugStepNamedStoreLoop(24);
3020 }
3021
3022
3023 // Test the stepping mechanism with different ICs.
3024 TEST(DebugStepLinearMixedICs) {
3025   DebugLocalContext env;
3026   v8::HandleScope scope(env->GetIsolate());
3027
3028   // Register a debug event listener which steps and counts.
3029   v8::Debug::SetDebugEventListener2(DebugEventStep);
3030
3031   // Create a function for testing stepping.
3032   v8::Local<v8::Function> foo = CompileFunction(&env,
3033       "function bar() {};"
3034       "function foo() {"
3035       "  var x;"
3036       "  var index='name';"
3037       "  var y = {};"
3038       "  a=1;b=2;x=a;y[index]=3;x=y[index];bar();}", "foo");
3039
3040   // Run functions to allow them to get optimized.
3041   CompileRun("a=0; b=0; bar(); foo();");
3042
3043   SetBreakPoint(foo, 0);
3044
3045   step_action = StepIn;
3046   break_point_hit_count = 0;
3047   foo->Call(env->Global(), 0, NULL);
3048
3049   // With stepping all break locations are hit.
3050   CHECK_EQ(11, break_point_hit_count);
3051
3052   v8::Debug::SetDebugEventListener2(NULL);
3053   CheckDebuggerUnloaded();
3054
3055   // Register a debug event listener which just counts.
3056   v8::Debug::SetDebugEventListener2(DebugEventBreakPointHitCount);
3057
3058   SetBreakPoint(foo, 0);
3059   break_point_hit_count = 0;
3060   foo->Call(env->Global(), 0, NULL);
3061
3062   // Without stepping only active break points are hit.
3063   CHECK_EQ(1, break_point_hit_count);
3064
3065   v8::Debug::SetDebugEventListener2(NULL);
3066   CheckDebuggerUnloaded();
3067 }
3068
3069
3070 TEST(DebugStepDeclarations) {
3071   DebugLocalContext env;
3072   v8::HandleScope scope(env->GetIsolate());
3073
3074   // Register a debug event listener which steps and counts.
3075   v8::Debug::SetDebugEventListener2(DebugEventStep);
3076
3077   // Create a function for testing stepping. Run it to allow it to get
3078   // optimized.
3079   const char* src = "function foo() { "
3080                     "  var a;"
3081                     "  var b = 1;"
3082                     "  var c = foo;"
3083                     "  var d = Math.floor;"
3084                     "  var e = b + d(1.2);"
3085                     "}"
3086                     "foo()";
3087   v8::Local<v8::Function> foo = CompileFunction(&env, src, "foo");
3088
3089   SetBreakPoint(foo, 0);
3090
3091   // Stepping through the declarations.
3092   step_action = StepIn;
3093   break_point_hit_count = 0;
3094   foo->Call(env->Global(), 0, NULL);
3095   CHECK_EQ(6, break_point_hit_count);
3096
3097   // Get rid of the debug event listener.
3098   v8::Debug::SetDebugEventListener2(NULL);
3099   CheckDebuggerUnloaded();
3100 }
3101
3102
3103 TEST(DebugStepLocals) {
3104   DebugLocalContext env;
3105   v8::HandleScope scope(env->GetIsolate());
3106
3107   // Register a debug event listener which steps and counts.
3108   v8::Debug::SetDebugEventListener2(DebugEventStep);
3109
3110   // Create a function for testing stepping. Run it to allow it to get
3111   // optimized.
3112   const char* src = "function foo() { "
3113                     "  var a,b;"
3114                     "  a = 1;"
3115                     "  b = a + 2;"
3116                     "  b = 1 + 2 + 3;"
3117                     "  a = Math.floor(b);"
3118                     "}"
3119                     "foo()";
3120   v8::Local<v8::Function> foo = CompileFunction(&env, src, "foo");
3121
3122   SetBreakPoint(foo, 0);
3123
3124   // Stepping through the declarations.
3125   step_action = StepIn;
3126   break_point_hit_count = 0;
3127   foo->Call(env->Global(), 0, NULL);
3128   CHECK_EQ(6, break_point_hit_count);
3129
3130   // Get rid of the debug event listener.
3131   v8::Debug::SetDebugEventListener2(NULL);
3132   CheckDebuggerUnloaded();
3133 }
3134
3135
3136 TEST(DebugStepIf) {
3137   DebugLocalContext env;
3138   v8::Isolate* isolate = env->GetIsolate();
3139   v8::HandleScope scope(isolate);
3140
3141   // Register a debug event listener which steps and counts.
3142   v8::Debug::SetDebugEventListener2(DebugEventStep);
3143
3144   // Create a function for testing stepping. Run it to allow it to get
3145   // optimized.
3146   const int argc = 1;
3147   const char* src = "function foo(x) { "
3148                     "  a = 1;"
3149                     "  if (x) {"
3150                     "    b = 1;"
3151                     "  } else {"
3152                     "    c = 1;"
3153                     "    d = 1;"
3154                     "  }"
3155                     "}"
3156                     "a=0; b=0; c=0; d=0; foo()";
3157   v8::Local<v8::Function> foo = CompileFunction(&env, src, "foo");
3158   SetBreakPoint(foo, 0);
3159
3160   // Stepping through the true part.
3161   step_action = StepIn;
3162   break_point_hit_count = 0;
3163   v8::Handle<v8::Value> argv_true[argc] = { v8::True(isolate) };
3164   foo->Call(env->Global(), argc, argv_true);
3165   CHECK_EQ(4, break_point_hit_count);
3166
3167   // Stepping through the false part.
3168   step_action = StepIn;
3169   break_point_hit_count = 0;
3170   v8::Handle<v8::Value> argv_false[argc] = { v8::False(isolate) };
3171   foo->Call(env->Global(), argc, argv_false);
3172   CHECK_EQ(5, break_point_hit_count);
3173
3174   // Get rid of the debug event listener.
3175   v8::Debug::SetDebugEventListener2(NULL);
3176   CheckDebuggerUnloaded();
3177 }
3178
3179
3180 TEST(DebugStepSwitch) {
3181   DebugLocalContext env;
3182   v8::Isolate* isolate = env->GetIsolate();
3183   v8::HandleScope scope(isolate);
3184
3185   // Register a debug event listener which steps and counts.
3186   v8::Debug::SetDebugEventListener2(DebugEventStep);
3187
3188   // Create a function for testing stepping. Run it to allow it to get
3189   // optimized.
3190   const int argc = 1;
3191   const char* src = "function foo(x) { "
3192                     "  a = 1;"
3193                     "  switch (x) {"
3194                     "    case 1:"
3195                     "      b = 1;"
3196                     "    case 2:"
3197                     "      c = 1;"
3198                     "      break;"
3199                     "    case 3:"
3200                     "      d = 1;"
3201                     "      e = 1;"
3202                     "      f = 1;"
3203                     "      break;"
3204                     "  }"
3205                     "}"
3206                     "a=0; b=0; c=0; d=0; e=0; f=0; foo()";
3207   v8::Local<v8::Function> foo = CompileFunction(&env, src, "foo");
3208   SetBreakPoint(foo, 0);
3209
3210   // One case with fall-through.
3211   step_action = StepIn;
3212   break_point_hit_count = 0;
3213   v8::Handle<v8::Value> argv_1[argc] = { v8::Number::New(isolate, 1) };
3214   foo->Call(env->Global(), argc, argv_1);
3215   CHECK_EQ(6, break_point_hit_count);
3216
3217   // Another case.
3218   step_action = StepIn;
3219   break_point_hit_count = 0;
3220   v8::Handle<v8::Value> argv_2[argc] = { v8::Number::New(isolate, 2) };
3221   foo->Call(env->Global(), argc, argv_2);
3222   CHECK_EQ(5, break_point_hit_count);
3223
3224   // Last case.
3225   step_action = StepIn;
3226   break_point_hit_count = 0;
3227   v8::Handle<v8::Value> argv_3[argc] = { v8::Number::New(isolate, 3) };
3228   foo->Call(env->Global(), argc, argv_3);
3229   CHECK_EQ(7, break_point_hit_count);
3230
3231   // Get rid of the debug event listener.
3232   v8::Debug::SetDebugEventListener2(NULL);
3233   CheckDebuggerUnloaded();
3234 }
3235
3236
3237 TEST(DebugStepWhile) {
3238   DebugLocalContext env;
3239   v8::Isolate* isolate = env->GetIsolate();
3240   v8::HandleScope scope(isolate);
3241
3242   // Register a debug event listener which steps and counts.
3243   v8::Debug::SetDebugEventListener2(DebugEventStep);
3244
3245   // Create a function for testing stepping. Run it to allow it to get
3246   // optimized.
3247   const int argc = 1;
3248   const char* src = "function foo(x) { "
3249                     "  var a = 0;"
3250                     "  while (a < x) {"
3251                     "    a++;"
3252                     "  }"
3253                     "}"
3254                     "foo()";
3255   v8::Local<v8::Function> foo = CompileFunction(&env, src, "foo");
3256   SetBreakPoint(foo, 8);  // "var a = 0;"
3257
3258   // Looping 10 times.
3259   step_action = StepIn;
3260   break_point_hit_count = 0;
3261   v8::Handle<v8::Value> argv_10[argc] = { v8::Number::New(isolate, 10) };
3262   foo->Call(env->Global(), argc, argv_10);
3263   CHECK_EQ(22, break_point_hit_count);
3264
3265   // Looping 100 times.
3266   step_action = StepIn;
3267   break_point_hit_count = 0;
3268   v8::Handle<v8::Value> argv_100[argc] = { v8::Number::New(isolate, 100) };
3269   foo->Call(env->Global(), argc, argv_100);
3270   CHECK_EQ(202, break_point_hit_count);
3271
3272   // Get rid of the debug event listener.
3273   v8::Debug::SetDebugEventListener2(NULL);
3274   CheckDebuggerUnloaded();
3275 }
3276
3277
3278 TEST(DebugStepDoWhile) {
3279   DebugLocalContext env;
3280   v8::Isolate* isolate = env->GetIsolate();
3281   v8::HandleScope scope(isolate);
3282
3283   // Register a debug event listener which steps and counts.
3284   v8::Debug::SetDebugEventListener2(DebugEventStep);
3285
3286   // Create a function for testing stepping. Run it to allow it to get
3287   // optimized.
3288   const int argc = 1;
3289   const char* src = "function foo(x) { "
3290                     "  var a = 0;"
3291                     "  do {"
3292                     "    a++;"
3293                     "  } while (a < x)"
3294                     "}"
3295                     "foo()";
3296   v8::Local<v8::Function> foo = CompileFunction(&env, src, "foo");
3297   SetBreakPoint(foo, 8);  // "var a = 0;"
3298
3299   // Looping 10 times.
3300   step_action = StepIn;
3301   break_point_hit_count = 0;
3302   v8::Handle<v8::Value> argv_10[argc] = { v8::Number::New(isolate, 10) };
3303   foo->Call(env->Global(), argc, argv_10);
3304   CHECK_EQ(22, break_point_hit_count);
3305
3306   // Looping 100 times.
3307   step_action = StepIn;
3308   break_point_hit_count = 0;
3309   v8::Handle<v8::Value> argv_100[argc] = { v8::Number::New(isolate, 100) };
3310   foo->Call(env->Global(), argc, argv_100);
3311   CHECK_EQ(202, break_point_hit_count);
3312
3313   // Get rid of the debug event listener.
3314   v8::Debug::SetDebugEventListener2(NULL);
3315   CheckDebuggerUnloaded();
3316 }
3317
3318
3319 TEST(DebugStepFor) {
3320   DebugLocalContext env;
3321   v8::Isolate* isolate = env->GetIsolate();
3322   v8::HandleScope scope(isolate);
3323
3324   // Register a debug event listener which steps and counts.
3325   v8::Debug::SetDebugEventListener2(DebugEventStep);
3326
3327   // Create a function for testing stepping. Run it to allow it to get
3328   // optimized.
3329   const int argc = 1;
3330   const char* src = "function foo(x) { "
3331                     "  a = 1;"
3332                     "  for (i = 0; i < x; i++) {"
3333                     "    b = 1;"
3334                     "  }"
3335                     "}"
3336                     "a=0; b=0; i=0; foo()";
3337   v8::Local<v8::Function> foo = CompileFunction(&env, src, "foo");
3338
3339   SetBreakPoint(foo, 8);  // "a = 1;"
3340
3341   // Looping 10 times.
3342   step_action = StepIn;
3343   break_point_hit_count = 0;
3344   v8::Handle<v8::Value> argv_10[argc] = { v8::Number::New(isolate, 10) };
3345   foo->Call(env->Global(), argc, argv_10);
3346   CHECK_EQ(23, break_point_hit_count);
3347
3348   // Looping 100 times.
3349   step_action = StepIn;
3350   break_point_hit_count = 0;
3351   v8::Handle<v8::Value> argv_100[argc] = { v8::Number::New(isolate, 100) };
3352   foo->Call(env->Global(), argc, argv_100);
3353   CHECK_EQ(203, break_point_hit_count);
3354
3355   // Get rid of the debug event listener.
3356   v8::Debug::SetDebugEventListener2(NULL);
3357   CheckDebuggerUnloaded();
3358 }
3359
3360
3361 TEST(DebugStepForContinue) {
3362   DebugLocalContext env;
3363   v8::Isolate* isolate = env->GetIsolate();
3364   v8::HandleScope scope(isolate);
3365
3366   // Register a debug event listener which steps and counts.
3367   v8::Debug::SetDebugEventListener2(DebugEventStep);
3368
3369   // Create a function for testing stepping. Run it to allow it to get
3370   // optimized.
3371   const int argc = 1;
3372   const char* src = "function foo(x) { "
3373                     "  var a = 0;"
3374                     "  var b = 0;"
3375                     "  var c = 0;"
3376                     "  for (var i = 0; i < x; i++) {"
3377                     "    a++;"
3378                     "    if (a % 2 == 0) continue;"
3379                     "    b++;"
3380                     "    c++;"
3381                     "  }"
3382                     "  return b;"
3383                     "}"
3384                     "foo()";
3385   v8::Local<v8::Function> foo = CompileFunction(&env, src, "foo");
3386   v8::Handle<v8::Value> result;
3387   SetBreakPoint(foo, 8);  // "var a = 0;"
3388
3389   // Each loop generates 4 or 5 steps depending on whether a is equal.
3390
3391   // Looping 10 times.
3392   step_action = StepIn;
3393   break_point_hit_count = 0;
3394   v8::Handle<v8::Value> argv_10[argc] = { v8::Number::New(isolate, 10) };
3395   result = foo->Call(env->Global(), argc, argv_10);
3396   CHECK_EQ(5, result->Int32Value());
3397   CHECK_EQ(52, break_point_hit_count);
3398
3399   // Looping 100 times.
3400   step_action = StepIn;
3401   break_point_hit_count = 0;
3402   v8::Handle<v8::Value> argv_100[argc] = { v8::Number::New(isolate, 100) };
3403   result = foo->Call(env->Global(), argc, argv_100);
3404   CHECK_EQ(50, result->Int32Value());
3405   CHECK_EQ(457, break_point_hit_count);
3406
3407   // Get rid of the debug event listener.
3408   v8::Debug::SetDebugEventListener2(NULL);
3409   CheckDebuggerUnloaded();
3410 }
3411
3412
3413 TEST(DebugStepForBreak) {
3414   DebugLocalContext env;
3415   v8::Isolate* isolate = env->GetIsolate();
3416   v8::HandleScope scope(isolate);
3417
3418   // Register a debug event listener which steps and counts.
3419   v8::Debug::SetDebugEventListener2(DebugEventStep);
3420
3421   // Create a function for testing stepping. Run it to allow it to get
3422   // optimized.
3423   const int argc = 1;
3424   const char* src = "function foo(x) { "
3425                     "  var a = 0;"
3426                     "  var b = 0;"
3427                     "  var c = 0;"
3428                     "  for (var i = 0; i < 1000; i++) {"
3429                     "    a++;"
3430                     "    if (a == x) break;"
3431                     "    b++;"
3432                     "    c++;"
3433                     "  }"
3434                     "  return b;"
3435                     "}"
3436                     "foo()";
3437   v8::Local<v8::Function> foo = CompileFunction(&env, src, "foo");
3438   v8::Handle<v8::Value> result;
3439   SetBreakPoint(foo, 8);  // "var a = 0;"
3440
3441   // Each loop generates 5 steps except for the last (when break is executed)
3442   // which only generates 4.
3443
3444   // Looping 10 times.
3445   step_action = StepIn;
3446   break_point_hit_count = 0;
3447   v8::Handle<v8::Value> argv_10[argc] = { v8::Number::New(isolate, 10) };
3448   result = foo->Call(env->Global(), argc, argv_10);
3449   CHECK_EQ(9, result->Int32Value());
3450   CHECK_EQ(55, break_point_hit_count);
3451
3452   // Looping 100 times.
3453   step_action = StepIn;
3454   break_point_hit_count = 0;
3455   v8::Handle<v8::Value> argv_100[argc] = { v8::Number::New(isolate, 100) };
3456   result = foo->Call(env->Global(), argc, argv_100);
3457   CHECK_EQ(99, result->Int32Value());
3458   CHECK_EQ(505, break_point_hit_count);
3459
3460   // Get rid of the debug event listener.
3461   v8::Debug::SetDebugEventListener2(NULL);
3462   CheckDebuggerUnloaded();
3463 }
3464
3465
3466 TEST(DebugStepForIn) {
3467   DebugLocalContext env;
3468   v8::HandleScope scope(env->GetIsolate());
3469
3470   // Register a debug event listener which steps and counts.
3471   v8::Debug::SetDebugEventListener2(DebugEventStep);
3472
3473   // Create a function for testing stepping. Run it to allow it to get
3474   // optimized.
3475   v8::Local<v8::Function> foo;
3476   const char* src_1 = "function foo() { "
3477                       "  var a = [1, 2];"
3478                       "  for (x in a) {"
3479                       "    b = 0;"
3480                       "  }"
3481                       "}"
3482                       "foo()";
3483   foo = CompileFunction(&env, src_1, "foo");
3484   SetBreakPoint(foo, 0);  // "var a = ..."
3485
3486   step_action = StepIn;
3487   break_point_hit_count = 0;
3488   foo->Call(env->Global(), 0, NULL);
3489   CHECK_EQ(6, break_point_hit_count);
3490
3491   // Create a function for testing stepping. Run it to allow it to get
3492   // optimized.
3493   const char* src_2 = "function foo() { "
3494                       "  var a = {a:[1, 2, 3]};"
3495                       "  for (x in a.a) {"
3496                       "    b = 0;"
3497                       "  }"
3498                       "}"
3499                       "foo()";
3500   foo = CompileFunction(&env, src_2, "foo");
3501   SetBreakPoint(foo, 0);  // "var a = ..."
3502
3503   step_action = StepIn;
3504   break_point_hit_count = 0;
3505   foo->Call(env->Global(), 0, NULL);
3506   CHECK_EQ(8, break_point_hit_count);
3507
3508   // Get rid of the debug event listener.
3509   v8::Debug::SetDebugEventListener2(NULL);
3510   CheckDebuggerUnloaded();
3511 }
3512
3513
3514 TEST(DebugStepWith) {
3515   DebugLocalContext env;
3516   v8::HandleScope scope(env->GetIsolate());
3517
3518   // Register a debug event listener which steps and counts.
3519   v8::Debug::SetDebugEventListener2(DebugEventStep);
3520
3521   // Create a function for testing stepping. Run it to allow it to get
3522   // optimized.
3523   const char* src = "function foo(x) { "
3524                     "  var a = {};"
3525                     "  with (a) {}"
3526                     "  with (b) {}"
3527                     "}"
3528                     "foo()";
3529   env->Global()->Set(v8::String::NewFromUtf8(env->GetIsolate(), "b"),
3530                      v8::Object::New(env->GetIsolate()));
3531   v8::Local<v8::Function> foo = CompileFunction(&env, src, "foo");
3532   v8::Handle<v8::Value> result;
3533   SetBreakPoint(foo, 8);  // "var a = {};"
3534
3535   step_action = StepIn;
3536   break_point_hit_count = 0;
3537   foo->Call(env->Global(), 0, NULL);
3538   CHECK_EQ(4, break_point_hit_count);
3539
3540   // Get rid of the debug event listener.
3541   v8::Debug::SetDebugEventListener2(NULL);
3542   CheckDebuggerUnloaded();
3543 }
3544
3545
3546 TEST(DebugConditional) {
3547   DebugLocalContext env;
3548   v8::Isolate* isolate = env->GetIsolate();
3549   v8::HandleScope scope(isolate);
3550
3551   // Register a debug event listener which steps and counts.
3552   v8::Debug::SetDebugEventListener2(DebugEventStep);
3553
3554   // Create a function for testing stepping. Run it to allow it to get
3555   // optimized.
3556   const char* src = "function foo(x) { "
3557                     "  var a;"
3558                     "  a = x ? 1 : 2;"
3559                     "  return a;"
3560                     "}"
3561                     "foo()";
3562   v8::Local<v8::Function> foo = CompileFunction(&env, src, "foo");
3563   SetBreakPoint(foo, 0);  // "var a;"
3564
3565   step_action = StepIn;
3566   break_point_hit_count = 0;
3567   foo->Call(env->Global(), 0, NULL);
3568   CHECK_EQ(5, break_point_hit_count);
3569
3570   step_action = StepIn;
3571   break_point_hit_count = 0;
3572   const int argc = 1;
3573   v8::Handle<v8::Value> argv_true[argc] = { v8::True(isolate) };
3574   foo->Call(env->Global(), argc, argv_true);
3575   CHECK_EQ(5, break_point_hit_count);
3576
3577   // Get rid of the debug event listener.
3578   v8::Debug::SetDebugEventListener2(NULL);
3579   CheckDebuggerUnloaded();
3580 }
3581
3582
3583 TEST(StepInOutSimple) {
3584   DebugLocalContext env;
3585   v8::HandleScope scope(env->GetIsolate());
3586
3587   // Create a function for checking the function when hitting a break point.
3588   frame_function_name = CompileFunction(&env,
3589                                         frame_function_name_source,
3590                                         "frame_function_name");
3591
3592   // Register a debug event listener which steps and counts.
3593   v8::Debug::SetDebugEventListener2(DebugEventStepSequence);
3594
3595   // Create a function for testing stepping. Run it to allow it to get
3596   // optimized.
3597   const char* src = "function a() {b();c();}; "
3598                     "function b() {c();}; "
3599                     "function c() {}; "
3600                     "a(); b(); c()";
3601   v8::Local<v8::Function> a = CompileFunction(&env, src, "a");
3602   SetBreakPoint(a, 0);
3603
3604   // Step through invocation of a with step in.
3605   step_action = StepIn;
3606   break_point_hit_count = 0;
3607   expected_step_sequence = "abcbaca";
3608   a->Call(env->Global(), 0, NULL);
3609   CHECK_EQ(StrLength(expected_step_sequence),
3610            break_point_hit_count);
3611
3612   // Step through invocation of a with step next.
3613   step_action = StepNext;
3614   break_point_hit_count = 0;
3615   expected_step_sequence = "aaa";
3616   a->Call(env->Global(), 0, NULL);
3617   CHECK_EQ(StrLength(expected_step_sequence),
3618            break_point_hit_count);
3619
3620   // Step through invocation of a with step out.
3621   step_action = StepOut;
3622   break_point_hit_count = 0;
3623   expected_step_sequence = "a";
3624   a->Call(env->Global(), 0, NULL);
3625   CHECK_EQ(StrLength(expected_step_sequence),
3626            break_point_hit_count);
3627
3628   // Get rid of the debug event listener.
3629   v8::Debug::SetDebugEventListener2(NULL);
3630   CheckDebuggerUnloaded();
3631 }
3632
3633
3634 TEST(StepInOutTree) {
3635   DebugLocalContext env;
3636   v8::HandleScope scope(env->GetIsolate());
3637
3638   // Create a function for checking the function when hitting a break point.
3639   frame_function_name = CompileFunction(&env,
3640                                         frame_function_name_source,
3641                                         "frame_function_name");
3642
3643   // Register a debug event listener which steps and counts.
3644   v8::Debug::SetDebugEventListener2(DebugEventStepSequence);
3645
3646   // Create a function for testing stepping. Run it to allow it to get
3647   // optimized.
3648   const char* src = "function a() {b(c(d()),d());c(d());d()}; "
3649                     "function b(x,y) {c();}; "
3650                     "function c(x) {}; "
3651                     "function d() {}; "
3652                     "a(); b(); c(); d()";
3653   v8::Local<v8::Function> a = CompileFunction(&env, src, "a");
3654   SetBreakPoint(a, 0);
3655
3656   // Step through invocation of a with step in.
3657   step_action = StepIn;
3658   break_point_hit_count = 0;
3659   expected_step_sequence = "adacadabcbadacada";
3660   a->Call(env->Global(), 0, NULL);
3661   CHECK_EQ(StrLength(expected_step_sequence),
3662            break_point_hit_count);
3663
3664   // Step through invocation of a with step next.
3665   step_action = StepNext;
3666   break_point_hit_count = 0;
3667   expected_step_sequence = "aaaa";
3668   a->Call(env->Global(), 0, NULL);
3669   CHECK_EQ(StrLength(expected_step_sequence),
3670            break_point_hit_count);
3671
3672   // Step through invocation of a with step out.
3673   step_action = StepOut;
3674   break_point_hit_count = 0;
3675   expected_step_sequence = "a";
3676   a->Call(env->Global(), 0, NULL);
3677   CHECK_EQ(StrLength(expected_step_sequence),
3678            break_point_hit_count);
3679
3680   // Get rid of the debug event listener.
3681   v8::Debug::SetDebugEventListener2(NULL);
3682   CheckDebuggerUnloaded(true);
3683 }
3684
3685
3686 TEST(StepInOutBranch) {
3687   DebugLocalContext env;
3688   v8::HandleScope scope(env->GetIsolate());
3689
3690   // Create a function for checking the function when hitting a break point.
3691   frame_function_name = CompileFunction(&env,
3692                                         frame_function_name_source,
3693                                         "frame_function_name");
3694
3695   // Register a debug event listener which steps and counts.
3696   v8::Debug::SetDebugEventListener2(DebugEventStepSequence);
3697
3698   // Create a function for testing stepping. Run it to allow it to get
3699   // optimized.
3700   const char* src = "function a() {b(false);c();}; "
3701                     "function b(x) {if(x){c();};}; "
3702                     "function c() {}; "
3703                     "a(); b(); c()";
3704   v8::Local<v8::Function> a = CompileFunction(&env, src, "a");
3705   SetBreakPoint(a, 0);
3706
3707   // Step through invocation of a.
3708   step_action = StepIn;
3709   break_point_hit_count = 0;
3710   expected_step_sequence = "abbaca";
3711   a->Call(env->Global(), 0, NULL);
3712   CHECK_EQ(StrLength(expected_step_sequence),
3713            break_point_hit_count);
3714
3715   // Get rid of the debug event listener.
3716   v8::Debug::SetDebugEventListener2(NULL);
3717   CheckDebuggerUnloaded();
3718 }
3719
3720
3721 // Test that step in does not step into native functions.
3722 TEST(DebugStepNatives) {
3723   DebugLocalContext env;
3724   v8::HandleScope scope(env->GetIsolate());
3725
3726   // Create a function for testing stepping.
3727   v8::Local<v8::Function> foo = CompileFunction(
3728       &env,
3729       "function foo(){debugger;Math.sin(1);}",
3730       "foo");
3731
3732   // Register a debug event listener which steps and counts.
3733   v8::Debug::SetDebugEventListener2(DebugEventStep);
3734
3735   step_action = StepIn;
3736   break_point_hit_count = 0;
3737   foo->Call(env->Global(), 0, NULL);
3738
3739   // With stepping all break locations are hit.
3740   CHECK_EQ(3, break_point_hit_count);
3741
3742   v8::Debug::SetDebugEventListener2(NULL);
3743   CheckDebuggerUnloaded();
3744
3745   // Register a debug event listener which just counts.
3746   v8::Debug::SetDebugEventListener2(DebugEventBreakPointHitCount);
3747
3748   break_point_hit_count = 0;
3749   foo->Call(env->Global(), 0, NULL);
3750
3751   // Without stepping only active break points are hit.
3752   CHECK_EQ(1, break_point_hit_count);
3753
3754   v8::Debug::SetDebugEventListener2(NULL);
3755   CheckDebuggerUnloaded();
3756 }
3757
3758
3759 // Test that step in works with function.apply.
3760 TEST(DebugStepFunctionApply) {
3761   DebugLocalContext env;
3762   v8::HandleScope scope(env->GetIsolate());
3763
3764   // Create a function for testing stepping.
3765   v8::Local<v8::Function> foo = CompileFunction(
3766       &env,
3767       "function bar(x, y, z) { if (x == 1) { a = y; b = z; } }"
3768       "function foo(){ debugger; bar.apply(this, [1,2,3]); }",
3769       "foo");
3770
3771   // Register a debug event listener which steps and counts.
3772   v8::Debug::SetDebugEventListener2(DebugEventStep);
3773
3774   step_action = StepIn;
3775   break_point_hit_count = 0;
3776   foo->Call(env->Global(), 0, NULL);
3777
3778   // With stepping all break locations are hit.
3779   CHECK_EQ(7, break_point_hit_count);
3780
3781   v8::Debug::SetDebugEventListener2(NULL);
3782   CheckDebuggerUnloaded();
3783
3784   // Register a debug event listener which just counts.
3785   v8::Debug::SetDebugEventListener2(DebugEventBreakPointHitCount);
3786
3787   break_point_hit_count = 0;
3788   foo->Call(env->Global(), 0, NULL);
3789
3790   // Without stepping only the debugger statement is hit.
3791   CHECK_EQ(1, break_point_hit_count);
3792
3793   v8::Debug::SetDebugEventListener2(NULL);
3794   CheckDebuggerUnloaded();
3795 }
3796
3797
3798 // Test that step in works with function.call.
3799 TEST(DebugStepFunctionCall) {
3800   DebugLocalContext env;
3801   v8::Isolate* isolate = env->GetIsolate();
3802   v8::HandleScope scope(isolate);
3803
3804   // Create a function for testing stepping.
3805   v8::Local<v8::Function> foo = CompileFunction(
3806       &env,
3807       "function bar(x, y, z) { if (x == 1) { a = y; b = z; } }"
3808       "function foo(a){ debugger;"
3809       "                 if (a) {"
3810       "                   bar.call(this, 1, 2, 3);"
3811       "                 } else {"
3812       "                   bar.call(this, 0);"
3813       "                 }"
3814       "}",
3815       "foo");
3816
3817   // Register a debug event listener which steps and counts.
3818   v8::Debug::SetDebugEventListener2(DebugEventStep);
3819   step_action = StepIn;
3820
3821   // Check stepping where the if condition in bar is false.
3822   break_point_hit_count = 0;
3823   foo->Call(env->Global(), 0, NULL);
3824   CHECK_EQ(6, break_point_hit_count);
3825
3826   // Check stepping where the if condition in bar is true.
3827   break_point_hit_count = 0;
3828   const int argc = 1;
3829   v8::Handle<v8::Value> argv[argc] = { v8::True(isolate) };
3830   foo->Call(env->Global(), argc, argv);
3831   CHECK_EQ(8, break_point_hit_count);
3832
3833   v8::Debug::SetDebugEventListener2(NULL);
3834   CheckDebuggerUnloaded();
3835
3836   // Register a debug event listener which just counts.
3837   v8::Debug::SetDebugEventListener2(DebugEventBreakPointHitCount);
3838
3839   break_point_hit_count = 0;
3840   foo->Call(env->Global(), 0, NULL);
3841
3842   // Without stepping only the debugger statement is hit.
3843   CHECK_EQ(1, break_point_hit_count);
3844
3845   v8::Debug::SetDebugEventListener2(NULL);
3846   CheckDebuggerUnloaded();
3847 }
3848
3849
3850 // Tests that breakpoint will be hit if it's set in script.
3851 TEST(PauseInScript) {
3852   DebugLocalContext env;
3853   v8::HandleScope scope(env->GetIsolate());
3854   env.ExposeDebug();
3855
3856   // Register a debug event listener which counts.
3857   v8::Debug::SetDebugEventListener2(DebugEventCounter);
3858
3859   // Create a script that returns a function.
3860   const char* src = "(function (evt) {})";
3861   const char* script_name = "StepInHandlerTest";
3862
3863   // Set breakpoint in the script.
3864   SetScriptBreakPointByNameFromJS(env->GetIsolate(), script_name, 0, -1);
3865   break_point_hit_count = 0;
3866
3867   v8::ScriptOrigin origin(
3868       v8::String::NewFromUtf8(env->GetIsolate(), script_name),
3869       v8::Integer::New(env->GetIsolate(), 0));
3870   v8::Handle<v8::Script> script = v8::Script::Compile(
3871       v8::String::NewFromUtf8(env->GetIsolate(), src), &origin);
3872   v8::Local<v8::Value> r = script->Run();
3873
3874   CHECK(r->IsFunction());
3875   CHECK_EQ(1, break_point_hit_count);
3876
3877   // Get rid of the debug event listener.
3878   v8::Debug::SetDebugEventListener2(NULL);
3879   CheckDebuggerUnloaded();
3880 }
3881
3882
3883 // Test break on exceptions. For each exception break combination the number
3884 // of debug event exception callbacks and message callbacks are collected. The
3885 // number of debug event exception callbacks are used to check that the
3886 // debugger is called correctly and the number of message callbacks is used to
3887 // check that uncaught exceptions are still returned even if there is a break
3888 // for them.
3889 TEST(BreakOnException) {
3890   DebugLocalContext env;
3891   v8::HandleScope scope(env->GetIsolate());
3892   env.ExposeDebug();
3893
3894   // Create functions for testing break on exception.
3895   CompileFunction(&env, "function throws(){throw 1;}", "throws");
3896   v8::Local<v8::Function> caught =
3897       CompileFunction(&env,
3898                       "function caught(){try {throws();} catch(e) {};}",
3899                       "caught");
3900   v8::Local<v8::Function> notCaught =
3901       CompileFunction(&env, "function notCaught(){throws();}", "notCaught");
3902
3903   v8::V8::AddMessageListener(MessageCallbackCount);
3904   v8::Debug::SetDebugEventListener2(DebugEventCounter);
3905
3906   // Initial state should be no break on exceptions.
3907   DebugEventCounterClear();
3908   MessageCallbackCountClear();
3909   caught->Call(env->Global(), 0, NULL);
3910   CHECK_EQ(0, exception_hit_count);
3911   CHECK_EQ(0, uncaught_exception_hit_count);
3912   CHECK_EQ(0, message_callback_count);
3913   notCaught->Call(env->Global(), 0, NULL);
3914   CHECK_EQ(0, exception_hit_count);
3915   CHECK_EQ(0, uncaught_exception_hit_count);
3916   CHECK_EQ(1, message_callback_count);
3917
3918   // No break on exception
3919   DebugEventCounterClear();
3920   MessageCallbackCountClear();
3921   ChangeBreakOnException(false, false);
3922   caught->Call(env->Global(), 0, NULL);
3923   CHECK_EQ(0, exception_hit_count);
3924   CHECK_EQ(0, uncaught_exception_hit_count);
3925   CHECK_EQ(0, message_callback_count);
3926   notCaught->Call(env->Global(), 0, NULL);
3927   CHECK_EQ(0, exception_hit_count);
3928   CHECK_EQ(0, uncaught_exception_hit_count);
3929   CHECK_EQ(1, message_callback_count);
3930
3931   // Break on uncaught exception
3932   DebugEventCounterClear();
3933   MessageCallbackCountClear();
3934   ChangeBreakOnException(false, true);
3935   caught->Call(env->Global(), 0, NULL);
3936   CHECK_EQ(0, exception_hit_count);
3937   CHECK_EQ(0, uncaught_exception_hit_count);
3938   CHECK_EQ(0, message_callback_count);
3939   notCaught->Call(env->Global(), 0, NULL);
3940   CHECK_EQ(1, exception_hit_count);
3941   CHECK_EQ(1, uncaught_exception_hit_count);
3942   CHECK_EQ(1, message_callback_count);
3943
3944   // Break on exception and uncaught exception
3945   DebugEventCounterClear();
3946   MessageCallbackCountClear();
3947   ChangeBreakOnException(true, true);
3948   caught->Call(env->Global(), 0, NULL);
3949   CHECK_EQ(1, exception_hit_count);
3950   CHECK_EQ(0, uncaught_exception_hit_count);
3951   CHECK_EQ(0, message_callback_count);
3952   notCaught->Call(env->Global(), 0, NULL);
3953   CHECK_EQ(2, exception_hit_count);
3954   CHECK_EQ(1, uncaught_exception_hit_count);
3955   CHECK_EQ(1, message_callback_count);
3956
3957   // Break on exception
3958   DebugEventCounterClear();
3959   MessageCallbackCountClear();
3960   ChangeBreakOnException(true, false);
3961   caught->Call(env->Global(), 0, NULL);
3962   CHECK_EQ(1, exception_hit_count);
3963   CHECK_EQ(0, uncaught_exception_hit_count);
3964   CHECK_EQ(0, message_callback_count);
3965   notCaught->Call(env->Global(), 0, NULL);
3966   CHECK_EQ(2, exception_hit_count);
3967   CHECK_EQ(1, uncaught_exception_hit_count);
3968   CHECK_EQ(1, message_callback_count);
3969
3970   // No break on exception using JavaScript
3971   DebugEventCounterClear();
3972   MessageCallbackCountClear();
3973   ChangeBreakOnExceptionFromJS(env->GetIsolate(), false, false);
3974   caught->Call(env->Global(), 0, NULL);
3975   CHECK_EQ(0, exception_hit_count);
3976   CHECK_EQ(0, uncaught_exception_hit_count);
3977   CHECK_EQ(0, message_callback_count);
3978   notCaught->Call(env->Global(), 0, NULL);
3979   CHECK_EQ(0, exception_hit_count);
3980   CHECK_EQ(0, uncaught_exception_hit_count);
3981   CHECK_EQ(1, message_callback_count);
3982
3983   // Break on uncaught exception using JavaScript
3984   DebugEventCounterClear();
3985   MessageCallbackCountClear();
3986   ChangeBreakOnExceptionFromJS(env->GetIsolate(), false, true);
3987   caught->Call(env->Global(), 0, NULL);
3988   CHECK_EQ(0, exception_hit_count);
3989   CHECK_EQ(0, uncaught_exception_hit_count);
3990   CHECK_EQ(0, message_callback_count);
3991   notCaught->Call(env->Global(), 0, NULL);
3992   CHECK_EQ(1, exception_hit_count);
3993   CHECK_EQ(1, uncaught_exception_hit_count);
3994   CHECK_EQ(1, message_callback_count);
3995
3996   // Break on exception and uncaught exception using JavaScript
3997   DebugEventCounterClear();
3998   MessageCallbackCountClear();
3999   ChangeBreakOnExceptionFromJS(env->GetIsolate(), true, true);
4000   caught->Call(env->Global(), 0, NULL);
4001   CHECK_EQ(1, exception_hit_count);
4002   CHECK_EQ(0, message_callback_count);
4003   CHECK_EQ(0, uncaught_exception_hit_count);
4004   notCaught->Call(env->Global(), 0, NULL);
4005   CHECK_EQ(2, exception_hit_count);
4006   CHECK_EQ(1, uncaught_exception_hit_count);
4007   CHECK_EQ(1, message_callback_count);
4008
4009   // Break on exception using JavaScript
4010   DebugEventCounterClear();
4011   MessageCallbackCountClear();
4012   ChangeBreakOnExceptionFromJS(env->GetIsolate(), true, false);
4013   caught->Call(env->Global(), 0, NULL);
4014   CHECK_EQ(1, exception_hit_count);
4015   CHECK_EQ(0, uncaught_exception_hit_count);
4016   CHECK_EQ(0, message_callback_count);
4017   notCaught->Call(env->Global(), 0, NULL);
4018   CHECK_EQ(2, exception_hit_count);
4019   CHECK_EQ(1, uncaught_exception_hit_count);
4020   CHECK_EQ(1, message_callback_count);
4021
4022   v8::Debug::SetDebugEventListener2(NULL);
4023   CheckDebuggerUnloaded();
4024   v8::V8::RemoveMessageListeners(MessageCallbackCount);
4025 }
4026
4027
4028 // Test break on exception from compiler errors. When compiling using
4029 // v8::Script::Compile there is no JavaScript stack whereas when compiling using
4030 // eval there are JavaScript frames.
4031 TEST(BreakOnCompileException) {
4032   DebugLocalContext env;
4033   v8::HandleScope scope(env->GetIsolate());
4034
4035   // For this test, we want to break on uncaught exceptions:
4036   ChangeBreakOnException(false, true);
4037
4038   // Create a function for checking the function when hitting a break point.
4039   frame_count = CompileFunction(&env, frame_count_source, "frame_count");
4040
4041   v8::V8::AddMessageListener(MessageCallbackCount);
4042   v8::Debug::SetDebugEventListener2(DebugEventCounter);
4043
4044   DebugEventCounterClear();
4045   MessageCallbackCountClear();
4046
4047   // Check initial state.
4048   CHECK_EQ(0, exception_hit_count);
4049   CHECK_EQ(0, uncaught_exception_hit_count);
4050   CHECK_EQ(0, message_callback_count);
4051   CHECK_EQ(-1, last_js_stack_height);
4052
4053   // Throws SyntaxError: Unexpected end of input
4054   v8::Script::Compile(v8::String::NewFromUtf8(env->GetIsolate(), "+++"));
4055   CHECK_EQ(1, exception_hit_count);
4056   CHECK_EQ(1, uncaught_exception_hit_count);
4057   CHECK_EQ(1, message_callback_count);
4058   CHECK_EQ(0, last_js_stack_height);  // No JavaScript stack.
4059
4060   // Throws SyntaxError: Unexpected identifier
4061   v8::Script::Compile(v8::String::NewFromUtf8(env->GetIsolate(), "x x"));
4062   CHECK_EQ(2, exception_hit_count);
4063   CHECK_EQ(2, uncaught_exception_hit_count);
4064   CHECK_EQ(2, message_callback_count);
4065   CHECK_EQ(0, last_js_stack_height);  // No JavaScript stack.
4066
4067   // Throws SyntaxError: Unexpected end of input
4068   v8::Script::Compile(v8::String::NewFromUtf8(env->GetIsolate(), "eval('+++')"))
4069       ->Run();
4070   CHECK_EQ(3, exception_hit_count);
4071   CHECK_EQ(3, uncaught_exception_hit_count);
4072   CHECK_EQ(3, message_callback_count);
4073   CHECK_EQ(1, last_js_stack_height);
4074
4075   // Throws SyntaxError: Unexpected identifier
4076   v8::Script::Compile(v8::String::NewFromUtf8(env->GetIsolate(), "eval('x x')"))
4077       ->Run();
4078   CHECK_EQ(4, exception_hit_count);
4079   CHECK_EQ(4, uncaught_exception_hit_count);
4080   CHECK_EQ(4, message_callback_count);
4081   CHECK_EQ(1, last_js_stack_height);
4082 }
4083
4084
4085 TEST(StepWithException) {
4086   DebugLocalContext env;
4087   v8::HandleScope scope(env->GetIsolate());
4088
4089   // For this test, we want to break on uncaught exceptions:
4090   ChangeBreakOnException(false, true);
4091
4092   // Create a function for checking the function when hitting a break point.
4093   frame_function_name = CompileFunction(&env,
4094                                         frame_function_name_source,
4095                                         "frame_function_name");
4096
4097   // Register a debug event listener which steps and counts.
4098   v8::Debug::SetDebugEventListener2(DebugEventStepSequence);
4099
4100   // Create functions for testing stepping.
4101   const char* src = "function a() { n(); }; "
4102                     "function b() { c(); }; "
4103                     "function c() { n(); }; "
4104                     "function d() { x = 1; try { e(); } catch(x) { x = 2; } }; "
4105                     "function e() { n(); }; "
4106                     "function f() { x = 1; try { g(); } catch(x) { x = 2; } }; "
4107                     "function g() { h(); }; "
4108                     "function h() { x = 1; throw 1; }; ";
4109
4110   // Step through invocation of a.
4111   v8::Local<v8::Function> a = CompileFunction(&env, src, "a");
4112   SetBreakPoint(a, 0);
4113   step_action = StepIn;
4114   break_point_hit_count = 0;
4115   expected_step_sequence = "aa";
4116   a->Call(env->Global(), 0, NULL);
4117   CHECK_EQ(StrLength(expected_step_sequence),
4118            break_point_hit_count);
4119
4120   // Step through invocation of b + c.
4121   v8::Local<v8::Function> b = CompileFunction(&env, src, "b");
4122   SetBreakPoint(b, 0);
4123   step_action = StepIn;
4124   break_point_hit_count = 0;
4125   expected_step_sequence = "bcc";
4126   b->Call(env->Global(), 0, NULL);
4127   CHECK_EQ(StrLength(expected_step_sequence),
4128            break_point_hit_count);
4129   // Step through invocation of d + e.
4130   v8::Local<v8::Function> d = CompileFunction(&env, src, "d");
4131   SetBreakPoint(d, 0);
4132   ChangeBreakOnException(false, true);
4133   step_action = StepIn;
4134   break_point_hit_count = 0;
4135   expected_step_sequence = "ddedd";
4136   d->Call(env->Global(), 0, NULL);
4137   CHECK_EQ(StrLength(expected_step_sequence),
4138            break_point_hit_count);
4139
4140   // Step through invocation of d + e now with break on caught exceptions.
4141   ChangeBreakOnException(true, true);
4142   step_action = StepIn;
4143   break_point_hit_count = 0;
4144   expected_step_sequence = "ddeedd";
4145   d->Call(env->Global(), 0, NULL);
4146   CHECK_EQ(StrLength(expected_step_sequence),
4147            break_point_hit_count);
4148
4149   // Step through invocation of f + g + h.
4150   v8::Local<v8::Function> f = CompileFunction(&env, src, "f");
4151   SetBreakPoint(f, 0);
4152   ChangeBreakOnException(false, true);
4153   step_action = StepIn;
4154   break_point_hit_count = 0;
4155   expected_step_sequence = "ffghhff";
4156   f->Call(env->Global(), 0, NULL);
4157   CHECK_EQ(StrLength(expected_step_sequence),
4158            break_point_hit_count);
4159
4160   // Step through invocation of f + g + h now with break on caught exceptions.
4161   ChangeBreakOnException(true, true);
4162   step_action = StepIn;
4163   break_point_hit_count = 0;
4164   expected_step_sequence = "ffghhhff";
4165   f->Call(env->Global(), 0, NULL);
4166   CHECK_EQ(StrLength(expected_step_sequence),
4167            break_point_hit_count);
4168
4169   // Get rid of the debug event listener.
4170   v8::Debug::SetDebugEventListener2(NULL);
4171   CheckDebuggerUnloaded();
4172 }
4173
4174
4175 TEST(DebugBreak) {
4176   i::FLAG_stress_compaction = false;
4177 #ifdef VERIFY_HEAP
4178   i::FLAG_verify_heap = true;
4179 #endif
4180   DebugLocalContext env;
4181   v8::Isolate* isolate = env->GetIsolate();
4182   v8::HandleScope scope(isolate);
4183
4184   // Register a debug event listener which sets the break flag and counts.
4185   v8::Debug::SetDebugEventListener2(DebugEventBreak);
4186
4187   // Create a function for testing stepping.
4188   const char* src = "function f0() {}"
4189                     "function f1(x1) {}"
4190                     "function f2(x1,x2) {}"
4191                     "function f3(x1,x2,x3) {}";
4192   v8::Local<v8::Function> f0 = CompileFunction(&env, src, "f0");
4193   v8::Local<v8::Function> f1 = CompileFunction(&env, src, "f1");
4194   v8::Local<v8::Function> f2 = CompileFunction(&env, src, "f2");
4195   v8::Local<v8::Function> f3 = CompileFunction(&env, src, "f3");
4196
4197   // Call the function to make sure it is compiled.
4198   v8::Handle<v8::Value> argv[] = { v8::Number::New(isolate, 1),
4199                                    v8::Number::New(isolate, 1),
4200                                    v8::Number::New(isolate, 1),
4201                                    v8::Number::New(isolate, 1) };
4202
4203   // Call all functions to make sure that they are compiled.
4204   f0->Call(env->Global(), 0, NULL);
4205   f1->Call(env->Global(), 0, NULL);
4206   f2->Call(env->Global(), 0, NULL);
4207   f3->Call(env->Global(), 0, NULL);
4208
4209   // Set the debug break flag.
4210   v8::Debug::DebugBreak(env->GetIsolate());
4211
4212   // Call all functions with different argument count.
4213   break_point_hit_count = 0;
4214   for (unsigned int i = 0; i < ARRAY_SIZE(argv); i++) {
4215     f0->Call(env->Global(), i, argv);
4216     f1->Call(env->Global(), i, argv);
4217     f2->Call(env->Global(), i, argv);
4218     f3->Call(env->Global(), i, argv);
4219   }
4220
4221   // One break for each function called.
4222   CHECK_EQ(4 * ARRAY_SIZE(argv), break_point_hit_count);
4223
4224   // Get rid of the debug event listener.
4225   v8::Debug::SetDebugEventListener2(NULL);
4226   CheckDebuggerUnloaded();
4227 }
4228
4229
4230 // Test to ensure that JavaScript code keeps running while the debug break
4231 // through the stack limit flag is set but breaks are disabled.
4232 TEST(DisableBreak) {
4233   DebugLocalContext env;
4234   v8::HandleScope scope(env->GetIsolate());
4235
4236   // Register a debug event listener which sets the break flag and counts.
4237   v8::Debug::SetDebugEventListener2(DebugEventCounter);
4238
4239   // Create a function for testing stepping.
4240   const char* src = "function f() {g()};function g(){i=0; while(i<10){i++}}";
4241   v8::Local<v8::Function> f = CompileFunction(&env, src, "f");
4242
4243   // Set the debug break flag.
4244   v8::Debug::DebugBreak(env->GetIsolate());
4245
4246   // Call all functions with different argument count.
4247   break_point_hit_count = 0;
4248   f->Call(env->Global(), 0, NULL);
4249   CHECK_EQ(1, break_point_hit_count);
4250
4251   {
4252     v8::Debug::DebugBreak(env->GetIsolate());
4253     i::Isolate* isolate = reinterpret_cast<i::Isolate*>(env->GetIsolate());
4254     v8::internal::DisableBreak disable_break(isolate, true);
4255     f->Call(env->Global(), 0, NULL);
4256     CHECK_EQ(1, break_point_hit_count);
4257   }
4258
4259   f->Call(env->Global(), 0, NULL);
4260   CHECK_EQ(2, break_point_hit_count);
4261
4262   // Get rid of the debug event listener.
4263   v8::Debug::SetDebugEventListener2(NULL);
4264   CheckDebuggerUnloaded();
4265 }
4266
4267 static const char* kSimpleExtensionSource =
4268   "(function Foo() {"
4269   "  return 4;"
4270   "})() ";
4271
4272 // http://crbug.com/28933
4273 // Test that debug break is disabled when bootstrapper is active.
4274 TEST(NoBreakWhenBootstrapping) {
4275   v8::Isolate* isolate = CcTest::isolate();
4276   v8::HandleScope scope(isolate);
4277
4278   // Register a debug event listener which sets the break flag and counts.
4279   v8::Debug::SetDebugEventListener2(DebugEventCounter);
4280
4281   // Set the debug break flag.
4282   v8::Debug::DebugBreak(isolate);
4283   break_point_hit_count = 0;
4284   {
4285     // Create a context with an extension to make sure that some JavaScript
4286     // code is executed during bootstrapping.
4287     v8::RegisterExtension(new v8::Extension("simpletest",
4288                                             kSimpleExtensionSource));
4289     const char* extension_names[] = { "simpletest" };
4290     v8::ExtensionConfiguration extensions(1, extension_names);
4291     v8::HandleScope handle_scope(isolate);
4292     v8::Context::New(isolate, &extensions);
4293   }
4294   // Check that no DebugBreak events occured during the context creation.
4295   CHECK_EQ(0, break_point_hit_count);
4296
4297   // Get rid of the debug event listener.
4298   v8::Debug::SetDebugEventListener2(NULL);
4299   CheckDebuggerUnloaded();
4300 }
4301
4302
4303 static void NamedEnum(const v8::PropertyCallbackInfo<v8::Array>& info) {
4304   v8::Handle<v8::Array> result = v8::Array::New(info.GetIsolate(), 3);
4305   result->Set(v8::Integer::New(info.GetIsolate(), 0),
4306               v8::String::NewFromUtf8(info.GetIsolate(), "a"));
4307   result->Set(v8::Integer::New(info.GetIsolate(), 1),
4308               v8::String::NewFromUtf8(info.GetIsolate(), "b"));
4309   result->Set(v8::Integer::New(info.GetIsolate(), 2),
4310               v8::String::NewFromUtf8(info.GetIsolate(), "c"));
4311   info.GetReturnValue().Set(result);
4312 }
4313
4314
4315 static void IndexedEnum(const v8::PropertyCallbackInfo<v8::Array>& info) {
4316   v8::Isolate* isolate = info.GetIsolate();
4317   v8::Handle<v8::Array> result = v8::Array::New(isolate, 2);
4318   result->Set(v8::Integer::New(isolate, 0), v8::Number::New(isolate, 1));
4319   result->Set(v8::Integer::New(isolate, 1), v8::Number::New(isolate, 10));
4320   info.GetReturnValue().Set(result);
4321 }
4322
4323
4324 static void NamedGetter(v8::Local<v8::String> name,
4325                         const v8::PropertyCallbackInfo<v8::Value>& info) {
4326   v8::String::Utf8Value n(name);
4327   if (strcmp(*n, "a") == 0) {
4328     info.GetReturnValue().Set(v8::String::NewFromUtf8(info.GetIsolate(), "AA"));
4329     return;
4330   } else if (strcmp(*n, "b") == 0) {
4331     info.GetReturnValue().Set(v8::String::NewFromUtf8(info.GetIsolate(), "BB"));
4332     return;
4333   } else if (strcmp(*n, "c") == 0) {
4334     info.GetReturnValue().Set(v8::String::NewFromUtf8(info.GetIsolate(), "CC"));
4335     return;
4336   } else {
4337     info.GetReturnValue().SetUndefined();
4338     return;
4339   }
4340   info.GetReturnValue().Set(name);
4341 }
4342
4343
4344 static void IndexedGetter(uint32_t index,
4345                           const v8::PropertyCallbackInfo<v8::Value>& info) {
4346   info.GetReturnValue().Set(static_cast<double>(index + 1));
4347 }
4348
4349
4350 TEST(InterceptorPropertyMirror) {
4351   // Create a V8 environment with debug access.
4352   DebugLocalContext env;
4353   v8::Isolate* isolate = env->GetIsolate();
4354   v8::HandleScope scope(isolate);
4355   env.ExposeDebug();
4356
4357   // Create object with named interceptor.
4358   v8::Handle<v8::ObjectTemplate> named = v8::ObjectTemplate::New(isolate);
4359   named->SetNamedPropertyHandler(NamedGetter, NULL, NULL, NULL, NamedEnum);
4360   env->Global()->Set(
4361       v8::String::NewFromUtf8(isolate, "intercepted_named"),
4362       named->NewInstance());
4363
4364   // Create object with indexed interceptor.
4365   v8::Handle<v8::ObjectTemplate> indexed = v8::ObjectTemplate::New(isolate);
4366   indexed->SetIndexedPropertyHandler(IndexedGetter,
4367                                      NULL,
4368                                      NULL,
4369                                      NULL,
4370                                      IndexedEnum);
4371   env->Global()->Set(
4372       v8::String::NewFromUtf8(isolate, "intercepted_indexed"),
4373       indexed->NewInstance());
4374
4375   // Create object with both named and indexed interceptor.
4376   v8::Handle<v8::ObjectTemplate> both = v8::ObjectTemplate::New(isolate);
4377   both->SetNamedPropertyHandler(NamedGetter, NULL, NULL, NULL, NamedEnum);
4378   both->SetIndexedPropertyHandler(IndexedGetter, NULL, NULL, NULL, IndexedEnum);
4379   env->Global()->Set(
4380       v8::String::NewFromUtf8(isolate, "intercepted_both"),
4381       both->NewInstance());
4382
4383   // Get mirrors for the three objects with interceptor.
4384   CompileRun(
4385       "var named_mirror = debug.MakeMirror(intercepted_named);"
4386       "var indexed_mirror = debug.MakeMirror(intercepted_indexed);"
4387       "var both_mirror = debug.MakeMirror(intercepted_both)");
4388   CHECK(CompileRun(
4389        "named_mirror instanceof debug.ObjectMirror")->BooleanValue());
4390   CHECK(CompileRun(
4391         "indexed_mirror instanceof debug.ObjectMirror")->BooleanValue());
4392   CHECK(CompileRun(
4393         "both_mirror instanceof debug.ObjectMirror")->BooleanValue());
4394
4395   // Get the property names from the interceptors
4396   CompileRun(
4397       "named_names = named_mirror.propertyNames();"
4398       "indexed_names = indexed_mirror.propertyNames();"
4399       "both_names = both_mirror.propertyNames()");
4400   CHECK_EQ(3, CompileRun("named_names.length")->Int32Value());
4401   CHECK_EQ(2, CompileRun("indexed_names.length")->Int32Value());
4402   CHECK_EQ(5, CompileRun("both_names.length")->Int32Value());
4403
4404   // Check the expected number of properties.
4405   const char* source;
4406   source = "named_mirror.properties().length";
4407   CHECK_EQ(3, CompileRun(source)->Int32Value());
4408
4409   source = "indexed_mirror.properties().length";
4410   CHECK_EQ(2, CompileRun(source)->Int32Value());
4411
4412   source = "both_mirror.properties().length";
4413   CHECK_EQ(5, CompileRun(source)->Int32Value());
4414
4415   // 1 is PropertyKind.Named;
4416   source = "both_mirror.properties(1).length";
4417   CHECK_EQ(3, CompileRun(source)->Int32Value());
4418
4419   // 2 is PropertyKind.Indexed;
4420   source = "both_mirror.properties(2).length";
4421   CHECK_EQ(2, CompileRun(source)->Int32Value());
4422
4423   // 3 is PropertyKind.Named  | PropertyKind.Indexed;
4424   source = "both_mirror.properties(3).length";
4425   CHECK_EQ(5, CompileRun(source)->Int32Value());
4426
4427   // Get the interceptor properties for the object with only named interceptor.
4428   CompileRun("var named_values = named_mirror.properties()");
4429
4430   // Check that the properties are interceptor properties.
4431   for (int i = 0; i < 3; i++) {
4432     EmbeddedVector<char, SMALL_STRING_BUFFER_SIZE> buffer;
4433     OS::SNPrintF(buffer,
4434                  "named_values[%d] instanceof debug.PropertyMirror", i);
4435     CHECK(CompileRun(buffer.start())->BooleanValue());
4436
4437     OS::SNPrintF(buffer, "named_values[%d].propertyType()", i);
4438     CHECK_EQ(v8::internal::INTERCEPTOR,
4439              CompileRun(buffer.start())->Int32Value());
4440
4441     OS::SNPrintF(buffer, "named_values[%d].isNative()", i);
4442     CHECK(CompileRun(buffer.start())->BooleanValue());
4443   }
4444
4445   // Get the interceptor properties for the object with only indexed
4446   // interceptor.
4447   CompileRun("var indexed_values = indexed_mirror.properties()");
4448
4449   // Check that the properties are interceptor properties.
4450   for (int i = 0; i < 2; i++) {
4451     EmbeddedVector<char, SMALL_STRING_BUFFER_SIZE> buffer;
4452     OS::SNPrintF(buffer,
4453                  "indexed_values[%d] instanceof debug.PropertyMirror", i);
4454     CHECK(CompileRun(buffer.start())->BooleanValue());
4455   }
4456
4457   // Get the interceptor properties for the object with both types of
4458   // interceptors.
4459   CompileRun("var both_values = both_mirror.properties()");
4460
4461   // Check that the properties are interceptor properties.
4462   for (int i = 0; i < 5; i++) {
4463     EmbeddedVector<char, SMALL_STRING_BUFFER_SIZE> buffer;
4464     OS::SNPrintF(buffer, "both_values[%d] instanceof debug.PropertyMirror", i);
4465     CHECK(CompileRun(buffer.start())->BooleanValue());
4466   }
4467
4468   // Check the property names.
4469   source = "both_values[0].name() == 'a'";
4470   CHECK(CompileRun(source)->BooleanValue());
4471
4472   source = "both_values[1].name() == 'b'";
4473   CHECK(CompileRun(source)->BooleanValue());
4474
4475   source = "both_values[2].name() == 'c'";
4476   CHECK(CompileRun(source)->BooleanValue());
4477
4478   source = "both_values[3].name() == 1";
4479   CHECK(CompileRun(source)->BooleanValue());
4480
4481   source = "both_values[4].name() == 10";
4482   CHECK(CompileRun(source)->BooleanValue());
4483 }
4484
4485
4486 TEST(HiddenPrototypePropertyMirror) {
4487   // Create a V8 environment with debug access.
4488   DebugLocalContext env;
4489   v8::Isolate* isolate = env->GetIsolate();
4490   v8::HandleScope scope(isolate);
4491   env.ExposeDebug();
4492
4493   v8::Handle<v8::FunctionTemplate> t0 = v8::FunctionTemplate::New(isolate);
4494   t0->InstanceTemplate()->Set(v8::String::NewFromUtf8(isolate, "x"),
4495                               v8::Number::New(isolate, 0));
4496   v8::Handle<v8::FunctionTemplate> t1 = v8::FunctionTemplate::New(isolate);
4497   t1->SetHiddenPrototype(true);
4498   t1->InstanceTemplate()->Set(v8::String::NewFromUtf8(isolate, "y"),
4499                               v8::Number::New(isolate, 1));
4500   v8::Handle<v8::FunctionTemplate> t2 = v8::FunctionTemplate::New(isolate);
4501   t2->SetHiddenPrototype(true);
4502   t2->InstanceTemplate()->Set(v8::String::NewFromUtf8(isolate, "z"),
4503                               v8::Number::New(isolate, 2));
4504   v8::Handle<v8::FunctionTemplate> t3 = v8::FunctionTemplate::New(isolate);
4505   t3->InstanceTemplate()->Set(v8::String::NewFromUtf8(isolate, "u"),
4506                               v8::Number::New(isolate, 3));
4507
4508   // Create object and set them on the global object.
4509   v8::Handle<v8::Object> o0 = t0->GetFunction()->NewInstance();
4510   env->Global()->Set(v8::String::NewFromUtf8(isolate, "o0"), o0);
4511   v8::Handle<v8::Object> o1 = t1->GetFunction()->NewInstance();
4512   env->Global()->Set(v8::String::NewFromUtf8(isolate, "o1"), o1);
4513   v8::Handle<v8::Object> o2 = t2->GetFunction()->NewInstance();
4514   env->Global()->Set(v8::String::NewFromUtf8(isolate, "o2"), o2);
4515   v8::Handle<v8::Object> o3 = t3->GetFunction()->NewInstance();
4516   env->Global()->Set(v8::String::NewFromUtf8(isolate, "o3"), o3);
4517
4518   // Get mirrors for the four objects.
4519   CompileRun(
4520       "var o0_mirror = debug.MakeMirror(o0);"
4521       "var o1_mirror = debug.MakeMirror(o1);"
4522       "var o2_mirror = debug.MakeMirror(o2);"
4523       "var o3_mirror = debug.MakeMirror(o3)");
4524   CHECK(CompileRun("o0_mirror instanceof debug.ObjectMirror")->BooleanValue());
4525   CHECK(CompileRun("o1_mirror instanceof debug.ObjectMirror")->BooleanValue());
4526   CHECK(CompileRun("o2_mirror instanceof debug.ObjectMirror")->BooleanValue());
4527   CHECK(CompileRun("o3_mirror instanceof debug.ObjectMirror")->BooleanValue());
4528
4529   // Check that each object has one property.
4530   CHECK_EQ(1, CompileRun(
4531               "o0_mirror.propertyNames().length")->Int32Value());
4532   CHECK_EQ(1, CompileRun(
4533               "o1_mirror.propertyNames().length")->Int32Value());
4534   CHECK_EQ(1, CompileRun(
4535               "o2_mirror.propertyNames().length")->Int32Value());
4536   CHECK_EQ(1, CompileRun(
4537               "o3_mirror.propertyNames().length")->Int32Value());
4538
4539   // Set o1 as prototype for o0. o1 has the hidden prototype flag so all
4540   // properties on o1 should be seen on o0.
4541   o0->Set(v8::String::NewFromUtf8(isolate, "__proto__"), o1);
4542   CHECK_EQ(2, CompileRun(
4543               "o0_mirror.propertyNames().length")->Int32Value());
4544   CHECK_EQ(0, CompileRun(
4545               "o0_mirror.property('x').value().value()")->Int32Value());
4546   CHECK_EQ(1, CompileRun(
4547               "o0_mirror.property('y').value().value()")->Int32Value());
4548
4549   // Set o2 as prototype for o0 (it will end up after o1 as o1 has the hidden
4550   // prototype flag. o2 also has the hidden prototype flag so all properties
4551   // on o2 should be seen on o0 as well as properties on o1.
4552   o0->Set(v8::String::NewFromUtf8(isolate, "__proto__"), o2);
4553   CHECK_EQ(3, CompileRun(
4554               "o0_mirror.propertyNames().length")->Int32Value());
4555   CHECK_EQ(0, CompileRun(
4556               "o0_mirror.property('x').value().value()")->Int32Value());
4557   CHECK_EQ(1, CompileRun(
4558               "o0_mirror.property('y').value().value()")->Int32Value());
4559   CHECK_EQ(2, CompileRun(
4560               "o0_mirror.property('z').value().value()")->Int32Value());
4561
4562   // Set o3 as prototype for o0 (it will end up after o1 and o2 as both o1 and
4563   // o2 has the hidden prototype flag. o3 does not have the hidden prototype
4564   // flag so properties on o3 should not be seen on o0 whereas the properties
4565   // from o1 and o2 should still be seen on o0.
4566   // Final prototype chain: o0 -> o1 -> o2 -> o3
4567   // Hidden prototypes:           ^^    ^^
4568   o0->Set(v8::String::NewFromUtf8(isolate, "__proto__"), o3);
4569   CHECK_EQ(3, CompileRun(
4570               "o0_mirror.propertyNames().length")->Int32Value());
4571   CHECK_EQ(1, CompileRun(
4572               "o3_mirror.propertyNames().length")->Int32Value());
4573   CHECK_EQ(0, CompileRun(
4574               "o0_mirror.property('x').value().value()")->Int32Value());
4575   CHECK_EQ(1, CompileRun(
4576               "o0_mirror.property('y').value().value()")->Int32Value());
4577   CHECK_EQ(2, CompileRun(
4578               "o0_mirror.property('z').value().value()")->Int32Value());
4579   CHECK(CompileRun("o0_mirror.property('u').isUndefined()")->BooleanValue());
4580
4581   // The prototype (__proto__) for o0 should be o3 as o1 and o2 are hidden.
4582   CHECK(CompileRun("o0_mirror.protoObject() == o3_mirror")->BooleanValue());
4583 }
4584
4585
4586 static void ProtperyXNativeGetter(
4587     v8::Local<v8::String> property,
4588     const v8::PropertyCallbackInfo<v8::Value>& info) {
4589   info.GetReturnValue().Set(10);
4590 }
4591
4592
4593 TEST(NativeGetterPropertyMirror) {
4594   // Create a V8 environment with debug access.
4595   DebugLocalContext env;
4596   v8::Isolate* isolate = env->GetIsolate();
4597   v8::HandleScope scope(isolate);
4598   env.ExposeDebug();
4599
4600   v8::Handle<v8::String> name = v8::String::NewFromUtf8(isolate, "x");
4601   // Create object with named accessor.
4602   v8::Handle<v8::ObjectTemplate> named = v8::ObjectTemplate::New(isolate);
4603   named->SetAccessor(name, &ProtperyXNativeGetter, NULL,
4604       v8::Handle<v8::Value>(), v8::DEFAULT, v8::None);
4605
4606   // Create object with named property getter.
4607   env->Global()->Set(v8::String::NewFromUtf8(isolate, "instance"),
4608                      named->NewInstance());
4609   CHECK_EQ(10, CompileRun("instance.x")->Int32Value());
4610
4611   // Get mirror for the object with property getter.
4612   CompileRun("var instance_mirror = debug.MakeMirror(instance);");
4613   CHECK(CompileRun(
4614       "instance_mirror instanceof debug.ObjectMirror")->BooleanValue());
4615
4616   CompileRun("var named_names = instance_mirror.propertyNames();");
4617   CHECK_EQ(1, CompileRun("named_names.length")->Int32Value());
4618   CHECK(CompileRun("named_names[0] == 'x'")->BooleanValue());
4619   CHECK(CompileRun(
4620       "instance_mirror.property('x').value().isNumber()")->BooleanValue());
4621   CHECK(CompileRun(
4622       "instance_mirror.property('x').value().value() == 10")->BooleanValue());
4623 }
4624
4625
4626 static void ProtperyXNativeGetterThrowingError(
4627     v8::Local<v8::String> property,
4628     const v8::PropertyCallbackInfo<v8::Value>& info) {
4629   CompileRun("throw new Error('Error message');");
4630 }
4631
4632
4633 TEST(NativeGetterThrowingErrorPropertyMirror) {
4634   // Create a V8 environment with debug access.
4635   DebugLocalContext env;
4636   v8::Isolate* isolate = env->GetIsolate();
4637   v8::HandleScope scope(isolate);
4638   env.ExposeDebug();
4639
4640   v8::Handle<v8::String> name = v8::String::NewFromUtf8(isolate, "x");
4641   // Create object with named accessor.
4642   v8::Handle<v8::ObjectTemplate> named = v8::ObjectTemplate::New(isolate);
4643   named->SetAccessor(name, &ProtperyXNativeGetterThrowingError, NULL,
4644       v8::Handle<v8::Value>(), v8::DEFAULT, v8::None);
4645
4646   // Create object with named property getter.
4647   env->Global()->Set(v8::String::NewFromUtf8(isolate, "instance"),
4648                      named->NewInstance());
4649
4650   // Get mirror for the object with property getter.
4651   CompileRun("var instance_mirror = debug.MakeMirror(instance);");
4652   CHECK(CompileRun(
4653       "instance_mirror instanceof debug.ObjectMirror")->BooleanValue());
4654   CompileRun("named_names = instance_mirror.propertyNames();");
4655   CHECK_EQ(1, CompileRun("named_names.length")->Int32Value());
4656   CHECK(CompileRun("named_names[0] == 'x'")->BooleanValue());
4657   CHECK(CompileRun(
4658       "instance_mirror.property('x').value().isError()")->BooleanValue());
4659
4660   // Check that the message is that passed to the Error constructor.
4661   CHECK(CompileRun(
4662       "instance_mirror.property('x').value().message() == 'Error message'")->
4663           BooleanValue());
4664 }
4665
4666
4667 // Test that hidden properties object is not returned as an unnamed property
4668 // among regular properties.
4669 // See http://crbug.com/26491
4670 TEST(NoHiddenProperties) {
4671   // Create a V8 environment with debug access.
4672   DebugLocalContext env;
4673   v8::Isolate* isolate = env->GetIsolate();
4674   v8::HandleScope scope(isolate);
4675   env.ExposeDebug();
4676
4677   // Create an object in the global scope.
4678   const char* source = "var obj = {a: 1};";
4679   v8::Script::Compile(v8::String::NewFromUtf8(isolate, source))
4680       ->Run();
4681   v8::Local<v8::Object> obj = v8::Local<v8::Object>::Cast(
4682       env->Global()->Get(v8::String::NewFromUtf8(isolate, "obj")));
4683   // Set a hidden property on the object.
4684   obj->SetHiddenValue(
4685       v8::String::NewFromUtf8(isolate, "v8::test-debug::a"),
4686       v8::Int32::New(isolate, 11));
4687
4688   // Get mirror for the object with property getter.
4689   CompileRun("var obj_mirror = debug.MakeMirror(obj);");
4690   CHECK(CompileRun(
4691       "obj_mirror instanceof debug.ObjectMirror")->BooleanValue());
4692   CompileRun("var named_names = obj_mirror.propertyNames();");
4693   // There should be exactly one property. But there is also an unnamed
4694   // property whose value is hidden properties dictionary. The latter
4695   // property should not be in the list of reguar properties.
4696   CHECK_EQ(1, CompileRun("named_names.length")->Int32Value());
4697   CHECK(CompileRun("named_names[0] == 'a'")->BooleanValue());
4698   CHECK(CompileRun(
4699       "obj_mirror.property('a').value().value() == 1")->BooleanValue());
4700
4701   // Object created by t0 will become hidden prototype of object 'obj'.
4702   v8::Handle<v8::FunctionTemplate> t0 = v8::FunctionTemplate::New(isolate);
4703   t0->InstanceTemplate()->Set(v8::String::NewFromUtf8(isolate, "b"),
4704                               v8::Number::New(isolate, 2));
4705   t0->SetHiddenPrototype(true);
4706   v8::Handle<v8::FunctionTemplate> t1 = v8::FunctionTemplate::New(isolate);
4707   t1->InstanceTemplate()->Set(v8::String::NewFromUtf8(isolate, "c"),
4708                               v8::Number::New(isolate, 3));
4709
4710   // Create proto objects, add hidden properties to them and set them on
4711   // the global object.
4712   v8::Handle<v8::Object> protoObj = t0->GetFunction()->NewInstance();
4713   protoObj->SetHiddenValue(
4714       v8::String::NewFromUtf8(isolate, "v8::test-debug::b"),
4715       v8::Int32::New(isolate, 12));
4716   env->Global()->Set(v8::String::NewFromUtf8(isolate, "protoObj"),
4717                      protoObj);
4718   v8::Handle<v8::Object> grandProtoObj = t1->GetFunction()->NewInstance();
4719   grandProtoObj->SetHiddenValue(
4720       v8::String::NewFromUtf8(isolate, "v8::test-debug::c"),
4721       v8::Int32::New(isolate, 13));
4722   env->Global()->Set(
4723       v8::String::NewFromUtf8(isolate, "grandProtoObj"),
4724       grandProtoObj);
4725
4726   // Setting prototypes: obj->protoObj->grandProtoObj
4727   protoObj->Set(v8::String::NewFromUtf8(isolate, "__proto__"),
4728                 grandProtoObj);
4729   obj->Set(v8::String::NewFromUtf8(isolate, "__proto__"), protoObj);
4730
4731   // Get mirror for the object with property getter.
4732   CompileRun("var obj_mirror = debug.MakeMirror(obj);");
4733   CHECK(CompileRun(
4734       "obj_mirror instanceof debug.ObjectMirror")->BooleanValue());
4735   CompileRun("var named_names = obj_mirror.propertyNames();");
4736   // There should be exactly two properties - one from the object itself and
4737   // another from its hidden prototype.
4738   CHECK_EQ(2, CompileRun("named_names.length")->Int32Value());
4739   CHECK(CompileRun("named_names.sort(); named_names[0] == 'a' &&"
4740                    "named_names[1] == 'b'")->BooleanValue());
4741   CHECK(CompileRun(
4742       "obj_mirror.property('a').value().value() == 1")->BooleanValue());
4743   CHECK(CompileRun(
4744       "obj_mirror.property('b').value().value() == 2")->BooleanValue());
4745 }
4746
4747
4748 // Multithreaded tests of JSON debugger protocol
4749
4750 // Support classes
4751
4752 // Provides synchronization between N threads, where N is a template parameter.
4753 // The Wait() call blocks a thread until it is called for the Nth time, then all
4754 // calls return.  Each ThreadBarrier object can only be used once.
4755 template <int N>
4756 class ThreadBarrier V8_FINAL {
4757  public:
4758   ThreadBarrier() : num_blocked_(0) {}
4759
4760   ~ThreadBarrier() {
4761     LockGuard<Mutex> lock_guard(&mutex_);
4762     if (num_blocked_ != 0) {
4763       CHECK_EQ(N, num_blocked_);
4764     }
4765   }
4766
4767   void Wait() {
4768     LockGuard<Mutex> lock_guard(&mutex_);
4769     CHECK_LT(num_blocked_, N);
4770     num_blocked_++;
4771     if (N == num_blocked_) {
4772       // Signal and unblock all waiting threads.
4773       cv_.NotifyAll();
4774       printf("BARRIER\n\n");
4775       fflush(stdout);
4776     } else {  // Wait for the semaphore.
4777       while (num_blocked_ < N) {
4778         cv_.Wait(&mutex_);
4779       }
4780     }
4781     CHECK_EQ(N, num_blocked_);
4782   }
4783
4784  private:
4785   ConditionVariable cv_;
4786   Mutex mutex_;
4787   int num_blocked_;
4788
4789   STATIC_CHECK(N > 0);
4790
4791   DISALLOW_COPY_AND_ASSIGN(ThreadBarrier);
4792 };
4793
4794
4795 // A set containing enough barriers and semaphores for any of the tests.
4796 class Barriers {
4797  public:
4798   Barriers() : semaphore_1(0), semaphore_2(0) {}
4799   ThreadBarrier<2> barrier_1;
4800   ThreadBarrier<2> barrier_2;
4801   ThreadBarrier<2> barrier_3;
4802   ThreadBarrier<2> barrier_4;
4803   ThreadBarrier<2> barrier_5;
4804   v8::internal::Semaphore semaphore_1;
4805   v8::internal::Semaphore semaphore_2;
4806 };
4807
4808
4809 // We match parts of the message to decide if it is a break message.
4810 bool IsBreakEventMessage(char *message) {
4811   const char* type_event = "\"type\":\"event\"";
4812   const char* event_break = "\"event\":\"break\"";
4813   // Does the message contain both type:event and event:break?
4814   return strstr(message, type_event) != NULL &&
4815          strstr(message, event_break) != NULL;
4816 }
4817
4818
4819 // We match parts of the message to decide if it is a exception message.
4820 bool IsExceptionEventMessage(char *message) {
4821   const char* type_event = "\"type\":\"event\"";
4822   const char* event_exception = "\"event\":\"exception\"";
4823   // Does the message contain both type:event and event:exception?
4824   return strstr(message, type_event) != NULL &&
4825       strstr(message, event_exception) != NULL;
4826 }
4827
4828
4829 // We match the message wether it is an evaluate response message.
4830 bool IsEvaluateResponseMessage(char* message) {
4831   const char* type_response = "\"type\":\"response\"";
4832   const char* command_evaluate = "\"command\":\"evaluate\"";
4833   // Does the message contain both type:response and command:evaluate?
4834   return strstr(message, type_response) != NULL &&
4835          strstr(message, command_evaluate) != NULL;
4836 }
4837
4838
4839 static int StringToInt(const char* s) {
4840   return atoi(s);  // NOLINT
4841 }
4842
4843
4844 // We match parts of the message to get evaluate result int value.
4845 int GetEvaluateIntResult(char *message) {
4846   const char* value = "\"value\":";
4847   char* pos = strstr(message, value);
4848   if (pos == NULL) {
4849     return -1;
4850   }
4851   int res = -1;
4852   res = StringToInt(pos + strlen(value));
4853   return res;
4854 }
4855
4856
4857 // We match parts of the message to get hit breakpoint id.
4858 int GetBreakpointIdFromBreakEventMessage(char *message) {
4859   const char* breakpoints = "\"breakpoints\":[";
4860   char* pos = strstr(message, breakpoints);
4861   if (pos == NULL) {
4862     return -1;
4863   }
4864   int res = -1;
4865   res = StringToInt(pos + strlen(breakpoints));
4866   return res;
4867 }
4868
4869
4870 // We match parts of the message to get total frames number.
4871 int GetTotalFramesInt(char *message) {
4872   const char* prefix = "\"totalFrames\":";
4873   char* pos = strstr(message, prefix);
4874   if (pos == NULL) {
4875     return -1;
4876   }
4877   pos += strlen(prefix);
4878   int res = StringToInt(pos);
4879   return res;
4880 }
4881
4882
4883 // We match parts of the message to get source line.
4884 int GetSourceLineFromBreakEventMessage(char *message) {
4885   const char* source_line = "\"sourceLine\":";
4886   char* pos = strstr(message, source_line);
4887   if (pos == NULL) {
4888     return -1;
4889   }
4890   int res = -1;
4891   res = StringToInt(pos + strlen(source_line));
4892   return res;
4893 }
4894
4895
4896 /* Test MessageQueues */
4897 /* Tests the message queues that hold debugger commands and
4898  * response messages to the debugger.  Fills queues and makes
4899  * them grow.
4900  */
4901 Barriers message_queue_barriers;
4902
4903 // This is the debugger thread, that executes no v8 calls except
4904 // placing JSON debugger commands in the queue.
4905 class MessageQueueDebuggerThread : public v8::internal::Thread {
4906  public:
4907   MessageQueueDebuggerThread()
4908       : Thread("MessageQueueDebuggerThread") { }
4909   void Run();
4910 };
4911
4912
4913 static void MessageHandler(const v8::Debug::Message& message) {
4914   v8::Handle<v8::String> json = message.GetJSON();
4915   v8::String::Utf8Value utf8(json);
4916   if (IsBreakEventMessage(*utf8)) {
4917     // Lets test script wait until break occurs to send commands.
4918     // Signals when a break is reported.
4919     message_queue_barriers.semaphore_2.Signal();
4920   }
4921
4922   // Allow message handler to block on a semaphore, to test queueing of
4923   // messages while blocked.
4924   message_queue_barriers.semaphore_1.Wait();
4925 }
4926
4927
4928 void MessageQueueDebuggerThread::Run() {
4929   const int kBufferSize = 1000;
4930   uint16_t buffer_1[kBufferSize];
4931   uint16_t buffer_2[kBufferSize];
4932   const char* command_1 =
4933       "{\"seq\":117,"
4934        "\"type\":\"request\","
4935        "\"command\":\"evaluate\","
4936        "\"arguments\":{\"expression\":\"1+2\"}}";
4937   const char* command_2 =
4938     "{\"seq\":118,"
4939      "\"type\":\"request\","
4940      "\"command\":\"evaluate\","
4941      "\"arguments\":{\"expression\":\"1+a\"}}";
4942   const char* command_3 =
4943     "{\"seq\":119,"
4944      "\"type\":\"request\","
4945      "\"command\":\"evaluate\","
4946      "\"arguments\":{\"expression\":\"c.d * b\"}}";
4947   const char* command_continue =
4948     "{\"seq\":106,"
4949      "\"type\":\"request\","
4950      "\"command\":\"continue\"}";
4951   const char* command_single_step =
4952     "{\"seq\":107,"
4953      "\"type\":\"request\","
4954      "\"command\":\"continue\","
4955      "\"arguments\":{\"stepaction\":\"next\"}}";
4956
4957   /* Interleaved sequence of actions by the two threads:*/
4958   // Main thread compiles and runs source_1
4959   message_queue_barriers.semaphore_1.Signal();
4960   message_queue_barriers.barrier_1.Wait();
4961   // Post 6 commands, filling the command queue and making it expand.
4962   // These calls return immediately, but the commands stay on the queue
4963   // until the execution of source_2.
4964   // Note: AsciiToUtf16 executes before SendCommand, so command is copied
4965   // to buffer before buffer is sent to SendCommand.
4966   v8::Isolate* isolate = CcTest::isolate();
4967   v8::Debug::SendCommand(isolate, buffer_1, AsciiToUtf16(command_1, buffer_1));
4968   v8::Debug::SendCommand(isolate, buffer_2, AsciiToUtf16(command_2, buffer_2));
4969   v8::Debug::SendCommand(isolate, buffer_2, AsciiToUtf16(command_3, buffer_2));
4970   v8::Debug::SendCommand(isolate, buffer_2, AsciiToUtf16(command_3, buffer_2));
4971   v8::Debug::SendCommand(isolate, buffer_2, AsciiToUtf16(command_3, buffer_2));
4972   message_queue_barriers.barrier_2.Wait();
4973   // Main thread compiles and runs source_2.
4974   // Queued commands are executed at the start of compilation of source_2(
4975   // beforeCompile event).
4976   // Free the message handler to process all the messages from the queue. 7
4977   // messages are expected: 2 afterCompile events and 5 responses.
4978   // All the commands added so far will fail to execute as long as call stack
4979   // is empty on beforeCompile event.
4980   for (int i = 0; i < 6 ; ++i) {
4981     message_queue_barriers.semaphore_1.Signal();
4982   }
4983   message_queue_barriers.barrier_3.Wait();
4984   // Main thread compiles and runs source_3.
4985   // Don't stop in the afterCompile handler.
4986   message_queue_barriers.semaphore_1.Signal();
4987   // source_3 includes a debugger statement, which causes a break event.
4988   // Wait on break event from hitting "debugger" statement
4989   message_queue_barriers.semaphore_2.Wait();
4990   // These should execute after the "debugger" statement in source_2
4991   v8::Debug::SendCommand(isolate, buffer_1, AsciiToUtf16(command_1, buffer_1));
4992   v8::Debug::SendCommand(isolate, buffer_2, AsciiToUtf16(command_2, buffer_2));
4993   v8::Debug::SendCommand(isolate, buffer_2, AsciiToUtf16(command_3, buffer_2));
4994   v8::Debug::SendCommand(
4995       isolate, buffer_2, AsciiToUtf16(command_single_step, buffer_2));
4996   // Run after 2 break events, 4 responses.
4997   for (int i = 0; i < 6 ; ++i) {
4998     message_queue_barriers.semaphore_1.Signal();
4999   }
5000   // Wait on break event after a single step executes.
5001   message_queue_barriers.semaphore_2.Wait();
5002   v8::Debug::SendCommand(isolate, buffer_1, AsciiToUtf16(command_2, buffer_1));
5003   v8::Debug::SendCommand(
5004       isolate, buffer_2, AsciiToUtf16(command_continue, buffer_2));
5005   // Run after 2 responses.
5006   for (int i = 0; i < 2 ; ++i) {
5007     message_queue_barriers.semaphore_1.Signal();
5008   }
5009   // Main thread continues running source_3 to end, waits for this thread.
5010 }
5011
5012
5013 // This thread runs the v8 engine.
5014 TEST(MessageQueues) {
5015   MessageQueueDebuggerThread message_queue_debugger_thread;
5016
5017   // Create a V8 environment
5018   DebugLocalContext env;
5019   v8::HandleScope scope(env->GetIsolate());
5020   v8::Debug::SetMessageHandler2(MessageHandler);
5021   message_queue_debugger_thread.Start();
5022
5023   const char* source_1 = "a = 3; b = 4; c = new Object(); c.d = 5;";
5024   const char* source_2 = "e = 17;";
5025   const char* source_3 = "a = 4; debugger; a = 5; a = 6; a = 7;";
5026
5027   // See MessageQueueDebuggerThread::Run for interleaved sequence of
5028   // API calls and events in the two threads.
5029   CompileRun(source_1);
5030   message_queue_barriers.barrier_1.Wait();
5031   message_queue_barriers.barrier_2.Wait();
5032   CompileRun(source_2);
5033   message_queue_barriers.barrier_3.Wait();
5034   CompileRun(source_3);
5035   message_queue_debugger_thread.Join();
5036   fflush(stdout);
5037 }
5038
5039
5040 class TestClientData : public v8::Debug::ClientData {
5041  public:
5042   TestClientData() {
5043     constructor_call_counter++;
5044   }
5045   virtual ~TestClientData() {
5046     destructor_call_counter++;
5047   }
5048
5049   static void ResetCounters() {
5050     constructor_call_counter = 0;
5051     destructor_call_counter = 0;
5052   }
5053
5054   static int constructor_call_counter;
5055   static int destructor_call_counter;
5056 };
5057
5058 int TestClientData::constructor_call_counter = 0;
5059 int TestClientData::destructor_call_counter = 0;
5060
5061
5062 // Tests that MessageQueue doesn't destroy client data when expands and
5063 // does destroy when it dies.
5064 TEST(MessageQueueExpandAndDestroy) {
5065   TestClientData::ResetCounters();
5066   { // Create a scope for the queue.
5067     CommandMessageQueue queue(1);
5068     queue.Put(CommandMessage::New(Vector<uint16_t>::empty(),
5069                                   new TestClientData()));
5070     queue.Put(CommandMessage::New(Vector<uint16_t>::empty(),
5071                                   new TestClientData()));
5072     queue.Put(CommandMessage::New(Vector<uint16_t>::empty(),
5073                                   new TestClientData()));
5074     CHECK_EQ(0, TestClientData::destructor_call_counter);
5075     queue.Get().Dispose();
5076     CHECK_EQ(1, TestClientData::destructor_call_counter);
5077     queue.Put(CommandMessage::New(Vector<uint16_t>::empty(),
5078                                   new TestClientData()));
5079     queue.Put(CommandMessage::New(Vector<uint16_t>::empty(),
5080                                   new TestClientData()));
5081     queue.Put(CommandMessage::New(Vector<uint16_t>::empty(),
5082                                   new TestClientData()));
5083     queue.Put(CommandMessage::New(Vector<uint16_t>::empty(),
5084                                   new TestClientData()));
5085     queue.Put(CommandMessage::New(Vector<uint16_t>::empty(),
5086                                   new TestClientData()));
5087     CHECK_EQ(1, TestClientData::destructor_call_counter);
5088     queue.Get().Dispose();
5089     CHECK_EQ(2, TestClientData::destructor_call_counter);
5090   }
5091   // All the client data should be destroyed when the queue is destroyed.
5092   CHECK_EQ(TestClientData::destructor_call_counter,
5093            TestClientData::destructor_call_counter);
5094 }
5095
5096
5097 static int handled_client_data_instances_count = 0;
5098 static void MessageHandlerCountingClientData(
5099     const v8::Debug::Message& message) {
5100   if (message.GetClientData() != NULL) {
5101     handled_client_data_instances_count++;
5102   }
5103 }
5104
5105
5106 // Tests that all client data passed to the debugger are sent to the handler.
5107 TEST(SendClientDataToHandler) {
5108   // Create a V8 environment
5109   DebugLocalContext env;
5110   v8::Isolate* isolate = env->GetIsolate();
5111   v8::HandleScope scope(isolate);
5112   TestClientData::ResetCounters();
5113   handled_client_data_instances_count = 0;
5114   v8::Debug::SetMessageHandler2(MessageHandlerCountingClientData);
5115   const char* source_1 = "a = 3; b = 4; c = new Object(); c.d = 5;";
5116   const int kBufferSize = 1000;
5117   uint16_t buffer[kBufferSize];
5118   const char* command_1 =
5119       "{\"seq\":117,"
5120        "\"type\":\"request\","
5121        "\"command\":\"evaluate\","
5122        "\"arguments\":{\"expression\":\"1+2\"}}";
5123   const char* command_2 =
5124     "{\"seq\":118,"
5125      "\"type\":\"request\","
5126      "\"command\":\"evaluate\","
5127      "\"arguments\":{\"expression\":\"1+a\"}}";
5128   const char* command_continue =
5129     "{\"seq\":106,"
5130      "\"type\":\"request\","
5131      "\"command\":\"continue\"}";
5132
5133   v8::Debug::SendCommand(isolate, buffer, AsciiToUtf16(command_1, buffer),
5134                          new TestClientData());
5135   v8::Debug::SendCommand(
5136       isolate, buffer, AsciiToUtf16(command_2, buffer), NULL);
5137   v8::Debug::SendCommand(isolate, buffer, AsciiToUtf16(command_2, buffer),
5138                          new TestClientData());
5139   v8::Debug::SendCommand(isolate, buffer, AsciiToUtf16(command_2, buffer),
5140                          new TestClientData());
5141   // All the messages will be processed on beforeCompile event.
5142   CompileRun(source_1);
5143   v8::Debug::SendCommand(
5144       isolate, buffer, AsciiToUtf16(command_continue, buffer));
5145   CHECK_EQ(3, TestClientData::constructor_call_counter);
5146   CHECK_EQ(TestClientData::constructor_call_counter,
5147            handled_client_data_instances_count);
5148   CHECK_EQ(TestClientData::constructor_call_counter,
5149            TestClientData::destructor_call_counter);
5150 }
5151
5152
5153 /* Test ThreadedDebugging */
5154 /* This test interrupts a running infinite loop that is
5155  * occupying the v8 thread by a break command from the
5156  * debugger thread.  It then changes the value of a
5157  * global object, to make the loop terminate.
5158  */
5159
5160 Barriers threaded_debugging_barriers;
5161
5162 class V8Thread : public v8::internal::Thread {
5163  public:
5164   V8Thread() : Thread("V8Thread") { }
5165   void Run();
5166 };
5167
5168 class DebuggerThread : public v8::internal::Thread {
5169  public:
5170   DebuggerThread() : Thread("DebuggerThread") { }
5171   void Run();
5172 };
5173
5174
5175 static void ThreadedAtBarrier1(
5176     const v8::FunctionCallbackInfo<v8::Value>& args) {
5177   threaded_debugging_barriers.barrier_1.Wait();
5178 }
5179
5180
5181 static void ThreadedMessageHandler(const v8::Debug::Message& message) {
5182   static char print_buffer[1000];
5183   v8::String::Value json(message.GetJSON());
5184   Utf16ToAscii(*json, json.length(), print_buffer);
5185   if (IsBreakEventMessage(print_buffer)) {
5186     // Check that we are inside the while loop.
5187     int source_line = GetSourceLineFromBreakEventMessage(print_buffer);
5188     // TODO(2047): This should really be 8 <= source_line <= 13; but we
5189     // currently have an off-by-one error when calculating the source
5190     // position corresponding to the program counter at the debug break.
5191     CHECK(7 <= source_line && source_line <= 13);
5192     threaded_debugging_barriers.barrier_2.Wait();
5193   }
5194 }
5195
5196
5197 void V8Thread::Run() {
5198   const char* source =
5199       "flag = true;\n"
5200       "function bar( new_value ) {\n"
5201       "  flag = new_value;\n"
5202       "  return \"Return from bar(\" + new_value + \")\";\n"
5203       "}\n"
5204       "\n"
5205       "function foo() {\n"
5206       "  var x = 1;\n"
5207       "  while ( flag == true ) {\n"
5208       "    if ( x == 1 ) {\n"
5209       "      ThreadedAtBarrier1();\n"
5210       "    }\n"
5211       "    x = x + 1;\n"
5212       "  }\n"
5213       "}\n"
5214       "\n"
5215       "foo();\n";
5216
5217   v8::Isolate* isolate = CcTest::isolate();
5218   v8::Isolate::Scope isolate_scope(isolate);
5219   DebugLocalContext env;
5220   v8::HandleScope scope(env->GetIsolate());
5221   v8::Debug::SetMessageHandler2(&ThreadedMessageHandler);
5222   v8::Handle<v8::ObjectTemplate> global_template =
5223       v8::ObjectTemplate::New(env->GetIsolate());
5224   global_template->Set(
5225       v8::String::NewFromUtf8(env->GetIsolate(), "ThreadedAtBarrier1"),
5226       v8::FunctionTemplate::New(isolate, ThreadedAtBarrier1));
5227   v8::Handle<v8::Context> context = v8::Context::New(isolate,
5228                                                      NULL,
5229                                                      global_template);
5230   v8::Context::Scope context_scope(context);
5231
5232   CompileRun(source);
5233 }
5234
5235
5236 void DebuggerThread::Run() {
5237   const int kBufSize = 1000;
5238   uint16_t buffer[kBufSize];
5239
5240   const char* command_1 = "{\"seq\":102,"
5241       "\"type\":\"request\","
5242       "\"command\":\"evaluate\","
5243       "\"arguments\":{\"expression\":\"bar(false)\"}}";
5244   const char* command_2 = "{\"seq\":103,"
5245       "\"type\":\"request\","
5246       "\"command\":\"continue\"}";
5247
5248   v8::Isolate* isolate = CcTest::isolate();
5249   threaded_debugging_barriers.barrier_1.Wait();
5250   v8::Debug::DebugBreak(isolate);
5251   threaded_debugging_barriers.barrier_2.Wait();
5252   v8::Debug::SendCommand(isolate, buffer, AsciiToUtf16(command_1, buffer));
5253   v8::Debug::SendCommand(isolate, buffer, AsciiToUtf16(command_2, buffer));
5254 }
5255
5256
5257 TEST(ThreadedDebugging) {
5258   DebuggerThread debugger_thread;
5259   V8Thread v8_thread;
5260
5261   // Create a V8 environment
5262   v8_thread.Start();
5263   debugger_thread.Start();
5264
5265   v8_thread.Join();
5266   debugger_thread.Join();
5267 }
5268
5269
5270 /* Test RecursiveBreakpoints */
5271 /* In this test, the debugger evaluates a function with a breakpoint, after
5272  * hitting a breakpoint in another function.  We do this with both values
5273  * of the flag enabling recursive breakpoints, and verify that the second
5274  * breakpoint is hit when enabled, and missed when disabled.
5275  */
5276
5277 class BreakpointsV8Thread : public v8::internal::Thread {
5278  public:
5279   BreakpointsV8Thread() : Thread("BreakpointsV8Thread") { }
5280   void Run();
5281 };
5282
5283 class BreakpointsDebuggerThread : public v8::internal::Thread {
5284  public:
5285   explicit BreakpointsDebuggerThread(bool global_evaluate)
5286       : Thread("BreakpointsDebuggerThread"),
5287         global_evaluate_(global_evaluate) {}
5288   void Run();
5289
5290  private:
5291   bool global_evaluate_;
5292 };
5293
5294
5295 Barriers* breakpoints_barriers;
5296 int break_event_breakpoint_id;
5297 int evaluate_int_result;
5298
5299 static void BreakpointsMessageHandler(const v8::Debug::Message& message) {
5300   static char print_buffer[1000];
5301   v8::String::Value json(message.GetJSON());
5302   Utf16ToAscii(*json, json.length(), print_buffer);
5303
5304   if (IsBreakEventMessage(print_buffer)) {
5305     break_event_breakpoint_id =
5306         GetBreakpointIdFromBreakEventMessage(print_buffer);
5307     breakpoints_barriers->semaphore_1.Signal();
5308   } else if (IsEvaluateResponseMessage(print_buffer)) {
5309     evaluate_int_result = GetEvaluateIntResult(print_buffer);
5310     breakpoints_barriers->semaphore_1.Signal();
5311   }
5312 }
5313
5314
5315 void BreakpointsV8Thread::Run() {
5316   const char* source_1 = "var y_global = 3;\n"
5317     "function cat( new_value ) {\n"
5318     "  var x = new_value;\n"
5319     "  y_global = y_global + 4;\n"
5320     "  x = 3 * x + 1;\n"
5321     "  y_global = y_global + 5;\n"
5322     "  return x;\n"
5323     "}\n"
5324     "\n"
5325     "function dog() {\n"
5326     "  var x = 1;\n"
5327     "  x = y_global;"
5328     "  var z = 3;"
5329     "  x += 100;\n"
5330     "  return x;\n"
5331     "}\n"
5332     "\n";
5333   const char* source_2 = "cat(17);\n"
5334     "cat(19);\n";
5335
5336   v8::Isolate* isolate = CcTest::isolate();
5337   v8::Isolate::Scope isolate_scope(isolate);
5338   DebugLocalContext env;
5339   v8::HandleScope scope(isolate);
5340   v8::Debug::SetMessageHandler2(&BreakpointsMessageHandler);
5341
5342   CompileRun(source_1);
5343   breakpoints_barriers->barrier_1.Wait();
5344   breakpoints_barriers->barrier_2.Wait();
5345   CompileRun(source_2);
5346 }
5347
5348
5349 void BreakpointsDebuggerThread::Run() {
5350   const int kBufSize = 1000;
5351   uint16_t buffer[kBufSize];
5352
5353   const char* command_1 = "{\"seq\":101,"
5354       "\"type\":\"request\","
5355       "\"command\":\"setbreakpoint\","
5356       "\"arguments\":{\"type\":\"function\",\"target\":\"cat\",\"line\":3}}";
5357   const char* command_2 = "{\"seq\":102,"
5358       "\"type\":\"request\","
5359       "\"command\":\"setbreakpoint\","
5360       "\"arguments\":{\"type\":\"function\",\"target\":\"dog\",\"line\":3}}";
5361   const char* command_3;
5362   if (this->global_evaluate_) {
5363     command_3 = "{\"seq\":103,"
5364         "\"type\":\"request\","
5365         "\"command\":\"evaluate\","
5366         "\"arguments\":{\"expression\":\"dog()\",\"disable_break\":false,"
5367         "\"global\":true}}";
5368   } else {
5369     command_3 = "{\"seq\":103,"
5370         "\"type\":\"request\","
5371         "\"command\":\"evaluate\","
5372         "\"arguments\":{\"expression\":\"dog()\",\"disable_break\":false}}";
5373   }
5374   const char* command_4;
5375   if (this->global_evaluate_) {
5376     command_4 = "{\"seq\":104,"
5377         "\"type\":\"request\","
5378         "\"command\":\"evaluate\","
5379         "\"arguments\":{\"expression\":\"100 + 8\",\"disable_break\":true,"
5380         "\"global\":true}}";
5381   } else {
5382     command_4 = "{\"seq\":104,"
5383         "\"type\":\"request\","
5384         "\"command\":\"evaluate\","
5385         "\"arguments\":{\"expression\":\"x + 1\",\"disable_break\":true}}";
5386   }
5387   const char* command_5 = "{\"seq\":105,"
5388       "\"type\":\"request\","
5389       "\"command\":\"continue\"}";
5390   const char* command_6 = "{\"seq\":106,"
5391       "\"type\":\"request\","
5392       "\"command\":\"continue\"}";
5393   const char* command_7;
5394   if (this->global_evaluate_) {
5395     command_7 = "{\"seq\":107,"
5396         "\"type\":\"request\","
5397         "\"command\":\"evaluate\","
5398         "\"arguments\":{\"expression\":\"dog()\",\"disable_break\":true,"
5399         "\"global\":true}}";
5400   } else {
5401     command_7 = "{\"seq\":107,"
5402         "\"type\":\"request\","
5403         "\"command\":\"evaluate\","
5404         "\"arguments\":{\"expression\":\"dog()\",\"disable_break\":true}}";
5405   }
5406   const char* command_8 = "{\"seq\":108,"
5407       "\"type\":\"request\","
5408       "\"command\":\"continue\"}";
5409
5410
5411   v8::Isolate* isolate = CcTest::isolate();
5412   v8::Isolate::Scope isolate_scope(isolate);
5413   // v8 thread initializes, runs source_1
5414   breakpoints_barriers->barrier_1.Wait();
5415   // 1:Set breakpoint in cat() (will get id 1).
5416   v8::Debug::SendCommand(isolate, buffer, AsciiToUtf16(command_1, buffer));
5417   // 2:Set breakpoint in dog() (will get id 2).
5418   v8::Debug::SendCommand(isolate, buffer, AsciiToUtf16(command_2, buffer));
5419   breakpoints_barriers->barrier_2.Wait();
5420   // V8 thread starts compiling source_2.
5421   // Automatic break happens, to run queued commands
5422   // breakpoints_barriers->semaphore_1.Wait();
5423   // Commands 1 through 3 run, thread continues.
5424   // v8 thread runs source_2 to breakpoint in cat().
5425   // message callback receives break event.
5426   breakpoints_barriers->semaphore_1.Wait();
5427   // Must have hit breakpoint #1.
5428   CHECK_EQ(1, break_event_breakpoint_id);
5429   // 4:Evaluate dog() (which has a breakpoint).
5430   v8::Debug::SendCommand(isolate, buffer, AsciiToUtf16(command_3, buffer));
5431   // V8 thread hits breakpoint in dog().
5432   breakpoints_barriers->semaphore_1.Wait();  // wait for break event
5433   // Must have hit breakpoint #2.
5434   CHECK_EQ(2, break_event_breakpoint_id);
5435   // 5:Evaluate (x + 1).
5436   v8::Debug::SendCommand(isolate, buffer, AsciiToUtf16(command_4, buffer));
5437   // Evaluate (x + 1) finishes.
5438   breakpoints_barriers->semaphore_1.Wait();
5439   // Must have result 108.
5440   CHECK_EQ(108, evaluate_int_result);
5441   // 6:Continue evaluation of dog().
5442   v8::Debug::SendCommand(isolate, buffer, AsciiToUtf16(command_5, buffer));
5443   // Evaluate dog() finishes.
5444   breakpoints_barriers->semaphore_1.Wait();
5445   // Must have result 107.
5446   CHECK_EQ(107, evaluate_int_result);
5447   // 7:Continue evaluation of source_2, finish cat(17), hit breakpoint
5448   // in cat(19).
5449   v8::Debug::SendCommand(isolate, buffer, AsciiToUtf16(command_6, buffer));
5450   // Message callback gets break event.
5451   breakpoints_barriers->semaphore_1.Wait();  // wait for break event
5452   // Must have hit breakpoint #1.
5453   CHECK_EQ(1, break_event_breakpoint_id);
5454   // 8: Evaluate dog() with breaks disabled.
5455   v8::Debug::SendCommand(isolate, buffer, AsciiToUtf16(command_7, buffer));
5456   // Evaluate dog() finishes.
5457   breakpoints_barriers->semaphore_1.Wait();
5458   // Must have result 116.
5459   CHECK_EQ(116, evaluate_int_result);
5460   // 9: Continue evaluation of source2, reach end.
5461   v8::Debug::SendCommand(isolate, buffer, AsciiToUtf16(command_8, buffer));
5462 }
5463
5464
5465 void TestRecursiveBreakpointsGeneric(bool global_evaluate) {
5466   i::FLAG_debugger_auto_break = true;
5467
5468   BreakpointsDebuggerThread breakpoints_debugger_thread(global_evaluate);
5469   BreakpointsV8Thread breakpoints_v8_thread;
5470
5471   // Create a V8 environment
5472   Barriers stack_allocated_breakpoints_barriers;
5473   breakpoints_barriers = &stack_allocated_breakpoints_barriers;
5474
5475   breakpoints_v8_thread.Start();
5476   breakpoints_debugger_thread.Start();
5477
5478   breakpoints_v8_thread.Join();
5479   breakpoints_debugger_thread.Join();
5480 }
5481
5482
5483 TEST(RecursiveBreakpoints) {
5484   TestRecursiveBreakpointsGeneric(false);
5485 }
5486
5487
5488 TEST(RecursiveBreakpointsGlobal) {
5489   TestRecursiveBreakpointsGeneric(true);
5490 }
5491
5492
5493 static void DummyDebugEventListener(
5494     const v8::Debug::EventDetails& event_details) {
5495 }
5496
5497
5498 TEST(SetDebugEventListenerOnUninitializedVM) {
5499   v8::Debug::SetDebugEventListener2(DummyDebugEventListener);
5500 }
5501
5502
5503 static void DummyMessageHandler(const v8::Debug::Message& message) {
5504 }
5505
5506
5507 TEST(SetMessageHandlerOnUninitializedVM) {
5508   v8::Debug::SetMessageHandler2(DummyMessageHandler);
5509 }
5510
5511
5512 // Source for a JavaScript function which returns the data parameter of a
5513 // function called in the context of the debugger. If no data parameter is
5514 // passed it throws an exception.
5515 static const char* debugger_call_with_data_source =
5516     "function debugger_call_with_data(exec_state, data) {"
5517     "  if (data) return data;"
5518     "  throw 'No data!'"
5519     "}";
5520 v8::Handle<v8::Function> debugger_call_with_data;
5521
5522
5523 // Source for a JavaScript function which returns the data parameter of a
5524 // function called in the context of the debugger. If no data parameter is
5525 // passed it throws an exception.
5526 static const char* debugger_call_with_closure_source =
5527     "var x = 3;"
5528     "(function (exec_state) {"
5529     "  if (exec_state.y) return x - 1;"
5530     "  exec_state.y = x;"
5531     "  return exec_state.y"
5532     "})";
5533 v8::Handle<v8::Function> debugger_call_with_closure;
5534
5535 // Function to retrieve the number of JavaScript frames by calling a JavaScript
5536 // in the debugger.
5537 static void CheckFrameCount(const v8::FunctionCallbackInfo<v8::Value>& args) {
5538   CHECK(v8::Debug::Call(frame_count)->IsNumber());
5539   CHECK_EQ(args[0]->Int32Value(),
5540            v8::Debug::Call(frame_count)->Int32Value());
5541 }
5542
5543
5544 // Function to retrieve the source line of the top JavaScript frame by calling a
5545 // JavaScript function in the debugger.
5546 static void CheckSourceLine(const v8::FunctionCallbackInfo<v8::Value>& args) {
5547   CHECK(v8::Debug::Call(frame_source_line)->IsNumber());
5548   CHECK_EQ(args[0]->Int32Value(),
5549            v8::Debug::Call(frame_source_line)->Int32Value());
5550 }
5551
5552
5553 // Function to test passing an additional parameter to a JavaScript function
5554 // called in the debugger. It also tests that functions called in the debugger
5555 // can throw exceptions.
5556 static void CheckDataParameter(
5557     const v8::FunctionCallbackInfo<v8::Value>& args) {
5558   v8::Handle<v8::String> data =
5559       v8::String::NewFromUtf8(args.GetIsolate(), "Test");
5560   CHECK(v8::Debug::Call(debugger_call_with_data, data)->IsString());
5561
5562   CHECK(v8::Debug::Call(debugger_call_with_data).IsEmpty());
5563   CHECK(v8::Debug::Call(debugger_call_with_data).IsEmpty());
5564
5565   v8::TryCatch catcher;
5566   v8::Debug::Call(debugger_call_with_data);
5567   CHECK(catcher.HasCaught());
5568   CHECK(catcher.Exception()->IsString());
5569 }
5570
5571
5572 // Function to test using a JavaScript with closure in the debugger.
5573 static void CheckClosure(const v8::FunctionCallbackInfo<v8::Value>& args) {
5574   CHECK(v8::Debug::Call(debugger_call_with_closure)->IsNumber());
5575   CHECK_EQ(3, v8::Debug::Call(debugger_call_with_closure)->Int32Value());
5576 }
5577
5578
5579 // Test functions called through the debugger.
5580 TEST(CallFunctionInDebugger) {
5581   // Create and enter a context with the functions CheckFrameCount,
5582   // CheckSourceLine and CheckDataParameter installed.
5583   v8::Isolate* isolate = CcTest::isolate();
5584   v8::HandleScope scope(isolate);
5585   v8::Handle<v8::ObjectTemplate> global_template =
5586       v8::ObjectTemplate::New(isolate);
5587   global_template->Set(
5588       v8::String::NewFromUtf8(isolate, "CheckFrameCount"),
5589       v8::FunctionTemplate::New(isolate, CheckFrameCount));
5590   global_template->Set(
5591       v8::String::NewFromUtf8(isolate, "CheckSourceLine"),
5592       v8::FunctionTemplate::New(isolate, CheckSourceLine));
5593   global_template->Set(
5594       v8::String::NewFromUtf8(isolate, "CheckDataParameter"),
5595       v8::FunctionTemplate::New(isolate, CheckDataParameter));
5596   global_template->Set(
5597       v8::String::NewFromUtf8(isolate, "CheckClosure"),
5598       v8::FunctionTemplate::New(isolate, CheckClosure));
5599   v8::Handle<v8::Context> context = v8::Context::New(isolate,
5600                                                      NULL,
5601                                                      global_template);
5602   v8::Context::Scope context_scope(context);
5603
5604   // Compile a function for checking the number of JavaScript frames.
5605   v8::Script::Compile(
5606       v8::String::NewFromUtf8(isolate, frame_count_source))->Run();
5607   frame_count = v8::Local<v8::Function>::Cast(context->Global()->Get(
5608       v8::String::NewFromUtf8(isolate, "frame_count")));
5609
5610   // Compile a function for returning the source line for the top frame.
5611   v8::Script::Compile(v8::String::NewFromUtf8(isolate,
5612                                               frame_source_line_source))->Run();
5613   frame_source_line = v8::Local<v8::Function>::Cast(context->Global()->Get(
5614       v8::String::NewFromUtf8(isolate, "frame_source_line")));
5615
5616   // Compile a function returning the data parameter.
5617   v8::Script::Compile(v8::String::NewFromUtf8(isolate,
5618                                               debugger_call_with_data_source))
5619       ->Run();
5620   debugger_call_with_data = v8::Local<v8::Function>::Cast(
5621       context->Global()->Get(v8::String::NewFromUtf8(
5622           isolate, "debugger_call_with_data")));
5623
5624   // Compile a function capturing closure.
5625   debugger_call_with_closure =
5626       v8::Local<v8::Function>::Cast(v8::Script::Compile(
5627           v8::String::NewFromUtf8(isolate,
5628                                   debugger_call_with_closure_source))->Run());
5629
5630   // Calling a function through the debugger returns 0 frames if there are
5631   // no JavaScript frames.
5632   CHECK_EQ(v8::Integer::New(isolate, 0),
5633            v8::Debug::Call(frame_count));
5634
5635   // Test that the number of frames can be retrieved.
5636   v8::Script::Compile(
5637       v8::String::NewFromUtf8(isolate, "CheckFrameCount(1)"))->Run();
5638   v8::Script::Compile(v8::String::NewFromUtf8(isolate,
5639                                               "function f() {"
5640                                               "  CheckFrameCount(2);"
5641                                               "}; f()"))->Run();
5642
5643   // Test that the source line can be retrieved.
5644   v8::Script::Compile(
5645       v8::String::NewFromUtf8(isolate, "CheckSourceLine(0)"))->Run();
5646   v8::Script::Compile(v8::String::NewFromUtf8(isolate,
5647                                               "function f() {\n"
5648                                               "  CheckSourceLine(1)\n"
5649                                               "  CheckSourceLine(2)\n"
5650                                               "  CheckSourceLine(3)\n"
5651                                               "}; f()"))->Run();
5652
5653   // Test that a parameter can be passed to a function called in the debugger.
5654   v8::Script::Compile(v8::String::NewFromUtf8(isolate,
5655                                               "CheckDataParameter()"))->Run();
5656
5657   // Test that a function with closure can be run in the debugger.
5658   v8::Script::Compile(
5659       v8::String::NewFromUtf8(isolate, "CheckClosure()"))->Run();
5660
5661   // Test that the source line is correct when there is a line offset.
5662   v8::ScriptOrigin origin(v8::String::NewFromUtf8(isolate, "test"),
5663                           v8::Integer::New(isolate, 7));
5664   v8::Script::Compile(
5665       v8::String::NewFromUtf8(isolate, "CheckSourceLine(7)"), &origin)
5666       ->Run();
5667   v8::Script::Compile(v8::String::NewFromUtf8(isolate,
5668                                               "function f() {\n"
5669                                               "  CheckSourceLine(8)\n"
5670                                               "  CheckSourceLine(9)\n"
5671                                               "  CheckSourceLine(10)\n"
5672                                               "}; f()"),
5673                       &origin)->Run();
5674 }
5675
5676
5677 // Debugger message handler which counts the number of breaks.
5678 static void SendContinueCommand();
5679 static void MessageHandlerBreakPointHitCount(
5680     const v8::Debug::Message& message) {
5681   if (message.IsEvent() && message.GetEvent() == v8::Break) {
5682     // Count the number of breaks.
5683     break_point_hit_count++;
5684
5685     SendContinueCommand();
5686   }
5687 }
5688
5689
5690 // Test that clearing the debug event listener actually clears all break points
5691 // and related information.
5692 TEST(DebuggerUnload) {
5693   DebugLocalContext env;
5694
5695   // Check debugger is unloaded before it is used.
5696   CheckDebuggerUnloaded();
5697
5698   // Set a debug event listener.
5699   break_point_hit_count = 0;
5700   v8::Debug::SetDebugEventListener2(DebugEventBreakPointHitCount);
5701   {
5702     v8::HandleScope scope(env->GetIsolate());
5703     // Create a couple of functions for the test.
5704     v8::Local<v8::Function> foo =
5705         CompileFunction(&env, "function foo(){x=1}", "foo");
5706     v8::Local<v8::Function> bar =
5707         CompileFunction(&env, "function bar(){y=2}", "bar");
5708
5709     // Set some break points.
5710     SetBreakPoint(foo, 0);
5711     SetBreakPoint(foo, 4);
5712     SetBreakPoint(bar, 0);
5713     SetBreakPoint(bar, 4);
5714
5715     // Make sure that the break points are there.
5716     break_point_hit_count = 0;
5717     foo->Call(env->Global(), 0, NULL);
5718     CHECK_EQ(2, break_point_hit_count);
5719     bar->Call(env->Global(), 0, NULL);
5720     CHECK_EQ(4, break_point_hit_count);
5721   }
5722
5723   // Remove the debug event listener without clearing breakpoints. Do this
5724   // outside a handle scope.
5725   v8::Debug::SetDebugEventListener2(NULL);
5726   CheckDebuggerUnloaded(true);
5727
5728   // Now set a debug message handler.
5729   break_point_hit_count = 0;
5730   v8::Debug::SetMessageHandler2(MessageHandlerBreakPointHitCount);
5731   {
5732     v8::HandleScope scope(env->GetIsolate());
5733
5734     // Get the test functions again.
5735     v8::Local<v8::Function> foo(v8::Local<v8::Function>::Cast(
5736         env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "foo"))));
5737
5738     foo->Call(env->Global(), 0, NULL);
5739     CHECK_EQ(0, break_point_hit_count);
5740
5741     // Set break points and run again.
5742     SetBreakPoint(foo, 0);
5743     SetBreakPoint(foo, 4);
5744     foo->Call(env->Global(), 0, NULL);
5745     CHECK_EQ(2, break_point_hit_count);
5746   }
5747
5748   // Remove the debug message handler without clearing breakpoints. Do this
5749   // outside a handle scope.
5750   v8::Debug::SetMessageHandler2(NULL);
5751   CheckDebuggerUnloaded(true);
5752 }
5753
5754
5755 // Sends continue command to the debugger.
5756 static void SendContinueCommand() {
5757   const int kBufferSize = 1000;
5758   uint16_t buffer[kBufferSize];
5759   const char* command_continue =
5760     "{\"seq\":0,"
5761      "\"type\":\"request\","
5762      "\"command\":\"continue\"}";
5763
5764   v8::Debug::SendCommand(
5765       CcTest::isolate(), buffer, AsciiToUtf16(command_continue, buffer));
5766 }
5767
5768
5769 // Debugger message handler which counts the number of times it is called.
5770 static int message_handler_hit_count = 0;
5771 static void MessageHandlerHitCount(const v8::Debug::Message& message) {
5772   message_handler_hit_count++;
5773
5774   static char print_buffer[1000];
5775   v8::String::Value json(message.GetJSON());
5776   Utf16ToAscii(*json, json.length(), print_buffer);
5777   if (IsExceptionEventMessage(print_buffer)) {
5778     // Send a continue command for exception events.
5779     SendContinueCommand();
5780   }
5781 }
5782
5783
5784 // Test clearing the debug message handler.
5785 TEST(DebuggerClearMessageHandler) {
5786   DebugLocalContext env;
5787   v8::HandleScope scope(env->GetIsolate());
5788
5789   // Check debugger is unloaded before it is used.
5790   CheckDebuggerUnloaded();
5791
5792   // Set a debug message handler.
5793   v8::Debug::SetMessageHandler2(MessageHandlerHitCount);
5794
5795   // Run code to throw a unhandled exception. This should end up in the message
5796   // handler.
5797   CompileRun("throw 1");
5798
5799   // The message handler should be called.
5800   CHECK_GT(message_handler_hit_count, 0);
5801
5802   // Clear debug message handler.
5803   message_handler_hit_count = 0;
5804   v8::Debug::SetMessageHandler2(NULL);
5805
5806   // Run code to throw a unhandled exception. This should end up in the message
5807   // handler.
5808   CompileRun("throw 1");
5809
5810   // The message handler should not be called more.
5811   CHECK_EQ(0, message_handler_hit_count);
5812
5813   CheckDebuggerUnloaded(true);
5814 }
5815
5816
5817 // Debugger message handler which clears the message handler while active.
5818 static void MessageHandlerClearingMessageHandler(
5819     const v8::Debug::Message& message) {
5820   message_handler_hit_count++;
5821
5822   // Clear debug message handler.
5823   v8::Debug::SetMessageHandler2(NULL);
5824 }
5825
5826
5827 // Test clearing the debug message handler while processing a debug event.
5828 TEST(DebuggerClearMessageHandlerWhileActive) {
5829   DebugLocalContext env;
5830   v8::HandleScope scope(env->GetIsolate());
5831
5832   // Check debugger is unloaded before it is used.
5833   CheckDebuggerUnloaded();
5834
5835   // Set a debug message handler.
5836   v8::Debug::SetMessageHandler2(MessageHandlerClearingMessageHandler);
5837
5838   // Run code to throw a unhandled exception. This should end up in the message
5839   // handler.
5840   CompileRun("throw 1");
5841
5842   // The message handler should be called.
5843   CHECK_EQ(1, message_handler_hit_count);
5844
5845   CheckDebuggerUnloaded(true);
5846 }
5847
5848
5849 /* Test DebuggerHostDispatch */
5850 /* In this test, the debugger waits for a command on a breakpoint
5851  * and is dispatching host commands while in the infinite loop.
5852  */
5853
5854 class HostDispatchV8Thread : public v8::internal::Thread {
5855  public:
5856   HostDispatchV8Thread() : Thread("HostDispatchV8Thread") { }
5857   void Run();
5858 };
5859
5860 class HostDispatchDebuggerThread : public v8::internal::Thread {
5861  public:
5862   HostDispatchDebuggerThread() : Thread("HostDispatchDebuggerThread") { }
5863   void Run();
5864 };
5865
5866 Barriers* host_dispatch_barriers;
5867
5868 static void HostDispatchMessageHandler(const v8::Debug::Message& message) {
5869   static char print_buffer[1000];
5870   v8::String::Value json(message.GetJSON());
5871   Utf16ToAscii(*json, json.length(), print_buffer);
5872 }
5873
5874
5875 static void HostDispatchDispatchHandler() {
5876   host_dispatch_barriers->semaphore_1.Signal();
5877 }
5878
5879
5880 void HostDispatchV8Thread::Run() {
5881   const char* source_1 = "var y_global = 3;\n"
5882     "function cat( new_value ) {\n"
5883     "  var x = new_value;\n"
5884     "  y_global = 4;\n"
5885     "  x = 3 * x + 1;\n"
5886     "  y_global = 5;\n"
5887     "  return x;\n"
5888     "}\n"
5889     "\n";
5890   const char* source_2 = "cat(17);\n";
5891
5892   v8::Isolate::Scope isolate_scope(CcTest::isolate());
5893   DebugLocalContext env;
5894   v8::HandleScope scope(env->GetIsolate());
5895
5896   // Set up message and host dispatch handlers.
5897   v8::Debug::SetMessageHandler2(HostDispatchMessageHandler);
5898   v8::Debug::SetHostDispatchHandler(HostDispatchDispatchHandler, 10 /* ms */);
5899
5900   CompileRun(source_1);
5901   host_dispatch_barriers->barrier_1.Wait();
5902   host_dispatch_barriers->barrier_2.Wait();
5903   CompileRun(source_2);
5904 }
5905
5906
5907 void HostDispatchDebuggerThread::Run() {
5908   const int kBufSize = 1000;
5909   uint16_t buffer[kBufSize];
5910
5911   const char* command_1 = "{\"seq\":101,"
5912       "\"type\":\"request\","
5913       "\"command\":\"setbreakpoint\","
5914       "\"arguments\":{\"type\":\"function\",\"target\":\"cat\",\"line\":3}}";
5915   const char* command_2 = "{\"seq\":102,"
5916       "\"type\":\"request\","
5917       "\"command\":\"continue\"}";
5918
5919   v8::Isolate* isolate = CcTest::isolate();
5920   // v8 thread initializes, runs source_1
5921   host_dispatch_barriers->barrier_1.Wait();
5922   // 1: Set breakpoint in cat().
5923   v8::Debug::SendCommand(isolate, buffer, AsciiToUtf16(command_1, buffer));
5924
5925   host_dispatch_barriers->barrier_2.Wait();
5926   // v8 thread starts compiling source_2.
5927   // Break happens, to run queued commands and host dispatches.
5928   // Wait for host dispatch to be processed.
5929   host_dispatch_barriers->semaphore_1.Wait();
5930   // 2: Continue evaluation
5931   v8::Debug::SendCommand(isolate, buffer, AsciiToUtf16(command_2, buffer));
5932 }
5933
5934
5935 TEST(DebuggerHostDispatch) {
5936   HostDispatchDebuggerThread host_dispatch_debugger_thread;
5937   HostDispatchV8Thread host_dispatch_v8_thread;
5938   i::FLAG_debugger_auto_break = true;
5939
5940   // Create a V8 environment
5941   Barriers stack_allocated_host_dispatch_barriers;
5942   host_dispatch_barriers = &stack_allocated_host_dispatch_barriers;
5943
5944   host_dispatch_v8_thread.Start();
5945   host_dispatch_debugger_thread.Start();
5946
5947   host_dispatch_v8_thread.Join();
5948   host_dispatch_debugger_thread.Join();
5949 }
5950
5951
5952 /* Test DebugMessageDispatch */
5953 /* In this test, the V8 thread waits for a message from the debug thread.
5954  * The DebugMessageDispatchHandler is executed from the debugger thread
5955  * which signals the V8 thread to wake up.
5956  */
5957
5958 class DebugMessageDispatchV8Thread : public v8::internal::Thread {
5959  public:
5960   DebugMessageDispatchV8Thread() : Thread("DebugMessageDispatchV8Thread") { }
5961   void Run();
5962 };
5963
5964 class DebugMessageDispatchDebuggerThread : public v8::internal::Thread {
5965  public:
5966   DebugMessageDispatchDebuggerThread()
5967       : Thread("DebugMessageDispatchDebuggerThread") { }
5968   void Run();
5969 };
5970
5971 Barriers* debug_message_dispatch_barriers;
5972
5973
5974 static void DebugMessageHandler() {
5975   debug_message_dispatch_barriers->semaphore_1.Signal();
5976 }
5977
5978
5979 void DebugMessageDispatchV8Thread::Run() {
5980   v8::Isolate::Scope isolate_scope(CcTest::isolate());
5981   DebugLocalContext env;
5982   v8::HandleScope scope(env->GetIsolate());
5983
5984   // Set up debug message dispatch handler.
5985   v8::Debug::SetDebugMessageDispatchHandler(DebugMessageHandler);
5986
5987   CompileRun("var y = 1 + 2;\n");
5988   debug_message_dispatch_barriers->barrier_1.Wait();
5989   debug_message_dispatch_barriers->semaphore_1.Wait();
5990   debug_message_dispatch_barriers->barrier_2.Wait();
5991 }
5992
5993
5994 void DebugMessageDispatchDebuggerThread::Run() {
5995   debug_message_dispatch_barriers->barrier_1.Wait();
5996   SendContinueCommand();
5997   debug_message_dispatch_barriers->barrier_2.Wait();
5998 }
5999
6000
6001 TEST(DebuggerDebugMessageDispatch) {
6002   DebugMessageDispatchDebuggerThread debug_message_dispatch_debugger_thread;
6003   DebugMessageDispatchV8Thread debug_message_dispatch_v8_thread;
6004
6005   i::FLAG_debugger_auto_break = true;
6006
6007   // Create a V8 environment
6008   Barriers stack_allocated_debug_message_dispatch_barriers;
6009   debug_message_dispatch_barriers =
6010       &stack_allocated_debug_message_dispatch_barriers;
6011
6012   debug_message_dispatch_v8_thread.Start();
6013   debug_message_dispatch_debugger_thread.Start();
6014
6015   debug_message_dispatch_v8_thread.Join();
6016   debug_message_dispatch_debugger_thread.Join();
6017 }
6018
6019
6020 TEST(DebuggerAgent) {
6021   v8::V8::Initialize();
6022   i::Debugger* debugger = CcTest::i_isolate()->debugger();
6023   // Make sure these ports is not used by other tests to allow tests to run in
6024   // parallel.
6025   const int kPort1 = 5858 + FlagDependentPortOffset();
6026   const int kPort2 = 5857 + FlagDependentPortOffset();
6027   const int kPort3 = 5856 + FlagDependentPortOffset();
6028
6029   // Make a string with the port2 number.
6030   const int kPortBufferLen = 6;
6031   char port2_str[kPortBufferLen];
6032   OS::SNPrintF(i::Vector<char>(port2_str, kPortBufferLen), "%d", kPort2);
6033
6034   bool ok;
6035
6036   // Test starting and stopping the agent without any client connection.
6037   debugger->StartAgent("test", kPort1);
6038   debugger->StopAgent();
6039   // Test starting the agent, connecting a client and shutting down the agent
6040   // with the client connected.
6041   ok = debugger->StartAgent("test", kPort2);
6042   CHECK(ok);
6043   debugger->WaitForAgent();
6044   i::Socket* client = new i::Socket;
6045   ok = client->Connect("localhost", port2_str);
6046   CHECK(ok);
6047   // It is important to wait for a message from the agent. Otherwise,
6048   // we can close the server socket during "accept" syscall, making it failing
6049   // (at least on Linux), and the test will work incorrectly.
6050   char buf;
6051   ok = client->Receive(&buf, 1) == 1;
6052   CHECK(ok);
6053   debugger->StopAgent();
6054   delete client;
6055
6056   // Test starting and stopping the agent with the required port already
6057   // occoupied.
6058   i::Socket* server = new i::Socket;
6059   ok = server->Bind(kPort3);
6060   CHECK(ok);
6061
6062   debugger->StartAgent("test", kPort3);
6063   debugger->StopAgent();
6064
6065   delete server;
6066 }
6067
6068
6069 class DebuggerAgentProtocolServerThread : public i::Thread {
6070  public:
6071   explicit DebuggerAgentProtocolServerThread(int port)
6072       : Thread("DebuggerAgentProtocolServerThread"),
6073         port_(port),
6074         server_(NULL),
6075         client_(NULL),
6076         listening_(0) {
6077   }
6078   ~DebuggerAgentProtocolServerThread() {
6079     // Close both sockets.
6080     delete client_;
6081     delete server_;
6082   }
6083
6084   void Run();
6085   void WaitForListening() { listening_.Wait(); }
6086   char* body() { return body_.get(); }
6087
6088  private:
6089   int port_;
6090   i::SmartArrayPointer<char> body_;
6091   i::Socket* server_;  // Server socket used for bind/accept.
6092   i::Socket* client_;  // Single client connection used by the test.
6093   i::Semaphore listening_;  // Signalled when the server is in listen mode.
6094 };
6095
6096
6097 void DebuggerAgentProtocolServerThread::Run() {
6098   bool ok;
6099
6100   // Create the server socket and bind it to the requested port.
6101   server_ = new i::Socket;
6102   CHECK(server_ != NULL);
6103   ok = server_->Bind(port_);
6104   CHECK(ok);
6105
6106   // Listen for new connections.
6107   ok = server_->Listen(1);
6108   CHECK(ok);
6109   listening_.Signal();
6110
6111   // Accept a connection.
6112   client_ = server_->Accept();
6113   CHECK(client_ != NULL);
6114
6115   // Receive a debugger agent protocol message.
6116   i::DebuggerAgentUtil::ReceiveMessage(client_);
6117 }
6118
6119
6120 TEST(DebuggerAgentProtocolOverflowHeader) {
6121   // Make sure this port is not used by other tests to allow tests to run in
6122   // parallel.
6123   const int kPort = 5860 + FlagDependentPortOffset();
6124   static const char* kLocalhost = "localhost";
6125
6126   // Make a string with the port number.
6127   const int kPortBufferLen = 6;
6128   char port_str[kPortBufferLen];
6129   OS::SNPrintF(i::Vector<char>(port_str, kPortBufferLen), "%d", kPort);
6130
6131   // Create a socket server to receive a debugger agent message.
6132   DebuggerAgentProtocolServerThread* server =
6133       new DebuggerAgentProtocolServerThread(kPort);
6134   server->Start();
6135   server->WaitForListening();
6136
6137   // Connect.
6138   i::Socket* client = new i::Socket;
6139   CHECK(client != NULL);
6140   bool ok = client->Connect(kLocalhost, port_str);
6141   CHECK(ok);
6142
6143   // Send headers which overflow the receive buffer.
6144   static const int kBufferSize = 1000;
6145   char buffer[kBufferSize];
6146
6147   // Long key and short value: XXXX....XXXX:0\r\n.
6148   for (int i = 0; i < kBufferSize - 4; i++) {
6149     buffer[i] = 'X';
6150   }
6151   buffer[kBufferSize - 4] = ':';
6152   buffer[kBufferSize - 3] = '0';
6153   buffer[kBufferSize - 2] = '\r';
6154   buffer[kBufferSize - 1] = '\n';
6155   int result = client->Send(buffer, kBufferSize);
6156   CHECK_EQ(kBufferSize, result);
6157
6158   // Short key and long value: X:XXXX....XXXX\r\n.
6159   buffer[0] = 'X';
6160   buffer[1] = ':';
6161   for (int i = 2; i < kBufferSize - 2; i++) {
6162     buffer[i] = 'X';
6163   }
6164   buffer[kBufferSize - 2] = '\r';
6165   buffer[kBufferSize - 1] = '\n';
6166   result = client->Send(buffer, kBufferSize);
6167   CHECK_EQ(kBufferSize, result);
6168
6169   // Add empty body to request.
6170   const char* content_length_zero_header = "Content-Length:0\r\n";
6171   int length = StrLength(content_length_zero_header);
6172   result = client->Send(content_length_zero_header, length);
6173   CHECK_EQ(length, result);
6174   result = client->Send("\r\n", 2);
6175   CHECK_EQ(2, result);
6176
6177   // Wait until data is received.
6178   server->Join();
6179
6180   // Check for empty body.
6181   CHECK(server->body() == NULL);
6182
6183   // Close the client before the server to avoid TIME_WAIT issues.
6184   client->Shutdown();
6185   delete client;
6186   delete server;
6187 }
6188
6189
6190 // Test for issue http://code.google.com/p/v8/issues/detail?id=289.
6191 // Make sure that DebugGetLoadedScripts doesn't return scripts
6192 // with disposed external source.
6193 class EmptyExternalStringResource : public v8::String::ExternalStringResource {
6194  public:
6195   EmptyExternalStringResource() { empty_[0] = 0; }
6196   virtual ~EmptyExternalStringResource() {}
6197   virtual size_t length() const { return empty_.length(); }
6198   virtual const uint16_t* data() const { return empty_.start(); }
6199  private:
6200   ::v8::internal::EmbeddedVector<uint16_t, 1> empty_;
6201 };
6202
6203
6204 TEST(DebugGetLoadedScripts) {
6205   DebugLocalContext env;
6206   v8::HandleScope scope(env->GetIsolate());
6207   env.ExposeDebug();
6208
6209   EmptyExternalStringResource source_ext_str;
6210   v8::Local<v8::String> source =
6211       v8::String::NewExternal(env->GetIsolate(), &source_ext_str);
6212   v8::Handle<v8::Script> evil_script(v8::Script::Compile(source));
6213   // "use" evil_script to make the compiler happy.
6214   (void) evil_script;
6215   Handle<i::ExternalTwoByteString> i_source(
6216       i::ExternalTwoByteString::cast(*v8::Utils::OpenHandle(*source)));
6217   // This situation can happen if source was an external string disposed
6218   // by its owner.
6219   i_source->set_resource(0);
6220
6221   bool allow_natives_syntax = i::FLAG_allow_natives_syntax;
6222   i::FLAG_allow_natives_syntax = true;
6223   CompileRun(
6224       "var scripts = %DebugGetLoadedScripts();"
6225       "var count = scripts.length;"
6226       "for (var i = 0; i < count; ++i) {"
6227       "  scripts[i].line_ends;"
6228       "}");
6229   // Must not crash while accessing line_ends.
6230   i::FLAG_allow_natives_syntax = allow_natives_syntax;
6231
6232   // Some scripts are retrieved - at least the number of native scripts.
6233   CHECK_GT((*env)
6234                ->Global()
6235                ->Get(v8::String::NewFromUtf8(env->GetIsolate(), "count"))
6236                ->Int32Value(),
6237            8);
6238 }
6239
6240
6241 // Test script break points set on lines.
6242 TEST(ScriptNameAndData) {
6243   DebugLocalContext env;
6244   v8::HandleScope scope(env->GetIsolate());
6245   env.ExposeDebug();
6246
6247   // Create functions for retrieving script name and data for the function on
6248   // the top frame when hitting a break point.
6249   frame_script_name = CompileFunction(&env,
6250                                       frame_script_name_source,
6251                                       "frame_script_name");
6252   frame_script_data = CompileFunction(&env,
6253                                       frame_script_data_source,
6254                                       "frame_script_data");
6255   compiled_script_data = CompileFunction(&env,
6256                                          compiled_script_data_source,
6257                                          "compiled_script_data");
6258
6259   v8::Debug::SetDebugEventListener2(DebugEventBreakPointHitCount);
6260
6261   // Test function source.
6262   v8::Local<v8::String> script = v8::String::NewFromUtf8(env->GetIsolate(),
6263                                                          "function f() {\n"
6264                                                          "  debugger;\n"
6265                                                          "}\n");
6266
6267   v8::ScriptOrigin origin1 =
6268       v8::ScriptOrigin(v8::String::NewFromUtf8(env->GetIsolate(), "name"));
6269   v8::Handle<v8::Script> script1 = v8::Script::Compile(script, &origin1);
6270   script1->SetData(v8::String::NewFromUtf8(env->GetIsolate(), "data"));
6271   script1->Run();
6272   v8::Local<v8::Function> f;
6273   f = v8::Local<v8::Function>::Cast(
6274       env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "f")));
6275
6276   f->Call(env->Global(), 0, NULL);
6277   CHECK_EQ(1, break_point_hit_count);
6278   CHECK_EQ("name", last_script_name_hit);
6279   CHECK_EQ("data", last_script_data_hit);
6280
6281   // Compile the same script again without setting data. As the compilation
6282   // cache is disabled when debugging expect the data to be missing.
6283   v8::Script::Compile(script, &origin1)->Run();
6284   f = v8::Local<v8::Function>::Cast(
6285       env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "f")));
6286   f->Call(env->Global(), 0, NULL);
6287   CHECK_EQ(2, break_point_hit_count);
6288   CHECK_EQ("name", last_script_name_hit);
6289   CHECK_EQ("", last_script_data_hit);  // Undefined results in empty string.
6290
6291   v8::Local<v8::String> data_obj_source = v8::String::NewFromUtf8(
6292       env->GetIsolate(),
6293       "({ a: 'abc',\n"
6294       "  b: 123,\n"
6295       "  toString: function() { return this.a + ' ' + this.b; }\n"
6296       "})\n");
6297   v8::Local<v8::Value> data_obj = v8::Script::Compile(data_obj_source)->Run();
6298   v8::ScriptOrigin origin2 =
6299       v8::ScriptOrigin(v8::String::NewFromUtf8(env->GetIsolate(), "new name"));
6300   v8::Handle<v8::Script> script2 = v8::Script::Compile(script, &origin2);
6301   script2->Run();
6302   script2->SetData(data_obj->ToString());
6303   f = v8::Local<v8::Function>::Cast(
6304       env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "f")));
6305   f->Call(env->Global(), 0, NULL);
6306   CHECK_EQ(3, break_point_hit_count);
6307   CHECK_EQ("new name", last_script_name_hit);
6308   CHECK_EQ("abc 123", last_script_data_hit);
6309
6310   v8::Handle<v8::Script> script3 = v8::Script::Compile(
6311       script, &origin2, NULL,
6312       v8::String::NewFromUtf8(env->GetIsolate(), "in compile"));
6313   CHECK_EQ("in compile", last_script_data_hit);
6314   script3->Run();
6315   f = v8::Local<v8::Function>::Cast(
6316       env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "f")));
6317   f->Call(env->Global(), 0, NULL);
6318   CHECK_EQ(4, break_point_hit_count);
6319   CHECK_EQ("in compile", last_script_data_hit);
6320 }
6321
6322
6323 static v8::Handle<v8::Context> expected_context;
6324 static v8::Handle<v8::Value> expected_context_data;
6325
6326
6327 // Check that the expected context is the one generating the debug event.
6328 static void ContextCheckMessageHandler(const v8::Debug::Message& message) {
6329   CHECK(message.GetEventContext() == expected_context);
6330   CHECK(message.GetEventContext()->GetEmbedderData(0)->StrictEquals(
6331       expected_context_data));
6332   message_handler_hit_count++;
6333
6334   static char print_buffer[1000];
6335   v8::String::Value json(message.GetJSON());
6336   Utf16ToAscii(*json, json.length(), print_buffer);
6337
6338   // Send a continue command for break events.
6339   if (IsBreakEventMessage(print_buffer)) {
6340     SendContinueCommand();
6341   }
6342 }
6343
6344
6345 // Test which creates two contexts and sets different embedder data on each.
6346 // Checks that this data is set correctly and that when the debug message
6347 // handler is called the expected context is the one active.
6348 TEST(ContextData) {
6349   v8::Isolate* isolate = CcTest::isolate();
6350   v8::HandleScope scope(isolate);
6351
6352   // Create two contexts.
6353   v8::Handle<v8::Context> context_1;
6354   v8::Handle<v8::Context> context_2;
6355   v8::Handle<v8::ObjectTemplate> global_template =
6356       v8::Handle<v8::ObjectTemplate>();
6357   v8::Handle<v8::Value> global_object = v8::Handle<v8::Value>();
6358   context_1 = v8::Context::New(isolate, NULL, global_template, global_object);
6359   context_2 = v8::Context::New(isolate, NULL, global_template, global_object);
6360
6361   v8::Debug::SetMessageHandler2(ContextCheckMessageHandler);
6362
6363   // Default data value is undefined.
6364   CHECK(context_1->GetEmbedderData(0)->IsUndefined());
6365   CHECK(context_2->GetEmbedderData(0)->IsUndefined());
6366
6367   // Set and check different data values.
6368   v8::Handle<v8::String> data_1 = v8::String::NewFromUtf8(isolate, "1");
6369   v8::Handle<v8::String> data_2 = v8::String::NewFromUtf8(isolate, "2");
6370   context_1->SetEmbedderData(0, data_1);
6371   context_2->SetEmbedderData(0, data_2);
6372   CHECK(context_1->GetEmbedderData(0)->StrictEquals(data_1));
6373   CHECK(context_2->GetEmbedderData(0)->StrictEquals(data_2));
6374
6375   // Simple test function which causes a break.
6376   const char* source = "function f() { debugger; }";
6377
6378   // Enter and run function in the first context.
6379   {
6380     v8::Context::Scope context_scope(context_1);
6381     expected_context = context_1;
6382     expected_context_data = data_1;
6383     v8::Local<v8::Function> f = CompileFunction(isolate, source, "f");
6384     f->Call(context_1->Global(), 0, NULL);
6385   }
6386
6387
6388   // Enter and run function in the second context.
6389   {
6390     v8::Context::Scope context_scope(context_2);
6391     expected_context = context_2;
6392     expected_context_data = data_2;
6393     v8::Local<v8::Function> f = CompileFunction(isolate, source, "f");
6394     f->Call(context_2->Global(), 0, NULL);
6395   }
6396
6397   // Two times compile event and two times break event.
6398   CHECK_GT(message_handler_hit_count, 4);
6399
6400   v8::Debug::SetMessageHandler2(NULL);
6401   CheckDebuggerUnloaded();
6402 }
6403
6404
6405 // Debug message handler which issues a debug break when it hits a break event.
6406 static int message_handler_break_hit_count = 0;
6407 static void DebugBreakMessageHandler(const v8::Debug::Message& message) {
6408   // Schedule a debug break for break events.
6409   if (message.IsEvent() && message.GetEvent() == v8::Break) {
6410     message_handler_break_hit_count++;
6411     if (message_handler_break_hit_count == 1) {
6412       v8::Debug::DebugBreak(message.GetIsolate());
6413     }
6414   }
6415
6416   // Issue a continue command if this event will not cause the VM to start
6417   // running.
6418   if (!message.WillStartRunning()) {
6419     SendContinueCommand();
6420   }
6421 }
6422
6423
6424 // Test that a debug break can be scheduled while in a message handler.
6425 TEST(DebugBreakInMessageHandler) {
6426   DebugLocalContext env;
6427   v8::HandleScope scope(env->GetIsolate());
6428
6429   v8::Debug::SetMessageHandler2(DebugBreakMessageHandler);
6430
6431   // Test functions.
6432   const char* script = "function f() { debugger; g(); } function g() { }";
6433   CompileRun(script);
6434   v8::Local<v8::Function> f = v8::Local<v8::Function>::Cast(
6435       env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "f")));
6436   v8::Local<v8::Function> g = v8::Local<v8::Function>::Cast(
6437       env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "g")));
6438
6439   // Call f then g. The debugger statement in f will casue a break which will
6440   // cause another break.
6441   f->Call(env->Global(), 0, NULL);
6442   CHECK_EQ(2, message_handler_break_hit_count);
6443   // Calling g will not cause any additional breaks.
6444   g->Call(env->Global(), 0, NULL);
6445   CHECK_EQ(2, message_handler_break_hit_count);
6446 }
6447
6448
6449 #ifndef V8_INTERPRETED_REGEXP
6450 // Debug event handler which gets the function on the top frame and schedules a
6451 // break a number of times.
6452 static void DebugEventDebugBreak(
6453     const v8::Debug::EventDetails& event_details) {
6454   v8::DebugEvent event = event_details.GetEvent();
6455   v8::Handle<v8::Object> exec_state = event_details.GetExecutionState();
6456
6457   if (event == v8::Break) {
6458     break_point_hit_count++;
6459
6460     // Get the name of the top frame function.
6461     if (!frame_function_name.IsEmpty()) {
6462       // Get the name of the function.
6463       const int argc = 2;
6464       v8::Handle<v8::Value> argv[argc] = {
6465         exec_state, v8::Integer::New(CcTest::isolate(), 0)
6466       };
6467       v8::Handle<v8::Value> result = frame_function_name->Call(exec_state,
6468                                                                argc, argv);
6469       if (result->IsUndefined()) {
6470         last_function_hit[0] = '\0';
6471       } else {
6472         CHECK(result->IsString());
6473         v8::Handle<v8::String> function_name(result->ToString());
6474         function_name->WriteUtf8(last_function_hit);
6475       }
6476     }
6477
6478     // Keep forcing breaks.
6479     if (break_point_hit_count < 20) {
6480       v8::Debug::DebugBreak(CcTest::isolate());
6481     }
6482   }
6483 }
6484
6485
6486 TEST(RegExpDebugBreak) {
6487   // This test only applies to native regexps.
6488   DebugLocalContext env;
6489   v8::HandleScope scope(env->GetIsolate());
6490
6491   // Create a function for checking the function when hitting a break point.
6492   frame_function_name = CompileFunction(&env,
6493                                         frame_function_name_source,
6494                                         "frame_function_name");
6495
6496   // Test RegExp which matches white spaces and comments at the begining of a
6497   // source line.
6498   const char* script =
6499     "var sourceLineBeginningSkip = /^(?:[ \\v\\h]*(?:\\/\\*.*?\\*\\/)*)*/;\n"
6500     "function f(s) { return s.match(sourceLineBeginningSkip)[0].length; }";
6501
6502   v8::Local<v8::Function> f = CompileFunction(env->GetIsolate(), script, "f");
6503   const int argc = 1;
6504   v8::Handle<v8::Value> argv[argc] = {
6505       v8::String::NewFromUtf8(env->GetIsolate(), "  /* xxx */ a=0;")};
6506   v8::Local<v8::Value> result = f->Call(env->Global(), argc, argv);
6507   CHECK_EQ(12, result->Int32Value());
6508
6509   v8::Debug::SetDebugEventListener2(DebugEventDebugBreak);
6510   v8::Debug::DebugBreak(env->GetIsolate());
6511   result = f->Call(env->Global(), argc, argv);
6512
6513   // Check that there was only one break event. Matching RegExp should not
6514   // cause Break events.
6515   CHECK_EQ(1, break_point_hit_count);
6516   CHECK_EQ("f", last_function_hit);
6517 }
6518 #endif  // V8_INTERPRETED_REGEXP
6519
6520
6521 // Common part of EvalContextData and NestedBreakEventContextData tests.
6522 static void ExecuteScriptForContextCheck(
6523     v8::Debug::MessageHandler2 message_handler) {
6524   // Create a context.
6525   v8::Handle<v8::Context> context_1;
6526   v8::Handle<v8::ObjectTemplate> global_template =
6527       v8::Handle<v8::ObjectTemplate>();
6528   context_1 =
6529       v8::Context::New(CcTest::isolate(), NULL, global_template);
6530
6531   v8::Debug::SetMessageHandler2(message_handler);
6532
6533   // Default data value is undefined.
6534   CHECK(context_1->GetEmbedderData(0)->IsUndefined());
6535
6536   // Set and check a data value.
6537   v8::Handle<v8::String> data_1 =
6538       v8::String::NewFromUtf8(CcTest::isolate(), "1");
6539   context_1->SetEmbedderData(0, data_1);
6540   CHECK(context_1->GetEmbedderData(0)->StrictEquals(data_1));
6541
6542   // Simple test function with eval that causes a break.
6543   const char* source = "function f() { eval('debugger;'); }";
6544
6545   // Enter and run function in the context.
6546   {
6547     v8::Context::Scope context_scope(context_1);
6548     expected_context = context_1;
6549     expected_context_data = data_1;
6550     v8::Local<v8::Function> f = CompileFunction(CcTest::isolate(), source, "f");
6551     f->Call(context_1->Global(), 0, NULL);
6552   }
6553
6554   v8::Debug::SetMessageHandler2(NULL);
6555 }
6556
6557
6558 // Test which creates a context and sets embedder data on it. Checks that this
6559 // data is set correctly and that when the debug message handler is called for
6560 // break event in an eval statement the expected context is the one returned by
6561 // Message.GetEventContext.
6562 TEST(EvalContextData) {
6563   v8::HandleScope scope(CcTest::isolate());
6564
6565   ExecuteScriptForContextCheck(ContextCheckMessageHandler);
6566
6567   // One time compile event and one time break event.
6568   CHECK_GT(message_handler_hit_count, 2);
6569   CheckDebuggerUnloaded();
6570 }
6571
6572
6573 static bool sent_eval = false;
6574 static int break_count = 0;
6575 static int continue_command_send_count = 0;
6576 // Check that the expected context is the one generating the debug event
6577 // including the case of nested break event.
6578 static void DebugEvalContextCheckMessageHandler(
6579     const v8::Debug::Message& message) {
6580   CHECK(message.GetEventContext() == expected_context);
6581   CHECK(message.GetEventContext()->GetEmbedderData(0)->StrictEquals(
6582       expected_context_data));
6583   message_handler_hit_count++;
6584
6585   static char print_buffer[1000];
6586   v8::String::Value json(message.GetJSON());
6587   Utf16ToAscii(*json, json.length(), print_buffer);
6588
6589   v8::Isolate* isolate = message.GetIsolate();
6590   if (IsBreakEventMessage(print_buffer)) {
6591     break_count++;
6592     if (!sent_eval) {
6593       sent_eval = true;
6594
6595       const int kBufferSize = 1000;
6596       uint16_t buffer[kBufferSize];
6597       const char* eval_command =
6598           "{\"seq\":0,"
6599           "\"type\":\"request\","
6600           "\"command\":\"evaluate\","
6601           "\"arguments\":{\"expression\":\"debugger;\","
6602           "\"global\":true,\"disable_break\":false}}";
6603
6604       // Send evaluate command.
6605       v8::Debug::SendCommand(
6606           isolate, buffer, AsciiToUtf16(eval_command, buffer));
6607       return;
6608     } else {
6609       // It's a break event caused by the evaluation request above.
6610       SendContinueCommand();
6611       continue_command_send_count++;
6612     }
6613   } else if (IsEvaluateResponseMessage(print_buffer) &&
6614       continue_command_send_count < 2) {
6615     // Response to the evaluation request. We're still on the breakpoint so
6616     // send continue.
6617     SendContinueCommand();
6618     continue_command_send_count++;
6619   }
6620 }
6621
6622
6623 // Tests that context returned for break event is correct when the event occurs
6624 // in 'evaluate' debugger request.
6625 TEST(NestedBreakEventContextData) {
6626   v8::HandleScope scope(CcTest::isolate());
6627   break_count = 0;
6628   message_handler_hit_count = 0;
6629
6630   ExecuteScriptForContextCheck(DebugEvalContextCheckMessageHandler);
6631
6632   // One time compile event and two times break event.
6633   CHECK_GT(message_handler_hit_count, 3);
6634
6635   // One break from the source and another from the evaluate request.
6636   CHECK_EQ(break_count, 2);
6637   CheckDebuggerUnloaded();
6638 }
6639
6640
6641 // Debug event listener which counts the script collected events.
6642 int script_collected_count = 0;
6643 static void DebugEventScriptCollectedEvent(
6644     const v8::Debug::EventDetails& event_details) {
6645   v8::DebugEvent event = event_details.GetEvent();
6646   // Count the number of breaks.
6647   if (event == v8::ScriptCollected) {
6648     script_collected_count++;
6649   }
6650 }
6651
6652
6653 // Test that scripts collected are reported through the debug event listener.
6654 TEST(ScriptCollectedEvent) {
6655   v8::internal::Debug* debug = CcTest::i_isolate()->debug();
6656   break_point_hit_count = 0;
6657   script_collected_count = 0;
6658   DebugLocalContext env;
6659   v8::HandleScope scope(env->GetIsolate());
6660
6661   // Request the loaded scripts to initialize the debugger script cache.
6662   debug->GetLoadedScripts();
6663
6664   // Do garbage collection to ensure that only the script in this test will be
6665   // collected afterwards.
6666   CcTest::heap()->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask);
6667
6668   script_collected_count = 0;
6669   v8::Debug::SetDebugEventListener2(DebugEventScriptCollectedEvent);
6670   {
6671     v8::Script::Compile(
6672         v8::String::NewFromUtf8(env->GetIsolate(), "eval('a=1')"))->Run();
6673     v8::Script::Compile(
6674         v8::String::NewFromUtf8(env->GetIsolate(), "eval('a=2')"))->Run();
6675   }
6676
6677   // Do garbage collection to collect the script above which is no longer
6678   // referenced.
6679   CcTest::heap()->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask);
6680
6681   CHECK_EQ(2, script_collected_count);
6682
6683   v8::Debug::SetDebugEventListener2(NULL);
6684   CheckDebuggerUnloaded();
6685 }
6686
6687
6688 // Debug event listener which counts the script collected events.
6689 int script_collected_message_count = 0;
6690 static void ScriptCollectedMessageHandler(const v8::Debug::Message& message) {
6691   // Count the number of scripts collected.
6692   if (message.IsEvent() && message.GetEvent() == v8::ScriptCollected) {
6693     script_collected_message_count++;
6694     v8::Handle<v8::Context> context = message.GetEventContext();
6695     CHECK(context.IsEmpty());
6696   }
6697 }
6698
6699
6700 // Test that GetEventContext doesn't fail and return empty handle for
6701 // ScriptCollected events.
6702 TEST(ScriptCollectedEventContext) {
6703   i::FLAG_stress_compaction = false;
6704   v8::Isolate* isolate = CcTest::isolate();
6705   v8::internal::Debug* debug =
6706       reinterpret_cast<v8::internal::Isolate*>(isolate)->debug();
6707   script_collected_message_count = 0;
6708   v8::HandleScope scope(isolate);
6709
6710   v8::Persistent<v8::Context> context;
6711   {
6712     v8::HandleScope scope(isolate);
6713     context.Reset(isolate, v8::Context::New(isolate));
6714   }
6715
6716   // Enter context.  We can't have a handle to the context in the outer
6717   // scope, so we have to do it the hard way.
6718   {
6719     v8::HandleScope scope(isolate);
6720     v8::Local<v8::Context> local_context =
6721         v8::Local<v8::Context>::New(isolate, context);
6722     local_context->Enter();
6723   }
6724
6725   // Request the loaded scripts to initialize the debugger script cache.
6726   debug->GetLoadedScripts();
6727
6728   // Do garbage collection to ensure that only the script in this test will be
6729   // collected afterwards.
6730   CcTest::heap()->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask);
6731
6732   v8::Debug::SetMessageHandler2(ScriptCollectedMessageHandler);
6733   v8::Script::Compile(v8::String::NewFromUtf8(isolate, "eval('a=1')"))->Run();
6734   v8::Script::Compile(v8::String::NewFromUtf8(isolate, "eval('a=2')"))->Run();
6735
6736   // Leave context
6737   {
6738     v8::HandleScope scope(isolate);
6739     v8::Local<v8::Context> local_context =
6740         v8::Local<v8::Context>::New(isolate, context);
6741     local_context->Exit();
6742   }
6743   context.Reset();
6744
6745   // Do garbage collection to collect the script above which is no longer
6746   // referenced.
6747   CcTest::heap()->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask);
6748
6749   CHECK_EQ(2, script_collected_message_count);
6750
6751   v8::Debug::SetMessageHandler2(NULL);
6752 }
6753
6754
6755 // Debug event listener which counts the after compile events.
6756 int after_compile_message_count = 0;
6757 static void AfterCompileMessageHandler(const v8::Debug::Message& message) {
6758   // Count the number of scripts collected.
6759   if (message.IsEvent()) {
6760     if (message.GetEvent() == v8::AfterCompile) {
6761       after_compile_message_count++;
6762     } else if (message.GetEvent() == v8::Break) {
6763       SendContinueCommand();
6764     }
6765   }
6766 }
6767
6768
6769 // Tests that after compile event is sent as many times as there are scripts
6770 // compiled.
6771 TEST(AfterCompileMessageWhenMessageHandlerIsReset) {
6772   DebugLocalContext env;
6773   v8::HandleScope scope(env->GetIsolate());
6774   after_compile_message_count = 0;
6775   const char* script = "var a=1";
6776
6777   v8::Debug::SetMessageHandler2(AfterCompileMessageHandler);
6778   v8::Script::Compile(v8::String::NewFromUtf8(env->GetIsolate(), script))
6779       ->Run();
6780   v8::Debug::SetMessageHandler2(NULL);
6781
6782   v8::Debug::SetMessageHandler2(AfterCompileMessageHandler);
6783   v8::Debug::DebugBreak(env->GetIsolate());
6784   v8::Script::Compile(v8::String::NewFromUtf8(env->GetIsolate(), script))
6785       ->Run();
6786
6787   // Setting listener to NULL should cause debugger unload.
6788   v8::Debug::SetMessageHandler2(NULL);
6789   CheckDebuggerUnloaded();
6790
6791   // Compilation cache should be disabled when debugger is active.
6792   CHECK_EQ(2, after_compile_message_count);
6793 }
6794
6795
6796 // Tests that break event is sent when message handler is reset.
6797 TEST(BreakMessageWhenMessageHandlerIsReset) {
6798   DebugLocalContext env;
6799   v8::HandleScope scope(env->GetIsolate());
6800   after_compile_message_count = 0;
6801   const char* script = "function f() {};";
6802
6803   v8::Debug::SetMessageHandler2(AfterCompileMessageHandler);
6804   v8::Script::Compile(v8::String::NewFromUtf8(env->GetIsolate(), script))
6805       ->Run();
6806   v8::Debug::SetMessageHandler2(NULL);
6807
6808   v8::Debug::SetMessageHandler2(AfterCompileMessageHandler);
6809   v8::Debug::DebugBreak(env->GetIsolate());
6810   v8::Local<v8::Function> f = v8::Local<v8::Function>::Cast(
6811       env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "f")));
6812   f->Call(env->Global(), 0, NULL);
6813
6814   // Setting message handler to NULL should cause debugger unload.
6815   v8::Debug::SetMessageHandler2(NULL);
6816   CheckDebuggerUnloaded();
6817
6818   // Compilation cache should be disabled when debugger is active.
6819   CHECK_EQ(1, after_compile_message_count);
6820 }
6821
6822
6823 static int exception_event_count = 0;
6824 static void ExceptionMessageHandler(const v8::Debug::Message& message) {
6825   if (message.IsEvent() && message.GetEvent() == v8::Exception) {
6826     exception_event_count++;
6827     SendContinueCommand();
6828   }
6829 }
6830
6831
6832 // Tests that exception event is sent when message handler is reset.
6833 TEST(ExceptionMessageWhenMessageHandlerIsReset) {
6834   DebugLocalContext env;
6835   v8::HandleScope scope(env->GetIsolate());
6836
6837   // For this test, we want to break on uncaught exceptions:
6838   ChangeBreakOnException(false, true);
6839
6840   exception_event_count = 0;
6841   const char* script = "function f() {throw new Error()};";
6842
6843   v8::Debug::SetMessageHandler2(AfterCompileMessageHandler);
6844   v8::Script::Compile(v8::String::NewFromUtf8(env->GetIsolate(), script))
6845       ->Run();
6846   v8::Debug::SetMessageHandler2(NULL);
6847
6848   v8::Debug::SetMessageHandler2(ExceptionMessageHandler);
6849   v8::Local<v8::Function> f = v8::Local<v8::Function>::Cast(
6850       env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "f")));
6851   f->Call(env->Global(), 0, NULL);
6852
6853   // Setting message handler to NULL should cause debugger unload.
6854   v8::Debug::SetMessageHandler2(NULL);
6855   CheckDebuggerUnloaded();
6856
6857   CHECK_EQ(1, exception_event_count);
6858 }
6859
6860
6861 // Tests after compile event is sent when there are some provisional
6862 // breakpoints out of the scripts lines range.
6863 TEST(ProvisionalBreakpointOnLineOutOfRange) {
6864   DebugLocalContext env;
6865   v8::HandleScope scope(env->GetIsolate());
6866   env.ExposeDebug();
6867   const char* script = "function f() {};";
6868   const char* resource_name = "test_resource";
6869
6870   // Set a couple of provisional breakpoint on lines out of the script lines
6871   // range.
6872   int sbp1 = SetScriptBreakPointByNameFromJS(env->GetIsolate(), resource_name,
6873                                              3, -1 /* no column */);
6874   int sbp2 =
6875       SetScriptBreakPointByNameFromJS(env->GetIsolate(), resource_name, 5, 5);
6876
6877   after_compile_message_count = 0;
6878   v8::Debug::SetMessageHandler2(AfterCompileMessageHandler);
6879
6880   v8::ScriptOrigin origin(
6881       v8::String::NewFromUtf8(env->GetIsolate(), resource_name),
6882       v8::Integer::New(env->GetIsolate(), 10),
6883       v8::Integer::New(env->GetIsolate(), 1));
6884   // Compile a script whose first line number is greater than the breakpoints'
6885   // lines.
6886   v8::Script::Compile(v8::String::NewFromUtf8(env->GetIsolate(), script),
6887                       &origin)->Run();
6888
6889   // If the script is compiled successfully there is exactly one after compile
6890   // event. In case of an exception in debugger code after compile event is not
6891   // sent.
6892   CHECK_EQ(1, after_compile_message_count);
6893
6894   ClearBreakPointFromJS(env->GetIsolate(), sbp1);
6895   ClearBreakPointFromJS(env->GetIsolate(), sbp2);
6896   v8::Debug::SetMessageHandler2(NULL);
6897 }
6898
6899
6900 static void BreakMessageHandler(const v8::Debug::Message& message) {
6901   i::Isolate* isolate = CcTest::i_isolate();
6902   if (message.IsEvent() && message.GetEvent() == v8::Break) {
6903     // Count the number of breaks.
6904     break_point_hit_count++;
6905
6906     i::HandleScope scope(isolate);
6907     message.GetJSON();
6908
6909     SendContinueCommand();
6910   } else if (message.IsEvent() && message.GetEvent() == v8::AfterCompile) {
6911     i::HandleScope scope(isolate);
6912
6913     bool is_debug_break = isolate->stack_guard()->IsDebugBreak();
6914     // Force DebugBreak flag while serializer is working.
6915     isolate->stack_guard()->DebugBreak();
6916
6917     // Force serialization to trigger some internal JS execution.
6918     message.GetJSON();
6919
6920     // Restore previous state.
6921     if (is_debug_break) {
6922       isolate->stack_guard()->DebugBreak();
6923     } else {
6924       isolate->stack_guard()->Continue(i::DEBUGBREAK);
6925     }
6926   }
6927 }
6928
6929
6930 // Test that if DebugBreak is forced it is ignored when code from
6931 // debug-delay.js is executed.
6932 TEST(NoDebugBreakInAfterCompileMessageHandler) {
6933   DebugLocalContext env;
6934   v8::HandleScope scope(env->GetIsolate());
6935
6936   // Register a debug event listener which sets the break flag and counts.
6937   v8::Debug::SetMessageHandler2(BreakMessageHandler);
6938
6939   // Set the debug break flag.
6940   v8::Debug::DebugBreak(env->GetIsolate());
6941
6942   // Create a function for testing stepping.
6943   const char* src = "function f() { eval('var x = 10;'); } ";
6944   v8::Local<v8::Function> f = CompileFunction(&env, src, "f");
6945
6946   // There should be only one break event.
6947   CHECK_EQ(1, break_point_hit_count);
6948
6949   // Set the debug break flag again.
6950   v8::Debug::DebugBreak(env->GetIsolate());
6951   f->Call(env->Global(), 0, NULL);
6952   // There should be one more break event when the script is evaluated in 'f'.
6953   CHECK_EQ(2, break_point_hit_count);
6954
6955   // Get rid of the debug message handler.
6956   v8::Debug::SetMessageHandler2(NULL);
6957   CheckDebuggerUnloaded();
6958 }
6959
6960
6961 static int counting_message_handler_counter;
6962
6963 static void CountingMessageHandler(const v8::Debug::Message& message) {
6964   counting_message_handler_counter++;
6965 }
6966
6967
6968 // Test that debug messages get processed when ProcessDebugMessages is called.
6969 TEST(ProcessDebugMessages) {
6970   DebugLocalContext env;
6971   v8::Isolate* isolate = env->GetIsolate();
6972   v8::HandleScope scope(isolate);
6973
6974   counting_message_handler_counter = 0;
6975
6976   v8::Debug::SetMessageHandler2(CountingMessageHandler);
6977
6978   const int kBufferSize = 1000;
6979   uint16_t buffer[kBufferSize];
6980   const char* scripts_command =
6981     "{\"seq\":0,"
6982      "\"type\":\"request\","
6983      "\"command\":\"scripts\"}";
6984
6985   // Send scripts command.
6986   v8::Debug::SendCommand(
6987       isolate, buffer, AsciiToUtf16(scripts_command, buffer));
6988
6989   CHECK_EQ(0, counting_message_handler_counter);
6990   v8::Debug::ProcessDebugMessages();
6991   // At least one message should come
6992   CHECK_GE(counting_message_handler_counter, 1);
6993
6994   counting_message_handler_counter = 0;
6995
6996   v8::Debug::SendCommand(
6997       isolate, buffer, AsciiToUtf16(scripts_command, buffer));
6998   v8::Debug::SendCommand(
6999       isolate, buffer, AsciiToUtf16(scripts_command, buffer));
7000   CHECK_EQ(0, counting_message_handler_counter);
7001   v8::Debug::ProcessDebugMessages();
7002   // At least two messages should come
7003   CHECK_GE(counting_message_handler_counter, 2);
7004
7005   // Get rid of the debug message handler.
7006   v8::Debug::SetMessageHandler2(NULL);
7007   CheckDebuggerUnloaded();
7008 }
7009
7010
7011 struct BacktraceData {
7012   static int frame_counter;
7013   static void MessageHandler(const v8::Debug::Message& message) {
7014     char print_buffer[1000];
7015     v8::String::Value json(message.GetJSON());
7016     Utf16ToAscii(*json, json.length(), print_buffer, 1000);
7017
7018     if (strstr(print_buffer, "backtrace") == NULL) {
7019       return;
7020     }
7021     frame_counter = GetTotalFramesInt(print_buffer);
7022   }
7023 };
7024
7025 int BacktraceData::frame_counter;
7026
7027
7028 // Test that debug messages get processed when ProcessDebugMessages is called.
7029 TEST(Backtrace) {
7030   DebugLocalContext env;
7031   v8::Isolate* isolate = env->GetIsolate();
7032   v8::HandleScope scope(isolate);
7033
7034   v8::Debug::SetMessageHandler2(BacktraceData::MessageHandler);
7035
7036   const int kBufferSize = 1000;
7037   uint16_t buffer[kBufferSize];
7038   const char* scripts_command =
7039     "{\"seq\":0,"
7040      "\"type\":\"request\","
7041      "\"command\":\"backtrace\"}";
7042
7043   // Check backtrace from ProcessDebugMessages.
7044   BacktraceData::frame_counter = -10;
7045   v8::Debug::SendCommand(
7046       isolate,
7047       buffer,
7048       AsciiToUtf16(scripts_command, buffer),
7049       NULL);
7050   v8::Debug::ProcessDebugMessages();
7051   CHECK_EQ(BacktraceData::frame_counter, 0);
7052
7053   v8::Handle<v8::String> void0 =
7054       v8::String::NewFromUtf8(env->GetIsolate(), "void(0)");
7055   v8::Handle<v8::Script> script = v8::Script::Compile(void0, void0);
7056
7057   // Check backtrace from "void(0)" script.
7058   BacktraceData::frame_counter = -10;
7059   v8::Debug::SendCommand(
7060       isolate,
7061       buffer,
7062       AsciiToUtf16(scripts_command, buffer),
7063       NULL);
7064   script->Run();
7065   CHECK_EQ(BacktraceData::frame_counter, 1);
7066
7067   // Get rid of the debug message handler.
7068   v8::Debug::SetMessageHandler2(NULL);
7069   CheckDebuggerUnloaded();
7070 }
7071
7072
7073 TEST(GetMirror) {
7074   DebugLocalContext env;
7075   v8::HandleScope scope(env->GetIsolate());
7076   v8::Handle<v8::Value> obj =
7077       v8::Debug::GetMirror(v8::String::NewFromUtf8(env->GetIsolate(), "hodja"));
7078   v8::Handle<v8::Function> run_test =
7079       v8::Handle<v8::Function>::Cast(v8::Script::New(
7080           v8::String::NewFromUtf8(
7081               env->GetIsolate(),
7082               "function runTest(mirror) {"
7083               "  return mirror.isString() && (mirror.length() == 5);"
7084               "}"
7085               ""
7086               "runTest;"))->Run());
7087   v8::Handle<v8::Value> result = run_test->Call(env->Global(), 1, &obj);
7088   CHECK(result->IsTrue());
7089 }
7090
7091
7092 // Test that the debug break flag works with function.apply.
7093 TEST(DebugBreakFunctionApply) {
7094   DebugLocalContext env;
7095   v8::HandleScope scope(env->GetIsolate());
7096
7097   // Create a function for testing breaking in apply.
7098   v8::Local<v8::Function> foo = CompileFunction(
7099       &env,
7100       "function baz(x) { }"
7101       "function bar(x) { baz(); }"
7102       "function foo(){ bar.apply(this, [1]); }",
7103       "foo");
7104
7105   // Register a debug event listener which steps and counts.
7106   v8::Debug::SetDebugEventListener2(DebugEventBreakMax);
7107
7108   // Set the debug break flag before calling the code using function.apply.
7109   v8::Debug::DebugBreak(env->GetIsolate());
7110
7111   // Limit the number of debug breaks. This is a regression test for issue 493
7112   // where this test would enter an infinite loop.
7113   break_point_hit_count = 0;
7114   max_break_point_hit_count = 10000;  // 10000 => infinite loop.
7115   foo->Call(env->Global(), 0, NULL);
7116
7117   // When keeping the debug break several break will happen.
7118   CHECK_GT(break_point_hit_count, 1);
7119
7120   v8::Debug::SetDebugEventListener2(NULL);
7121   CheckDebuggerUnloaded();
7122 }
7123
7124
7125 v8::Handle<v8::Context> debugee_context;
7126 v8::Handle<v8::Context> debugger_context;
7127
7128
7129 // Property getter that checks that current and calling contexts
7130 // are both the debugee contexts.
7131 static void NamedGetterWithCallingContextCheck(
7132     v8::Local<v8::String> name,
7133     const v8::PropertyCallbackInfo<v8::Value>& info) {
7134   CHECK_EQ(0, strcmp(*v8::String::Utf8Value(name), "a"));
7135   v8::Handle<v8::Context> current = info.GetIsolate()->GetCurrentContext();
7136   CHECK(current == debugee_context);
7137   CHECK(current != debugger_context);
7138   v8::Handle<v8::Context> calling = info.GetIsolate()->GetCallingContext();
7139   CHECK(calling == debugee_context);
7140   CHECK(calling != debugger_context);
7141   info.GetReturnValue().Set(1);
7142 }
7143
7144
7145 // Debug event listener that checks if the first argument of a function is
7146 // an object with property 'a' == 1. If the property has custom accessor
7147 // this handler will eventually invoke it.
7148 static void DebugEventGetAtgumentPropertyValue(
7149     const v8::Debug::EventDetails& event_details) {
7150   v8::DebugEvent event = event_details.GetEvent();
7151   v8::Handle<v8::Object> exec_state = event_details.GetExecutionState();
7152   if (event == v8::Break) {
7153     break_point_hit_count++;
7154     CHECK(debugger_context == CcTest::isolate()->GetCurrentContext());
7155     v8::Handle<v8::Function> func = v8::Handle<v8::Function>::Cast(CompileRun(
7156         "(function(exec_state) {\n"
7157         "    return (exec_state.frame(0).argumentValue(0).property('a').\n"
7158         "            value().value() == 1);\n"
7159         "})"));
7160     const int argc = 1;
7161     v8::Handle<v8::Value> argv[argc] = { exec_state };
7162     v8::Handle<v8::Value> result = func->Call(exec_state, argc, argv);
7163     CHECK(result->IsTrue());
7164   }
7165 }
7166
7167
7168 TEST(CallingContextIsNotDebugContext) {
7169   v8::internal::Debug* debug = CcTest::i_isolate()->debug();
7170   // Create and enter a debugee context.
7171   DebugLocalContext env;
7172   v8::Isolate* isolate = env->GetIsolate();
7173   v8::HandleScope scope(isolate);
7174   env.ExposeDebug();
7175
7176   // Save handles to the debugger and debugee contexts to be used in
7177   // NamedGetterWithCallingContextCheck.
7178   debugee_context = env.context();
7179   debugger_context = v8::Utils::ToLocal(debug->debug_context());
7180
7181   // Create object with 'a' property accessor.
7182   v8::Handle<v8::ObjectTemplate> named = v8::ObjectTemplate::New(isolate);
7183   named->SetAccessor(v8::String::NewFromUtf8(isolate, "a"),
7184                      NamedGetterWithCallingContextCheck);
7185   env->Global()->Set(v8::String::NewFromUtf8(isolate, "obj"),
7186                      named->NewInstance());
7187
7188   // Register the debug event listener
7189   v8::Debug::SetDebugEventListener2(DebugEventGetAtgumentPropertyValue);
7190
7191   // Create a function that invokes debugger.
7192   v8::Local<v8::Function> foo = CompileFunction(
7193       &env,
7194       "function bar(x) { debugger; }"
7195       "function foo(){ bar(obj); }",
7196       "foo");
7197
7198   break_point_hit_count = 0;
7199   foo->Call(env->Global(), 0, NULL);
7200   CHECK_EQ(1, break_point_hit_count);
7201
7202   v8::Debug::SetDebugEventListener2(NULL);
7203   debugee_context = v8::Handle<v8::Context>();
7204   debugger_context = v8::Handle<v8::Context>();
7205   CheckDebuggerUnloaded();
7206 }
7207
7208
7209 TEST(DebugContextIsPreservedBetweenAccesses) {
7210   v8::HandleScope scope(CcTest::isolate());
7211   v8::Local<v8::Context> context1 = v8::Debug::GetDebugContext();
7212   v8::Local<v8::Context> context2 = v8::Debug::GetDebugContext();
7213   CHECK_EQ(*context1, *context2);
7214 }
7215
7216
7217 static v8::Handle<v8::Value> expected_callback_data;
7218 static void DebugEventContextChecker(const v8::Debug::EventDetails& details) {
7219   CHECK(details.GetEventContext() == expected_context);
7220   CHECK_EQ(expected_callback_data, details.GetCallbackData());
7221 }
7222
7223
7224 // Check that event details contain context where debug event occured.
7225 TEST(DebugEventContext) {
7226   v8::Isolate* isolate = CcTest::isolate();
7227   v8::HandleScope scope(isolate);
7228   expected_context = v8::Context::New(isolate);
7229   expected_callback_data = v8::Int32::New(isolate, 2010);
7230   v8::Debug::SetDebugEventListener2(DebugEventContextChecker,
7231                                     expected_callback_data);
7232   v8::Context::Scope context_scope(expected_context);
7233   v8::Script::Compile(
7234       v8::String::NewFromUtf8(isolate, "(function(){debugger;})();"))->Run();
7235   expected_context.Clear();
7236   v8::Debug::SetDebugEventListener2(NULL);
7237   expected_context_data = v8::Handle<v8::Value>();
7238   CheckDebuggerUnloaded();
7239 }
7240
7241
7242 static void* expected_break_data;
7243 static bool was_debug_break_called;
7244 static bool was_debug_event_called;
7245 static void DebugEventBreakDataChecker(const v8::Debug::EventDetails& details) {
7246   if (details.GetEvent() == v8::BreakForCommand) {
7247     CHECK_EQ(expected_break_data, details.GetClientData());
7248     was_debug_event_called = true;
7249   } else if (details.GetEvent() == v8::Break) {
7250     was_debug_break_called = true;
7251   }
7252 }
7253
7254
7255 // Check that event details contain context where debug event occured.
7256 TEST(DebugEventBreakData) {
7257   DebugLocalContext env;
7258   v8::Isolate* isolate = env->GetIsolate();
7259   v8::HandleScope scope(isolate);
7260   v8::Debug::SetDebugEventListener2(DebugEventBreakDataChecker);
7261
7262   TestClientData::constructor_call_counter = 0;
7263   TestClientData::destructor_call_counter = 0;
7264
7265   expected_break_data = NULL;
7266   was_debug_event_called = false;
7267   was_debug_break_called = false;
7268   v8::Debug::DebugBreakForCommand(NULL, isolate);
7269   v8::Script::Compile(v8::String::NewFromUtf8(env->GetIsolate(),
7270                                               "(function(x){return x;})(1);"))
7271       ->Run();
7272   CHECK(was_debug_event_called);
7273   CHECK(!was_debug_break_called);
7274
7275   TestClientData* data1 = new TestClientData();
7276   expected_break_data = data1;
7277   was_debug_event_called = false;
7278   was_debug_break_called = false;
7279   v8::Debug::DebugBreakForCommand(data1, isolate);
7280   v8::Script::Compile(v8::String::NewFromUtf8(env->GetIsolate(),
7281                                               "(function(x){return x+1;})(1);"))
7282       ->Run();
7283   CHECK(was_debug_event_called);
7284   CHECK(!was_debug_break_called);
7285
7286   expected_break_data = NULL;
7287   was_debug_event_called = false;
7288   was_debug_break_called = false;
7289   v8::Debug::DebugBreak(isolate);
7290   v8::Script::Compile(v8::String::NewFromUtf8(env->GetIsolate(),
7291                                               "(function(x){return x+2;})(1);"))
7292       ->Run();
7293   CHECK(!was_debug_event_called);
7294   CHECK(was_debug_break_called);
7295
7296   TestClientData* data2 = new TestClientData();
7297   expected_break_data = data2;
7298   was_debug_event_called = false;
7299   was_debug_break_called = false;
7300   v8::Debug::DebugBreak(isolate);
7301   v8::Debug::DebugBreakForCommand(data2, isolate);
7302   v8::Script::Compile(v8::String::NewFromUtf8(env->GetIsolate(),
7303                                               "(function(x){return x+3;})(1);"))
7304       ->Run();
7305   CHECK(was_debug_event_called);
7306   CHECK(was_debug_break_called);
7307
7308   CHECK_EQ(2, TestClientData::constructor_call_counter);
7309   CHECK_EQ(TestClientData::constructor_call_counter,
7310            TestClientData::destructor_call_counter);
7311
7312   v8::Debug::SetDebugEventListener2(NULL);
7313   CheckDebuggerUnloaded();
7314 }
7315
7316 static bool debug_event_break_deoptimize_done = false;
7317
7318 static void DebugEventBreakDeoptimize(
7319     const v8::Debug::EventDetails& event_details) {
7320   v8::DebugEvent event = event_details.GetEvent();
7321   v8::Handle<v8::Object> exec_state = event_details.GetExecutionState();
7322   if (event == v8::Break) {
7323     if (!frame_function_name.IsEmpty()) {
7324       // Get the name of the function.
7325       const int argc = 2;
7326       v8::Handle<v8::Value> argv[argc] = {
7327         exec_state, v8::Integer::New(CcTest::isolate(), 0)
7328       };
7329       v8::Handle<v8::Value> result =
7330           frame_function_name->Call(exec_state, argc, argv);
7331       if (!result->IsUndefined()) {
7332         char fn[80];
7333         CHECK(result->IsString());
7334         v8::Handle<v8::String> function_name(result->ToString());
7335         function_name->WriteUtf8(fn);
7336         if (strcmp(fn, "bar") == 0) {
7337           i::Deoptimizer::DeoptimizeAll(CcTest::i_isolate());
7338           debug_event_break_deoptimize_done = true;
7339         }
7340       }
7341     }
7342
7343     v8::Debug::DebugBreak(CcTest::isolate());
7344   }
7345 }
7346
7347
7348 // Test deoptimization when execution is broken using the debug break stack
7349 // check interrupt.
7350 TEST(DeoptimizeDuringDebugBreak) {
7351   DebugLocalContext env;
7352   v8::HandleScope scope(env->GetIsolate());
7353   env.ExposeDebug();
7354
7355   // Create a function for checking the function when hitting a break point.
7356   frame_function_name = CompileFunction(&env,
7357                                         frame_function_name_source,
7358                                         "frame_function_name");
7359
7360
7361   // Set a debug event listener which will keep interrupting execution until
7362   // debug break. When inside function bar it will deoptimize all functions.
7363   // This tests lazy deoptimization bailout for the stack check, as the first
7364   // time in function bar when using debug break and no break points will be at
7365   // the initial stack check.
7366   v8::Debug::SetDebugEventListener2(DebugEventBreakDeoptimize);
7367
7368   // Compile and run function bar which will optimize it for some flag settings.
7369   v8::Script::Compile(v8::String::NewFromUtf8(
7370                           env->GetIsolate(), "function bar(){}; bar()"))->Run();
7371
7372   // Set debug break and call bar again.
7373   v8::Debug::DebugBreak(env->GetIsolate());
7374   v8::Script::Compile(v8::String::NewFromUtf8(env->GetIsolate(), "bar()"))
7375       ->Run();
7376
7377   CHECK(debug_event_break_deoptimize_done);
7378
7379   v8::Debug::SetDebugEventListener2(NULL);
7380 }
7381
7382
7383 static void DebugEventBreakWithOptimizedStack(
7384     const v8::Debug::EventDetails& event_details) {
7385   v8::Isolate* isolate = event_details.GetEventContext()->GetIsolate();
7386   v8::DebugEvent event = event_details.GetEvent();
7387   v8::Handle<v8::Object> exec_state = event_details.GetExecutionState();
7388   if (event == v8::Break) {
7389     if (!frame_function_name.IsEmpty()) {
7390       for (int i = 0; i < 2; i++) {
7391         const int argc = 2;
7392         v8::Handle<v8::Value> argv[argc] = {
7393           exec_state, v8::Integer::New(isolate, i)
7394         };
7395         // Get the name of the function in frame i.
7396         v8::Handle<v8::Value> result =
7397             frame_function_name->Call(exec_state, argc, argv);
7398         CHECK(result->IsString());
7399         v8::Handle<v8::String> function_name(result->ToString());
7400         CHECK(function_name->Equals(v8::String::NewFromUtf8(isolate, "loop")));
7401         // Get the name of the first argument in frame i.
7402         result = frame_argument_name->Call(exec_state, argc, argv);
7403         CHECK(result->IsString());
7404         v8::Handle<v8::String> argument_name(result->ToString());
7405         CHECK(argument_name->Equals(v8::String::NewFromUtf8(isolate, "count")));
7406         // Get the value of the first argument in frame i. If the
7407         // funtion is optimized the value will be undefined, otherwise
7408         // the value will be '1 - i'.
7409         //
7410         // TODO(3141533): We should be able to get the real value for
7411         // optimized frames.
7412         result = frame_argument_value->Call(exec_state, argc, argv);
7413         CHECK(result->IsUndefined() || (result->Int32Value() == 1 - i));
7414         // Get the name of the first local variable.
7415         result = frame_local_name->Call(exec_state, argc, argv);
7416         CHECK(result->IsString());
7417         v8::Handle<v8::String> local_name(result->ToString());
7418         CHECK(local_name->Equals(v8::String::NewFromUtf8(isolate, "local")));
7419         // Get the value of the first local variable. If the function
7420         // is optimized the value will be undefined, otherwise it will
7421         // be 42.
7422         //
7423         // TODO(3141533): We should be able to get the real value for
7424         // optimized frames.
7425         result = frame_local_value->Call(exec_state, argc, argv);
7426         CHECK(result->IsUndefined() || (result->Int32Value() == 42));
7427       }
7428     }
7429   }
7430 }
7431
7432
7433 static void ScheduleBreak(const v8::FunctionCallbackInfo<v8::Value>& args) {
7434   v8::Debug::SetDebugEventListener2(DebugEventBreakWithOptimizedStack);
7435   v8::Debug::DebugBreak(args.GetIsolate());
7436 }
7437
7438
7439 TEST(DebugBreakStackInspection) {
7440   DebugLocalContext env;
7441   v8::HandleScope scope(env->GetIsolate());
7442
7443   frame_function_name =
7444       CompileFunction(&env, frame_function_name_source, "frame_function_name");
7445   frame_argument_name =
7446       CompileFunction(&env, frame_argument_name_source, "frame_argument_name");
7447   frame_argument_value = CompileFunction(&env,
7448                                          frame_argument_value_source,
7449                                          "frame_argument_value");
7450   frame_local_name =
7451       CompileFunction(&env, frame_local_name_source, "frame_local_name");
7452   frame_local_value =
7453       CompileFunction(&env, frame_local_value_source, "frame_local_value");
7454
7455   v8::Handle<v8::FunctionTemplate> schedule_break_template =
7456       v8::FunctionTemplate::New(env->GetIsolate(), ScheduleBreak);
7457   v8::Handle<v8::Function> schedule_break =
7458       schedule_break_template->GetFunction();
7459   env->Global()->Set(v8_str("scheduleBreak"), schedule_break);
7460
7461   const char* src =
7462       "function loop(count) {"
7463       "  var local = 42;"
7464       "  if (count < 1) { scheduleBreak(); loop(count + 1); }"
7465       "}"
7466       "loop(0);";
7467   v8::Script::Compile(v8::String::NewFromUtf8(env->GetIsolate(), src))->Run();
7468 }
7469
7470
7471 // Test that setting the terminate execution flag during debug break processing.
7472 static void TestDebugBreakInLoop(const char* loop_head,
7473                                  const char** loop_bodies,
7474                                  const char* loop_tail) {
7475   // Receive 100 breaks for each test and then terminate JavaScript execution.
7476   static const int kBreaksPerTest = 100;
7477
7478   for (int i = 0; loop_bodies[i] != NULL; i++) {
7479     // Perform a lazy deoptimization after various numbers of breaks
7480     // have been hit.
7481     for (int j = 0; j < 7; j++) {
7482       break_point_hit_count_deoptimize = j;
7483       if (j == 6) {
7484         break_point_hit_count_deoptimize = kBreaksPerTest;
7485       }
7486
7487       break_point_hit_count = 0;
7488       max_break_point_hit_count = kBreaksPerTest;
7489       terminate_after_max_break_point_hit = true;
7490
7491       EmbeddedVector<char, 1024> buffer;
7492       OS::SNPrintF(buffer,
7493                    "function f() {%s%s%s}",
7494                    loop_head, loop_bodies[i], loop_tail);
7495
7496       // Function with infinite loop.
7497       CompileRun(buffer.start());
7498
7499       // Set the debug break to enter the debugger as soon as possible.
7500       v8::Debug::DebugBreak(CcTest::isolate());
7501
7502       // Call function with infinite loop.
7503       CompileRun("f();");
7504       CHECK_EQ(kBreaksPerTest, break_point_hit_count);
7505
7506       CHECK(!v8::V8::IsExecutionTerminating());
7507     }
7508   }
7509 }
7510
7511
7512 TEST(DebugBreakLoop) {
7513   DebugLocalContext env;
7514   v8::HandleScope scope(env->GetIsolate());
7515
7516   // Register a debug event listener which sets the break flag and counts.
7517   v8::Debug::SetDebugEventListener2(DebugEventBreakMax);
7518
7519   // Create a function for getting the frame count when hitting the break.
7520   frame_count = CompileFunction(&env, frame_count_source, "frame_count");
7521
7522   CompileRun("var a = 1;");
7523   CompileRun("function g() { }");
7524   CompileRun("function h() { }");
7525
7526   const char* loop_bodies[] = {
7527       "",
7528       "g()",
7529       "if (a == 0) { g() }",
7530       "if (a == 1) { g() }",
7531       "if (a == 0) { g() } else { h() }",
7532       "if (a == 0) { continue }",
7533       "if (a == 1) { continue }",
7534       "switch (a) { case 1: g(); }",
7535       "switch (a) { case 1: continue; }",
7536       "switch (a) { case 1: g(); break; default: h() }",
7537       "switch (a) { case 1: continue; break; default: h() }",
7538       NULL
7539   };
7540
7541   TestDebugBreakInLoop("while (true) {", loop_bodies, "}");
7542   TestDebugBreakInLoop("while (a == 1) {", loop_bodies, "}");
7543
7544   TestDebugBreakInLoop("do {", loop_bodies, "} while (true)");
7545   TestDebugBreakInLoop("do {", loop_bodies, "} while (a == 1)");
7546
7547   TestDebugBreakInLoop("for (;;) {", loop_bodies, "}");
7548   TestDebugBreakInLoop("for (;a == 1;) {", loop_bodies, "}");
7549
7550   // Get rid of the debug event listener.
7551   v8::Debug::SetDebugEventListener2(NULL);
7552   CheckDebuggerUnloaded();
7553 }
7554
7555
7556 v8::Local<v8::Script> inline_script;
7557
7558 static void DebugBreakInlineListener(
7559     const v8::Debug::EventDetails& event_details) {
7560   v8::DebugEvent event = event_details.GetEvent();
7561   if (event != v8::Break) return;
7562
7563   int expected_frame_count = 4;
7564   int expected_line_number[] = {1, 4, 7, 12};
7565
7566   i::Handle<i::Object> compiled_script = v8::Utils::OpenHandle(*inline_script);
7567   i::Handle<i::Script> source_script = i::Handle<i::Script>(i::Script::cast(
7568       i::JSFunction::cast(*compiled_script)->shared()->script()));
7569
7570   int break_id = CcTest::i_isolate()->debug()->break_id();
7571   char script[128];
7572   i::Vector<char> script_vector(script, sizeof(script));
7573   OS::SNPrintF(script_vector, "%%GetFrameCount(%d)", break_id);
7574   v8::Local<v8::Value> result = CompileRun(script);
7575
7576   int frame_count = result->Int32Value();
7577   CHECK_EQ(expected_frame_count, frame_count);
7578
7579   for (int i = 0; i < frame_count; i++) {
7580     // The 5. element in the returned array of GetFrameDetails contains the
7581     // source position of that frame.
7582     OS::SNPrintF(script_vector, "%%GetFrameDetails(%d, %d)[5]", break_id, i);
7583     v8::Local<v8::Value> result = CompileRun(script);
7584     CHECK_EQ(expected_line_number[i],
7585              i::GetScriptLineNumber(source_script, result->Int32Value()));
7586   }
7587   v8::Debug::SetDebugEventListener2(NULL);
7588   v8::V8::TerminateExecution(CcTest::isolate());
7589 }
7590
7591
7592 TEST(DebugBreakInline) {
7593   i::FLAG_allow_natives_syntax = true;
7594   DebugLocalContext env;
7595   v8::HandleScope scope(env->GetIsolate());
7596   const char* source =
7597       "function debug(b) {             \n"
7598       "  if (b) debugger;              \n"
7599       "}                               \n"
7600       "function f(b) {                 \n"
7601       "  debug(b)                      \n"
7602       "};                              \n"
7603       "function g(b) {                 \n"
7604       "  f(b);                         \n"
7605       "};                              \n"
7606       "g(false);                       \n"
7607       "g(false);                       \n"
7608       "%OptimizeFunctionOnNextCall(g); \n"
7609       "g(true);";
7610   v8::Debug::SetDebugEventListener2(DebugBreakInlineListener);
7611   inline_script =
7612       v8::Script::Compile(v8::String::NewFromUtf8(env->GetIsolate(), source));
7613   inline_script->Run();
7614 }
7615
7616
7617 static void DebugEventStepNext(
7618     const v8::Debug::EventDetails& event_details) {
7619   v8::DebugEvent event = event_details.GetEvent();
7620   if (event == v8::Break) {
7621     PrepareStep(StepNext);
7622   }
7623 }
7624
7625
7626 static void RunScriptInANewCFrame(const char* source) {
7627   v8::TryCatch try_catch;
7628   CompileRun(source);
7629   CHECK(try_catch.HasCaught());
7630 }
7631
7632
7633 TEST(Regress131642) {
7634   // Bug description:
7635   // When doing StepNext through the first script, the debugger is not reset
7636   // after exiting through exception.  A flawed implementation enabling the
7637   // debugger to step into Array.prototype.forEach breaks inside the callback
7638   // for forEach in the second script under the assumption that we are in a
7639   // recursive call.  In an attempt to step out, we crawl the stack using the
7640   // recorded frame pointer from the first script and fail when not finding it
7641   // on the stack.
7642   DebugLocalContext env;
7643   v8::HandleScope scope(env->GetIsolate());
7644   v8::Debug::SetDebugEventListener2(DebugEventStepNext);
7645
7646   // We step through the first script.  It exits through an exception.  We run
7647   // this inside a new frame to record a different FP than the second script
7648   // would expect.
7649   const char* script_1 = "debugger; throw new Error();";
7650   RunScriptInANewCFrame(script_1);
7651
7652   // The second script uses forEach.
7653   const char* script_2 = "[0].forEach(function() { });";
7654   CompileRun(script_2);
7655
7656   v8::Debug::SetDebugEventListener2(NULL);
7657 }
7658
7659
7660 // Import from test-heap.cc
7661 int CountNativeContexts();
7662
7663
7664 static void NopListener(const v8::Debug::EventDetails& event_details) {
7665 }
7666
7667
7668 TEST(DebuggerCreatesContextIffActive) {
7669   DebugLocalContext env;
7670   v8::HandleScope scope(env->GetIsolate());
7671   CHECK_EQ(1, CountNativeContexts());
7672
7673   v8::Debug::SetDebugEventListener2(NULL);
7674   CompileRun("debugger;");
7675   CHECK_EQ(1, CountNativeContexts());
7676
7677   v8::Debug::SetDebugEventListener2(NopListener);
7678   CompileRun("debugger;");
7679   CHECK_EQ(2, CountNativeContexts());
7680
7681   v8::Debug::SetDebugEventListener2(NULL);
7682 }
7683
7684
7685 TEST(LiveEditEnabled) {
7686   v8::internal::FLAG_allow_natives_syntax = true;
7687   LocalContext env;
7688   v8::HandleScope scope(env->GetIsolate());
7689   v8::Debug::SetLiveEditEnabled(true, env->GetIsolate());
7690   CompileRun("%LiveEditCompareStrings('', '')");
7691 }
7692
7693
7694 TEST(LiveEditDisabled) {
7695   v8::internal::FLAG_allow_natives_syntax = true;
7696   LocalContext env;
7697   v8::HandleScope scope(env->GetIsolate());
7698   v8::Debug::SetLiveEditEnabled(false, env->GetIsolate());
7699   CompileRun("%LiveEditCompareStrings('', '')");
7700 }
7701
7702
7703 #endif  // ENABLE_DEBUGGER_SUPPORT