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