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