13ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Copyright 2012 the V8 project authors. All rights reserved. 2a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Redistribution and use in source and binary forms, with or without 3a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// modification, are permitted provided that the following conditions are 4a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// met: 5a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 6a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// * Redistributions of source code must retain the above copyright 7a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// notice, this list of conditions and the following disclaimer. 8a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// * Redistributions in binary form must reproduce the above 9a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// copyright notice, this list of conditions and the following 10a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// disclaimer in the documentation and/or other materials provided 11a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// with the distribution. 12a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// * Neither the name of Google Inc. nor the names of its 13a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// contributors may be used to endorse or promote products derived 14a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// from this software without specific prior written permission. 15a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 16a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 289dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen#ifdef ENABLE_DEBUGGER_SUPPORT 29a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 309dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen#include <stdlib.h> 317f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 32a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "v8.h" 33a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 34a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "api.h" 35b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#include "cctest.h" 36a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "compilation-cache.h" 37a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "debug.h" 38b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#include "deoptimizer.h" 39a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "platform.h" 40a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "stub-cache.h" 41b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#include "utils.h" 42a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 43a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 44a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockusing ::v8::internal::EmbeddedVector; 45a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockusing ::v8::internal::Object; 46a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockusing ::v8::internal::OS; 47a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockusing ::v8::internal::Handle; 48a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockusing ::v8::internal::Heap; 49a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockusing ::v8::internal::JSGlobalProxy; 50a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockusing ::v8::internal::Code; 51a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockusing ::v8::internal::Debug; 52a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockusing ::v8::internal::Debugger; 53a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockusing ::v8::internal::CommandMessage; 54a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockusing ::v8::internal::CommandMessageQueue; 55a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockusing ::v8::internal::StepAction; 56a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockusing ::v8::internal::StepIn; // From StepAction enum 57a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockusing ::v8::internal::StepNext; // From StepAction enum 58a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockusing ::v8::internal::StepOut; // From StepAction enum 59a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockusing ::v8::internal::Vector; 60d0582a6c46733687d045e4188a1bcd0123c758a1Steve Blockusing ::v8::internal::StrLength; 61a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 62a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Size of temp buffer for formatting small strings. 63a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define SMALL_STRING_BUFFER_SIZE 80 64a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 65a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// --- A d d i t i o n a l C h e c k H e l p e r s 66a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 67a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 68a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Helper function used by the CHECK_EQ function when given Address 69a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// arguments. Should not be called directly. 70a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic inline void CheckEqualsHelper(const char* file, int line, 71a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const char* expected_source, 72a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ::v8::internal::Address expected, 73a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const char* value_source, 74a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ::v8::internal::Address value) { 75a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (expected != value) { 76a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block V8_Fatal(file, line, "CHECK_EQ(%s, %s) failed\n# " 77a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "Expected: %i\n# Found: %i", 78a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block expected_source, value_source, expected, value); 79a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 80a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 81a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 82a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 83a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Helper function used by the CHECK_NE function when given Address 84a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// arguments. Should not be called directly. 85a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic inline void CheckNonEqualsHelper(const char* file, int line, 86a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const char* unexpected_source, 87a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ::v8::internal::Address unexpected, 88a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const char* value_source, 89a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ::v8::internal::Address value) { 90a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (unexpected == value) { 91a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block V8_Fatal(file, line, "CHECK_NE(%s, %s) failed\n# Value: %i", 92a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block unexpected_source, value_source, value); 93a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 94a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 95a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 96a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 97a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Helper function used by the CHECK function when given code 98a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// arguments. Should not be called directly. 99a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic inline void CheckEqualsHelper(const char* file, int line, 100a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const char* expected_source, 101a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const Code* expected, 102a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const char* value_source, 103a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const Code* value) { 104a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (expected != value) { 105a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block V8_Fatal(file, line, "CHECK_EQ(%s, %s) failed\n# " 106a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "Expected: %p\n# Found: %p", 107a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block expected_source, value_source, expected, value); 108a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 109a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 110a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 111a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 112a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic inline void CheckNonEqualsHelper(const char* file, int line, 113a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const char* expected_source, 114a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const Code* expected, 115a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const char* value_source, 116a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const Code* value) { 117a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (expected == value) { 118a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block V8_Fatal(file, line, "CHECK_NE(%s, %s) failed\n# Value: %p", 119a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block expected_source, value_source, value); 120a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 121a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 122a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 123a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 124a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// --- H e l p e r C l a s s e s 125a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 126a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 127a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Helper class for creating a V8 enviromnent for running tests 128a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass DebugLocalContext { 129a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 130a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline DebugLocalContext( 131a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::ExtensionConfiguration* extensions = 0, 132a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<v8::ObjectTemplate> global_template = 133a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<v8::ObjectTemplate>(), 134a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<v8::Value> global_object = v8::Handle<v8::Value>()) 135a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : context_(v8::Context::New(extensions, global_template, global_object)) { 136a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block context_->Enter(); 137a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 138a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline ~DebugLocalContext() { 139a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block context_->Exit(); 140a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block context_.Dispose(); 141a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 142a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline v8::Context* operator->() { return *context_; } 143a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline v8::Context* operator*() { return *context_; } 144a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline bool IsReady() { return !context_.IsEmpty(); } 145a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void ExposeDebug() { 14644f0eee88ff00398ff7f715fab053374d808c90dSteve Block v8::internal::Debug* debug = v8::internal::Isolate::Current()->debug(); 147a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Expose the debug context global object in the global object for testing. 14844f0eee88ff00398ff7f715fab053374d808c90dSteve Block debug->Load(); 14944f0eee88ff00398ff7f715fab053374d808c90dSteve Block debug->debug_context()->set_security_token( 150a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Utils::OpenHandle(*context_)->security_token()); 151a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 152a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<JSGlobalProxy> global(Handle<JSGlobalProxy>::cast( 153a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Utils::OpenHandle(*context_->Global()))); 154a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<v8::internal::String> debug_string = 15544f0eee88ff00398ff7f715fab053374d808c90dSteve Block FACTORY->LookupAsciiSymbol("debug"); 156a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block SetProperty(global, debug_string, 15744f0eee88ff00398ff7f715fab053374d808c90dSteve Block Handle<Object>(debug->debug_context()->global_proxy()), DONT_ENUM, 158e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch ::v8::internal::kNonStrictMode); 159a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 160589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch 161a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private: 162a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Persistent<v8::Context> context_; 163a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 164a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 165a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 166a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// --- H e l p e r F u n c t i o n s 167a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 168a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 169a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Compile and run the supplied source and return the fequested function. 170a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic v8::Local<v8::Function> CompileFunction(DebugLocalContext* env, 171a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const char* source, 172a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const char* function_name) { 173a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Script::Compile(v8::String::New(source))->Run(); 174a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return v8::Local<v8::Function>::Cast( 175a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block (*env)->Global()->Get(v8::String::New(function_name))); 176a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 177a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 178a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 179a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Compile and run the supplied source and return the requested function. 180a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic v8::Local<v8::Function> CompileFunction(const char* source, 181a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const char* function_name) { 182a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Script::Compile(v8::String::New(source))->Run(); 183a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return v8::Local<v8::Function>::Cast( 184a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Context::GetCurrent()->Global()->Get(v8::String::New(function_name))); 185a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 186a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 187a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 188a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Is there any debug info for the function? 189a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic bool HasDebugInfo(v8::Handle<v8::Function> fun) { 190a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<v8::internal::JSFunction> f = v8::Utils::OpenHandle(*fun); 191a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<v8::internal::SharedFunctionInfo> shared(f->shared()); 192a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return Debug::HasDebugInfo(shared); 193a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 194a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 195a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 196a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Set a break point in a function and return the associated break point 197a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// number. 198a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic int SetBreakPoint(Handle<v8::internal::JSFunction> fun, int position) { 199a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static int break_point = 0; 200a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<v8::internal::SharedFunctionInfo> shared(fun->shared()); 20144f0eee88ff00398ff7f715fab053374d808c90dSteve Block v8::internal::Debug* debug = v8::internal::Isolate::Current()->debug(); 20244f0eee88ff00398ff7f715fab053374d808c90dSteve Block debug->SetBreakPoint( 2039dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen shared, 2049dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen Handle<Object>(v8::internal::Smi::FromInt(++break_point)), 2059dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen &position); 206a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return break_point; 207a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 208a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 209a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 210a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Set a break point in a function and return the associated break point 211a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// number. 212a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic int SetBreakPoint(v8::Handle<v8::Function> fun, int position) { 213a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return SetBreakPoint(v8::Utils::OpenHandle(*fun), position); 214a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 215a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 216a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 217a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Set a break point in a function using the Debug object and return the 218a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// associated break point number. 219a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic int SetBreakPointFromJS(const char* function_name, 220a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int line, int position) { 221a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EmbeddedVector<char, SMALL_STRING_BUFFER_SIZE> buffer; 222a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block OS::SNPrintF(buffer, 223a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "debug.Debug.setBreakPoint(%s,%d,%d)", 224a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block function_name, line, position); 225a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block buffer[SMALL_STRING_BUFFER_SIZE - 1] = '\0'; 226a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<v8::String> str = v8::String::New(buffer.start()); 227a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return v8::Script::Compile(str)->Run()->Int32Value(); 228a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 229a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 230a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 231a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Set a break point in a script identified by id using the global Debug object. 232a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic int SetScriptBreakPointByIdFromJS(int script_id, int line, int column) { 233a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EmbeddedVector<char, SMALL_STRING_BUFFER_SIZE> buffer; 234a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (column >= 0) { 235a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Column specified set script break point on precise location. 236a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block OS::SNPrintF(buffer, 237a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "debug.Debug.setScriptBreakPointById(%d,%d,%d)", 238a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block script_id, line, column); 239a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 240a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Column not specified set script break point on line. 241a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block OS::SNPrintF(buffer, 242a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "debug.Debug.setScriptBreakPointById(%d,%d)", 243a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block script_id, line); 244a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 245a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block buffer[SMALL_STRING_BUFFER_SIZE - 1] = '\0'; 246a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block { 247a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::TryCatch try_catch; 248a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<v8::String> str = v8::String::New(buffer.start()); 249a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<v8::Value> value = v8::Script::Compile(str)->Run(); 250a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(!try_catch.HasCaught()); 251a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return value->Int32Value(); 252a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 253a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 254a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 255a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 256a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Set a break point in a script identified by name using the global Debug 257a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// object. 258a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic int SetScriptBreakPointByNameFromJS(const char* script_name, 259a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int line, int column) { 260a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EmbeddedVector<char, SMALL_STRING_BUFFER_SIZE> buffer; 261a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (column >= 0) { 262a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Column specified set script break point on precise location. 263a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block OS::SNPrintF(buffer, 264a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "debug.Debug.setScriptBreakPointByName(\"%s\",%d,%d)", 265a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block script_name, line, column); 266a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 267a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Column not specified set script break point on line. 268a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block OS::SNPrintF(buffer, 269a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "debug.Debug.setScriptBreakPointByName(\"%s\",%d)", 270a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block script_name, line); 271a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 272a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block buffer[SMALL_STRING_BUFFER_SIZE - 1] = '\0'; 273a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block { 274a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::TryCatch try_catch; 275a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<v8::String> str = v8::String::New(buffer.start()); 276a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<v8::Value> value = v8::Script::Compile(str)->Run(); 277a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(!try_catch.HasCaught()); 278a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return value->Int32Value(); 279a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 280a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 281a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 282a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 283a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Clear a break point. 284a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic void ClearBreakPoint(int break_point) { 28544f0eee88ff00398ff7f715fab053374d808c90dSteve Block v8::internal::Debug* debug = v8::internal::Isolate::Current()->debug(); 28644f0eee88ff00398ff7f715fab053374d808c90dSteve Block debug->ClearBreakPoint( 287a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Object>(v8::internal::Smi::FromInt(break_point))); 288a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 289a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 290a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 291a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Clear a break point using the global Debug object. 292a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic void ClearBreakPointFromJS(int break_point_number) { 293a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EmbeddedVector<char, SMALL_STRING_BUFFER_SIZE> buffer; 294a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block OS::SNPrintF(buffer, 295a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "debug.Debug.clearBreakPoint(%d)", 296a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_number); 297a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block buffer[SMALL_STRING_BUFFER_SIZE - 1] = '\0'; 298a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Script::Compile(v8::String::New(buffer.start()))->Run(); 299a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 300a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 301a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 302a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic void EnableScriptBreakPointFromJS(int break_point_number) { 303a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EmbeddedVector<char, SMALL_STRING_BUFFER_SIZE> buffer; 304a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block OS::SNPrintF(buffer, 305a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "debug.Debug.enableScriptBreakPoint(%d)", 306a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_number); 307a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block buffer[SMALL_STRING_BUFFER_SIZE - 1] = '\0'; 308a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Script::Compile(v8::String::New(buffer.start()))->Run(); 309a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 310a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 311a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 312a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic void DisableScriptBreakPointFromJS(int break_point_number) { 313a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EmbeddedVector<char, SMALL_STRING_BUFFER_SIZE> buffer; 314a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block OS::SNPrintF(buffer, 315a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "debug.Debug.disableScriptBreakPoint(%d)", 316a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_number); 317a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block buffer[SMALL_STRING_BUFFER_SIZE - 1] = '\0'; 318a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Script::Compile(v8::String::New(buffer.start()))->Run(); 319a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 320a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 321a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 322a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic void ChangeScriptBreakPointConditionFromJS(int break_point_number, 323a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const char* condition) { 324a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EmbeddedVector<char, SMALL_STRING_BUFFER_SIZE> buffer; 325a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block OS::SNPrintF(buffer, 326a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "debug.Debug.changeScriptBreakPointCondition(%d, \"%s\")", 327a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_number, condition); 328a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block buffer[SMALL_STRING_BUFFER_SIZE - 1] = '\0'; 329a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Script::Compile(v8::String::New(buffer.start()))->Run(); 330a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 331a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 332a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 333a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic void ChangeScriptBreakPointIgnoreCountFromJS(int break_point_number, 334a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int ignoreCount) { 335a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EmbeddedVector<char, SMALL_STRING_BUFFER_SIZE> buffer; 336a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block OS::SNPrintF(buffer, 337a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "debug.Debug.changeScriptBreakPointIgnoreCount(%d, %d)", 338a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_number, ignoreCount); 339a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block buffer[SMALL_STRING_BUFFER_SIZE - 1] = '\0'; 340a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Script::Compile(v8::String::New(buffer.start()))->Run(); 341a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 342a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 343a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 344a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Change break on exception. 345a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic void ChangeBreakOnException(bool caught, bool uncaught) { 34644f0eee88ff00398ff7f715fab053374d808c90dSteve Block v8::internal::Debug* debug = v8::internal::Isolate::Current()->debug(); 34744f0eee88ff00398ff7f715fab053374d808c90dSteve Block debug->ChangeBreakOnException(v8::internal::BreakException, caught); 34844f0eee88ff00398ff7f715fab053374d808c90dSteve Block debug->ChangeBreakOnException(v8::internal::BreakUncaughtException, uncaught); 349a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 350a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 351a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 352a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Change break on exception using the global Debug object. 353a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic void ChangeBreakOnExceptionFromJS(bool caught, bool uncaught) { 354a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (caught) { 355a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Script::Compile( 356a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::String::New("debug.Debug.setBreakOnException()"))->Run(); 357a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 358a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Script::Compile( 359a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::String::New("debug.Debug.clearBreakOnException()"))->Run(); 360a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 361a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (uncaught) { 362a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Script::Compile( 363a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::String::New("debug.Debug.setBreakOnUncaughtException()"))->Run(); 364a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 365a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Script::Compile( 366a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::String::New("debug.Debug.clearBreakOnUncaughtException()"))->Run(); 367a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 368a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 369a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 370a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 371a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Prepare to step to next break location. 372a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic void PrepareStep(StepAction step_action) { 37344f0eee88ff00398ff7f715fab053374d808c90dSteve Block v8::internal::Debug* debug = v8::internal::Isolate::Current()->debug(); 37444f0eee88ff00398ff7f715fab053374d808c90dSteve Block debug->PrepareStep(step_action, 1); 375a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 376a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 377a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 378a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// This function is in namespace v8::internal to be friend with class 379a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// v8::internal::Debug. 380a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace v8 { 381a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace internal { 382a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 383a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Collect the currently debugged functions. 384a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<FixedArray> GetDebuggedFunctions() { 38544f0eee88ff00398ff7f715fab053374d808c90dSteve Block Debug* debug = Isolate::Current()->debug(); 38644f0eee88ff00398ff7f715fab053374d808c90dSteve Block 38744f0eee88ff00398ff7f715fab053374d808c90dSteve Block v8::internal::DebugInfoListNode* node = debug->debug_info_list_; 388a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 389a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Find the number of debugged functions. 390a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int count = 0; 391a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block while (node) { 392a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block count++; 393a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block node = node->next(); 394a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 395a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 396a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Allocate array for the debugged functions 397a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<FixedArray> debugged_functions = 39844f0eee88ff00398ff7f715fab053374d808c90dSteve Block FACTORY->NewFixedArray(count); 399a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 400a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Run through the debug info objects and collect all functions. 401a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block count = 0; 402a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block while (node) { 403a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block debugged_functions->set(count++, *node->debug_info()); 404a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block node = node->next(); 405a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 406a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 407a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return debugged_functions; 408a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 409a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 410a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 411a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic Handle<Code> ComputeCallDebugBreak(int argc) { 4123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return Isolate::Current()->stub_cache()->ComputeCallDebugBreak(argc, 4133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Code::CALL_IC); 414a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 415a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 416a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 417a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Check that the debugger has been fully unloaded. 418a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid CheckDebuggerUnloaded(bool check_functions) { 419a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Check that the debugger context is cleared and that there is no debug 420a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // information stored for the debugger. 42144f0eee88ff00398ff7f715fab053374d808c90dSteve Block CHECK(Isolate::Current()->debug()->debug_context().is_null()); 42244f0eee88ff00398ff7f715fab053374d808c90dSteve Block CHECK_EQ(NULL, Isolate::Current()->debug()->debug_info_list_); 423a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 424a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Collect garbage to ensure weak handles are cleared. 4253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch HEAP->CollectAllGarbage(Heap::kNoGCFlags); 4263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch HEAP->CollectAllGarbage(Heap::kMakeHeapIterableMask); 427a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 428a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Iterate the head and check that there are no debugger related objects left. 429a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block HeapIterator iterator; 430d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke for (HeapObject* obj = iterator.next(); obj != NULL; obj = iterator.next()) { 431a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(!obj->IsDebugInfo()); 432a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(!obj->IsBreakPointInfo()); 433a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 434a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // If deep check of functions is requested check that no debug break code 435a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // is left in all functions. 436a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (check_functions) { 437a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (obj->IsJSFunction()) { 438a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block JSFunction* fun = JSFunction::cast(obj); 439a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (RelocIterator it(fun->shared()->code()); !it.done(); it.next()) { 440a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block RelocInfo::Mode rmode = it.rinfo()->rmode(); 441a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (RelocInfo::IsCodeTarget(rmode)) { 442a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(!Debug::IsDebugBreak(it.rinfo()->target_address())); 443a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else if (RelocInfo::IsJSReturn(rmode)) { 444a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(!Debug::IsDebugBreakAtReturn(it.rinfo())); 445a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 446a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 447a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 448a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 449a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 450a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 451a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 452a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4536ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockvoid ForceUnloadDebugger() { 45444f0eee88ff00398ff7f715fab053374d808c90dSteve Block Isolate::Current()->debugger()->never_unload_debugger_ = false; 45544f0eee88ff00398ff7f715fab053374d808c90dSteve Block Isolate::Current()->debugger()->UnloadDebugger(); 4566ded16be15dd865a9b21ea304d5273c8be299c87Steve Block} 4576ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 4586ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 459a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} } // namespace v8::internal 460a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 461a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 462a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Check that the debugger has been fully unloaded. 463a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic void CheckDebuggerUnloaded(bool check_functions = false) { 464e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // Let debugger to unload itself synchronously 465e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke v8::Debug::ProcessDebugMessages(); 466e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 467a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::internal::CheckDebuggerUnloaded(check_functions); 468a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 469a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 470a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 471a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Inherit from BreakLocationIterator to get access to protected parts for 472a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// testing. 473a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass TestBreakLocationIterator: public v8::internal::BreakLocationIterator { 474a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 475a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block explicit TestBreakLocationIterator(Handle<v8::internal::DebugInfo> debug_info) 476a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : BreakLocationIterator(debug_info, v8::internal::SOURCE_BREAK_LOCATIONS) {} 477a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::internal::RelocIterator* it() { return reloc_iterator_; } 478a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::internal::RelocIterator* it_original() { 479a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return reloc_iterator_original_; 480a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 481a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 482a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 483a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 484a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Compile a function, set a break point and check that the call at the break 485a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// location in the code is the expected debug_break function. 486a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid CheckDebugBreakFunction(DebugLocalContext* env, 487a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const char* source, const char* name, 488a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int position, v8::internal::RelocInfo::Mode mode, 489a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Code* debug_break) { 49044f0eee88ff00398ff7f715fab053374d808c90dSteve Block v8::internal::Debug* debug = v8::internal::Isolate::Current()->debug(); 49144f0eee88ff00398ff7f715fab053374d808c90dSteve Block 492a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Create function and set the break point. 493a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<v8::internal::JSFunction> fun = v8::Utils::OpenHandle( 494a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block *CompileFunction(env, source, name)); 495a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int bp = SetBreakPoint(fun, position); 496a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 497a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Check that the debug break function is as expected. 498a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<v8::internal::SharedFunctionInfo> shared(fun->shared()); 499a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(Debug::HasDebugInfo(shared)); 500a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block TestBreakLocationIterator it1(Debug::GetDebugInfo(shared)); 501a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block it1.FindBreakLocationFromPosition(position); 502257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch v8::internal::RelocInfo::Mode actual_mode = it1.it()->rinfo()->rmode(); 503257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (actual_mode == v8::internal::RelocInfo::CODE_TARGET_WITH_ID) { 504257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch actual_mode = v8::internal::RelocInfo::CODE_TARGET; 505257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 506257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch CHECK_EQ(mode, actual_mode); 507a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (mode != v8::internal::RelocInfo::JS_RETURN) { 508a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(debug_break, 509a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Code::GetCodeFromTargetAddress(it1.it()->rinfo()->target_address())); 510a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 511a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(Debug::IsDebugBreakAtReturn(it1.it()->rinfo())); 512a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 513a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 514a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Clear the break point and check that the debug break function is no longer 515a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // there 516a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ClearBreakPoint(bp); 51744f0eee88ff00398ff7f715fab053374d808c90dSteve Block CHECK(!debug->HasDebugInfo(shared)); 51844f0eee88ff00398ff7f715fab053374d808c90dSteve Block CHECK(debug->EnsureDebugInfo(shared)); 519a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block TestBreakLocationIterator it2(Debug::GetDebugInfo(shared)); 520a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block it2.FindBreakLocationFromPosition(position); 521257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch actual_mode = it2.it()->rinfo()->rmode(); 522257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (actual_mode == v8::internal::RelocInfo::CODE_TARGET_WITH_ID) { 523257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch actual_mode = v8::internal::RelocInfo::CODE_TARGET; 524257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 525257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch CHECK_EQ(mode, actual_mode); 526a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (mode == v8::internal::RelocInfo::JS_RETURN) { 527a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(!Debug::IsDebugBreakAtReturn(it2.it()->rinfo())); 528a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 529a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 530a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 531a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 532a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// --- D e b u g E v e n t H a n d l e r s 533a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// --- 534a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// --- The different tests uses a number of debug event handlers. 535a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// --- 536a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 537a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 538b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// Source for the JavaScript function which picks out the function 539b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// name of a frame. 540a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockconst char* frame_function_name_source = 541b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "function frame_function_name(exec_state, frame_number) {" 542b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch " return exec_state.frame(frame_number).func().name();" 543a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "}"; 544a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockv8::Local<v8::Function> frame_function_name; 545a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 546a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 547b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// Source for the JavaScript function which pick out the name of the 548b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// first argument of a frame. 549b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochconst char* frame_argument_name_source = 550b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "function frame_argument_name(exec_state, frame_number) {" 551b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch " return exec_state.frame(frame_number).argumentName(0);" 552b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "}"; 553b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochv8::Local<v8::Function> frame_argument_name; 554b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 555b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 556b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// Source for the JavaScript function which pick out the value of the 557b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// first argument of a frame. 558b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochconst char* frame_argument_value_source = 559b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "function frame_argument_value(exec_state, frame_number) {" 560b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch " return exec_state.frame(frame_number).argumentValue(0).value_;" 561b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "}"; 562b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochv8::Local<v8::Function> frame_argument_value; 563b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 564b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 565b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// Source for the JavaScript function which pick out the name of the 566b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// first argument of a frame. 567b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochconst char* frame_local_name_source = 568b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "function frame_local_name(exec_state, frame_number) {" 569b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch " return exec_state.frame(frame_number).localName(0);" 570b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "}"; 571b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochv8::Local<v8::Function> frame_local_name; 572b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 573b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 574b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// Source for the JavaScript function which pick out the value of the 575b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// first argument of a frame. 576b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochconst char* frame_local_value_source = 577b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "function frame_local_value(exec_state, frame_number) {" 578b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch " return exec_state.frame(frame_number).localValue(0).value_;" 579b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "}"; 580b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochv8::Local<v8::Function> frame_local_value; 581b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 582b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 583b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// Source for the JavaScript function which picks out the source line for the 584a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// top frame. 585a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockconst char* frame_source_line_source = 586a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "function frame_source_line(exec_state) {" 587a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " return exec_state.frame(0).sourceLine();" 588a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "}"; 589a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockv8::Local<v8::Function> frame_source_line; 590a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 591a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 592b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// Source for the JavaScript function which picks out the source column for the 593a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// top frame. 594a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockconst char* frame_source_column_source = 595a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "function frame_source_column(exec_state) {" 596a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " return exec_state.frame(0).sourceColumn();" 597a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "}"; 598a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockv8::Local<v8::Function> frame_source_column; 599a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 600a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 601b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// Source for the JavaScript function which picks out the script name for the 602a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// top frame. 603a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockconst char* frame_script_name_source = 604a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "function frame_script_name(exec_state) {" 605a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " return exec_state.frame(0).func().script().name();" 606a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "}"; 607a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockv8::Local<v8::Function> frame_script_name; 608a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 609a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 610b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// Source for the JavaScript function which picks out the script data for the 611a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// top frame. 612a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockconst char* frame_script_data_source = 613a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "function frame_script_data(exec_state) {" 614a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " return exec_state.frame(0).func().script().data();" 615a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "}"; 616a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockv8::Local<v8::Function> frame_script_data; 617a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 618a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 619b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// Source for the JavaScript function which picks out the script data from 620402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu// AfterCompile event 621402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescuconst char* compiled_script_data_source = 622402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu "function compiled_script_data(event_data) {" 623402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu " return event_data.script().data();" 624402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu "}"; 625402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescuv8::Local<v8::Function> compiled_script_data; 626402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu 627402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu 628b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// Source for the JavaScript function which returns the number of frames. 629a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic const char* frame_count_source = 630a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "function frame_count(exec_state) {" 631a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " return exec_state.frameCount();" 632a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "}"; 633a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockv8::Handle<v8::Function> frame_count; 634a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 635a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 636a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Global variable to store the last function hit - used by some tests. 637a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockchar last_function_hit[80]; 638a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 639a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Global variable to store the name and data for last script hit - used by some 640a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// tests. 641a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockchar last_script_name_hit[80]; 642a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockchar last_script_data_hit[80]; 643a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 644a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Global variables to store the last source position - used by some tests. 645a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockint last_source_line = -1; 646a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockint last_source_column = -1; 647a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 648a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Debug event handler which counts the break points which have been hit. 649a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockint break_point_hit_count = 0; 6503fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochint break_point_hit_count_deoptimize = 0; 651a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic void DebugEventBreakPointHitCount(v8::DebugEvent event, 652a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<v8::Object> exec_state, 653a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<v8::Object> event_data, 654a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<v8::Value> data) { 65544f0eee88ff00398ff7f715fab053374d808c90dSteve Block Debug* debug = v8::internal::Isolate::Current()->debug(); 656a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // When hitting a debug event listener there must be a break set. 65744f0eee88ff00398ff7f715fab053374d808c90dSteve Block CHECK_NE(debug->break_id(), 0); 658a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 659a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Count the number of breaks. 660a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (event == v8::Break) { 661a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count++; 662a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!frame_function_name.IsEmpty()) { 663a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Get the name of the function. 664b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch const int argc = 2; 665b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch v8::Handle<v8::Value> argv[argc] = { exec_state, v8::Integer::New(0) }; 666a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<v8::Value> result = frame_function_name->Call(exec_state, 667a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block argc, argv); 668a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (result->IsUndefined()) { 669a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_function_hit[0] = '\0'; 670a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 671a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(result->IsString()); 672a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<v8::String> function_name(result->ToString()); 673a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block function_name->WriteAscii(last_function_hit); 674a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 675a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 676a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 677a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!frame_source_line.IsEmpty()) { 678a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Get the source line. 679a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const int argc = 1; 680a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<v8::Value> argv[argc] = { exec_state }; 681a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<v8::Value> result = frame_source_line->Call(exec_state, 682a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block argc, argv); 683a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(result->IsNumber()); 684a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_source_line = result->Int32Value(); 685a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 686a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 687a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!frame_source_column.IsEmpty()) { 688a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Get the source column. 689a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const int argc = 1; 690a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<v8::Value> argv[argc] = { exec_state }; 691a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<v8::Value> result = frame_source_column->Call(exec_state, 692a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block argc, argv); 693a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(result->IsNumber()); 694a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_source_column = result->Int32Value(); 695a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 696a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 697a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!frame_script_name.IsEmpty()) { 698a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Get the script name of the function script. 699a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const int argc = 1; 700a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<v8::Value> argv[argc] = { exec_state }; 701a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<v8::Value> result = frame_script_name->Call(exec_state, 702a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block argc, argv); 703a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (result->IsUndefined()) { 704a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_script_name_hit[0] = '\0'; 705a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 706a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(result->IsString()); 707a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<v8::String> script_name(result->ToString()); 708a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block script_name->WriteAscii(last_script_name_hit); 709a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 710a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 711a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 712a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!frame_script_data.IsEmpty()) { 713a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Get the script data of the function script. 714a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const int argc = 1; 715a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<v8::Value> argv[argc] = { exec_state }; 716a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<v8::Value> result = frame_script_data->Call(exec_state, 717a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block argc, argv); 718a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (result->IsUndefined()) { 719a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_script_data_hit[0] = '\0'; 720a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 721a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block result = result->ToString(); 722a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(result->IsString()); 723a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<v8::String> script_data(result->ToString()); 724a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block script_data->WriteAscii(last_script_data_hit); 725a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 726a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 7273fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 7283fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Perform a full deoptimization when the specified number of 7293fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // breaks have been hit. 7303fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (break_point_hit_count == break_point_hit_count_deoptimize) { 7313fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch i::Deoptimizer::DeoptimizeAll(); 7323fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 733402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu } else if (event == v8::AfterCompile && !compiled_script_data.IsEmpty()) { 734402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu const int argc = 1; 735402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu v8::Handle<v8::Value> argv[argc] = { event_data }; 736402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu v8::Handle<v8::Value> result = compiled_script_data->Call(exec_state, 737402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu argc, argv); 738402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu if (result->IsUndefined()) { 739402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu last_script_data_hit[0] = '\0'; 740402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu } else { 741402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu result = result->ToString(); 742402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu CHECK(result->IsString()); 743402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu v8::Handle<v8::String> script_data(result->ToString()); 744402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu script_data->WriteAscii(last_script_data_hit); 745402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu } 746a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 747a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 748a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 749a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 750a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Debug event handler which counts a number of events and collects the stack 751a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// height if there is a function compiled for that. 752a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockint exception_hit_count = 0; 753a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockint uncaught_exception_hit_count = 0; 754a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockint last_js_stack_height = -1; 755a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 756a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic void DebugEventCounterClear() { 757a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 758a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block exception_hit_count = 0; 759a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block uncaught_exception_hit_count = 0; 760a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 761a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 762a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic void DebugEventCounter(v8::DebugEvent event, 763a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<v8::Object> exec_state, 764a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<v8::Object> event_data, 765a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<v8::Value> data) { 76644f0eee88ff00398ff7f715fab053374d808c90dSteve Block v8::internal::Debug* debug = v8::internal::Isolate::Current()->debug(); 76744f0eee88ff00398ff7f715fab053374d808c90dSteve Block 768a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // When hitting a debug event listener there must be a break set. 76944f0eee88ff00398ff7f715fab053374d808c90dSteve Block CHECK_NE(debug->break_id(), 0); 770a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 771a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Count the number of breaks. 772a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (event == v8::Break) { 773a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count++; 774a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else if (event == v8::Exception) { 775a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block exception_hit_count++; 776a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 777a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Check whether the exception was uncaught. 778a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Local<v8::String> fun_name = v8::String::New("uncaught"); 779a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Local<v8::Function> fun = 780a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Function::Cast(*event_data->Get(fun_name)); 781a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Local<v8::Value> result = *fun->Call(event_data, 0, NULL); 782a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (result->IsTrue()) { 783a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block uncaught_exception_hit_count++; 784a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 785a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 786a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 787a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Collect the JavsScript stack height if the function frame_count is 788a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // compiled. 789a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!frame_count.IsEmpty()) { 790a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static const int kArgc = 1; 791a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<v8::Value> argv[kArgc] = { exec_state }; 792a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Using exec_state as receiver is just to have a receiver. 793a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<v8::Value> result = frame_count->Call(exec_state, kArgc, argv); 794a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_js_stack_height = result->Int32Value(); 795a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 796a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 797a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 798a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 799a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Debug event handler which evaluates a number of expressions when a break 800a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// point is hit. Each evaluated expression is compared with an expected value. 801a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// For this debug event handler to work the following two global varaibles 802a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// must be initialized. 803a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// checks: An array of expressions and expected results 804a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// evaluate_check_function: A JavaScript function (see below) 805a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 806a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Structure for holding checks to do. 807a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstruct EvaluateCheck { 808a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const char* expr; // An expression to evaluate when a break point is hit. 809a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<v8::Value> expected; // The expected result. 810a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 811a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Array of checks to do. 812a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstruct EvaluateCheck* checks = NULL; 813a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Source for The JavaScript function which can do the evaluation when a break 814a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// point is hit. 815a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockconst char* evaluate_check_source = 816a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "function evaluate_check(exec_state, expr, expected) {" 817a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " return exec_state.frame(0).evaluate(expr).value() === expected;" 818a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "}"; 819a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockv8::Local<v8::Function> evaluate_check_function; 820a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 821a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// The actual debug event described by the longer comment above. 822a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic void DebugEventEvaluate(v8::DebugEvent event, 823a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<v8::Object> exec_state, 824a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<v8::Object> event_data, 825a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<v8::Value> data) { 82644f0eee88ff00398ff7f715fab053374d808c90dSteve Block v8::internal::Debug* debug = v8::internal::Isolate::Current()->debug(); 827a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // When hitting a debug event listener there must be a break set. 82844f0eee88ff00398ff7f715fab053374d808c90dSteve Block CHECK_NE(debug->break_id(), 0); 829a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 830a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (event == v8::Break) { 831a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (int i = 0; checks[i].expr != NULL; i++) { 832a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const int argc = 3; 833a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<v8::Value> argv[argc] = { exec_state, 834a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::String::New(checks[i].expr), 835a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block checks[i].expected }; 836a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<v8::Value> result = 837a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block evaluate_check_function->Call(exec_state, argc, argv); 838a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!result->IsTrue()) { 839a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::String::AsciiValue ascii(checks[i].expected->ToString()); 840a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block V8_Fatal(__FILE__, __LINE__, "%s != %s", checks[i].expr, *ascii); 841a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 842a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 843a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 844a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 845a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 846a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 847a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// This debug event listener removes a breakpoint in a function 848a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockint debug_event_remove_break_point = 0; 849a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic void DebugEventRemoveBreakPoint(v8::DebugEvent event, 850a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<v8::Object> exec_state, 851a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<v8::Object> event_data, 852a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<v8::Value> data) { 85344f0eee88ff00398ff7f715fab053374d808c90dSteve Block v8::internal::Debug* debug = v8::internal::Isolate::Current()->debug(); 854a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // When hitting a debug event listener there must be a break set. 85544f0eee88ff00398ff7f715fab053374d808c90dSteve Block CHECK_NE(debug->break_id(), 0); 856a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 857a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (event == v8::Break) { 858a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count++; 8593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CHECK(data->IsFunction()); 860a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ClearBreakPoint(debug_event_remove_break_point); 861a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 862a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 863a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 864a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 865a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Debug event handler which counts break points hit and performs a step 866a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// afterwards. 867a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockStepAction step_action = StepIn; // Step action to perform when stepping. 868a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic void DebugEventStep(v8::DebugEvent event, 869a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<v8::Object> exec_state, 870a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<v8::Object> event_data, 871a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<v8::Value> data) { 87244f0eee88ff00398ff7f715fab053374d808c90dSteve Block v8::internal::Debug* debug = v8::internal::Isolate::Current()->debug(); 873a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // When hitting a debug event listener there must be a break set. 87444f0eee88ff00398ff7f715fab053374d808c90dSteve Block CHECK_NE(debug->break_id(), 0); 875a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 876a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (event == v8::Break) { 877a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count++; 878a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block PrepareStep(step_action); 879a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 880a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 881a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 882a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 883a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Debug event handler which counts break points hit and performs a step 884a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// afterwards. For each call the expected function is checked. 885a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// For this debug event handler to work the following two global varaibles 886a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// must be initialized. 887a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// expected_step_sequence: An array of the expected function call sequence. 888a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// frame_function_name: A JavaScript function (see below). 889a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 890a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// String containing the expected function call sequence. Note: this only works 891a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// if functions have name length of one. 892a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockconst char* expected_step_sequence = NULL; 893a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 894a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// The actual debug event described by the longer comment above. 895a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic void DebugEventStepSequence(v8::DebugEvent event, 896a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<v8::Object> exec_state, 897a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<v8::Object> event_data, 898a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<v8::Value> data) { 89944f0eee88ff00398ff7f715fab053374d808c90dSteve Block v8::internal::Debug* debug = v8::internal::Isolate::Current()->debug(); 900a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // When hitting a debug event listener there must be a break set. 90144f0eee88ff00398ff7f715fab053374d808c90dSteve Block CHECK_NE(debug->break_id(), 0); 902a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 903a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (event == v8::Break || event == v8::Exception) { 904a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Check that the current function is the expected. 905a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(break_point_hit_count < 906d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block StrLength(expected_step_sequence)); 907b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch const int argc = 2; 908b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch v8::Handle<v8::Value> argv[argc] = { exec_state, v8::Integer::New(0) }; 909a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<v8::Value> result = frame_function_name->Call(exec_state, 910a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block argc, argv); 911a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(result->IsString()); 912a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::String::AsciiValue function_name(result->ToString()); 913d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block CHECK_EQ(1, StrLength(*function_name)); 914a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ((*function_name)[0], 915a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block expected_step_sequence[break_point_hit_count]); 916a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 917a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Perform step. 918a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count++; 919a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block PrepareStep(step_action); 920a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 921a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 922a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 923a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 924a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Debug event handler which performs a garbage collection. 925a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic void DebugEventBreakPointCollectGarbage( 926a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::DebugEvent event, 927a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<v8::Object> exec_state, 928a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<v8::Object> event_data, 929a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<v8::Value> data) { 93044f0eee88ff00398ff7f715fab053374d808c90dSteve Block v8::internal::Debug* debug = v8::internal::Isolate::Current()->debug(); 931a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // When hitting a debug event listener there must be a break set. 93244f0eee88ff00398ff7f715fab053374d808c90dSteve Block CHECK_NE(debug->break_id(), 0); 933a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 934a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Perform a garbage collection when break point is hit and continue. Based 935a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // on the number of break points hit either scavenge or mark compact 936a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // collector is used. 937a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (event == v8::Break) { 938a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count++; 939a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (break_point_hit_count % 2 == 0) { 940a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Scavenge. 94144f0eee88ff00398ff7f715fab053374d808c90dSteve Block HEAP->CollectGarbage(v8::internal::NEW_SPACE); 942a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 94380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // Mark sweep compact. 9443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch HEAP->CollectAllGarbage(Heap::kNoGCFlags); 945a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 946a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 947a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 948a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 949a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 950a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Debug event handler which re-issues a debug break and calls the garbage 951a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// collector to have the heap verified. 952a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic void DebugEventBreak(v8::DebugEvent event, 953a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<v8::Object> exec_state, 954a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<v8::Object> event_data, 955a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<v8::Value> data) { 95644f0eee88ff00398ff7f715fab053374d808c90dSteve Block v8::internal::Debug* debug = v8::internal::Isolate::Current()->debug(); 957a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // When hitting a debug event listener there must be a break set. 95844f0eee88ff00398ff7f715fab053374d808c90dSteve Block CHECK_NE(debug->break_id(), 0); 959a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 960a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (event == v8::Break) { 961a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Count the number of breaks. 962a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count++; 963a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 964a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Run the garbage collector to enforce heap verification if option 965a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // --verify-heap is set. 96644f0eee88ff00398ff7f715fab053374d808c90dSteve Block HEAP->CollectGarbage(v8::internal::NEW_SPACE); 967a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 968a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Set the break flag again to come back here as soon as possible. 969a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::DebugBreak(); 970a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 971a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 972a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 973a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 974d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block// Debug event handler which re-issues a debug break until a limit has been 975d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block// reached. 976d0582a6c46733687d045e4188a1bcd0123c758a1Steve Blockint max_break_point_hit_count = 0; 9773e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhubool terminate_after_max_break_point_hit = false; 978d0582a6c46733687d045e4188a1bcd0123c758a1Steve Blockstatic void DebugEventBreakMax(v8::DebugEvent event, 979d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block v8::Handle<v8::Object> exec_state, 980d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block v8::Handle<v8::Object> event_data, 981d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block v8::Handle<v8::Value> data) { 98244f0eee88ff00398ff7f715fab053374d808c90dSteve Block v8::internal::Debug* debug = v8::internal::Isolate::Current()->debug(); 983d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // When hitting a debug event listener there must be a break set. 98444f0eee88ff00398ff7f715fab053374d808c90dSteve Block CHECK_NE(debug->break_id(), 0); 985d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 9863e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu if (event == v8::Break) { 9873e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu if (break_point_hit_count < max_break_point_hit_count) { 9883e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu // Count the number of breaks. 9893e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu break_point_hit_count++; 990d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 9913fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Collect the JavsScript stack height if the function frame_count is 9923fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // compiled. 9933fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (!frame_count.IsEmpty()) { 9943fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch static const int kArgc = 1; 9953fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch v8::Handle<v8::Value> argv[kArgc] = { exec_state }; 9963fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Using exec_state as receiver is just to have a receiver. 9973fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch v8::Handle<v8::Value> result = 9983fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch frame_count->Call(exec_state, kArgc, argv); 9993fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch last_js_stack_height = result->Int32Value(); 10003fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 10013fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 10023e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu // Set the break flag again to come back here as soon as possible. 10033e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu v8::Debug::DebugBreak(); 10043fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 10053e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu } else if (terminate_after_max_break_point_hit) { 10063e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu // Terminate execution after the last break if requested. 10073e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu v8::V8::TerminateExecution(); 10083e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu } 10093fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 10103fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Perform a full deoptimization when the specified number of 10113fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // breaks have been hit. 10123fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (break_point_hit_count == break_point_hit_count_deoptimize) { 10133fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch i::Deoptimizer::DeoptimizeAll(); 10143fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 1015d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block } 1016d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block} 1017d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 1018d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 1019a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// --- M e s s a g e C a l l b a c k 1020a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1021a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1022a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Message callback which counts the number of messages. 1023a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockint message_callback_count = 0; 1024a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1025a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic void MessageCallbackCountClear() { 1026a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block message_callback_count = 0; 1027a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1028a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1029a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic void MessageCallbackCount(v8::Handle<v8::Message> message, 1030a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<v8::Value> data) { 1031a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block message_callback_count++; 1032a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1033a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1034a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1035a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// --- T h e A c t u a l T e s t s 1036a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1037a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1038a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Test that the debug break function is the expected one for different kinds 1039a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// of break locations. 1040a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(DebugStub) { 1041a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block using ::v8::internal::Builtins; 104244f0eee88ff00398ff7f715fab053374d808c90dSteve Block using ::v8::internal::Isolate; 1043a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::HandleScope scope; 1044a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DebugLocalContext env; 1045a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1046a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CheckDebugBreakFunction(&env, 1047a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "function f1(){}", "f1", 1048a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 0, 1049a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::internal::RelocInfo::JS_RETURN, 1050a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block NULL); 1051a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CheckDebugBreakFunction(&env, 1052a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "function f2(){x=1;}", "f2", 1053a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 0, 10541e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block v8::internal::RelocInfo::CODE_TARGET_CONTEXT, 105544f0eee88ff00398ff7f715fab053374d808c90dSteve Block Isolate::Current()->builtins()->builtin( 105644f0eee88ff00398ff7f715fab053374d808c90dSteve Block Builtins::kStoreIC_DebugBreak)); 1057a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CheckDebugBreakFunction(&env, 1058a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "function f3(){var a=x;}", "f3", 1059a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 0, 1060a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::internal::RelocInfo::CODE_TARGET_CONTEXT, 106144f0eee88ff00398ff7f715fab053374d808c90dSteve Block Isolate::Current()->builtins()->builtin( 106244f0eee88ff00398ff7f715fab053374d808c90dSteve Block Builtins::kLoadIC_DebugBreak)); 1063a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1064a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// TODO(1240753): Make the test architecture independent or split 1065a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// parts of the debugger into architecture dependent files. This 1066a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// part currently disabled as it is not portable between IA32/ARM. 1067a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Currently on ICs for keyed store/load on ARM. 1068a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#if !defined (__arm__) && !defined(__thumb__) 1069a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CheckDebugBreakFunction( 1070a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block &env, 1071a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "function f4(){var index='propertyName'; var a={}; a[index] = 'x';}", 1072a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "f4", 1073a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 0, 1074a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::internal::RelocInfo::CODE_TARGET, 107544f0eee88ff00398ff7f715fab053374d808c90dSteve Block Isolate::Current()->builtins()->builtin( 107644f0eee88ff00398ff7f715fab053374d808c90dSteve Block Builtins::kKeyedStoreIC_DebugBreak)); 1077a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CheckDebugBreakFunction( 1078a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block &env, 1079a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "function f5(){var index='propertyName'; var a={}; return a[index];}", 1080a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "f5", 1081a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 0, 1082a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::internal::RelocInfo::CODE_TARGET, 108344f0eee88ff00398ff7f715fab053374d808c90dSteve Block Isolate::Current()->builtins()->builtin( 108444f0eee88ff00398ff7f715fab053374d808c90dSteve Block Builtins::kKeyedLoadIC_DebugBreak)); 1085a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 1086a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1087a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Check the debug break code stubs for call ICs with different number of 1088a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // parameters. 1089a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Code> debug_break_0 = v8::internal::ComputeCallDebugBreak(0); 1090a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Code> debug_break_1 = v8::internal::ComputeCallDebugBreak(1); 1091a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Code> debug_break_4 = v8::internal::ComputeCallDebugBreak(4); 1092a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1093a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CheckDebugBreakFunction(&env, 1094a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "function f4_0(){x();}", "f4_0", 1095a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 0, 1096a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::internal::RelocInfo::CODE_TARGET_CONTEXT, 1097a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block *debug_break_0); 1098a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1099a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CheckDebugBreakFunction(&env, 1100a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "function f4_1(){x(1);}", "f4_1", 1101a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 0, 1102a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::internal::RelocInfo::CODE_TARGET_CONTEXT, 1103a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block *debug_break_1); 1104a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1105a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CheckDebugBreakFunction(&env, 1106a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "function f4_4(){x(1,2,3,4);}", "f4_4", 1107a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 0, 1108a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::internal::RelocInfo::CODE_TARGET_CONTEXT, 1109a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block *debug_break_4); 1110a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1111a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1112a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1113a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Test that the debug info in the VM is in sync with the functions being 1114a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// debugged. 1115a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(DebugInfo) { 1116a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::HandleScope scope; 1117a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DebugLocalContext env; 1118a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Create a couple of functions for the test. 1119a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Local<v8::Function> foo = 1120a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CompileFunction(&env, "function foo(){}", "foo"); 1121a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Local<v8::Function> bar = 1122a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CompileFunction(&env, "function bar(){}", "bar"); 1123a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Initially no functions are debugged. 1124a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(0, v8::internal::GetDebuggedFunctions()->length()); 1125a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(!HasDebugInfo(foo)); 1126a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(!HasDebugInfo(bar)); 1127a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // One function (foo) is debugged. 1128a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int bp1 = SetBreakPoint(foo, 0); 1129a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1, v8::internal::GetDebuggedFunctions()->length()); 1130a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(HasDebugInfo(foo)); 1131a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(!HasDebugInfo(bar)); 1132a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Two functions are debugged. 1133a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int bp2 = SetBreakPoint(bar, 0); 1134a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(2, v8::internal::GetDebuggedFunctions()->length()); 1135a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(HasDebugInfo(foo)); 1136a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(HasDebugInfo(bar)); 1137a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // One function (bar) is debugged. 1138a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ClearBreakPoint(bp1); 1139a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1, v8::internal::GetDebuggedFunctions()->length()); 1140a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(!HasDebugInfo(foo)); 1141a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(HasDebugInfo(bar)); 1142a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // No functions are debugged. 1143a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ClearBreakPoint(bp2); 1144a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(0, v8::internal::GetDebuggedFunctions()->length()); 1145a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(!HasDebugInfo(foo)); 1146a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(!HasDebugInfo(bar)); 1147a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1148a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1149a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1150a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Test that a break point can be set at an IC store location. 1151a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(BreakPointICStore) { 1152a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 1153a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::HandleScope scope; 1154a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DebugLocalContext env; 1155a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1156a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount, 1157a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Undefined()); 1158a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Script::Compile(v8::String::New("function foo(){bar=0;}"))->Run(); 1159a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Local<v8::Function> foo = 1160a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("foo"))); 1161a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1162a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Run without breakpoints. 1163a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block foo->Call(env->Global(), 0, NULL); 1164a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(0, break_point_hit_count); 1165a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1166a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Run with breakpoint 1167a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int bp = SetBreakPoint(foo, 0); 1168a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block foo->Call(env->Global(), 0, NULL); 1169a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1, break_point_hit_count); 1170a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block foo->Call(env->Global(), 0, NULL); 1171a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(2, break_point_hit_count); 1172a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1173a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Run without breakpoints. 1174a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ClearBreakPoint(bp); 1175a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block foo->Call(env->Global(), 0, NULL); 1176a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(2, break_point_hit_count); 1177a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1178a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetDebugEventListener(NULL); 1179a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CheckDebuggerUnloaded(); 1180a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1181a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1182a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1183a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Test that a break point can be set at an IC load location. 1184a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(BreakPointICLoad) { 1185a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 1186a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::HandleScope scope; 1187a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DebugLocalContext env; 1188a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount, 1189a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Undefined()); 1190a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Script::Compile(v8::String::New("bar=1"))->Run(); 1191a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Script::Compile(v8::String::New("function foo(){var x=bar;}"))->Run(); 1192a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Local<v8::Function> foo = 1193a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("foo"))); 1194a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1195a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Run without breakpoints. 1196a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block foo->Call(env->Global(), 0, NULL); 1197a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(0, break_point_hit_count); 1198a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 119944f0eee88ff00398ff7f715fab053374d808c90dSteve Block // Run with breakpoint. 1200a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int bp = SetBreakPoint(foo, 0); 1201a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block foo->Call(env->Global(), 0, NULL); 1202a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1, break_point_hit_count); 1203a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block foo->Call(env->Global(), 0, NULL); 1204a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(2, break_point_hit_count); 1205a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1206a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Run without breakpoints. 1207a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ClearBreakPoint(bp); 1208a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block foo->Call(env->Global(), 0, NULL); 1209a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(2, break_point_hit_count); 1210a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1211a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetDebugEventListener(NULL); 1212a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CheckDebuggerUnloaded(); 1213a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1214a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1215a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1216a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Test that a break point can be set at an IC call location. 1217a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(BreakPointICCall) { 1218a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 1219a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::HandleScope scope; 1220a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DebugLocalContext env; 1221a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount, 1222a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Undefined()); 1223a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Script::Compile(v8::String::New("function bar(){}"))->Run(); 1224a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Script::Compile(v8::String::New("function foo(){bar();}"))->Run(); 1225a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Local<v8::Function> foo = 1226a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("foo"))); 1227a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1228a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Run without breakpoints. 1229a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block foo->Call(env->Global(), 0, NULL); 1230a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(0, break_point_hit_count); 1231a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 123244f0eee88ff00398ff7f715fab053374d808c90dSteve Block // Run with breakpoint 1233a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int bp = SetBreakPoint(foo, 0); 1234a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block foo->Call(env->Global(), 0, NULL); 1235a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1, break_point_hit_count); 1236a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block foo->Call(env->Global(), 0, NULL); 1237a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(2, break_point_hit_count); 1238a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1239a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Run without breakpoints. 1240a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ClearBreakPoint(bp); 1241a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block foo->Call(env->Global(), 0, NULL); 1242a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(2, break_point_hit_count); 1243a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1244a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetDebugEventListener(NULL); 1245a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CheckDebuggerUnloaded(); 1246a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1247a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1248a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 124980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen// Test that a break point can be set at an IC call location and survive a GC. 125080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian MonsenTEST(BreakPointICCallWithGC) { 125180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen break_point_hit_count = 0; 125280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen v8::HandleScope scope; 125380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen DebugLocalContext env; 125480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen v8::Debug::SetDebugEventListener(DebugEventBreakPointCollectGarbage, 125580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen v8::Undefined()); 125680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen v8::Script::Compile(v8::String::New("function bar(){return 1;}"))->Run(); 125780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen v8::Script::Compile(v8::String::New("function foo(){return bar();}"))->Run(); 125880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen v8::Local<v8::Function> foo = 125980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("foo"))); 126080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 126180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // Run without breakpoints. 126280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen CHECK_EQ(1, foo->Call(env->Global(), 0, NULL)->Int32Value()); 126380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen CHECK_EQ(0, break_point_hit_count); 126480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 126580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // Run with breakpoint. 126680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen int bp = SetBreakPoint(foo, 0); 126780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen CHECK_EQ(1, foo->Call(env->Global(), 0, NULL)->Int32Value()); 126880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen CHECK_EQ(1, break_point_hit_count); 126980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen CHECK_EQ(1, foo->Call(env->Global(), 0, NULL)->Int32Value()); 127080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen CHECK_EQ(2, break_point_hit_count); 127180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 127280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // Run without breakpoints. 127380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen ClearBreakPoint(bp); 127480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen foo->Call(env->Global(), 0, NULL); 127580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen CHECK_EQ(2, break_point_hit_count); 127680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 127780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen v8::Debug::SetDebugEventListener(NULL); 127880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen CheckDebuggerUnloaded(); 127980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen} 128080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 128180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 128280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen// Test that a break point can be set at an IC call location and survive a GC. 128380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian MonsenTEST(BreakPointConstructCallWithGC) { 128480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen break_point_hit_count = 0; 128580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen v8::HandleScope scope; 128680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen DebugLocalContext env; 128780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen v8::Debug::SetDebugEventListener(DebugEventBreakPointCollectGarbage, 128880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen v8::Undefined()); 128980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen v8::Script::Compile(v8::String::New("function bar(){ this.x = 1;}"))->Run(); 129080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen v8::Script::Compile(v8::String::New( 129180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen "function foo(){return new bar(1).x;}"))->Run(); 129280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen v8::Local<v8::Function> foo = 129380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("foo"))); 129480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 129580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // Run without breakpoints. 129680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen CHECK_EQ(1, foo->Call(env->Global(), 0, NULL)->Int32Value()); 129780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen CHECK_EQ(0, break_point_hit_count); 129880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 129980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // Run with breakpoint. 130080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen int bp = SetBreakPoint(foo, 0); 130180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen CHECK_EQ(1, foo->Call(env->Global(), 0, NULL)->Int32Value()); 130280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen CHECK_EQ(1, break_point_hit_count); 130380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen CHECK_EQ(1, foo->Call(env->Global(), 0, NULL)->Int32Value()); 130480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen CHECK_EQ(2, break_point_hit_count); 130580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 130680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // Run without breakpoints. 130780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen ClearBreakPoint(bp); 130880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen foo->Call(env->Global(), 0, NULL); 130980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen CHECK_EQ(2, break_point_hit_count); 131080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 131180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen v8::Debug::SetDebugEventListener(NULL); 131280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen CheckDebuggerUnloaded(); 131380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen} 131480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 131580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 1316a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Test that a break point can be set at a return store location. 1317a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(BreakPointReturn) { 1318a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 1319a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::HandleScope scope; 1320a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DebugLocalContext env; 1321a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1322a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Create a functions for checking the source line and column when hitting 1323a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // a break point. 1324a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block frame_source_line = CompileFunction(&env, 1325a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block frame_source_line_source, 1326a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "frame_source_line"); 1327a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block frame_source_column = CompileFunction(&env, 1328a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block frame_source_column_source, 1329a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "frame_source_column"); 1330a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1331a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1332a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount, 1333a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Undefined()); 1334a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Script::Compile(v8::String::New("function foo(){}"))->Run(); 1335a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Local<v8::Function> foo = 1336a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("foo"))); 1337a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1338a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Run without breakpoints. 1339a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block foo->Call(env->Global(), 0, NULL); 1340a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(0, break_point_hit_count); 1341a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1342a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Run with breakpoint 1343a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int bp = SetBreakPoint(foo, 0); 1344a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block foo->Call(env->Global(), 0, NULL); 1345a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1, break_point_hit_count); 1346a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(0, last_source_line); 1347bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch CHECK_EQ(15, last_source_column); 1348a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block foo->Call(env->Global(), 0, NULL); 1349a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(2, break_point_hit_count); 1350a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(0, last_source_line); 1351bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch CHECK_EQ(15, last_source_column); 1352a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1353a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Run without breakpoints. 1354a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ClearBreakPoint(bp); 1355a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block foo->Call(env->Global(), 0, NULL); 1356a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(2, break_point_hit_count); 1357a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1358a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetDebugEventListener(NULL); 1359a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CheckDebuggerUnloaded(); 1360a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1361a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1362a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1363a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic void CallWithBreakPoints(v8::Local<v8::Object> recv, 1364a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Local<v8::Function> f, 1365a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int break_point_count, 1366a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int call_count) { 1367a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 1368a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (int i = 0; i < call_count; i++) { 1369a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block f->Call(recv, 0, NULL); 1370a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ((i + 1) * break_point_count, break_point_hit_count); 1371a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1372a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1373a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1374a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Test GC during break point processing. 1375a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(GCDuringBreakPointProcessing) { 1376a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 1377a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::HandleScope scope; 1378a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DebugLocalContext env; 1379a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1380a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetDebugEventListener(DebugEventBreakPointCollectGarbage, 1381a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Undefined()); 1382a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Local<v8::Function> foo; 1383a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1384a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Test IC store break point with garbage collection. 1385a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block foo = CompileFunction(&env, "function foo(){bar=0;}", "foo"); 1386a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block SetBreakPoint(foo, 0); 1387a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CallWithBreakPoints(env->Global(), foo, 1, 10); 1388a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1389a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Test IC load break point with garbage collection. 1390a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block foo = CompileFunction(&env, "bar=1;function foo(){var x=bar;}", "foo"); 1391a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block SetBreakPoint(foo, 0); 1392a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CallWithBreakPoints(env->Global(), foo, 1, 10); 1393a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1394a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Test IC call break point with garbage collection. 1395a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block foo = CompileFunction(&env, "function bar(){};function foo(){bar();}", "foo"); 1396a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block SetBreakPoint(foo, 0); 1397a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CallWithBreakPoints(env->Global(), foo, 1, 10); 1398a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1399a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Test return break point with garbage collection. 1400a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block foo = CompileFunction(&env, "function foo(){}", "foo"); 1401a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block SetBreakPoint(foo, 0); 1402a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CallWithBreakPoints(env->Global(), foo, 1, 25); 1403a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 14047f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Test debug break slot break point with garbage collection. 14057f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch foo = CompileFunction(&env, "function foo(){var a;}", "foo"); 14067f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch SetBreakPoint(foo, 0); 14077f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch CallWithBreakPoints(env->Global(), foo, 1, 25); 14087f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 1409a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetDebugEventListener(NULL); 1410a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CheckDebuggerUnloaded(); 1411a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1412a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1413a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1414a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Call the function three times with different garbage collections in between 1415a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// and make sure that the break point survives. 1416bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdochstatic void CallAndGC(v8::Local<v8::Object> recv, 14173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch v8::Local<v8::Function> f) { 1418a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 1419a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1420a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (int i = 0; i < 3; i++) { 1421a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Call function. 1422a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block f->Call(recv, 0, NULL); 1423a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1 + i * 3, break_point_hit_count); 1424a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1425a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Scavenge and call function. 142644f0eee88ff00398ff7f715fab053374d808c90dSteve Block HEAP->CollectGarbage(v8::internal::NEW_SPACE); 1427a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block f->Call(recv, 0, NULL); 1428a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(2 + i * 3, break_point_hit_count); 1429a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1430a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Mark sweep (and perhaps compact) and call function. 14313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch HEAP->CollectAllGarbage(Heap::kNoGCFlags); 1432a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block f->Call(recv, 0, NULL); 1433a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(3 + i * 3, break_point_hit_count); 1434a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1435a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1436a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1437a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 14383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Test that a break point can be set at a return store location. 14393ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochTEST(BreakPointSurviveGC) { 1440a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 1441a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::HandleScope scope; 1442a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DebugLocalContext env; 1443a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1444a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount, 1445a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Undefined()); 1446a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Local<v8::Function> foo; 1447a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1448a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Test IC store break point with garbage collection. 1449bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch { 14503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CompileFunction(&env, "function foo(){}", "foo"); 1451bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch foo = CompileFunction(&env, "function foo(){bar=0;}", "foo"); 1452bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch SetBreakPoint(foo, 0); 1453bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch } 14543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CallAndGC(env->Global(), foo); 1455a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1456a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Test IC load break point with garbage collection. 1457bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch { 14583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CompileFunction(&env, "function foo(){}", "foo"); 1459bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch foo = CompileFunction(&env, "bar=1;function foo(){var x=bar;}", "foo"); 1460bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch SetBreakPoint(foo, 0); 1461bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch } 14623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CallAndGC(env->Global(), foo); 1463a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1464a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Test IC call break point with garbage collection. 1465bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch { 14663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CompileFunction(&env, "function foo(){}", "foo"); 1467bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch foo = CompileFunction(&env, 1468bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch "function bar(){};function foo(){bar();}", 1469bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch "foo"); 1470bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch SetBreakPoint(foo, 0); 1471bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch } 14723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CallAndGC(env->Global(), foo); 1473a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1474a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Test return break point with garbage collection. 1475bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch { 14763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CompileFunction(&env, "function foo(){}", "foo"); 1477bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch foo = CompileFunction(&env, "function foo(){}", "foo"); 1478bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch SetBreakPoint(foo, 0); 1479bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch } 14803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CallAndGC(env->Global(), foo); 1481bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch 1482bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch // Test non IC break point with garbage collection. 1483bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch { 14843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CompileFunction(&env, "function foo(){}", "foo"); 1485bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch foo = CompileFunction(&env, "function foo(){var bar=0;}", "foo"); 1486bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch SetBreakPoint(foo, 0); 1487bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch } 14883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CallAndGC(env->Global(), foo); 1489bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch 1490a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1491a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetDebugEventListener(NULL); 1492a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CheckDebuggerUnloaded(); 1493a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1494a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1495a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1496a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Test that break points can be set using the global Debug object. 1497a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(BreakPointThroughJavaScript) { 1498a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 1499a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::HandleScope scope; 1500a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DebugLocalContext env; 1501a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block env.ExposeDebug(); 1502a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1503a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount, 1504a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Undefined()); 1505a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Script::Compile(v8::String::New("function bar(){}"))->Run(); 1506a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Script::Compile(v8::String::New("function foo(){bar();bar();}"))->Run(); 1507a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // 012345678901234567890 1508a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // 1 2 1509a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Break points are set at position 3 and 9 1510a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Local<v8::Script> foo = v8::Script::Compile(v8::String::New("foo()")); 1511a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1512a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Run without breakpoints. 1513a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block foo->Run(); 1514a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(0, break_point_hit_count); 1515a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1516a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Run with one breakpoint 1517a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int bp1 = SetBreakPointFromJS("foo", 0, 3); 1518a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block foo->Run(); 1519a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1, break_point_hit_count); 1520a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block foo->Run(); 1521a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(2, break_point_hit_count); 1522a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1523a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Run with two breakpoints 1524a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int bp2 = SetBreakPointFromJS("foo", 0, 9); 1525a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block foo->Run(); 1526a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(4, break_point_hit_count); 1527a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block foo->Run(); 1528a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(6, break_point_hit_count); 1529a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1530a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Run with one breakpoint 1531a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ClearBreakPointFromJS(bp2); 1532a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block foo->Run(); 1533a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(7, break_point_hit_count); 1534a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block foo->Run(); 1535a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(8, break_point_hit_count); 1536a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1537a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Run without breakpoints. 1538a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ClearBreakPointFromJS(bp1); 1539a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block foo->Run(); 1540a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(8, break_point_hit_count); 1541a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1542a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetDebugEventListener(NULL); 1543a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CheckDebuggerUnloaded(); 1544a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1545a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Make sure that the break point numbers are consecutive. 1546a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1, bp1); 1547a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(2, bp2); 1548a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1549a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1550a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1551a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Test that break points on scripts identified by name can be set using the 1552a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// global Debug object. 1553a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(ScriptBreakPointByNameThroughJavaScript) { 1554a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 1555a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::HandleScope scope; 1556a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DebugLocalContext env; 1557a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block env.ExposeDebug(); 1558a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1559a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount, 1560a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Undefined()); 1561a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1562a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Local<v8::String> script = v8::String::New( 1563a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "function f() {\n" 1564a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " function h() {\n" 1565a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " a = 0; // line 2\n" 1566a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " }\n" 1567a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " b = 1; // line 4\n" 1568a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " return h();\n" 1569a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "}\n" 1570a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "\n" 1571a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "function g() {\n" 1572a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " function h() {\n" 1573a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " a = 0;\n" 1574a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " }\n" 1575a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " b = 2; // line 12\n" 1576a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " h();\n" 1577a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " b = 3; // line 14\n" 1578a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " f(); // line 15\n" 1579a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "}"); 1580a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1581a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Compile the script and get the two functions. 1582a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::ScriptOrigin origin = 1583a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::ScriptOrigin(v8::String::New("test")); 1584a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Script::Compile(script, &origin)->Run(); 1585a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Local<v8::Function> f = 1586a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("f"))); 1587a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Local<v8::Function> g = 1588a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("g"))); 1589a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1590a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Call f and g without break points. 1591a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 1592a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block f->Call(env->Global(), 0, NULL); 1593a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(0, break_point_hit_count); 1594a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block g->Call(env->Global(), 0, NULL); 1595a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(0, break_point_hit_count); 1596a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1597a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Call f and g with break point on line 12. 1598a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int sbp1 = SetScriptBreakPointByNameFromJS("test", 12, 0); 1599a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 1600a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block f->Call(env->Global(), 0, NULL); 1601a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(0, break_point_hit_count); 1602a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block g->Call(env->Global(), 0, NULL); 1603a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1, break_point_hit_count); 1604a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1605a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Remove the break point again. 1606a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 1607a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ClearBreakPointFromJS(sbp1); 1608a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block f->Call(env->Global(), 0, NULL); 1609a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(0, break_point_hit_count); 1610a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block g->Call(env->Global(), 0, NULL); 1611a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(0, break_point_hit_count); 1612a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1613a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Call f and g with break point on line 2. 1614a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int sbp2 = SetScriptBreakPointByNameFromJS("test", 2, 0); 1615a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 1616a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block f->Call(env->Global(), 0, NULL); 1617a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1, break_point_hit_count); 1618a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block g->Call(env->Global(), 0, NULL); 1619a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(2, break_point_hit_count); 1620a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1621a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Call f and g with break point on line 2, 4, 12, 14 and 15. 1622a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int sbp3 = SetScriptBreakPointByNameFromJS("test", 4, 0); 1623a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int sbp4 = SetScriptBreakPointByNameFromJS("test", 12, 0); 1624a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int sbp5 = SetScriptBreakPointByNameFromJS("test", 14, 0); 1625a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int sbp6 = SetScriptBreakPointByNameFromJS("test", 15, 0); 1626a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 1627a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block f->Call(env->Global(), 0, NULL); 1628a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(2, break_point_hit_count); 1629a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block g->Call(env->Global(), 0, NULL); 1630a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(7, break_point_hit_count); 1631a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1632a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Remove all the break points again. 1633a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 1634a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ClearBreakPointFromJS(sbp2); 1635a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ClearBreakPointFromJS(sbp3); 1636a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ClearBreakPointFromJS(sbp4); 1637a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ClearBreakPointFromJS(sbp5); 1638a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ClearBreakPointFromJS(sbp6); 1639a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block f->Call(env->Global(), 0, NULL); 1640a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(0, break_point_hit_count); 1641a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block g->Call(env->Global(), 0, NULL); 1642a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(0, break_point_hit_count); 1643a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1644a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetDebugEventListener(NULL); 1645a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CheckDebuggerUnloaded(); 1646a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1647a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Make sure that the break point numbers are consecutive. 1648a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1, sbp1); 1649a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(2, sbp2); 1650a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(3, sbp3); 1651a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(4, sbp4); 1652a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(5, sbp5); 1653a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(6, sbp6); 1654a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1655a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1656a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1657a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(ScriptBreakPointByIdThroughJavaScript) { 1658a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 1659a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::HandleScope scope; 1660a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DebugLocalContext env; 1661a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block env.ExposeDebug(); 1662a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1663a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount, 1664a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Undefined()); 1665a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1666a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Local<v8::String> source = v8::String::New( 1667a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "function f() {\n" 1668a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " function h() {\n" 1669a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " a = 0; // line 2\n" 1670a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " }\n" 1671a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " b = 1; // line 4\n" 1672a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " return h();\n" 1673a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "}\n" 1674a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "\n" 1675a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "function g() {\n" 1676a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " function h() {\n" 1677a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " a = 0;\n" 1678a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " }\n" 1679a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " b = 2; // line 12\n" 1680a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " h();\n" 1681a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " b = 3; // line 14\n" 1682a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " f(); // line 15\n" 1683a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "}"); 1684a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1685a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Compile the script and get the two functions. 1686a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::ScriptOrigin origin = 1687a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::ScriptOrigin(v8::String::New("test")); 1688a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Local<v8::Script> script = v8::Script::Compile(source, &origin); 1689a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block script->Run(); 1690a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Local<v8::Function> f = 1691a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("f"))); 1692a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Local<v8::Function> g = 1693a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("g"))); 1694a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1695a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Get the script id knowing that internally it is a 32 integer. 1696a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block uint32_t script_id = script->Id()->Uint32Value(); 1697a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1698a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Call f and g without break points. 1699a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 1700a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block f->Call(env->Global(), 0, NULL); 1701a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(0, break_point_hit_count); 1702a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block g->Call(env->Global(), 0, NULL); 1703a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(0, break_point_hit_count); 1704a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1705a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Call f and g with break point on line 12. 1706a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int sbp1 = SetScriptBreakPointByIdFromJS(script_id, 12, 0); 1707a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 1708a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block f->Call(env->Global(), 0, NULL); 1709a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(0, break_point_hit_count); 1710a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block g->Call(env->Global(), 0, NULL); 1711a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1, break_point_hit_count); 1712a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1713a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Remove the break point again. 1714a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 1715a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ClearBreakPointFromJS(sbp1); 1716a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block f->Call(env->Global(), 0, NULL); 1717a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(0, break_point_hit_count); 1718a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block g->Call(env->Global(), 0, NULL); 1719a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(0, break_point_hit_count); 1720a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1721a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Call f and g with break point on line 2. 1722a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int sbp2 = SetScriptBreakPointByIdFromJS(script_id, 2, 0); 1723a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 1724a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block f->Call(env->Global(), 0, NULL); 1725a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1, break_point_hit_count); 1726a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block g->Call(env->Global(), 0, NULL); 1727a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(2, break_point_hit_count); 1728a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1729a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Call f and g with break point on line 2, 4, 12, 14 and 15. 1730a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int sbp3 = SetScriptBreakPointByIdFromJS(script_id, 4, 0); 1731a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int sbp4 = SetScriptBreakPointByIdFromJS(script_id, 12, 0); 1732a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int sbp5 = SetScriptBreakPointByIdFromJS(script_id, 14, 0); 1733a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int sbp6 = SetScriptBreakPointByIdFromJS(script_id, 15, 0); 1734a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 1735a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block f->Call(env->Global(), 0, NULL); 1736a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(2, break_point_hit_count); 1737a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block g->Call(env->Global(), 0, NULL); 1738a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(7, break_point_hit_count); 1739a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1740a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Remove all the break points again. 1741a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 1742a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ClearBreakPointFromJS(sbp2); 1743a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ClearBreakPointFromJS(sbp3); 1744a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ClearBreakPointFromJS(sbp4); 1745a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ClearBreakPointFromJS(sbp5); 1746a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ClearBreakPointFromJS(sbp6); 1747a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block f->Call(env->Global(), 0, NULL); 1748a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(0, break_point_hit_count); 1749a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block g->Call(env->Global(), 0, NULL); 1750a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(0, break_point_hit_count); 1751a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1752a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetDebugEventListener(NULL); 1753a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CheckDebuggerUnloaded(); 1754a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1755a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Make sure that the break point numbers are consecutive. 1756a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1, sbp1); 1757a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(2, sbp2); 1758a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(3, sbp3); 1759a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(4, sbp4); 1760a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(5, sbp5); 1761a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(6, sbp6); 1762a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1763a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1764a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1765a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Test conditional script break points. 1766a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(EnableDisableScriptBreakPoint) { 1767a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 1768a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::HandleScope scope; 1769a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DebugLocalContext env; 1770a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block env.ExposeDebug(); 1771a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1772a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount, 1773a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Undefined()); 1774a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1775a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Local<v8::String> script = v8::String::New( 1776a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "function f() {\n" 1777a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " a = 0; // line 1\n" 1778a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "};"); 1779a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1780a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Compile the script and get function f. 1781a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::ScriptOrigin origin = 1782a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::ScriptOrigin(v8::String::New("test")); 1783a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Script::Compile(script, &origin)->Run(); 1784a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Local<v8::Function> f = 1785a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("f"))); 1786a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1787a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Set script break point on line 1 (in function f). 1788a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int sbp = SetScriptBreakPointByNameFromJS("test", 1, 0); 1789a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1790a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Call f while enabeling and disabling the script break point. 1791a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 1792a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block f->Call(env->Global(), 0, NULL); 1793a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1, break_point_hit_count); 1794a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1795a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DisableScriptBreakPointFromJS(sbp); 1796a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block f->Call(env->Global(), 0, NULL); 1797a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1, break_point_hit_count); 1798a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1799a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnableScriptBreakPointFromJS(sbp); 1800a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block f->Call(env->Global(), 0, NULL); 1801a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(2, break_point_hit_count); 1802a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1803a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DisableScriptBreakPointFromJS(sbp); 1804a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block f->Call(env->Global(), 0, NULL); 1805a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(2, break_point_hit_count); 1806a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1807a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Reload the script and get f again checking that the disabeling survives. 1808a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Script::Compile(script, &origin)->Run(); 1809a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block f = v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("f"))); 1810a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block f->Call(env->Global(), 0, NULL); 1811a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(2, break_point_hit_count); 1812a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1813a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnableScriptBreakPointFromJS(sbp); 1814a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block f->Call(env->Global(), 0, NULL); 1815a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(3, break_point_hit_count); 1816a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1817a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetDebugEventListener(NULL); 1818a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CheckDebuggerUnloaded(); 1819a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1820a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1821a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1822a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Test conditional script break points. 1823a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(ConditionalScriptBreakPoint) { 1824a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 1825a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::HandleScope scope; 1826a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DebugLocalContext env; 1827a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block env.ExposeDebug(); 1828a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1829a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount, 1830a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Undefined()); 1831a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1832a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Local<v8::String> script = v8::String::New( 1833a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "count = 0;\n" 1834a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "function f() {\n" 1835a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " g(count++); // line 2\n" 1836a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "};\n" 1837a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "function g(x) {\n" 1838a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " var a=x; // line 5\n" 1839a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "};"); 1840a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1841a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Compile the script and get function f. 1842a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::ScriptOrigin origin = 1843a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::ScriptOrigin(v8::String::New("test")); 1844a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Script::Compile(script, &origin)->Run(); 1845a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Local<v8::Function> f = 1846a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("f"))); 1847a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1848a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Set script break point on line 5 (in function g). 1849a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int sbp1 = SetScriptBreakPointByNameFromJS("test", 5, 0); 1850a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1851a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Call f with different conditions on the script break point. 1852a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 1853a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ChangeScriptBreakPointConditionFromJS(sbp1, "false"); 1854a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block f->Call(env->Global(), 0, NULL); 1855a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(0, break_point_hit_count); 1856a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1857a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ChangeScriptBreakPointConditionFromJS(sbp1, "true"); 1858a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 1859a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block f->Call(env->Global(), 0, NULL); 1860a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1, break_point_hit_count); 1861a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 18627f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch ChangeScriptBreakPointConditionFromJS(sbp1, "x % 2 == 0"); 1863a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 1864a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (int i = 0; i < 10; i++) { 1865a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block f->Call(env->Global(), 0, NULL); 1866a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1867a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(5, break_point_hit_count); 1868a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1869a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Reload the script and get f again checking that the condition survives. 1870a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Script::Compile(script, &origin)->Run(); 1871a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block f = v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("f"))); 1872a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1873a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 1874a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (int i = 0; i < 10; i++) { 1875a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block f->Call(env->Global(), 0, NULL); 1876a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1877a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(5, break_point_hit_count); 1878a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1879a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetDebugEventListener(NULL); 1880a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CheckDebuggerUnloaded(); 1881a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1882a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1883a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1884a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Test ignore count on script break points. 1885a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(ScriptBreakPointIgnoreCount) { 1886a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 1887a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::HandleScope scope; 1888a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DebugLocalContext env; 1889a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block env.ExposeDebug(); 1890a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1891a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount, 1892a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Undefined()); 1893a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1894a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Local<v8::String> script = v8::String::New( 1895a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "function f() {\n" 1896a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " a = 0; // line 1\n" 1897a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "};"); 1898a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1899a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Compile the script and get function f. 1900a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::ScriptOrigin origin = 1901a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::ScriptOrigin(v8::String::New("test")); 1902a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Script::Compile(script, &origin)->Run(); 1903a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Local<v8::Function> f = 1904a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("f"))); 1905a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1906a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Set script break point on line 1 (in function f). 1907a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int sbp = SetScriptBreakPointByNameFromJS("test", 1, 0); 1908a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1909a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Call f with different ignores on the script break point. 1910a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 1911a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ChangeScriptBreakPointIgnoreCountFromJS(sbp, 1); 1912a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block f->Call(env->Global(), 0, NULL); 1913a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(0, break_point_hit_count); 1914a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block f->Call(env->Global(), 0, NULL); 1915a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1, break_point_hit_count); 1916a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1917a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ChangeScriptBreakPointIgnoreCountFromJS(sbp, 5); 1918a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 1919a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (int i = 0; i < 10; i++) { 1920a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block f->Call(env->Global(), 0, NULL); 1921a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1922a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(5, break_point_hit_count); 1923a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1924a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Reload the script and get f again checking that the ignore survives. 1925a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Script::Compile(script, &origin)->Run(); 1926a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block f = v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("f"))); 1927a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1928a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 1929a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (int i = 0; i < 10; i++) { 1930a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block f->Call(env->Global(), 0, NULL); 1931a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1932a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(5, break_point_hit_count); 1933a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1934a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetDebugEventListener(NULL); 1935a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CheckDebuggerUnloaded(); 1936a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1937a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1938a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1939a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Test that script break points survive when a script is reloaded. 1940a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(ScriptBreakPointReload) { 1941a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 1942a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::HandleScope scope; 1943a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DebugLocalContext env; 1944a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block env.ExposeDebug(); 1945a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1946a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount, 1947a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Undefined()); 1948a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1949a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Local<v8::Function> f; 1950a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Local<v8::String> script = v8::String::New( 1951a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "function f() {\n" 1952a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " function h() {\n" 1953a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " a = 0; // line 2\n" 1954a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " }\n" 1955a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " b = 1; // line 4\n" 1956a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " return h();\n" 1957a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "}"); 1958a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1959a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::ScriptOrigin origin_1 = v8::ScriptOrigin(v8::String::New("1")); 1960a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::ScriptOrigin origin_2 = v8::ScriptOrigin(v8::String::New("2")); 1961a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1962a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Set a script break point before the script is loaded. 1963a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block SetScriptBreakPointByNameFromJS("1", 2, 0); 1964a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1965a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Compile the script and get the function. 1966a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Script::Compile(script, &origin_1)->Run(); 1967a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block f = v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("f"))); 1968a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1969a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Call f and check that the script break point is active. 1970a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 1971a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block f->Call(env->Global(), 0, NULL); 1972a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1, break_point_hit_count); 1973a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1974a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Compile the script again with a different script data and get the 1975a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // function. 1976a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Script::Compile(script, &origin_2)->Run(); 1977a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block f = v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("f"))); 1978a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1979a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Call f and check that no break points are set. 1980a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 1981a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block f->Call(env->Global(), 0, NULL); 1982a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(0, break_point_hit_count); 1983a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1984a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Compile the script again and get the function. 1985a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Script::Compile(script, &origin_1)->Run(); 1986a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block f = v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("f"))); 1987a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1988a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Call f and check that the script break point is active. 1989a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 1990a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block f->Call(env->Global(), 0, NULL); 1991a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1, break_point_hit_count); 1992a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1993a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetDebugEventListener(NULL); 1994a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CheckDebuggerUnloaded(); 1995a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1996a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1997a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1998a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Test when several scripts has the same script data 1999a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(ScriptBreakPointMultiple) { 2000a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 2001a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::HandleScope scope; 2002a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DebugLocalContext env; 2003a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block env.ExposeDebug(); 2004a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2005a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount, 2006a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Undefined()); 2007a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2008a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Local<v8::Function> f; 2009a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Local<v8::String> script_f = v8::String::New( 2010a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "function f() {\n" 2011a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " a = 0; // line 1\n" 2012a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "}"); 2013a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2014a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Local<v8::Function> g; 2015a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Local<v8::String> script_g = v8::String::New( 2016a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "function g() {\n" 2017a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " b = 0; // line 1\n" 2018a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "}"); 2019a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2020a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::ScriptOrigin origin = 2021a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::ScriptOrigin(v8::String::New("test")); 2022a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2023a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Set a script break point before the scripts are loaded. 2024a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int sbp = SetScriptBreakPointByNameFromJS("test", 1, 0); 2025a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2026a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Compile the scripts with same script data and get the functions. 2027a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Script::Compile(script_f, &origin)->Run(); 2028a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block f = v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("f"))); 2029a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Script::Compile(script_g, &origin)->Run(); 2030a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block g = v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("g"))); 2031a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2032a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Call f and g and check that the script break point is active. 2033a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 2034a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block f->Call(env->Global(), 0, NULL); 2035a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1, break_point_hit_count); 2036a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block g->Call(env->Global(), 0, NULL); 2037a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(2, break_point_hit_count); 2038a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2039a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Clear the script break point. 2040a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ClearBreakPointFromJS(sbp); 2041a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2042a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Call f and g and check that the script break point is no longer active. 2043a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 2044a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block f->Call(env->Global(), 0, NULL); 2045a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(0, break_point_hit_count); 2046a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block g->Call(env->Global(), 0, NULL); 2047a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(0, break_point_hit_count); 2048a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2049a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Set script break point with the scripts loaded. 2050a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block sbp = SetScriptBreakPointByNameFromJS("test", 1, 0); 2051a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2052a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Call f and g and check that the script break point is active. 2053a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 2054a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block f->Call(env->Global(), 0, NULL); 2055a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1, break_point_hit_count); 2056a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block g->Call(env->Global(), 0, NULL); 2057a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(2, break_point_hit_count); 2058a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2059a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetDebugEventListener(NULL); 2060a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CheckDebuggerUnloaded(); 2061a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2062a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2063a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2064a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Test the script origin which has both name and line offset. 2065a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(ScriptBreakPointLineOffset) { 2066a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 2067a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::HandleScope scope; 2068a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DebugLocalContext env; 2069a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block env.ExposeDebug(); 2070a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2071a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount, 2072a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Undefined()); 2073a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2074a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Local<v8::Function> f; 2075a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Local<v8::String> script = v8::String::New( 2076a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "function f() {\n" 2077a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " a = 0; // line 8 as this script has line offset 7\n" 2078a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " b = 0; // line 9 as this script has line offset 7\n" 2079a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "}"); 2080a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2081a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Create script origin both name and line offset. 2082a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::ScriptOrigin origin(v8::String::New("test.html"), 2083a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Integer::New(7)); 2084a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2085a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Set two script break points before the script is loaded. 2086a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int sbp1 = SetScriptBreakPointByNameFromJS("test.html", 8, 0); 2087a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int sbp2 = SetScriptBreakPointByNameFromJS("test.html", 9, 0); 2088a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2089a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Compile the script and get the function. 2090a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Script::Compile(script, &origin)->Run(); 2091a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block f = v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("f"))); 2092a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2093a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Call f and check that the script break point is active. 2094a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 2095a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block f->Call(env->Global(), 0, NULL); 2096a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(2, break_point_hit_count); 2097a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2098a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Clear the script break points. 2099a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ClearBreakPointFromJS(sbp1); 2100a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ClearBreakPointFromJS(sbp2); 2101a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2102a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Call f and check that no script break points are active. 2103a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 2104a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block f->Call(env->Global(), 0, NULL); 2105a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(0, break_point_hit_count); 2106a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2107a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Set a script break point with the script loaded. 2108a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block sbp1 = SetScriptBreakPointByNameFromJS("test.html", 9, 0); 2109a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2110a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Call f and check that the script break point is active. 2111a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 2112a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block f->Call(env->Global(), 0, NULL); 2113a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1, break_point_hit_count); 2114a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2115a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetDebugEventListener(NULL); 2116a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CheckDebuggerUnloaded(); 2117a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2118a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2119a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2120a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Test script break points set on lines. 2121a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(ScriptBreakPointLine) { 2122a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::HandleScope scope; 2123a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DebugLocalContext env; 2124a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block env.ExposeDebug(); 2125a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2126a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Create a function for checking the function when hitting a break point. 2127a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block frame_function_name = CompileFunction(&env, 2128a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block frame_function_name_source, 2129a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "frame_function_name"); 2130a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2131a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount, 2132a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Undefined()); 2133a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2134a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Local<v8::Function> f; 2135a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Local<v8::Function> g; 2136a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Local<v8::String> script = v8::String::New( 2137a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "a = 0 // line 0\n" 2138a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "function f() {\n" 2139a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " a = 1; // line 2\n" 2140a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "}\n" 2141a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " a = 2; // line 4\n" 2142a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " /* xx */ function g() { // line 5\n" 2143a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " function h() { // line 6\n" 2144a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " a = 3; // line 7\n" 2145a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " }\n" 2146a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " h(); // line 9\n" 2147a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " a = 4; // line 10\n" 2148a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " }\n" 2149a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " a=5; // line 12"); 2150a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2151a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Set a couple script break point before the script is loaded. 2152a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int sbp1 = SetScriptBreakPointByNameFromJS("test.html", 0, -1); 2153a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int sbp2 = SetScriptBreakPointByNameFromJS("test.html", 1, -1); 2154a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int sbp3 = SetScriptBreakPointByNameFromJS("test.html", 5, -1); 2155a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2156a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Compile the script and get the function. 2157a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 2158a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::ScriptOrigin origin(v8::String::New("test.html"), v8::Integer::New(0)); 2159a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Script::Compile(script, &origin)->Run(); 2160a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block f = v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("f"))); 2161a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block g = v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("g"))); 2162a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 216369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch // Check that a break point was hit when the script was run. 2164a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1, break_point_hit_count); 2165d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block CHECK_EQ(0, StrLength(last_function_hit)); 2166a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2167a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Call f and check that the script break point. 2168a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block f->Call(env->Global(), 0, NULL); 2169a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(2, break_point_hit_count); 2170a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ("f", last_function_hit); 2171a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2172a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Call g and check that the script break point. 2173a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block g->Call(env->Global(), 0, NULL); 2174a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(3, break_point_hit_count); 2175a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ("g", last_function_hit); 2176a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2177a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Clear the script break point on g and set one on h. 2178a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ClearBreakPointFromJS(sbp3); 2179a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int sbp4 = SetScriptBreakPointByNameFromJS("test.html", 6, -1); 2180a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2181a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Call g and check that the script break point in h is hit. 2182a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block g->Call(env->Global(), 0, NULL); 2183a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(4, break_point_hit_count); 2184a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ("h", last_function_hit); 2185a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2186a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Clear break points in f and h. Set a new one in the script between 2187a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // functions f and g and test that there is no break points in f and g any 2188a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // more. 2189a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ClearBreakPointFromJS(sbp2); 2190a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ClearBreakPointFromJS(sbp4); 2191a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int sbp5 = SetScriptBreakPointByNameFromJS("test.html", 4, -1); 2192a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 2193a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block f->Call(env->Global(), 0, NULL); 2194a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block g->Call(env->Global(), 0, NULL); 2195a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(0, break_point_hit_count); 2196a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2197a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Reload the script which should hit two break points. 2198a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 2199a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Script::Compile(script, &origin)->Run(); 2200a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(2, break_point_hit_count); 2201d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block CHECK_EQ(0, StrLength(last_function_hit)); 2202a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2203a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Set a break point in the code after the last function decleration. 2204a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int sbp6 = SetScriptBreakPointByNameFromJS("test.html", 12, -1); 2205a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2206a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Reload the script which should hit three break points. 2207a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 2208a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Script::Compile(script, &origin)->Run(); 2209a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(3, break_point_hit_count); 2210d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block CHECK_EQ(0, StrLength(last_function_hit)); 2211a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2212a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Clear the last break points, and reload the script which should not hit any 2213a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // break points. 2214a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ClearBreakPointFromJS(sbp1); 2215a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ClearBreakPointFromJS(sbp5); 2216a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ClearBreakPointFromJS(sbp6); 2217a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 2218a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Script::Compile(script, &origin)->Run(); 2219a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(0, break_point_hit_count); 2220a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2221a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetDebugEventListener(NULL); 2222a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CheckDebuggerUnloaded(); 2223a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2224a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2225a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 22269dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen// Test top level script break points set on lines. 22279dcf7e2f83591d471e88bf7d230651900b8e424bKristian MonsenTEST(ScriptBreakPointLineTopLevel) { 22289dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen v8::HandleScope scope; 22299dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen DebugLocalContext env; 22309dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen env.ExposeDebug(); 22319dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen 22329dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount, 22339dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen v8::Undefined()); 22349dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen 22359dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen v8::Local<v8::String> script = v8::String::New( 22369dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen "function f() {\n" 22379dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen " a = 1; // line 1\n" 22389dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen "}\n" 22399dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen "a = 2; // line 3\n"); 22409dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen v8::Local<v8::Function> f; 22419dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen { 22429dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen v8::HandleScope scope; 22439dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen v8::Script::Compile(script, v8::String::New("test.html"))->Run(); 22449dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen } 22459dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen f = v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("f"))); 22469dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen 22473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch HEAP->CollectAllGarbage(Heap::kNoGCFlags); 22489dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen 22499dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen SetScriptBreakPointByNameFromJS("test.html", 3, -1); 22509dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen 22519dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen // Call f and check that there was no break points. 22529dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen break_point_hit_count = 0; 22539dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen f->Call(env->Global(), 0, NULL); 22549dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen CHECK_EQ(0, break_point_hit_count); 22559dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen 22569dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen // Recompile and run script and check that break point was hit. 22579dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen break_point_hit_count = 0; 22589dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen v8::Script::Compile(script, v8::String::New("test.html"))->Run(); 22599dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen CHECK_EQ(1, break_point_hit_count); 22609dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen 22619dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen // Call f and check that there are still no break points. 22629dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen break_point_hit_count = 0; 22639dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen f = v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("f"))); 22649dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen CHECK_EQ(0, break_point_hit_count); 22659dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen 22669dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen v8::Debug::SetDebugEventListener(NULL); 22679dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen CheckDebuggerUnloaded(); 22689dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen} 22699dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen 22709dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen 22718defd9ff6930b4e24729971a61cf7469daf119beSteve Block// Test that it is possible to add and remove break points in a top level 22728defd9ff6930b4e24729971a61cf7469daf119beSteve Block// function which has no references but has not been collected yet. 22738defd9ff6930b4e24729971a61cf7469daf119beSteve BlockTEST(ScriptBreakPointTopLevelCrash) { 22748defd9ff6930b4e24729971a61cf7469daf119beSteve Block v8::HandleScope scope; 22758defd9ff6930b4e24729971a61cf7469daf119beSteve Block DebugLocalContext env; 22768defd9ff6930b4e24729971a61cf7469daf119beSteve Block env.ExposeDebug(); 22778defd9ff6930b4e24729971a61cf7469daf119beSteve Block 22788defd9ff6930b4e24729971a61cf7469daf119beSteve Block v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount, 22798defd9ff6930b4e24729971a61cf7469daf119beSteve Block v8::Undefined()); 22808defd9ff6930b4e24729971a61cf7469daf119beSteve Block 22818defd9ff6930b4e24729971a61cf7469daf119beSteve Block v8::Local<v8::String> script_source = v8::String::New( 22828defd9ff6930b4e24729971a61cf7469daf119beSteve Block "function f() {\n" 22838defd9ff6930b4e24729971a61cf7469daf119beSteve Block " return 0;\n" 22848defd9ff6930b4e24729971a61cf7469daf119beSteve Block "}\n" 22858defd9ff6930b4e24729971a61cf7469daf119beSteve Block "f()"); 22868defd9ff6930b4e24729971a61cf7469daf119beSteve Block 22878defd9ff6930b4e24729971a61cf7469daf119beSteve Block int sbp1 = SetScriptBreakPointByNameFromJS("test.html", 3, -1); 22888defd9ff6930b4e24729971a61cf7469daf119beSteve Block { 22898defd9ff6930b4e24729971a61cf7469daf119beSteve Block v8::HandleScope scope; 22908defd9ff6930b4e24729971a61cf7469daf119beSteve Block break_point_hit_count = 0; 22918defd9ff6930b4e24729971a61cf7469daf119beSteve Block v8::Script::Compile(script_source, v8::String::New("test.html"))->Run(); 22928defd9ff6930b4e24729971a61cf7469daf119beSteve Block CHECK_EQ(1, break_point_hit_count); 22938defd9ff6930b4e24729971a61cf7469daf119beSteve Block } 22948defd9ff6930b4e24729971a61cf7469daf119beSteve Block 22958defd9ff6930b4e24729971a61cf7469daf119beSteve Block int sbp2 = SetScriptBreakPointByNameFromJS("test.html", 3, -1); 22968defd9ff6930b4e24729971a61cf7469daf119beSteve Block ClearBreakPointFromJS(sbp1); 22978defd9ff6930b4e24729971a61cf7469daf119beSteve Block ClearBreakPointFromJS(sbp2); 22988defd9ff6930b4e24729971a61cf7469daf119beSteve Block 22998defd9ff6930b4e24729971a61cf7469daf119beSteve Block v8::Debug::SetDebugEventListener(NULL); 23008defd9ff6930b4e24729971a61cf7469daf119beSteve Block CheckDebuggerUnloaded(); 23018defd9ff6930b4e24729971a61cf7469daf119beSteve Block} 23028defd9ff6930b4e24729971a61cf7469daf119beSteve Block 23038defd9ff6930b4e24729971a61cf7469daf119beSteve Block 2304a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Test that it is possible to remove the last break point for a function 2305a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// inside the break handling of that break point. 2306a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(RemoveBreakPointInBreak) { 2307a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::HandleScope scope; 2308a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DebugLocalContext env; 2309a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2310a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Local<v8::Function> foo = 2311a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CompileFunction(&env, "function foo(){a=1;}", "foo"); 2312a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block debug_event_remove_break_point = SetBreakPoint(foo, 0); 2313a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2314a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Register the debug event listener pasing the function 2315a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetDebugEventListener(DebugEventRemoveBreakPoint, foo); 2316a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2317a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 2318a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block foo->Call(env->Global(), 0, NULL); 2319a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1, break_point_hit_count); 2320a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2321a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 2322a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block foo->Call(env->Global(), 0, NULL); 2323a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(0, break_point_hit_count); 2324a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2325a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetDebugEventListener(NULL); 2326a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CheckDebuggerUnloaded(); 2327a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2328a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2329a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2330a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Test that the debugger statement causes a break. 2331a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(DebuggerStatement) { 2332a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 2333a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::HandleScope scope; 2334a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DebugLocalContext env; 2335a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount, 2336a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Undefined()); 2337a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Script::Compile(v8::String::New("function bar(){debugger}"))->Run(); 2338a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Script::Compile(v8::String::New( 2339a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "function foo(){debugger;debugger;}"))->Run(); 2340a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Local<v8::Function> foo = 2341a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("foo"))); 2342a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Local<v8::Function> bar = 2343a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("bar"))); 2344a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2345a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Run function with debugger statement 2346a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bar->Call(env->Global(), 0, NULL); 2347a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1, break_point_hit_count); 2348a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2349a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Run function with two debugger statement 2350a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block foo->Call(env->Global(), 0, NULL); 2351a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(3, break_point_hit_count); 2352a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2353a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetDebugEventListener(NULL); 2354a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CheckDebuggerUnloaded(); 2355a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2356a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2357a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 23588defd9ff6930b4e24729971a61cf7469daf119beSteve Block// Test setting a breakpoint on the debugger statement. 23594515c472dc3e5ed2448a564600976759e569a0a8Leon ClarkeTEST(DebuggerStatementBreakpoint) { 23604515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke break_point_hit_count = 0; 23614515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke v8::HandleScope scope; 23624515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke DebugLocalContext env; 23634515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount, 23644515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke v8::Undefined()); 23654515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke v8::Script::Compile(v8::String::New("function foo(){debugger;}"))->Run(); 23664515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke v8::Local<v8::Function> foo = 23674515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("foo"))); 23684515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke 23694515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke // The debugger statement triggers breakpint hit 23704515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke foo->Call(env->Global(), 0, NULL); 23714515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke CHECK_EQ(1, break_point_hit_count); 23724515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke 23734515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke int bp = SetBreakPoint(foo, 0); 23744515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke 23754515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke // Set breakpoint does not duplicate hits 23764515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke foo->Call(env->Global(), 0, NULL); 23774515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke CHECK_EQ(2, break_point_hit_count); 23784515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke 23794515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke ClearBreakPoint(bp); 23804515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke v8::Debug::SetDebugEventListener(NULL); 23814515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke CheckDebuggerUnloaded(); 23824515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke} 23834515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke 23844515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke 2385a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Thest that the evaluation of expressions when a break point is hit generates 2386a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// the correct results. 2387a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(DebugEvaluate) { 2388a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::HandleScope scope; 2389a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DebugLocalContext env; 2390a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block env.ExposeDebug(); 2391a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2392a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Create a function for checking the evaluation when hitting a break point. 2393a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block evaluate_check_function = CompileFunction(&env, 2394a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block evaluate_check_source, 2395a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "evaluate_check"); 2396a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Register the debug event listener 2397a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetDebugEventListener(DebugEventEvaluate); 2398a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2399a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Different expected vaules of x and a when in a break point (u = undefined, 2400a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // d = Hello, world!). 2401a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block struct EvaluateCheck checks_uu[] = { 2402a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block {"x", v8::Undefined()}, 2403a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block {"a", v8::Undefined()}, 2404a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block {NULL, v8::Handle<v8::Value>()} 2405a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block }; 2406a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block struct EvaluateCheck checks_hu[] = { 2407a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block {"x", v8::String::New("Hello, world!")}, 2408a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block {"a", v8::Undefined()}, 2409a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block {NULL, v8::Handle<v8::Value>()} 2410a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block }; 2411a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block struct EvaluateCheck checks_hh[] = { 2412a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block {"x", v8::String::New("Hello, world!")}, 2413a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block {"a", v8::String::New("Hello, world!")}, 2414a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block {NULL, v8::Handle<v8::Value>()} 2415a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block }; 2416a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2417a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Simple test function. The "y=0" is in the function foo to provide a break 2418a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // location. For "y=0" the "y" is at position 15 in the barbar function 2419a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // therefore setting breakpoint at position 15 will break at "y=0" and 2420a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // setting it higher will break after. 2421a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Local<v8::Function> foo = CompileFunction(&env, 2422a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "function foo(x) {" 2423a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " var a;" 24247f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch " y=0;" // To ensure break location 1. 2425a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " a=x;" 24267f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch " y=0;" // To ensure break location 2. 2427a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "}", 2428a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "foo"); 24297f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch const int foo_break_position_1 = 15; 24307f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch const int foo_break_position_2 = 29; 2431a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2432a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Arguments with one parameter "Hello, world!" 2433a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<v8::Value> argv_foo[1] = { v8::String::New("Hello, world!") }; 2434a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2435a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Call foo with breakpoint set before a=x and undefined as parameter. 24367f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch int bp = SetBreakPoint(foo, foo_break_position_1); 2437a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block checks = checks_uu; 2438a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block foo->Call(env->Global(), 0, NULL); 2439a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2440a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Call foo with breakpoint set before a=x and parameter "Hello, world!". 2441a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block checks = checks_hu; 2442a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block foo->Call(env->Global(), 1, argv_foo); 2443a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2444a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Call foo with breakpoint set after a=x and parameter "Hello, world!". 2445a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ClearBreakPoint(bp); 24467f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch SetBreakPoint(foo, foo_break_position_2); 2447a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block checks = checks_hh; 2448a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block foo->Call(env->Global(), 1, argv_foo); 2449a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2450a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Test function with an inner function. The "y=0" is in function barbar 2451a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // to provide a break location. For "y=0" the "y" is at position 8 in the 2452a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // barbar function therefore setting breakpoint at position 8 will break at 2453a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // "y=0" and setting it higher will break after. 2454a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Local<v8::Function> bar = CompileFunction(&env, 2455a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "y = 0;" 2456a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "x = 'Goodbye, world!';" 2457a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "function bar(x, b) {" 2458a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " var a;" 2459a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " function barbar() {" 2460a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " y=0; /* To ensure break location.*/" 2461a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " a=x;" 2462a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " };" 2463a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " debug.Debug.clearAllBreakPoints();" 2464a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " barbar();" 2465a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " y=0;a=x;" 2466a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "}", 2467a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "bar"); 2468a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const int barbar_break_position = 8; 2469a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2470a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Call bar setting breakpoint before a=x in barbar and undefined as 2471a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // parameter. 2472a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block checks = checks_uu; 2473a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<v8::Value> argv_bar_1[2] = { 2474a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Undefined(), 2475a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Number::New(barbar_break_position) 2476a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block }; 2477a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bar->Call(env->Global(), 2, argv_bar_1); 2478a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2479a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Call bar setting breakpoint before a=x in barbar and parameter 2480a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // "Hello, world!". 2481a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block checks = checks_hu; 2482a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<v8::Value> argv_bar_2[2] = { 2483a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::String::New("Hello, world!"), 2484a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Number::New(barbar_break_position) 2485a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block }; 2486a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bar->Call(env->Global(), 2, argv_bar_2); 2487a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2488a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Call bar setting breakpoint after a=x in barbar and parameter 2489a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // "Hello, world!". 2490a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block checks = checks_hh; 2491a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<v8::Value> argv_bar_3[2] = { 2492a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::String::New("Hello, world!"), 2493a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Number::New(barbar_break_position + 1) 2494a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block }; 2495a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bar->Call(env->Global(), 2, argv_bar_3); 2496a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2497a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetDebugEventListener(NULL); 2498a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CheckDebuggerUnloaded(); 2499a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2500a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2501e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke// Copies a C string to a 16-bit string. Does not check for buffer overflow. 2502e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke// Does not use the V8 engine to convert strings, so it can be used 2503e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke// in any thread. Returns the length of the string. 2504e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarkeint AsciiToUtf16(const char* input_buffer, uint16_t* output_buffer) { 2505e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke int i; 2506e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke for (i = 0; input_buffer[i] != '\0'; ++i) { 2507e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // ASCII does not use chars > 127, but be careful anyway. 2508e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke output_buffer[i] = static_cast<unsigned char>(input_buffer[i]); 2509e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke } 2510e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke output_buffer[i] = 0; 2511e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke return i; 2512e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke} 2513e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 2514e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke// Copies a 16-bit string to a C string by dropping the high byte of 2515e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke// each character. Does not check for buffer overflow. 2516e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke// Can be used in any thread. Requires string length as an input. 2517e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarkeint Utf16ToAscii(const uint16_t* input_buffer, int length, 2518e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke char* output_buffer, int output_len = -1) { 2519e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke if (output_len >= 0) { 2520e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke if (length > output_len - 1) { 2521e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke length = output_len - 1; 2522e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke } 2523e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke } 2524e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 2525e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke for (int i = 0; i < length; ++i) { 2526e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke output_buffer[i] = static_cast<char>(input_buffer[i]); 2527e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke } 2528e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke output_buffer[length] = '\0'; 2529e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke return length; 2530e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke} 2531e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 2532e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 2533e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke// We match parts of the message to get evaluate result int value. 2534e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarkebool GetEvaluateStringResult(char *message, char* buffer, int buffer_size) { 2535d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke if (strstr(message, "\"command\":\"evaluate\"") == NULL) { 2536d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke return false; 2537d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 2538d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke const char* prefix = "\"text\":\""; 2539d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke char* pos1 = strstr(message, prefix); 2540d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke if (pos1 == NULL) { 2541d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke return false; 2542d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 2543d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke pos1 += strlen(prefix); 2544d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke char* pos2 = strchr(pos1, '"'); 2545d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke if (pos2 == NULL) { 2546e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke return false; 2547e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke } 2548e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke Vector<char> buf(buffer, buffer_size); 2549d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke int len = static_cast<int>(pos2 - pos1); 2550d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke if (len > buffer_size - 1) { 2551d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke len = buffer_size - 1; 2552d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 2553d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke OS::StrNCpy(buf, pos1, len); 2554e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke buffer[buffer_size - 1] = '\0'; 2555e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke return true; 2556e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke} 2557e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 2558e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 2559e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarkestruct EvaluateResult { 2560e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke static const int kBufferSize = 20; 2561e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke char buffer[kBufferSize]; 2562e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke}; 2563e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 2564e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarkestruct DebugProcessDebugMessagesData { 2565e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke static const int kArraySize = 5; 2566e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke int counter; 2567e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke EvaluateResult results[kArraySize]; 2568e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 2569e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke void reset() { 2570e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke counter = 0; 2571e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke } 2572e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke EvaluateResult* current() { 2573e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke return &results[counter % kArraySize]; 2574e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke } 2575e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke void next() { 2576e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke counter++; 2577e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke } 2578e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke}; 2579e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 2580e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon ClarkeDebugProcessDebugMessagesData process_debug_messages_data; 2581e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 2582e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarkestatic void DebugProcessDebugMessagesHandler( 2583e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke const uint16_t* message, 2584e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke int length, 2585e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke v8::Debug::ClientData* client_data) { 2586e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 2587e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke const int kBufferSize = 100000; 2588e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke char print_buffer[kBufferSize]; 2589e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke Utf16ToAscii(message, length, print_buffer, kBufferSize); 2590e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 2591e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke EvaluateResult* array_item = process_debug_messages_data.current(); 2592e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 2593e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke bool res = GetEvaluateStringResult(print_buffer, 2594e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke array_item->buffer, 2595e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke EvaluateResult::kBufferSize); 2596e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke if (res) { 2597e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke process_debug_messages_data.next(); 2598e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke } 2599e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke} 2600e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 2601e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke// Test that the evaluation of expressions works even from ProcessDebugMessages 2602e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke// i.e. with empty stack. 2603e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon ClarkeTEST(DebugEvaluateWithoutStack) { 2604e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke v8::Debug::SetMessageHandler(DebugProcessDebugMessagesHandler); 2605e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 2606e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke v8::HandleScope scope; 2607e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke DebugLocalContext env; 2608e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 2609e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke const char* source = 2610e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke "var v1 = 'Pinguin';\n function getAnimal() { return 'Capy' + 'bara'; }"; 2611e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 2612e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke v8::Script::Compile(v8::String::New(source))->Run(); 2613e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 2614e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke v8::Debug::ProcessDebugMessages(); 2615e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 2616e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke const int kBufferSize = 1000; 2617e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke uint16_t buffer[kBufferSize]; 2618e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 2619e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke const char* command_111 = "{\"seq\":111," 2620e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke "\"type\":\"request\"," 2621e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke "\"command\":\"evaluate\"," 2622e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke "\"arguments\":{" 2623e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke " \"global\":true," 2624e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke " \"expression\":\"v1\",\"disable_break\":true" 2625e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke "}}"; 2626e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 2627e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke v8::Debug::SendCommand(buffer, AsciiToUtf16(command_111, buffer)); 2628e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 2629e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke const char* command_112 = "{\"seq\":112," 2630e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke "\"type\":\"request\"," 2631e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke "\"command\":\"evaluate\"," 2632e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke "\"arguments\":{" 2633e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke " \"global\":true," 2634e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke " \"expression\":\"getAnimal()\",\"disable_break\":true" 2635e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke "}}"; 2636e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 2637e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke v8::Debug::SendCommand(buffer, AsciiToUtf16(command_112, buffer)); 2638e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 2639e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke const char* command_113 = "{\"seq\":113," 2640e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke "\"type\":\"request\"," 2641e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke "\"command\":\"evaluate\"," 2642e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke "\"arguments\":{" 2643e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke " \"global\":true," 2644e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke " \"expression\":\"239 + 566\",\"disable_break\":true" 2645e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke "}}"; 2646e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 2647e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke v8::Debug::SendCommand(buffer, AsciiToUtf16(command_113, buffer)); 2648e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 2649e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke v8::Debug::ProcessDebugMessages(); 2650e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 2651e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke CHECK_EQ(3, process_debug_messages_data.counter); 2652e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 2653d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke CHECK_EQ(strcmp("Pinguin", process_debug_messages_data.results[0].buffer), 0); 2654d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke CHECK_EQ(strcmp("Capybara", process_debug_messages_data.results[1].buffer), 2655d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 0); 2656d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke CHECK_EQ(strcmp("805", process_debug_messages_data.results[2].buffer), 0); 2657e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 2658e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke v8::Debug::SetMessageHandler(NULL); 2659e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke v8::Debug::SetDebugEventListener(NULL); 2660e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke CheckDebuggerUnloaded(); 2661e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke} 2662e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 2663a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2664a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Simple test of the stepping mechanism using only store ICs. 2665a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(DebugStepLinear) { 2666a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::HandleScope scope; 2667a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DebugLocalContext env; 2668a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2669a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Create a function for testing stepping. 2670a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Local<v8::Function> foo = CompileFunction(&env, 2671a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "function foo(){a=1;b=1;c=1;}", 2672a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "foo"); 2673b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 2674b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Run foo to allow it to get optimized. 2675b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CompileRun("a=0; b=0; c=0; foo();"); 2676b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 2677a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block SetBreakPoint(foo, 3); 2678a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2679a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Register a debug event listener which steps and counts. 2680a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetDebugEventListener(DebugEventStep); 2681a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2682a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block step_action = StepIn; 2683a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 2684a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block foo->Call(env->Global(), 0, NULL); 2685a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2686a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // With stepping all break locations are hit. 2687a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(4, break_point_hit_count); 2688a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2689a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetDebugEventListener(NULL); 2690a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CheckDebuggerUnloaded(); 2691a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2692a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Register a debug event listener which just counts. 2693a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount); 2694a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2695a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block SetBreakPoint(foo, 3); 2696a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 2697a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block foo->Call(env->Global(), 0, NULL); 2698a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2699a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Without stepping only active break points are hit. 2700a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1, break_point_hit_count); 2701a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2702a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetDebugEventListener(NULL); 2703a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CheckDebuggerUnloaded(); 2704a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2705a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2706a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2707a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Test of the stepping mechanism for keyed load in a loop. 2708a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(DebugStepKeyedLoadLoop) { 2709a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::HandleScope scope; 2710a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DebugLocalContext env; 2711a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 27127f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Register a debug event listener which steps and counts. 27137f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch v8::Debug::SetDebugEventListener(DebugEventStep); 27147f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 2715a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Create a function for testing stepping of keyed load. The statement 'y=1' 2716a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // is there to have more than one breakable statement in the loop, TODO(315). 2717a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Local<v8::Function> foo = CompileFunction( 2718a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block &env, 2719a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "function foo(a) {\n" 2720a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " var x;\n" 2721a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " var len = a.length;\n" 2722a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " for (var i = 0; i < len; i++) {\n" 2723a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " y = 1;\n" 2724a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " x = a[i];\n" 2725a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " }\n" 2726b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "}\n" 2727b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "y=0\n", 2728a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "foo"); 2729a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2730a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Create array [0,1,2,3,4,5,6,7,8,9] 2731a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Local<v8::Array> a = v8::Array::New(10); 2732a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (int i = 0; i < 10; i++) { 2733a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block a->Set(v8::Number::New(i), v8::Number::New(i)); 2734a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2735a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2736a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Call function without any break points to ensure inlining is in place. 2737a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const int kArgc = 1; 2738a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<v8::Value> args[kArgc] = { a }; 2739a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block foo->Call(env->Global(), kArgc, args); 2740a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 27413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Set up break point and step through the function. 2742a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block SetBreakPoint(foo, 3); 2743a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block step_action = StepNext; 2744a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 2745a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block foo->Call(env->Global(), kArgc, args); 2746a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2747a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // With stepping all break locations are hit. 27483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CHECK_EQ(34, break_point_hit_count); 2749a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2750a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetDebugEventListener(NULL); 2751a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CheckDebuggerUnloaded(); 2752a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2753a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2754a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2755a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Test of the stepping mechanism for keyed store in a loop. 2756a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(DebugStepKeyedStoreLoop) { 2757a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::HandleScope scope; 2758a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DebugLocalContext env; 2759a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 27607f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Register a debug event listener which steps and counts. 27617f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch v8::Debug::SetDebugEventListener(DebugEventStep); 27627f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 2763a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Create a function for testing stepping of keyed store. The statement 'y=1' 2764a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // is there to have more than one breakable statement in the loop, TODO(315). 2765a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Local<v8::Function> foo = CompileFunction( 2766a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block &env, 2767a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "function foo(a) {\n" 2768a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " var len = a.length;\n" 2769a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " for (var i = 0; i < len; i++) {\n" 2770a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " y = 1;\n" 2771a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " a[i] = 42;\n" 2772a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " }\n" 2773b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "}\n" 2774b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "y=0\n", 2775a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "foo"); 2776a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2777a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Create array [0,1,2,3,4,5,6,7,8,9] 2778a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Local<v8::Array> a = v8::Array::New(10); 2779a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (int i = 0; i < 10; i++) { 2780a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block a->Set(v8::Number::New(i), v8::Number::New(i)); 2781a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2782a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2783a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Call function without any break points to ensure inlining is in place. 2784a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const int kArgc = 1; 2785a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<v8::Value> args[kArgc] = { a }; 2786a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block foo->Call(env->Global(), kArgc, args); 2787a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 27883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Set up break point and step through the function. 2789a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block SetBreakPoint(foo, 3); 2790a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block step_action = StepNext; 2791a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 2792a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block foo->Call(env->Global(), kArgc, args); 2793a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2794a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // With stepping all break locations are hit. 27953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CHECK_EQ(33, break_point_hit_count); 2796a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2797a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetDebugEventListener(NULL); 2798a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CheckDebuggerUnloaded(); 2799a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2800a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2801a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 280225f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen// Test of the stepping mechanism for named load in a loop. 280325f6136652d8341ed047e7fc1a450af5bd218ea9Kristian MonsenTEST(DebugStepNamedLoadLoop) { 280425f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen v8::HandleScope scope; 280525f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen DebugLocalContext env; 280625f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen 28077f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Register a debug event listener which steps and counts. 28087f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch v8::Debug::SetDebugEventListener(DebugEventStep); 28097f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 281025f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen // Create a function for testing stepping of named load. 281125f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen v8::Local<v8::Function> foo = CompileFunction( 281225f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen &env, 281325f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen "function foo() {\n" 281425f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen " var a = [];\n" 281525f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen " var s = \"\";\n" 281625f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen " for (var i = 0; i < 10; i++) {\n" 281725f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen " var v = new V(i, i + 1);\n" 281825f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen " v.y;\n" 281925f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen " a.length;\n" // Special case: array length. 282025f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen " s.length;\n" // Special case: string length. 282125f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen " }\n" 282225f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen "}\n" 282325f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen "function V(x, y) {\n" 282425f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen " this.x = x;\n" 282525f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen " this.y = y;\n" 282625f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen "}\n", 282725f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen "foo"); 282825f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen 282925f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen // Call function without any break points to ensure inlining is in place. 283025f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen foo->Call(env->Global(), 0, NULL); 283125f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen 28323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Set up break point and step through the function. 283325f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen SetBreakPoint(foo, 4); 283425f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen step_action = StepNext; 283525f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen break_point_hit_count = 0; 283625f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen foo->Call(env->Global(), 0, NULL); 283725f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen 283825f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen // With stepping all break locations are hit. 28393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CHECK_EQ(54, break_point_hit_count); 284025f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen 284125f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen v8::Debug::SetDebugEventListener(NULL); 284225f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen CheckDebuggerUnloaded(); 284325f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen} 284425f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen 284525f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen 2846b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochstatic void DoDebugStepNamedStoreLoop(int expected) { 2847756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick v8::HandleScope scope; 2848756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick DebugLocalContext env; 2849756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 2850b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Register a debug event listener which steps and counts. 2851b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch v8::Debug::SetDebugEventListener(DebugEventStep); 2852756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 2853756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick // Create a function for testing stepping of named store. 2854756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick v8::Local<v8::Function> foo = CompileFunction( 2855756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick &env, 2856756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick "function foo() {\n" 2857756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick " var a = {a:1};\n" 2858756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick " for (var i = 0; i < 10; i++) {\n" 2859756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick " a.a = 2\n" 2860756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick " }\n" 2861756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick "}\n", 2862756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick "foo"); 2863756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 2864756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick // Call function without any break points to ensure inlining is in place. 2865756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick foo->Call(env->Global(), 0, NULL); 2866756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 28673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Set up break point and step through the function. 2868756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick SetBreakPoint(foo, 3); 2869756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick step_action = StepNext; 2870756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick break_point_hit_count = 0; 2871756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick foo->Call(env->Global(), 0, NULL); 2872756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 2873756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick // With stepping all expected break locations are hit. 2874756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick CHECK_EQ(expected, break_point_hit_count); 2875756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 2876756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick v8::Debug::SetDebugEventListener(NULL); 2877756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick CheckDebuggerUnloaded(); 2878756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick} 2879756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 2880756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 2881756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick// Test of the stepping mechanism for named load in a loop. 2882b0fe1620dcb4135ac3ab2d66ff93072373911299Ben MurdochTEST(DebugStepNamedStoreLoop) { 28833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DoDebugStepNamedStoreLoop(23); 2884756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick} 2885756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 2886756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 2887a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Test the stepping mechanism with different ICs. 2888a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(DebugStepLinearMixedICs) { 2889a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::HandleScope scope; 2890a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DebugLocalContext env; 2891a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 28927f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Register a debug event listener which steps and counts. 28937f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch v8::Debug::SetDebugEventListener(DebugEventStep); 28947f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 2895a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Create a function for testing stepping. 2896a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Local<v8::Function> foo = CompileFunction(&env, 2897a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "function bar() {};" 2898a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "function foo() {" 2899a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " var x;" 2900a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " var index='name';" 2901a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " var y = {};" 2902a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " a=1;b=2;x=a;y[index]=3;x=y[index];bar();}", "foo"); 2903b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 2904b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Run functions to allow them to get optimized. 2905b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CompileRun("a=0; b=0; bar(); foo();"); 2906b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 2907a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block SetBreakPoint(foo, 0); 2908a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2909a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block step_action = StepIn; 2910a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 2911a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block foo->Call(env->Global(), 0, NULL); 2912a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2913a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // With stepping all break locations are hit. 29147f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch CHECK_EQ(11, break_point_hit_count); 2915a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2916a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetDebugEventListener(NULL); 2917a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CheckDebuggerUnloaded(); 2918a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2919a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Register a debug event listener which just counts. 2920a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount); 2921a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2922a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block SetBreakPoint(foo, 0); 2923a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 2924a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block foo->Call(env->Global(), 0, NULL); 2925a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2926a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Without stepping only active break points are hit. 2927a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1, break_point_hit_count); 2928a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2929a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetDebugEventListener(NULL); 2930a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CheckDebuggerUnloaded(); 2931a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2932a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2933a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 29347f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen MurdochTEST(DebugStepDeclarations) { 29357f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch v8::HandleScope scope; 29367f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch DebugLocalContext env; 29377f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 29387f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Register a debug event listener which steps and counts. 29397f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch v8::Debug::SetDebugEventListener(DebugEventStep); 29407f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 2941b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Create a function for testing stepping. Run it to allow it to get 2942b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // optimized. 29437f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch const char* src = "function foo() { " 29447f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch " var a;" 29457f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch " var b = 1;" 29467f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch " var c = foo;" 29477f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch " var d = Math.floor;" 29487f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch " var e = b + d(1.2);" 2949b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "}" 2950b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "foo()"; 29517f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch v8::Local<v8::Function> foo = CompileFunction(&env, src, "foo"); 2952b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 29537f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch SetBreakPoint(foo, 0); 29547f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 29557f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Stepping through the declarations. 29567f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch step_action = StepIn; 29577f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch break_point_hit_count = 0; 29587f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch foo->Call(env->Global(), 0, NULL); 29597f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch CHECK_EQ(6, break_point_hit_count); 29607f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 29617f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Get rid of the debug event listener. 29627f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch v8::Debug::SetDebugEventListener(NULL); 29637f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch CheckDebuggerUnloaded(); 29647f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 29657f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 29667f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 29677f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen MurdochTEST(DebugStepLocals) { 29687f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch v8::HandleScope scope; 29697f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch DebugLocalContext env; 29707f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 29717f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Register a debug event listener which steps and counts. 29727f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch v8::Debug::SetDebugEventListener(DebugEventStep); 29737f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 2974b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Create a function for testing stepping. Run it to allow it to get 2975b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // optimized. 29767f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch const char* src = "function foo() { " 29777f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch " var a,b;" 29787f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch " a = 1;" 29797f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch " b = a + 2;" 29807f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch " b = 1 + 2 + 3;" 29817f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch " a = Math.floor(b);" 2982b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "}" 2983b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "foo()"; 29847f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch v8::Local<v8::Function> foo = CompileFunction(&env, src, "foo"); 2985b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 29867f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch SetBreakPoint(foo, 0); 29877f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 29887f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Stepping through the declarations. 29897f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch step_action = StepIn; 29907f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch break_point_hit_count = 0; 29917f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch foo->Call(env->Global(), 0, NULL); 29927f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch CHECK_EQ(6, break_point_hit_count); 29937f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 29947f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Get rid of the debug event listener. 29957f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch v8::Debug::SetDebugEventListener(NULL); 29967f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch CheckDebuggerUnloaded(); 29977f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 29987f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 29997f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 3000a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(DebugStepIf) { 3001a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::HandleScope scope; 3002a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DebugLocalContext env; 3003a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3004a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Register a debug event listener which steps and counts. 3005a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetDebugEventListener(DebugEventStep); 3006a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3007b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Create a function for testing stepping. Run it to allow it to get 3008b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // optimized. 3009a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const int argc = 1; 3010a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const char* src = "function foo(x) { " 3011a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " a = 1;" 3012a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " if (x) {" 3013a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " b = 1;" 3014a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " } else {" 3015a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " c = 1;" 3016a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " d = 1;" 3017a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " }" 3018b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "}" 3019b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "a=0; b=0; c=0; d=0; foo()"; 3020a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Local<v8::Function> foo = CompileFunction(&env, src, "foo"); 3021a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block SetBreakPoint(foo, 0); 3022a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3023a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Stepping through the true part. 3024a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block step_action = StepIn; 3025a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 3026a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<v8::Value> argv_true[argc] = { v8::True() }; 3027a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block foo->Call(env->Global(), argc, argv_true); 30287f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch CHECK_EQ(4, break_point_hit_count); 3029a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3030a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Stepping through the false part. 3031a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block step_action = StepIn; 3032a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 3033a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<v8::Value> argv_false[argc] = { v8::False() }; 3034a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block foo->Call(env->Global(), argc, argv_false); 30357f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch CHECK_EQ(5, break_point_hit_count); 3036a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3037a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Get rid of the debug event listener. 3038a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetDebugEventListener(NULL); 3039a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CheckDebuggerUnloaded(); 3040a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 3041a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3042a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3043a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(DebugStepSwitch) { 3044a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::HandleScope scope; 3045a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DebugLocalContext env; 3046a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3047a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Register a debug event listener which steps and counts. 3048a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetDebugEventListener(DebugEventStep); 3049a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3050b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Create a function for testing stepping. Run it to allow it to get 3051b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // optimized. 3052a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const int argc = 1; 3053a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const char* src = "function foo(x) { " 3054a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " a = 1;" 3055a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " switch (x) {" 3056a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " case 1:" 3057a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " b = 1;" 3058a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " case 2:" 3059a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " c = 1;" 3060a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " break;" 3061a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " case 3:" 3062a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " d = 1;" 3063a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " e = 1;" 30647f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch " f = 1;" 3065a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " break;" 3066a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " }" 3067b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "}" 3068b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "a=0; b=0; c=0; d=0; e=0; f=0; foo()"; 3069a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Local<v8::Function> foo = CompileFunction(&env, src, "foo"); 3070a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block SetBreakPoint(foo, 0); 3071a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3072a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // One case with fall-through. 3073a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block step_action = StepIn; 3074a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 3075a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<v8::Value> argv_1[argc] = { v8::Number::New(1) }; 3076a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block foo->Call(env->Global(), argc, argv_1); 30777f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch CHECK_EQ(6, break_point_hit_count); 3078a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3079a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Another case. 3080a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block step_action = StepIn; 3081a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 3082a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<v8::Value> argv_2[argc] = { v8::Number::New(2) }; 3083a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block foo->Call(env->Global(), argc, argv_2); 30847f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch CHECK_EQ(5, break_point_hit_count); 3085a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3086a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Last case. 3087a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block step_action = StepIn; 3088a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 3089a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<v8::Value> argv_3[argc] = { v8::Number::New(3) }; 3090a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block foo->Call(env->Global(), argc, argv_3); 30917f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch CHECK_EQ(7, break_point_hit_count); 30927f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 30937f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Get rid of the debug event listener. 30947f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch v8::Debug::SetDebugEventListener(NULL); 30957f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch CheckDebuggerUnloaded(); 30967f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 30977f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 30987f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 30997f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen MurdochTEST(DebugStepWhile) { 31007f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch v8::HandleScope scope; 31017f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch DebugLocalContext env; 31027f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 31037f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Register a debug event listener which steps and counts. 31047f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch v8::Debug::SetDebugEventListener(DebugEventStep); 31057f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 3106b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Create a function for testing stepping. Run it to allow it to get 3107b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // optimized. 31087f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch const int argc = 1; 31097f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch const char* src = "function foo(x) { " 31107f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch " var a = 0;" 31117f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch " while (a < x) {" 31127f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch " a++;" 31137f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch " }" 3114b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "}" 3115b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "foo()"; 31167f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch v8::Local<v8::Function> foo = CompileFunction(&env, src, "foo"); 31177f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch SetBreakPoint(foo, 8); // "var a = 0;" 31187f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 31197f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Looping 10 times. 31207f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch step_action = StepIn; 31217f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch break_point_hit_count = 0; 31227f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch v8::Handle<v8::Value> argv_10[argc] = { v8::Number::New(10) }; 31237f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch foo->Call(env->Global(), argc, argv_10); 3124b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CHECK_EQ(22, break_point_hit_count); 31257f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 31267f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Looping 100 times. 31277f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch step_action = StepIn; 31287f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch break_point_hit_count = 0; 31297f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch v8::Handle<v8::Value> argv_100[argc] = { v8::Number::New(100) }; 31307f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch foo->Call(env->Global(), argc, argv_100); 3131b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CHECK_EQ(202, break_point_hit_count); 31327f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 31337f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Get rid of the debug event listener. 31347f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch v8::Debug::SetDebugEventListener(NULL); 31357f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch CheckDebuggerUnloaded(); 31367f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 31377f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 31387f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 31397f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen MurdochTEST(DebugStepDoWhile) { 31407f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch v8::HandleScope scope; 31417f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch DebugLocalContext env; 31427f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 31437f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Register a debug event listener which steps and counts. 31447f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch v8::Debug::SetDebugEventListener(DebugEventStep); 31457f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 3146b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Create a function for testing stepping. Run it to allow it to get 3147b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // optimized. 31487f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch const int argc = 1; 31497f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch const char* src = "function foo(x) { " 31507f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch " var a = 0;" 31517f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch " do {" 31527f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch " a++;" 31537f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch " } while (a < x)" 3154b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "}" 3155b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "foo()"; 31567f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch v8::Local<v8::Function> foo = CompileFunction(&env, src, "foo"); 31577f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch SetBreakPoint(foo, 8); // "var a = 0;" 31587f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 31597f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Looping 10 times. 31607f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch step_action = StepIn; 31617f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch break_point_hit_count = 0; 31627f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch v8::Handle<v8::Value> argv_10[argc] = { v8::Number::New(10) }; 31637f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch foo->Call(env->Global(), argc, argv_10); 31647f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch CHECK_EQ(22, break_point_hit_count); 31657f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 31667f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Looping 100 times. 31677f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch step_action = StepIn; 31687f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch break_point_hit_count = 0; 31697f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch v8::Handle<v8::Value> argv_100[argc] = { v8::Number::New(100) }; 31707f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch foo->Call(env->Global(), argc, argv_100); 31717f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch CHECK_EQ(202, break_point_hit_count); 3172a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3173a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Get rid of the debug event listener. 3174a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetDebugEventListener(NULL); 3175a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CheckDebuggerUnloaded(); 3176a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 3177a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3178a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3179a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(DebugStepFor) { 3180a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::HandleScope scope; 3181a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DebugLocalContext env; 3182a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3183a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Register a debug event listener which steps and counts. 3184a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetDebugEventListener(DebugEventStep); 3185a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3186b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Create a function for testing stepping. Run it to allow it to get 3187b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // optimized. 3188a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const int argc = 1; 3189a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const char* src = "function foo(x) { " 3190a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " a = 1;" 3191a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " for (i = 0; i < x; i++) {" 3192a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " b = 1;" 3193a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " }" 3194b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "}" 3195b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "a=0; b=0; i=0; foo()"; 3196a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Local<v8::Function> foo = CompileFunction(&env, src, "foo"); 3197b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 3198a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block SetBreakPoint(foo, 8); // "a = 1;" 3199a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3200a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Looping 10 times. 3201a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block step_action = StepIn; 3202a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 3203a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<v8::Value> argv_10[argc] = { v8::Number::New(10) }; 3204a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block foo->Call(env->Global(), argc, argv_10); 3205a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(23, break_point_hit_count); 3206a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3207a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Looping 100 times. 3208a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block step_action = StepIn; 3209a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 3210a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<v8::Value> argv_100[argc] = { v8::Number::New(100) }; 3211a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block foo->Call(env->Global(), argc, argv_100); 3212a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(203, break_point_hit_count); 3213a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3214a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Get rid of the debug event listener. 3215a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetDebugEventListener(NULL); 3216a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CheckDebuggerUnloaded(); 3217a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 3218a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3219a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 32207f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen MurdochTEST(DebugStepForContinue) { 32217f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch v8::HandleScope scope; 32227f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch DebugLocalContext env; 32237f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 32247f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Register a debug event listener which steps and counts. 32257f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch v8::Debug::SetDebugEventListener(DebugEventStep); 32267f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 3227b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Create a function for testing stepping. Run it to allow it to get 3228b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // optimized. 32297f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch const int argc = 1; 32307f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch const char* src = "function foo(x) { " 32317f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch " var a = 0;" 32327f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch " var b = 0;" 32337f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch " var c = 0;" 32347f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch " for (var i = 0; i < x; i++) {" 32357f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch " a++;" 32367f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch " if (a % 2 == 0) continue;" 32377f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch " b++;" 32387f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch " c++;" 32397f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch " }" 32407f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch " return b;" 3241b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "}" 3242b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "foo()"; 32437f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch v8::Local<v8::Function> foo = CompileFunction(&env, src, "foo"); 32447f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch v8::Handle<v8::Value> result; 32457f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch SetBreakPoint(foo, 8); // "var a = 0;" 32467f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 32477f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Each loop generates 4 or 5 steps depending on whether a is equal. 32487f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 32497f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Looping 10 times. 32507f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch step_action = StepIn; 32517f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch break_point_hit_count = 0; 32527f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch v8::Handle<v8::Value> argv_10[argc] = { v8::Number::New(10) }; 32537f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch result = foo->Call(env->Global(), argc, argv_10); 32547f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch CHECK_EQ(5, result->Int32Value()); 32553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CHECK_EQ(51, break_point_hit_count); 32567f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 32577f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Looping 100 times. 32587f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch step_action = StepIn; 32597f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch break_point_hit_count = 0; 32607f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch v8::Handle<v8::Value> argv_100[argc] = { v8::Number::New(100) }; 32617f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch result = foo->Call(env->Global(), argc, argv_100); 32627f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch CHECK_EQ(50, result->Int32Value()); 32633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CHECK_EQ(456, break_point_hit_count); 32647f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 32657f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Get rid of the debug event listener. 32667f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch v8::Debug::SetDebugEventListener(NULL); 32677f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch CheckDebuggerUnloaded(); 32687f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 32697f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 32707f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 32717f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen MurdochTEST(DebugStepForBreak) { 32727f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch v8::HandleScope scope; 32737f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch DebugLocalContext env; 32747f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 32757f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Register a debug event listener which steps and counts. 32767f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch v8::Debug::SetDebugEventListener(DebugEventStep); 32777f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 3278b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Create a function for testing stepping. Run it to allow it to get 3279b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // optimized. 32807f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch const int argc = 1; 32817f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch const char* src = "function foo(x) { " 32827f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch " var a = 0;" 32837f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch " var b = 0;" 32847f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch " var c = 0;" 32857f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch " for (var i = 0; i < 1000; i++) {" 32867f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch " a++;" 32877f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch " if (a == x) break;" 32887f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch " b++;" 32897f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch " c++;" 32907f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch " }" 32917f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch " return b;" 3292b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "}" 3293b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "foo()"; 32947f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch v8::Local<v8::Function> foo = CompileFunction(&env, src, "foo"); 32957f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch v8::Handle<v8::Value> result; 32967f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch SetBreakPoint(foo, 8); // "var a = 0;" 32977f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 32987f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Each loop generates 5 steps except for the last (when break is executed) 32997f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // which only generates 4. 33007f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 33017f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Looping 10 times. 33027f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch step_action = StepIn; 33037f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch break_point_hit_count = 0; 33047f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch v8::Handle<v8::Value> argv_10[argc] = { v8::Number::New(10) }; 33057f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch result = foo->Call(env->Global(), argc, argv_10); 33067f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch CHECK_EQ(9, result->Int32Value()); 33073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CHECK_EQ(54, break_point_hit_count); 33087f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 33097f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Looping 100 times. 33107f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch step_action = StepIn; 33117f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch break_point_hit_count = 0; 33127f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch v8::Handle<v8::Value> argv_100[argc] = { v8::Number::New(100) }; 33137f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch result = foo->Call(env->Global(), argc, argv_100); 33147f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch CHECK_EQ(99, result->Int32Value()); 33153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CHECK_EQ(504, break_point_hit_count); 33167f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 33177f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Get rid of the debug event listener. 33187f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch v8::Debug::SetDebugEventListener(NULL); 33197f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch CheckDebuggerUnloaded(); 33207f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 33217f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 33227f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 33237f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen MurdochTEST(DebugStepForIn) { 33247f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch v8::HandleScope scope; 33257f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch DebugLocalContext env; 33267f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 33277f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Register a debug event listener which steps and counts. 33287f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch v8::Debug::SetDebugEventListener(DebugEventStep); 33297f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 3330b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Create a function for testing stepping. Run it to allow it to get 3331b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // optimized. 33327f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch v8::Local<v8::Function> foo; 33337f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch const char* src_1 = "function foo() { " 33347f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch " var a = [1, 2];" 33357f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch " for (x in a) {" 33367f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch " b = 0;" 33377f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch " }" 3338b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "}" 3339b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "foo()"; 33407f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch foo = CompileFunction(&env, src_1, "foo"); 33417f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch SetBreakPoint(foo, 0); // "var a = ..." 33427f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 33437f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch step_action = StepIn; 33447f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch break_point_hit_count = 0; 33457f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch foo->Call(env->Global(), 0, NULL); 33467f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch CHECK_EQ(6, break_point_hit_count); 33477f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 3348b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Create a function for testing stepping. Run it to allow it to get 3349b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // optimized. 33507f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch const char* src_2 = "function foo() { " 33517f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch " var a = {a:[1, 2, 3]};" 33527f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch " for (x in a.a) {" 33537f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch " b = 0;" 33547f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch " }" 3355b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "}" 3356b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "foo()"; 33577f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch foo = CompileFunction(&env, src_2, "foo"); 33587f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch SetBreakPoint(foo, 0); // "var a = ..." 33597f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 33607f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch step_action = StepIn; 33617f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch break_point_hit_count = 0; 33627f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch foo->Call(env->Global(), 0, NULL); 33637f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch CHECK_EQ(8, break_point_hit_count); 33647f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 33657f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Get rid of the debug event listener. 33667f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch v8::Debug::SetDebugEventListener(NULL); 33677f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch CheckDebuggerUnloaded(); 33687f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 33697f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 33707f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 33717f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen MurdochTEST(DebugStepWith) { 33727f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch v8::HandleScope scope; 33737f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch DebugLocalContext env; 33747f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 33757f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Register a debug event listener which steps and counts. 33767f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch v8::Debug::SetDebugEventListener(DebugEventStep); 33777f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 3378b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Create a function for testing stepping. Run it to allow it to get 3379b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // optimized. 33807f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch const char* src = "function foo(x) { " 33817f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch " var a = {};" 33827f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch " with (a) {}" 33837f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch " with (b) {}" 3384b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "}" 3385b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "foo()"; 33867f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch env->Global()->Set(v8::String::New("b"), v8::Object::New()); 33877f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch v8::Local<v8::Function> foo = CompileFunction(&env, src, "foo"); 33887f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch v8::Handle<v8::Value> result; 33897f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch SetBreakPoint(foo, 8); // "var a = {};" 33907f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 33917f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch step_action = StepIn; 33927f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch break_point_hit_count = 0; 33937f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch foo->Call(env->Global(), 0, NULL); 33947f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch CHECK_EQ(4, break_point_hit_count); 33957f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 33967f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Get rid of the debug event listener. 33977f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch v8::Debug::SetDebugEventListener(NULL); 33987f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch CheckDebuggerUnloaded(); 33997f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 34007f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 34017f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 34027f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen MurdochTEST(DebugConditional) { 34037f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch v8::HandleScope scope; 34047f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch DebugLocalContext env; 34057f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 34067f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Register a debug event listener which steps and counts. 34077f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch v8::Debug::SetDebugEventListener(DebugEventStep); 34087f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 3409b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Create a function for testing stepping. Run it to allow it to get 3410b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // optimized. 34117f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch const char* src = "function foo(x) { " 34127f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch " var a;" 34137f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch " a = x ? 1 : 2;" 34147f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch " return a;" 3415b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "}" 3416b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "foo()"; 34177f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch v8::Local<v8::Function> foo = CompileFunction(&env, src, "foo"); 34187f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch SetBreakPoint(foo, 0); // "var a;" 34197f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 34207f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch step_action = StepIn; 34217f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch break_point_hit_count = 0; 34227f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch foo->Call(env->Global(), 0, NULL); 34237f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch CHECK_EQ(5, break_point_hit_count); 34247f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 34257f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch step_action = StepIn; 34267f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch break_point_hit_count = 0; 34277f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch const int argc = 1; 34287f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch v8::Handle<v8::Value> argv_true[argc] = { v8::True() }; 34297f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch foo->Call(env->Global(), argc, argv_true); 34307f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch CHECK_EQ(5, break_point_hit_count); 34317f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 34327f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Get rid of the debug event listener. 34337f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch v8::Debug::SetDebugEventListener(NULL); 34347f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch CheckDebuggerUnloaded(); 34357f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 34367f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 34377f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 3438a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(StepInOutSimple) { 3439a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::HandleScope scope; 3440a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DebugLocalContext env; 3441a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3442a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Create a function for checking the function when hitting a break point. 3443a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block frame_function_name = CompileFunction(&env, 3444a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block frame_function_name_source, 3445a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "frame_function_name"); 3446a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3447a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Register a debug event listener which steps and counts. 3448a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetDebugEventListener(DebugEventStepSequence); 3449a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3450b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Create a function for testing stepping. Run it to allow it to get 3451b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // optimized. 3452a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const char* src = "function a() {b();c();}; " 3453a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "function b() {c();}; " 3454b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "function c() {}; " 3455b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "a(); b(); c()"; 3456a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Local<v8::Function> a = CompileFunction(&env, src, "a"); 3457a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block SetBreakPoint(a, 0); 3458a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3459a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Step through invocation of a with step in. 3460a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block step_action = StepIn; 3461a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 3462a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block expected_step_sequence = "abcbaca"; 3463a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block a->Call(env->Global(), 0, NULL); 3464d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block CHECK_EQ(StrLength(expected_step_sequence), 3465d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block break_point_hit_count); 3466a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3467a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Step through invocation of a with step next. 3468a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block step_action = StepNext; 3469a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 3470a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block expected_step_sequence = "aaa"; 3471a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block a->Call(env->Global(), 0, NULL); 3472d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block CHECK_EQ(StrLength(expected_step_sequence), 3473d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block break_point_hit_count); 3474a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3475a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Step through invocation of a with step out. 3476a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block step_action = StepOut; 3477a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 3478a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block expected_step_sequence = "a"; 3479a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block a->Call(env->Global(), 0, NULL); 3480d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block CHECK_EQ(StrLength(expected_step_sequence), 3481d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block break_point_hit_count); 3482a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3483a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Get rid of the debug event listener. 3484a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetDebugEventListener(NULL); 3485a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CheckDebuggerUnloaded(); 3486a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 3487a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3488a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3489a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(StepInOutTree) { 3490a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::HandleScope scope; 3491a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DebugLocalContext env; 3492a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3493a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Create a function for checking the function when hitting a break point. 3494a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block frame_function_name = CompileFunction(&env, 3495a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block frame_function_name_source, 3496a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "frame_function_name"); 3497a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3498a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Register a debug event listener which steps and counts. 3499a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetDebugEventListener(DebugEventStepSequence); 3500a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3501b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Create a function for testing stepping. Run it to allow it to get 3502b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // optimized. 3503a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const char* src = "function a() {b(c(d()),d());c(d());d()}; " 3504a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "function b(x,y) {c();}; " 3505a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "function c(x) {}; " 3506b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "function d() {}; " 3507b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "a(); b(); c(); d()"; 3508a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Local<v8::Function> a = CompileFunction(&env, src, "a"); 3509a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block SetBreakPoint(a, 0); 3510a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3511a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Step through invocation of a with step in. 3512a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block step_action = StepIn; 3513a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 3514a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block expected_step_sequence = "adacadabcbadacada"; 3515a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block a->Call(env->Global(), 0, NULL); 3516d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block CHECK_EQ(StrLength(expected_step_sequence), 3517d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block break_point_hit_count); 3518a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3519a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Step through invocation of a with step next. 3520a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block step_action = StepNext; 3521a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 3522a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block expected_step_sequence = "aaaa"; 3523a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block a->Call(env->Global(), 0, NULL); 3524d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block CHECK_EQ(StrLength(expected_step_sequence), 3525d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block break_point_hit_count); 3526a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3527a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Step through invocation of a with step out. 3528a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block step_action = StepOut; 3529a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 3530a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block expected_step_sequence = "a"; 3531a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block a->Call(env->Global(), 0, NULL); 3532d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block CHECK_EQ(StrLength(expected_step_sequence), 3533d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block break_point_hit_count); 3534a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3535a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Get rid of the debug event listener. 3536a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetDebugEventListener(NULL); 3537a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CheckDebuggerUnloaded(true); 3538a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 3539a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3540a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3541a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(StepInOutBranch) { 3542a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::HandleScope scope; 3543a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DebugLocalContext env; 3544a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3545a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Create a function for checking the function when hitting a break point. 3546a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block frame_function_name = CompileFunction(&env, 3547a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block frame_function_name_source, 3548a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "frame_function_name"); 3549a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3550a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Register a debug event listener which steps and counts. 3551a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetDebugEventListener(DebugEventStepSequence); 3552a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3553b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Create a function for testing stepping. Run it to allow it to get 3554b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // optimized. 3555a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const char* src = "function a() {b(false);c();}; " 3556a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "function b(x) {if(x){c();};}; " 3557b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "function c() {}; " 3558b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "a(); b(); c()"; 3559a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Local<v8::Function> a = CompileFunction(&env, src, "a"); 3560a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block SetBreakPoint(a, 0); 3561a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3562a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Step through invocation of a. 3563a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block step_action = StepIn; 3564a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 35657f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch expected_step_sequence = "abbaca"; 3566a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block a->Call(env->Global(), 0, NULL); 3567d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block CHECK_EQ(StrLength(expected_step_sequence), 3568d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block break_point_hit_count); 3569a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3570a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Get rid of the debug event listener. 3571a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetDebugEventListener(NULL); 3572a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CheckDebuggerUnloaded(); 3573a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 3574a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3575a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3576a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Test that step in does not step into native functions. 3577a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(DebugStepNatives) { 3578a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::HandleScope scope; 3579a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DebugLocalContext env; 3580a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3581a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Create a function for testing stepping. 3582a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Local<v8::Function> foo = CompileFunction( 3583a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block &env, 3584a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "function foo(){debugger;Math.sin(1);}", 3585a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "foo"); 3586a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3587a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Register a debug event listener which steps and counts. 3588a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetDebugEventListener(DebugEventStep); 3589a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3590a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block step_action = StepIn; 3591a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 3592a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block foo->Call(env->Global(), 0, NULL); 3593a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3594a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // With stepping all break locations are hit. 3595a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(3, break_point_hit_count); 3596a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3597a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetDebugEventListener(NULL); 3598a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CheckDebuggerUnloaded(); 3599a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3600a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Register a debug event listener which just counts. 3601a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount); 3602a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3603a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 3604a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block foo->Call(env->Global(), 0, NULL); 3605a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3606a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Without stepping only active break points are hit. 3607a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1, break_point_hit_count); 3608a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3609a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetDebugEventListener(NULL); 3610a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CheckDebuggerUnloaded(); 3611a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 3612a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3613a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3614a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Test that step in works with function.apply. 3615a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(DebugStepFunctionApply) { 3616a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::HandleScope scope; 3617a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DebugLocalContext env; 3618a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3619a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Create a function for testing stepping. 3620a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Local<v8::Function> foo = CompileFunction( 3621a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block &env, 3622a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "function bar(x, y, z) { if (x == 1) { a = y; b = z; } }" 3623a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "function foo(){ debugger; bar.apply(this, [1,2,3]); }", 3624a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "foo"); 3625a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3626a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Register a debug event listener which steps and counts. 3627a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetDebugEventListener(DebugEventStep); 3628a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3629a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block step_action = StepIn; 3630a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 3631a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block foo->Call(env->Global(), 0, NULL); 3632a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3633a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // With stepping all break locations are hit. 36347f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch CHECK_EQ(7, break_point_hit_count); 3635a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3636a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetDebugEventListener(NULL); 3637a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CheckDebuggerUnloaded(); 3638a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3639a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Register a debug event listener which just counts. 3640a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount); 3641a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3642a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 3643a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block foo->Call(env->Global(), 0, NULL); 3644a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3645a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Without stepping only the debugger statement is hit. 3646a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1, break_point_hit_count); 3647a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3648a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetDebugEventListener(NULL); 3649a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CheckDebuggerUnloaded(); 3650a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 3651a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3652a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3653a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Test that step in works with function.call. 3654a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(DebugStepFunctionCall) { 3655a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::HandleScope scope; 3656a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DebugLocalContext env; 3657a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3658a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Create a function for testing stepping. 3659a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Local<v8::Function> foo = CompileFunction( 3660a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block &env, 3661a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "function bar(x, y, z) { if (x == 1) { a = y; b = z; } }" 3662a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "function foo(a){ debugger;" 3663a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " if (a) {" 3664a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " bar.call(this, 1, 2, 3);" 3665a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " } else {" 3666a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " bar.call(this, 0);" 3667a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " }" 3668a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "}", 3669a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "foo"); 3670a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3671a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Register a debug event listener which steps and counts. 3672a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetDebugEventListener(DebugEventStep); 3673a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block step_action = StepIn; 3674a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3675a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Check stepping where the if condition in bar is false. 3676a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 3677a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block foo->Call(env->Global(), 0, NULL); 36787f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch CHECK_EQ(6, break_point_hit_count); 3679a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3680a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Check stepping where the if condition in bar is true. 3681a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 3682a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const int argc = 1; 3683a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<v8::Value> argv[argc] = { v8::True() }; 3684a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block foo->Call(env->Global(), argc, argv); 36857f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch CHECK_EQ(8, break_point_hit_count); 3686a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3687a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetDebugEventListener(NULL); 3688a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CheckDebuggerUnloaded(); 3689a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3690a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Register a debug event listener which just counts. 3691a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount); 3692a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3693a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 3694a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block foo->Call(env->Global(), 0, NULL); 3695a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3696a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Without stepping only the debugger statement is hit. 3697a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1, break_point_hit_count); 3698a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3699a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetDebugEventListener(NULL); 3700a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CheckDebuggerUnloaded(); 3701a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 3702a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3703a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3704d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block// Tests that breakpoint will be hit if it's set in script. 3705d0582a6c46733687d045e4188a1bcd0123c758a1Steve BlockTEST(PauseInScript) { 3706d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block v8::HandleScope scope; 3707d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block DebugLocalContext env; 3708d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block env.ExposeDebug(); 3709d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 3710d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // Register a debug event listener which counts. 3711d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block v8::Debug::SetDebugEventListener(DebugEventCounter); 3712d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 3713d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // Create a script that returns a function. 3714d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block const char* src = "(function (evt) {})"; 3715d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block const char* script_name = "StepInHandlerTest"; 3716d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 3717d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // Set breakpoint in the script. 3718d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block SetScriptBreakPointByNameFromJS(script_name, 0, -1); 3719d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block break_point_hit_count = 0; 3720d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 3721d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block v8::ScriptOrigin origin(v8::String::New(script_name), v8::Integer::New(0)); 3722d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block v8::Handle<v8::Script> script = v8::Script::Compile(v8::String::New(src), 3723d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block &origin); 3724d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block v8::Local<v8::Value> r = script->Run(); 3725d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 3726d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block CHECK(r->IsFunction()); 3727d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block CHECK_EQ(1, break_point_hit_count); 3728d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 3729d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // Get rid of the debug event listener. 3730d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block v8::Debug::SetDebugEventListener(NULL); 3731d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block CheckDebuggerUnloaded(); 3732d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block} 3733d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 3734d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 3735a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Test break on exceptions. For each exception break combination the number 3736a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// of debug event exception callbacks and message callbacks are collected. The 3737a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// number of debug event exception callbacks are used to check that the 3738a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// debugger is called correctly and the number of message callbacks is used to 3739a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// check that uncaught exceptions are still returned even if there is a break 3740a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// for them. 3741a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(BreakOnException) { 3742a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::HandleScope scope; 3743a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DebugLocalContext env; 3744a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block env.ExposeDebug(); 3745a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 374644f0eee88ff00398ff7f715fab053374d808c90dSteve Block v8::internal::Isolate::Current()->TraceException(false); 3747a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3748a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Create functions for testing break on exception. 37493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CompileFunction(&env, "function throws(){throw 1;}", "throws"); 3750a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Local<v8::Function> caught = 3751a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CompileFunction(&env, 3752a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "function caught(){try {throws();} catch(e) {};}", 3753a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "caught"); 3754a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Local<v8::Function> notCaught = 3755a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CompileFunction(&env, "function notCaught(){throws();}", "notCaught"); 3756a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3757a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::V8::AddMessageListener(MessageCallbackCount); 3758a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetDebugEventListener(DebugEventCounter); 3759a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3760086aeeaae12517475c22695a200be45495516549Ben Murdoch // Initial state should be no break on exceptions. 3761a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DebugEventCounterClear(); 3762a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block MessageCallbackCountClear(); 3763a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block caught->Call(env->Global(), 0, NULL); 3764a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(0, exception_hit_count); 3765a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(0, uncaught_exception_hit_count); 3766a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(0, message_callback_count); 3767a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block notCaught->Call(env->Global(), 0, NULL); 3768086aeeaae12517475c22695a200be45495516549Ben Murdoch CHECK_EQ(0, exception_hit_count); 3769086aeeaae12517475c22695a200be45495516549Ben Murdoch CHECK_EQ(0, uncaught_exception_hit_count); 3770a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1, message_callback_count); 3771a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3772a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // No break on exception 3773a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DebugEventCounterClear(); 3774a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block MessageCallbackCountClear(); 3775a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ChangeBreakOnException(false, false); 3776a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block caught->Call(env->Global(), 0, NULL); 3777a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(0, exception_hit_count); 3778a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(0, uncaught_exception_hit_count); 3779a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(0, message_callback_count); 3780a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block notCaught->Call(env->Global(), 0, NULL); 3781a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(0, exception_hit_count); 3782a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(0, uncaught_exception_hit_count); 3783a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1, message_callback_count); 3784a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3785a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Break on uncaught exception 3786a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DebugEventCounterClear(); 3787a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block MessageCallbackCountClear(); 3788a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ChangeBreakOnException(false, true); 3789a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block caught->Call(env->Global(), 0, NULL); 3790a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(0, exception_hit_count); 3791a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(0, uncaught_exception_hit_count); 3792a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(0, message_callback_count); 3793a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block notCaught->Call(env->Global(), 0, NULL); 3794a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1, exception_hit_count); 3795a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1, uncaught_exception_hit_count); 3796a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1, message_callback_count); 3797a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3798a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Break on exception and uncaught exception 3799a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DebugEventCounterClear(); 3800a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block MessageCallbackCountClear(); 3801a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ChangeBreakOnException(true, true); 3802a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block caught->Call(env->Global(), 0, NULL); 3803a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1, exception_hit_count); 3804a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(0, uncaught_exception_hit_count); 3805a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(0, message_callback_count); 3806a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block notCaught->Call(env->Global(), 0, NULL); 3807a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(2, exception_hit_count); 3808a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1, uncaught_exception_hit_count); 3809a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1, message_callback_count); 3810a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3811a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Break on exception 3812a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DebugEventCounterClear(); 3813a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block MessageCallbackCountClear(); 3814a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ChangeBreakOnException(true, false); 3815a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block caught->Call(env->Global(), 0, NULL); 3816a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1, exception_hit_count); 3817a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(0, uncaught_exception_hit_count); 3818a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(0, message_callback_count); 3819a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block notCaught->Call(env->Global(), 0, NULL); 3820a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(2, exception_hit_count); 3821a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1, uncaught_exception_hit_count); 3822a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1, message_callback_count); 3823a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3824a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // No break on exception using JavaScript 3825a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DebugEventCounterClear(); 3826a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block MessageCallbackCountClear(); 3827a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ChangeBreakOnExceptionFromJS(false, false); 3828a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block caught->Call(env->Global(), 0, NULL); 3829a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(0, exception_hit_count); 3830a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(0, uncaught_exception_hit_count); 3831a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(0, message_callback_count); 3832a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block notCaught->Call(env->Global(), 0, NULL); 3833a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(0, exception_hit_count); 3834a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(0, uncaught_exception_hit_count); 3835a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1, message_callback_count); 3836a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3837a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Break on uncaught exception using JavaScript 3838a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DebugEventCounterClear(); 3839a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block MessageCallbackCountClear(); 3840a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ChangeBreakOnExceptionFromJS(false, true); 3841a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block caught->Call(env->Global(), 0, NULL); 3842a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(0, exception_hit_count); 3843a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(0, uncaught_exception_hit_count); 3844a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(0, message_callback_count); 3845a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block notCaught->Call(env->Global(), 0, NULL); 3846a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1, exception_hit_count); 3847a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1, uncaught_exception_hit_count); 3848a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1, message_callback_count); 3849a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3850a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Break on exception and uncaught exception using JavaScript 3851a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DebugEventCounterClear(); 3852a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block MessageCallbackCountClear(); 3853a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ChangeBreakOnExceptionFromJS(true, true); 3854a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block caught->Call(env->Global(), 0, NULL); 3855a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1, exception_hit_count); 3856a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(0, message_callback_count); 3857a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(0, uncaught_exception_hit_count); 3858a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block notCaught->Call(env->Global(), 0, NULL); 3859a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(2, exception_hit_count); 3860a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1, uncaught_exception_hit_count); 3861a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1, message_callback_count); 3862a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3863a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Break on exception using JavaScript 3864a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DebugEventCounterClear(); 3865a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block MessageCallbackCountClear(); 3866a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ChangeBreakOnExceptionFromJS(true, false); 3867a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block caught->Call(env->Global(), 0, NULL); 3868a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1, exception_hit_count); 3869a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(0, uncaught_exception_hit_count); 3870a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(0, message_callback_count); 3871a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block notCaught->Call(env->Global(), 0, NULL); 3872a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(2, exception_hit_count); 3873a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1, uncaught_exception_hit_count); 3874a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1, message_callback_count); 3875a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3876a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetDebugEventListener(NULL); 3877a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CheckDebuggerUnloaded(); 3878a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::V8::RemoveMessageListeners(MessageCallbackCount); 3879a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 3880a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3881a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3882a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Test break on exception from compiler errors. When compiling using 3883a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// v8::Script::Compile there is no JavaScript stack whereas when compiling using 3884a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// eval there are JavaScript frames. 3885a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(BreakOnCompileException) { 3886a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::HandleScope scope; 3887a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DebugLocalContext env; 3888a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3889086aeeaae12517475c22695a200be45495516549Ben Murdoch // For this test, we want to break on uncaught exceptions: 3890086aeeaae12517475c22695a200be45495516549Ben Murdoch ChangeBreakOnException(false, true); 3891086aeeaae12517475c22695a200be45495516549Ben Murdoch 389244f0eee88ff00398ff7f715fab053374d808c90dSteve Block v8::internal::Isolate::Current()->TraceException(false); 3893a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3894a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Create a function for checking the function when hitting a break point. 3895a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block frame_count = CompileFunction(&env, frame_count_source, "frame_count"); 3896a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3897a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::V8::AddMessageListener(MessageCallbackCount); 3898a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetDebugEventListener(DebugEventCounter); 3899a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3900a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DebugEventCounterClear(); 3901a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block MessageCallbackCountClear(); 3902a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3903a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Check initial state. 3904a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(0, exception_hit_count); 3905a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(0, uncaught_exception_hit_count); 3906a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(0, message_callback_count); 3907a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(-1, last_js_stack_height); 3908a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3909a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Throws SyntaxError: Unexpected end of input 3910a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Script::Compile(v8::String::New("+++")); 3911a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1, exception_hit_count); 3912a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1, uncaught_exception_hit_count); 3913a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1, message_callback_count); 3914a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(0, last_js_stack_height); // No JavaScript stack. 3915a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3916a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Throws SyntaxError: Unexpected identifier 3917a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Script::Compile(v8::String::New("x x")); 3918a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(2, exception_hit_count); 3919a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(2, uncaught_exception_hit_count); 3920a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(2, message_callback_count); 3921a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(0, last_js_stack_height); // No JavaScript stack. 3922a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3923a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Throws SyntaxError: Unexpected end of input 3924a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Script::Compile(v8::String::New("eval('+++')"))->Run(); 3925a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(3, exception_hit_count); 3926a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(3, uncaught_exception_hit_count); 3927a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(3, message_callback_count); 3928a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1, last_js_stack_height); 3929a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3930a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Throws SyntaxError: Unexpected identifier 3931a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Script::Compile(v8::String::New("eval('x x')"))->Run(); 3932a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(4, exception_hit_count); 3933a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(4, uncaught_exception_hit_count); 3934a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(4, message_callback_count); 3935a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1, last_js_stack_height); 3936a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 3937a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3938a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3939a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(StepWithException) { 3940a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::HandleScope scope; 3941a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DebugLocalContext env; 3942a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3943086aeeaae12517475c22695a200be45495516549Ben Murdoch // For this test, we want to break on uncaught exceptions: 3944086aeeaae12517475c22695a200be45495516549Ben Murdoch ChangeBreakOnException(false, true); 3945086aeeaae12517475c22695a200be45495516549Ben Murdoch 3946a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Create a function for checking the function when hitting a break point. 3947a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block frame_function_name = CompileFunction(&env, 3948a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block frame_function_name_source, 3949a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "frame_function_name"); 3950a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3951a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Register a debug event listener which steps and counts. 3952a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetDebugEventListener(DebugEventStepSequence); 3953a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3954a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Create functions for testing stepping. 3955a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const char* src = "function a() { n(); }; " 3956a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "function b() { c(); }; " 3957a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "function c() { n(); }; " 3958a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "function d() { x = 1; try { e(); } catch(x) { x = 2; } }; " 3959a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "function e() { n(); }; " 3960a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "function f() { x = 1; try { g(); } catch(x) { x = 2; } }; " 3961a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "function g() { h(); }; " 3962a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "function h() { x = 1; throw 1; }; "; 3963a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3964a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Step through invocation of a. 3965a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Local<v8::Function> a = CompileFunction(&env, src, "a"); 3966a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block SetBreakPoint(a, 0); 3967a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block step_action = StepIn; 3968a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 3969a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block expected_step_sequence = "aa"; 3970a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block a->Call(env->Global(), 0, NULL); 3971d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block CHECK_EQ(StrLength(expected_step_sequence), 3972d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block break_point_hit_count); 3973a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3974a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Step through invocation of b + c. 3975a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Local<v8::Function> b = CompileFunction(&env, src, "b"); 3976a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block SetBreakPoint(b, 0); 3977a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block step_action = StepIn; 3978a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 3979a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block expected_step_sequence = "bcc"; 3980a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block b->Call(env->Global(), 0, NULL); 3981d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block CHECK_EQ(StrLength(expected_step_sequence), 3982d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block break_point_hit_count); 3983a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Step through invocation of d + e. 3984a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Local<v8::Function> d = CompileFunction(&env, src, "d"); 3985a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block SetBreakPoint(d, 0); 3986a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ChangeBreakOnException(false, true); 3987a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block step_action = StepIn; 3988a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 39897f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch expected_step_sequence = "ddedd"; 3990a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block d->Call(env->Global(), 0, NULL); 3991d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block CHECK_EQ(StrLength(expected_step_sequence), 3992d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block break_point_hit_count); 3993a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3994a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Step through invocation of d + e now with break on caught exceptions. 3995a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ChangeBreakOnException(true, true); 3996a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block step_action = StepIn; 3997a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 39987f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch expected_step_sequence = "ddeedd"; 3999a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block d->Call(env->Global(), 0, NULL); 4000d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block CHECK_EQ(StrLength(expected_step_sequence), 4001d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block break_point_hit_count); 4002a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4003a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Step through invocation of f + g + h. 4004a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Local<v8::Function> f = CompileFunction(&env, src, "f"); 4005a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block SetBreakPoint(f, 0); 4006a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ChangeBreakOnException(false, true); 4007a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block step_action = StepIn; 4008a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 40097f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch expected_step_sequence = "ffghhff"; 4010a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block f->Call(env->Global(), 0, NULL); 4011d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block CHECK_EQ(StrLength(expected_step_sequence), 4012d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block break_point_hit_count); 4013a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4014a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Step through invocation of f + g + h now with break on caught exceptions. 4015a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ChangeBreakOnException(true, true); 4016a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block step_action = StepIn; 4017a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 40187f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch expected_step_sequence = "ffghhhff"; 4019a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block f->Call(env->Global(), 0, NULL); 4020d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block CHECK_EQ(StrLength(expected_step_sequence), 4021d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block break_point_hit_count); 4022a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4023a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Get rid of the debug event listener. 4024a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetDebugEventListener(NULL); 4025a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CheckDebuggerUnloaded(); 4026a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 4027a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4028a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4029a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(DebugBreak) { 4030a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::HandleScope scope; 4031a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DebugLocalContext env; 4032a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4033a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // This test should be run with option --verify-heap. As --verify-heap is 4034a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // only available in debug mode only check for it in that case. 4035a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef DEBUG 4036a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(v8::internal::FLAG_verify_heap); 4037a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 4038a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4039a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Register a debug event listener which sets the break flag and counts. 4040a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetDebugEventListener(DebugEventBreak); 4041a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4042a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Create a function for testing stepping. 4043a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const char* src = "function f0() {}" 4044a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "function f1(x1) {}" 4045a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "function f2(x1,x2) {}" 4046a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "function f3(x1,x2,x3) {}"; 4047a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Local<v8::Function> f0 = CompileFunction(&env, src, "f0"); 4048a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Local<v8::Function> f1 = CompileFunction(&env, src, "f1"); 4049a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Local<v8::Function> f2 = CompileFunction(&env, src, "f2"); 4050a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Local<v8::Function> f3 = CompileFunction(&env, src, "f3"); 4051a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4052a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Call the function to make sure it is compiled. 4053a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<v8::Value> argv[] = { v8::Number::New(1), 4054a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Number::New(1), 4055a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Number::New(1), 4056a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Number::New(1) }; 4057a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4058a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Call all functions to make sure that they are compiled. 4059a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block f0->Call(env->Global(), 0, NULL); 4060a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block f1->Call(env->Global(), 0, NULL); 4061a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block f2->Call(env->Global(), 0, NULL); 4062a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block f3->Call(env->Global(), 0, NULL); 4063a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4064a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Set the debug break flag. 4065a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::DebugBreak(); 4066a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4067a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Call all functions with different argument count. 4068a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 4069a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (unsigned int i = 0; i < ARRAY_SIZE(argv); i++) { 4070a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block f0->Call(env->Global(), i, argv); 4071a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block f1->Call(env->Global(), i, argv); 4072a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block f2->Call(env->Global(), i, argv); 4073a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block f3->Call(env->Global(), i, argv); 4074a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 4075a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4076a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // One break for each function called. 4077a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(4 * ARRAY_SIZE(argv), break_point_hit_count); 4078a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4079a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Get rid of the debug event listener. 4080a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetDebugEventListener(NULL); 4081a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CheckDebuggerUnloaded(); 4082a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 4083a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4084a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4085a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Test to ensure that JavaScript code keeps running while the debug break 4086a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// through the stack limit flag is set but breaks are disabled. 4087a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(DisableBreak) { 4088a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::HandleScope scope; 4089a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DebugLocalContext env; 4090a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4091a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Register a debug event listener which sets the break flag and counts. 4092a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetDebugEventListener(DebugEventCounter); 4093a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4094a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Create a function for testing stepping. 4095a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const char* src = "function f() {g()};function g(){i=0; while(i<10){i++}}"; 4096a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Local<v8::Function> f = CompileFunction(&env, src, "f"); 4097a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4098a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Set the debug break flag. 4099a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::DebugBreak(); 4100a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4101a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Call all functions with different argument count. 4102a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 4103a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block f->Call(env->Global(), 0, NULL); 4104a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1, break_point_hit_count); 4105a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4106a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block { 4107a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::DebugBreak(); 4108a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::internal::DisableBreak disable_break(true); 4109a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block f->Call(env->Global(), 0, NULL); 4110a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1, break_point_hit_count); 4111a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 4112a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4113a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block f->Call(env->Global(), 0, NULL); 4114a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(2, break_point_hit_count); 4115a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4116a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Get rid of the debug event listener. 4117a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetDebugEventListener(NULL); 4118a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CheckDebuggerUnloaded(); 4119a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 4120a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4121e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarkestatic const char* kSimpleExtensionSource = 4122e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke "(function Foo() {" 4123e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke " return 4;" 4124e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke "})() "; 4125e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 4126e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke// http://crbug.com/28933 4127e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke// Test that debug break is disabled when bootstrapper is active. 4128e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon ClarkeTEST(NoBreakWhenBootstrapping) { 4129e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke v8::HandleScope scope; 4130e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 4131e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // Register a debug event listener which sets the break flag and counts. 4132e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke v8::Debug::SetDebugEventListener(DebugEventCounter); 4133e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 4134e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // Set the debug break flag. 4135e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke v8::Debug::DebugBreak(); 4136e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke break_point_hit_count = 0; 4137e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke { 4138e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // Create a context with an extension to make sure that some JavaScript 4139e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // code is executed during bootstrapping. 4140e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke v8::RegisterExtension(new v8::Extension("simpletest", 4141e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke kSimpleExtensionSource)); 4142e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke const char* extension_names[] = { "simpletest" }; 4143e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke v8::ExtensionConfiguration extensions(1, extension_names); 4144e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke v8::Persistent<v8::Context> context = v8::Context::New(&extensions); 4145e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke context.Dispose(); 4146e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke } 4147e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // Check that no DebugBreak events occured during the context creation. 4148e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke CHECK_EQ(0, break_point_hit_count); 4149e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 4150e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // Get rid of the debug event listener. 4151e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke v8::Debug::SetDebugEventListener(NULL); 4152e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke CheckDebuggerUnloaded(); 4153e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke} 4154a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4155a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic v8::Handle<v8::Array> NamedEnum(const v8::AccessorInfo&) { 4156a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<v8::Array> result = v8::Array::New(3); 4157a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block result->Set(v8::Integer::New(0), v8::String::New("a")); 4158a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block result->Set(v8::Integer::New(1), v8::String::New("b")); 4159a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block result->Set(v8::Integer::New(2), v8::String::New("c")); 4160a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return result; 4161a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 4162a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4163a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4164a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic v8::Handle<v8::Array> IndexedEnum(const v8::AccessorInfo&) { 4165a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<v8::Array> result = v8::Array::New(2); 4166a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block result->Set(v8::Integer::New(0), v8::Number::New(1)); 4167a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block result->Set(v8::Integer::New(1), v8::Number::New(10)); 4168a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return result; 4169a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 4170a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4171a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4172a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic v8::Handle<v8::Value> NamedGetter(v8::Local<v8::String> name, 4173a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const v8::AccessorInfo& info) { 4174a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::String::AsciiValue n(name); 4175a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (strcmp(*n, "a") == 0) { 4176a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return v8::String::New("AA"); 4177a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else if (strcmp(*n, "b") == 0) { 4178a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return v8::String::New("BB"); 4179a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else if (strcmp(*n, "c") == 0) { 4180a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return v8::String::New("CC"); 4181a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 4182a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return v8::Undefined(); 4183a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 4184a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4185a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return name; 4186a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 4187a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4188a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4189a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic v8::Handle<v8::Value> IndexedGetter(uint32_t index, 4190a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const v8::AccessorInfo& info) { 4191a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return v8::Number::New(index + 1); 4192a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 4193a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4194a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4195a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(InterceptorPropertyMirror) { 4196a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Create a V8 environment with debug access. 4197a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::HandleScope scope; 4198a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DebugLocalContext env; 4199a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block env.ExposeDebug(); 4200a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4201a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Create object with named interceptor. 4202a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<v8::ObjectTemplate> named = v8::ObjectTemplate::New(); 4203a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block named->SetNamedPropertyHandler(NamedGetter, NULL, NULL, NULL, NamedEnum); 4204a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block env->Global()->Set(v8::String::New("intercepted_named"), 4205a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block named->NewInstance()); 4206a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4207a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Create object with indexed interceptor. 4208a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<v8::ObjectTemplate> indexed = v8::ObjectTemplate::New(); 4209a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block indexed->SetIndexedPropertyHandler(IndexedGetter, 4210a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block NULL, 4211a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block NULL, 4212a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block NULL, 4213a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block IndexedEnum); 4214a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block env->Global()->Set(v8::String::New("intercepted_indexed"), 4215a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block indexed->NewInstance()); 4216a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4217a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Create object with both named and indexed interceptor. 4218a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<v8::ObjectTemplate> both = v8::ObjectTemplate::New(); 4219a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block both->SetNamedPropertyHandler(NamedGetter, NULL, NULL, NULL, NamedEnum); 4220a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block both->SetIndexedPropertyHandler(IndexedGetter, NULL, NULL, NULL, IndexedEnum); 4221a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block env->Global()->Set(v8::String::New("intercepted_both"), both->NewInstance()); 4222a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4223a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Get mirrors for the three objects with interceptor. 4224a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CompileRun( 42253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch "var named_mirror = debug.MakeMirror(intercepted_named);" 42263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch "var indexed_mirror = debug.MakeMirror(intercepted_indexed);" 42273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch "var both_mirror = debug.MakeMirror(intercepted_both)"); 4228a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(CompileRun( 4229a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "named_mirror instanceof debug.ObjectMirror")->BooleanValue()); 4230a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(CompileRun( 4231a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "indexed_mirror instanceof debug.ObjectMirror")->BooleanValue()); 4232a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(CompileRun( 4233a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "both_mirror instanceof debug.ObjectMirror")->BooleanValue()); 4234a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4235a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Get the property names from the interceptors 4236a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CompileRun( 4237a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "named_names = named_mirror.propertyNames();" 4238a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "indexed_names = indexed_mirror.propertyNames();" 4239a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "both_names = both_mirror.propertyNames()"); 4240a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(3, CompileRun("named_names.length")->Int32Value()); 4241a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(2, CompileRun("indexed_names.length")->Int32Value()); 4242a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(5, CompileRun("both_names.length")->Int32Value()); 4243a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4244a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Check the expected number of properties. 4245a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const char* source; 4246a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block source = "named_mirror.properties().length"; 4247a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(3, CompileRun(source)->Int32Value()); 4248a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4249a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block source = "indexed_mirror.properties().length"; 4250a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(2, CompileRun(source)->Int32Value()); 4251a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4252a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block source = "both_mirror.properties().length"; 4253a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(5, CompileRun(source)->Int32Value()); 4254a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4255a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // 1 is PropertyKind.Named; 4256a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block source = "both_mirror.properties(1).length"; 4257a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(3, CompileRun(source)->Int32Value()); 4258a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4259a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // 2 is PropertyKind.Indexed; 4260a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block source = "both_mirror.properties(2).length"; 4261a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(2, CompileRun(source)->Int32Value()); 4262a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4263a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // 3 is PropertyKind.Named | PropertyKind.Indexed; 4264a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block source = "both_mirror.properties(3).length"; 4265a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(5, CompileRun(source)->Int32Value()); 4266a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4267a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Get the interceptor properties for the object with only named interceptor. 42683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CompileRun("var named_values = named_mirror.properties()"); 4269a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4270a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Check that the properties are interceptor properties. 4271a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (int i = 0; i < 3; i++) { 4272a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EmbeddedVector<char, SMALL_STRING_BUFFER_SIZE> buffer; 4273a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block OS::SNPrintF(buffer, 4274a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "named_values[%d] instanceof debug.PropertyMirror", i); 4275a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(CompileRun(buffer.start())->BooleanValue()); 4276a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4277257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // 5 is PropertyType.Interceptor 4278a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block OS::SNPrintF(buffer, "named_values[%d].propertyType()", i); 4279257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch CHECK_EQ(5, CompileRun(buffer.start())->Int32Value()); 4280a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4281a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block OS::SNPrintF(buffer, "named_values[%d].isNative()", i); 4282a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(CompileRun(buffer.start())->BooleanValue()); 4283a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 4284a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4285a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Get the interceptor properties for the object with only indexed 4286a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // interceptor. 42873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CompileRun("var indexed_values = indexed_mirror.properties()"); 4288a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4289a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Check that the properties are interceptor properties. 4290a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (int i = 0; i < 2; i++) { 4291a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EmbeddedVector<char, SMALL_STRING_BUFFER_SIZE> buffer; 4292a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block OS::SNPrintF(buffer, 4293a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "indexed_values[%d] instanceof debug.PropertyMirror", i); 4294a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(CompileRun(buffer.start())->BooleanValue()); 4295a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 4296a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4297a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Get the interceptor properties for the object with both types of 4298a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // interceptors. 42993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CompileRun("var both_values = both_mirror.properties()"); 4300a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4301a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Check that the properties are interceptor properties. 4302a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (int i = 0; i < 5; i++) { 4303a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EmbeddedVector<char, SMALL_STRING_BUFFER_SIZE> buffer; 4304a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block OS::SNPrintF(buffer, "both_values[%d] instanceof debug.PropertyMirror", i); 4305a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(CompileRun(buffer.start())->BooleanValue()); 4306a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 4307a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4308a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Check the property names. 4309a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block source = "both_values[0].name() == 'a'"; 4310a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(CompileRun(source)->BooleanValue()); 4311a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4312a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block source = "both_values[1].name() == 'b'"; 4313a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(CompileRun(source)->BooleanValue()); 4314a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4315a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block source = "both_values[2].name() == 'c'"; 4316a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(CompileRun(source)->BooleanValue()); 4317a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4318a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block source = "both_values[3].name() == 1"; 4319a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(CompileRun(source)->BooleanValue()); 4320a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4321a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block source = "both_values[4].name() == 10"; 4322a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(CompileRun(source)->BooleanValue()); 4323a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 4324a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4325a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4326a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(HiddenPrototypePropertyMirror) { 4327a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Create a V8 environment with debug access. 4328a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::HandleScope scope; 4329a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DebugLocalContext env; 4330a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block env.ExposeDebug(); 4331a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4332a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<v8::FunctionTemplate> t0 = v8::FunctionTemplate::New(); 4333a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block t0->InstanceTemplate()->Set(v8::String::New("x"), v8::Number::New(0)); 4334a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<v8::FunctionTemplate> t1 = v8::FunctionTemplate::New(); 4335a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block t1->SetHiddenPrototype(true); 4336a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block t1->InstanceTemplate()->Set(v8::String::New("y"), v8::Number::New(1)); 4337a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<v8::FunctionTemplate> t2 = v8::FunctionTemplate::New(); 4338a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block t2->SetHiddenPrototype(true); 4339a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block t2->InstanceTemplate()->Set(v8::String::New("z"), v8::Number::New(2)); 4340a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<v8::FunctionTemplate> t3 = v8::FunctionTemplate::New(); 4341a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block t3->InstanceTemplate()->Set(v8::String::New("u"), v8::Number::New(3)); 4342a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4343a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Create object and set them on the global object. 4344a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<v8::Object> o0 = t0->GetFunction()->NewInstance(); 4345a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block env->Global()->Set(v8::String::New("o0"), o0); 4346a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<v8::Object> o1 = t1->GetFunction()->NewInstance(); 4347a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block env->Global()->Set(v8::String::New("o1"), o1); 4348a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<v8::Object> o2 = t2->GetFunction()->NewInstance(); 4349a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block env->Global()->Set(v8::String::New("o2"), o2); 4350a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<v8::Object> o3 = t3->GetFunction()->NewInstance(); 4351a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block env->Global()->Set(v8::String::New("o3"), o3); 4352a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4353a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Get mirrors for the four objects. 4354a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CompileRun( 43553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch "var o0_mirror = debug.MakeMirror(o0);" 43563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch "var o1_mirror = debug.MakeMirror(o1);" 43573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch "var o2_mirror = debug.MakeMirror(o2);" 43583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch "var o3_mirror = debug.MakeMirror(o3)"); 4359a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(CompileRun("o0_mirror instanceof debug.ObjectMirror")->BooleanValue()); 4360a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(CompileRun("o1_mirror instanceof debug.ObjectMirror")->BooleanValue()); 4361a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(CompileRun("o2_mirror instanceof debug.ObjectMirror")->BooleanValue()); 4362a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(CompileRun("o3_mirror instanceof debug.ObjectMirror")->BooleanValue()); 4363a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4364a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Check that each object has one property. 4365a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1, CompileRun( 4366a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "o0_mirror.propertyNames().length")->Int32Value()); 4367a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1, CompileRun( 4368a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "o1_mirror.propertyNames().length")->Int32Value()); 4369a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1, CompileRun( 4370a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "o2_mirror.propertyNames().length")->Int32Value()); 4371a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1, CompileRun( 4372a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "o3_mirror.propertyNames().length")->Int32Value()); 4373a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4374a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Set o1 as prototype for o0. o1 has the hidden prototype flag so all 4375a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // properties on o1 should be seen on o0. 4376a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block o0->Set(v8::String::New("__proto__"), o1); 4377a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(2, CompileRun( 4378a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "o0_mirror.propertyNames().length")->Int32Value()); 4379a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(0, CompileRun( 4380a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "o0_mirror.property('x').value().value()")->Int32Value()); 4381a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1, CompileRun( 4382a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "o0_mirror.property('y').value().value()")->Int32Value()); 4383a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4384a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Set o2 as prototype for o0 (it will end up after o1 as o1 has the hidden 4385a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // prototype flag. o2 also has the hidden prototype flag so all properties 4386a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // on o2 should be seen on o0 as well as properties on o1. 4387a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block o0->Set(v8::String::New("__proto__"), o2); 4388a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(3, CompileRun( 4389a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "o0_mirror.propertyNames().length")->Int32Value()); 4390a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(0, CompileRun( 4391a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "o0_mirror.property('x').value().value()")->Int32Value()); 4392a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1, CompileRun( 4393a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "o0_mirror.property('y').value().value()")->Int32Value()); 4394a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(2, CompileRun( 4395a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "o0_mirror.property('z').value().value()")->Int32Value()); 4396a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4397a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Set o3 as prototype for o0 (it will end up after o1 and o2 as both o1 and 4398a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // o2 has the hidden prototype flag. o3 does not have the hidden prototype 4399a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // flag so properties on o3 should not be seen on o0 whereas the properties 4400a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // from o1 and o2 should still be seen on o0. 4401a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Final prototype chain: o0 -> o1 -> o2 -> o3 4402a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Hidden prototypes: ^^ ^^ 4403a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block o0->Set(v8::String::New("__proto__"), o3); 4404a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(3, CompileRun( 4405a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "o0_mirror.propertyNames().length")->Int32Value()); 4406a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1, CompileRun( 4407a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "o3_mirror.propertyNames().length")->Int32Value()); 4408a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(0, CompileRun( 4409a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "o0_mirror.property('x').value().value()")->Int32Value()); 4410a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1, CompileRun( 4411a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "o0_mirror.property('y').value().value()")->Int32Value()); 4412a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(2, CompileRun( 4413a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "o0_mirror.property('z').value().value()")->Int32Value()); 4414a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(CompileRun("o0_mirror.property('u').isUndefined()")->BooleanValue()); 4415a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4416a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // The prototype (__proto__) for o0 should be o3 as o1 and o2 are hidden. 4417a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(CompileRun("o0_mirror.protoObject() == o3_mirror")->BooleanValue()); 4418a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 4419a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4420a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4421a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic v8::Handle<v8::Value> ProtperyXNativeGetter( 4422a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Local<v8::String> property, const v8::AccessorInfo& info) { 4423a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return v8::Integer::New(10); 4424a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 4425a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4426a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4427a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(NativeGetterPropertyMirror) { 4428a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Create a V8 environment with debug access. 4429a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::HandleScope scope; 4430a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DebugLocalContext env; 4431a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block env.ExposeDebug(); 4432a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4433a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<v8::String> name = v8::String::New("x"); 4434a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Create object with named accessor. 4435a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<v8::ObjectTemplate> named = v8::ObjectTemplate::New(); 4436a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block named->SetAccessor(name, &ProtperyXNativeGetter, NULL, 4437a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<v8::Value>(), v8::DEFAULT, v8::None); 4438a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4439a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Create object with named property getter. 4440a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block env->Global()->Set(v8::String::New("instance"), named->NewInstance()); 4441a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(10, CompileRun("instance.x")->Int32Value()); 4442a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4443a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Get mirror for the object with property getter. 44443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CompileRun("var instance_mirror = debug.MakeMirror(instance);"); 4445a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(CompileRun( 4446a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "instance_mirror instanceof debug.ObjectMirror")->BooleanValue()); 4447a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 44483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CompileRun("var named_names = instance_mirror.propertyNames();"); 4449a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1, CompileRun("named_names.length")->Int32Value()); 4450a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(CompileRun("named_names[0] == 'x'")->BooleanValue()); 4451a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(CompileRun( 4452a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "instance_mirror.property('x').value().isNumber()")->BooleanValue()); 4453a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(CompileRun( 4454a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "instance_mirror.property('x').value().value() == 10")->BooleanValue()); 4455a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 4456a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4457a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4458a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic v8::Handle<v8::Value> ProtperyXNativeGetterThrowingError( 4459a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Local<v8::String> property, const v8::AccessorInfo& info) { 4460a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return CompileRun("throw new Error('Error message');"); 4461a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 4462a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4463a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4464a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(NativeGetterThrowingErrorPropertyMirror) { 4465a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Create a V8 environment with debug access. 4466a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::HandleScope scope; 4467a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DebugLocalContext env; 4468a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block env.ExposeDebug(); 4469a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4470a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<v8::String> name = v8::String::New("x"); 4471a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Create object with named accessor. 4472a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<v8::ObjectTemplate> named = v8::ObjectTemplate::New(); 4473a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block named->SetAccessor(name, &ProtperyXNativeGetterThrowingError, NULL, 4474a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<v8::Value>(), v8::DEFAULT, v8::None); 4475a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4476a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Create object with named property getter. 4477a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block env->Global()->Set(v8::String::New("instance"), named->NewInstance()); 4478a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4479a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Get mirror for the object with property getter. 44803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CompileRun("var instance_mirror = debug.MakeMirror(instance);"); 4481a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(CompileRun( 4482a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "instance_mirror instanceof debug.ObjectMirror")->BooleanValue()); 4483a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CompileRun("named_names = instance_mirror.propertyNames();"); 4484a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1, CompileRun("named_names.length")->Int32Value()); 4485a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(CompileRun("named_names[0] == 'x'")->BooleanValue()); 4486a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(CompileRun( 4487a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "instance_mirror.property('x').value().isError()")->BooleanValue()); 4488a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4489a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Check that the message is that passed to the Error constructor. 4490a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(CompileRun( 4491a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "instance_mirror.property('x').value().message() == 'Error message'")-> 4492a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block BooleanValue()); 4493a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 4494a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4495a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4496d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block// Test that hidden properties object is not returned as an unnamed property 4497d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block// among regular properties. 4498d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block// See http://crbug.com/26491 4499d0582a6c46733687d045e4188a1bcd0123c758a1Steve BlockTEST(NoHiddenProperties) { 4500d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // Create a V8 environment with debug access. 4501d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block v8::HandleScope scope; 4502d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block DebugLocalContext env; 4503d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block env.ExposeDebug(); 4504d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 4505d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // Create an object in the global scope. 4506d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block const char* source = "var obj = {a: 1};"; 4507d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block v8::Script::Compile(v8::String::New(source))->Run(); 4508d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block v8::Local<v8::Object> obj = v8::Local<v8::Object>::Cast( 4509d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block env->Global()->Get(v8::String::New("obj"))); 4510d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // Set a hidden property on the object. 4511d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block obj->SetHiddenValue(v8::String::New("v8::test-debug::a"), 4512d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block v8::Int32::New(11)); 4513d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 4514d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // Get mirror for the object with property getter. 4515d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block CompileRun("var obj_mirror = debug.MakeMirror(obj);"); 4516d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block CHECK(CompileRun( 4517d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block "obj_mirror instanceof debug.ObjectMirror")->BooleanValue()); 4518d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block CompileRun("var named_names = obj_mirror.propertyNames();"); 4519d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // There should be exactly one property. But there is also an unnamed 4520d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // property whose value is hidden properties dictionary. The latter 4521d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // property should not be in the list of reguar properties. 4522d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block CHECK_EQ(1, CompileRun("named_names.length")->Int32Value()); 4523d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block CHECK(CompileRun("named_names[0] == 'a'")->BooleanValue()); 4524d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block CHECK(CompileRun( 4525d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block "obj_mirror.property('a').value().value() == 1")->BooleanValue()); 4526d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 4527d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // Object created by t0 will become hidden prototype of object 'obj'. 4528d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block v8::Handle<v8::FunctionTemplate> t0 = v8::FunctionTemplate::New(); 4529d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block t0->InstanceTemplate()->Set(v8::String::New("b"), v8::Number::New(2)); 4530d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block t0->SetHiddenPrototype(true); 4531d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block v8::Handle<v8::FunctionTemplate> t1 = v8::FunctionTemplate::New(); 4532d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block t1->InstanceTemplate()->Set(v8::String::New("c"), v8::Number::New(3)); 4533d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 4534d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // Create proto objects, add hidden properties to them and set them on 4535d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // the global object. 4536d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block v8::Handle<v8::Object> protoObj = t0->GetFunction()->NewInstance(); 4537d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block protoObj->SetHiddenValue(v8::String::New("v8::test-debug::b"), 4538d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block v8::Int32::New(12)); 4539d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block env->Global()->Set(v8::String::New("protoObj"), protoObj); 4540d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block v8::Handle<v8::Object> grandProtoObj = t1->GetFunction()->NewInstance(); 4541d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block grandProtoObj->SetHiddenValue(v8::String::New("v8::test-debug::c"), 4542d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block v8::Int32::New(13)); 4543d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block env->Global()->Set(v8::String::New("grandProtoObj"), grandProtoObj); 4544d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 4545d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // Setting prototypes: obj->protoObj->grandProtoObj 4546d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block protoObj->Set(v8::String::New("__proto__"), grandProtoObj); 4547d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block obj->Set(v8::String::New("__proto__"), protoObj); 4548d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 4549d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // Get mirror for the object with property getter. 4550d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block CompileRun("var obj_mirror = debug.MakeMirror(obj);"); 4551d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block CHECK(CompileRun( 4552d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block "obj_mirror instanceof debug.ObjectMirror")->BooleanValue()); 4553d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block CompileRun("var named_names = obj_mirror.propertyNames();"); 4554d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // There should be exactly two properties - one from the object itself and 4555d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // another from its hidden prototype. 4556d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block CHECK_EQ(2, CompileRun("named_names.length")->Int32Value()); 4557d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block CHECK(CompileRun("named_names.sort(); named_names[0] == 'a' &&" 4558d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block "named_names[1] == 'b'")->BooleanValue()); 4559d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block CHECK(CompileRun( 4560d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block "obj_mirror.property('a').value().value() == 1")->BooleanValue()); 4561d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block CHECK(CompileRun( 4562d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block "obj_mirror.property('b').value().value() == 2")->BooleanValue()); 4563d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block} 4564d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 4565a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4566a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Multithreaded tests of JSON debugger protocol 4567a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4568a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Support classes 4569a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4570a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Provides synchronization between k threads, where k is an input to the 4571a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// constructor. The Wait() call blocks a thread until it is called for the 4572a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// k'th time, then all calls return. Each ThreadBarrier object can only 4573a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// be used once. 4574a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass ThreadBarrier { 4575a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 4576a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block explicit ThreadBarrier(int num_threads); 4577a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ~ThreadBarrier(); 4578a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void Wait(); 4579a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private: 4580a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int num_threads_; 4581a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int num_blocked_; 4582a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::internal::Mutex* lock_; 4583a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::internal::Semaphore* sem_; 4584a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool invalid_; 4585a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 4586a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4587a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockThreadBarrier::ThreadBarrier(int num_threads) 4588a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : num_threads_(num_threads), num_blocked_(0) { 4589a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block lock_ = OS::CreateMutex(); 4590a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block sem_ = OS::CreateSemaphore(0); 4591a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block invalid_ = false; // A barrier may only be used once. Then it is invalid. 4592a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 4593a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4594a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Do not call, due to race condition with Wait(). 4595a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Could be resolved with Pthread condition variables. 4596a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockThreadBarrier::~ThreadBarrier() { 4597a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block lock_->Lock(); 4598a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block delete lock_; 4599a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block delete sem_; 4600a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 4601a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4602a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid ThreadBarrier::Wait() { 4603a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block lock_->Lock(); 4604a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(!invalid_); 4605a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (num_blocked_ == num_threads_ - 1) { 4606a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Signal and unblock all waiting threads. 4607a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (int i = 0; i < num_threads_ - 1; ++i) { 4608a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block sem_->Signal(); 4609a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 4610a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block invalid_ = true; 4611a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block printf("BARRIER\n\n"); 4612a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block fflush(stdout); 4613a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block lock_->Unlock(); 4614a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { // Wait for the semaphore. 4615a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ++num_blocked_; 4616a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block lock_->Unlock(); // Potential race condition with destructor because 4617a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block sem_->Wait(); // these two lines are not atomic. 4618a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 4619a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 4620a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4621a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// A set containing enough barriers and semaphores for any of the tests. 4622a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass Barriers { 4623a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 4624a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Barriers(); 4625a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void Initialize(); 4626a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ThreadBarrier barrier_1; 4627a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ThreadBarrier barrier_2; 4628a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ThreadBarrier barrier_3; 4629a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ThreadBarrier barrier_4; 4630a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ThreadBarrier barrier_5; 4631a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::internal::Semaphore* semaphore_1; 4632a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::internal::Semaphore* semaphore_2; 4633a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 4634a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4635a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockBarriers::Barriers() : barrier_1(2), barrier_2(2), 4636a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block barrier_3(2), barrier_4(2), barrier_5(2) {} 4637a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4638a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Barriers::Initialize() { 4639a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block semaphore_1 = OS::CreateSemaphore(0); 4640a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block semaphore_2 = OS::CreateSemaphore(0); 4641a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 4642a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4643a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4644a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// We match parts of the message to decide if it is a break message. 4645a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockbool IsBreakEventMessage(char *message) { 4646a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const char* type_event = "\"type\":\"event\""; 4647a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const char* event_break = "\"event\":\"break\""; 4648a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Does the message contain both type:event and event:break? 4649a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return strstr(message, type_event) != NULL && 4650a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block strstr(message, event_break) != NULL; 4651a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 4652a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4653a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 46543ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block// We match parts of the message to decide if it is a exception message. 46553ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Blockbool IsExceptionEventMessage(char *message) { 46563ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block const char* type_event = "\"type\":\"event\""; 46573ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block const char* event_exception = "\"event\":\"exception\""; 46583ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // Does the message contain both type:event and event:exception? 46593ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block return strstr(message, type_event) != NULL && 46603ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block strstr(message, event_exception) != NULL; 46613ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block} 46623ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 46633ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 46643ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block// We match the message wether it is an evaluate response message. 46653ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Blockbool IsEvaluateResponseMessage(char* message) { 46663ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block const char* type_response = "\"type\":\"response\""; 46673ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block const char* command_evaluate = "\"command\":\"evaluate\""; 46683ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // Does the message contain both type:response and command:evaluate? 46693ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block return strstr(message, type_response) != NULL && 46703ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block strstr(message, command_evaluate) != NULL; 46713ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block} 46723ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 46733ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 4674402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescustatic int StringToInt(const char* s) { 4675402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu return atoi(s); // NOLINT 4676402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu} 4677402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu 4678402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu 46793ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block// We match parts of the message to get evaluate result int value. 46803ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Blockint GetEvaluateIntResult(char *message) { 46813ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block const char* value = "\"value\":"; 46823ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block char* pos = strstr(message, value); 46833ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block if (pos == NULL) { 46843ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block return -1; 46853ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block } 46863ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block int res = -1; 4687402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu res = StringToInt(pos + strlen(value)); 46883ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block return res; 46893ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block} 46903ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 46913ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 46923ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block// We match parts of the message to get hit breakpoint id. 46933ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Blockint GetBreakpointIdFromBreakEventMessage(char *message) { 46943ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block const char* breakpoints = "\"breakpoints\":["; 46953ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block char* pos = strstr(message, breakpoints); 46963ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block if (pos == NULL) { 46973ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block return -1; 46983ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block } 46993ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block int res = -1; 4700402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu res = StringToInt(pos + strlen(breakpoints)); 47013ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block return res; 47023ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block} 47033ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 47043ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 4705d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke// We match parts of the message to get total frames number. 4706d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkeint GetTotalFramesInt(char *message) { 4707d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke const char* prefix = "\"totalFrames\":"; 4708d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke char* pos = strstr(message, prefix); 4709d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke if (pos == NULL) { 4710d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke return -1; 4711d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 4712d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke pos += strlen(prefix); 4713402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu int res = StringToInt(pos); 4714d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke return res; 4715d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 4716d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 4717d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 47189ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick// We match parts of the message to get source line. 47199ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrickint GetSourceLineFromBreakEventMessage(char *message) { 47209ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick const char* source_line = "\"sourceLine\":"; 47219ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick char* pos = strstr(message, source_line); 47229ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick if (pos == NULL) { 47239ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick return -1; 47249ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick } 47259ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick int res = -1; 47269ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick res = StringToInt(pos + strlen(source_line)); 47279ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick return res; 47289ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick} 47299ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick 4730a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block/* Test MessageQueues */ 4731a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block/* Tests the message queues that hold debugger commands and 4732a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block * response messages to the debugger. Fills queues and makes 4733a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block * them grow. 4734a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block */ 4735a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockBarriers message_queue_barriers; 4736a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4737a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// This is the debugger thread, that executes no v8 calls except 4738a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// placing JSON debugger commands in the queue. 4739a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass MessageQueueDebuggerThread : public v8::internal::Thread { 4740a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 47413fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch MessageQueueDebuggerThread() 47423fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch : Thread("MessageQueueDebuggerThread") { } 4743a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void Run(); 4744a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 4745a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4746a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic void MessageHandler(const uint16_t* message, int length, 4747a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::ClientData* client_data) { 4748a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static char print_buffer[1000]; 4749a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Utf16ToAscii(message, length, print_buffer); 4750a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (IsBreakEventMessage(print_buffer)) { 4751a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Lets test script wait until break occurs to send commands. 4752a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Signals when a break is reported. 4753a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block message_queue_barriers.semaphore_2->Signal(); 4754a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 4755a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4756a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Allow message handler to block on a semaphore, to test queueing of 4757a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // messages while blocked. 4758a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block message_queue_barriers.semaphore_1->Wait(); 4759a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 4760a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4761a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid MessageQueueDebuggerThread::Run() { 4762a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const int kBufferSize = 1000; 4763a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block uint16_t buffer_1[kBufferSize]; 4764a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block uint16_t buffer_2[kBufferSize]; 4765a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const char* command_1 = 4766a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "{\"seq\":117," 4767a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "\"type\":\"request\"," 4768a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "\"command\":\"evaluate\"," 4769a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "\"arguments\":{\"expression\":\"1+2\"}}"; 4770a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const char* command_2 = 4771a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "{\"seq\":118," 4772a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "\"type\":\"request\"," 4773a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "\"command\":\"evaluate\"," 4774a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "\"arguments\":{\"expression\":\"1+a\"}}"; 4775a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const char* command_3 = 4776a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "{\"seq\":119," 4777a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "\"type\":\"request\"," 4778a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "\"command\":\"evaluate\"," 4779a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "\"arguments\":{\"expression\":\"c.d * b\"}}"; 4780a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const char* command_continue = 4781a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "{\"seq\":106," 4782a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "\"type\":\"request\"," 4783a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "\"command\":\"continue\"}"; 4784a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const char* command_single_step = 4785a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "{\"seq\":107," 4786a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "\"type\":\"request\"," 4787a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "\"command\":\"continue\"," 4788a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "\"arguments\":{\"stepaction\":\"next\"}}"; 4789a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4790a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block /* Interleaved sequence of actions by the two threads:*/ 4791a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Main thread compiles and runs source_1 4792a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block message_queue_barriers.semaphore_1->Signal(); 4793a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block message_queue_barriers.barrier_1.Wait(); 4794a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Post 6 commands, filling the command queue and making it expand. 4795a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // These calls return immediately, but the commands stay on the queue 4796a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // until the execution of source_2. 4797a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Note: AsciiToUtf16 executes before SendCommand, so command is copied 4798a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // to buffer before buffer is sent to SendCommand. 4799a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SendCommand(buffer_1, AsciiToUtf16(command_1, buffer_1)); 4800a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SendCommand(buffer_2, AsciiToUtf16(command_2, buffer_2)); 4801a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SendCommand(buffer_2, AsciiToUtf16(command_3, buffer_2)); 4802a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SendCommand(buffer_2, AsciiToUtf16(command_3, buffer_2)); 4803a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SendCommand(buffer_2, AsciiToUtf16(command_3, buffer_2)); 4804a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block message_queue_barriers.barrier_2.Wait(); 4805a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Main thread compiles and runs source_2. 4806a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Queued commands are executed at the start of compilation of source_2( 4807a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // beforeCompile event). 4808a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Free the message handler to process all the messages from the queue. 7 4809a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // messages are expected: 2 afterCompile events and 5 responses. 4810a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // All the commands added so far will fail to execute as long as call stack 4811a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // is empty on beforeCompile event. 4812a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (int i = 0; i < 6 ; ++i) { 4813a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block message_queue_barriers.semaphore_1->Signal(); 4814a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 4815a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block message_queue_barriers.barrier_3.Wait(); 4816a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Main thread compiles and runs source_3. 4817a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Don't stop in the afterCompile handler. 4818a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block message_queue_barriers.semaphore_1->Signal(); 4819a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // source_3 includes a debugger statement, which causes a break event. 4820a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Wait on break event from hitting "debugger" statement 4821a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block message_queue_barriers.semaphore_2->Wait(); 4822a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // These should execute after the "debugger" statement in source_2 4823a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SendCommand(buffer_1, AsciiToUtf16(command_1, buffer_1)); 4824a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SendCommand(buffer_2, AsciiToUtf16(command_2, buffer_2)); 4825a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SendCommand(buffer_2, AsciiToUtf16(command_3, buffer_2)); 4826a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SendCommand(buffer_2, AsciiToUtf16(command_single_step, buffer_2)); 4827a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Run after 2 break events, 4 responses. 4828a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (int i = 0; i < 6 ; ++i) { 4829a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block message_queue_barriers.semaphore_1->Signal(); 4830a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 4831a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Wait on break event after a single step executes. 4832a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block message_queue_barriers.semaphore_2->Wait(); 4833a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SendCommand(buffer_1, AsciiToUtf16(command_2, buffer_1)); 4834a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SendCommand(buffer_2, AsciiToUtf16(command_continue, buffer_2)); 4835a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Run after 2 responses. 4836a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (int i = 0; i < 2 ; ++i) { 4837a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block message_queue_barriers.semaphore_1->Signal(); 4838a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 4839a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Main thread continues running source_3 to end, waits for this thread. 4840a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 4841a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4842a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4843a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// This thread runs the v8 engine. 4844a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(MessageQueues) { 48453fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch MessageQueueDebuggerThread message_queue_debugger_thread; 484644f0eee88ff00398ff7f715fab053374d808c90dSteve Block 4847a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Create a V8 environment 4848a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::HandleScope scope; 4849a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DebugLocalContext env; 4850a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block message_queue_barriers.Initialize(); 4851a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetMessageHandler(MessageHandler); 4852a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block message_queue_debugger_thread.Start(); 4853a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4854a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const char* source_1 = "a = 3; b = 4; c = new Object(); c.d = 5;"; 4855a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const char* source_2 = "e = 17;"; 4856a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const char* source_3 = "a = 4; debugger; a = 5; a = 6; a = 7;"; 4857a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4858a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // See MessageQueueDebuggerThread::Run for interleaved sequence of 4859a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // API calls and events in the two threads. 4860a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CompileRun(source_1); 4861a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block message_queue_barriers.barrier_1.Wait(); 4862a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block message_queue_barriers.barrier_2.Wait(); 4863a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CompileRun(source_2); 4864a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block message_queue_barriers.barrier_3.Wait(); 4865a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CompileRun(source_3); 4866a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block message_queue_debugger_thread.Join(); 4867a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block fflush(stdout); 4868a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 4869a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4870a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4871a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass TestClientData : public v8::Debug::ClientData { 4872a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 4873a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block TestClientData() { 4874a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block constructor_call_counter++; 4875a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 4876a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block virtual ~TestClientData() { 4877a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block destructor_call_counter++; 4878a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 4879a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4880a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static void ResetCounters() { 4881a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block constructor_call_counter = 0; 4882a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block destructor_call_counter = 0; 4883a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 4884a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4885a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static int constructor_call_counter; 4886a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static int destructor_call_counter; 4887a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 4888a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4889a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockint TestClientData::constructor_call_counter = 0; 4890a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockint TestClientData::destructor_call_counter = 0; 4891a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4892a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4893a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Tests that MessageQueue doesn't destroy client data when expands and 4894a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// does destroy when it dies. 4895a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(MessageQueueExpandAndDestroy) { 4896a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block TestClientData::ResetCounters(); 4897a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block { // Create a scope for the queue. 4898a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CommandMessageQueue queue(1); 4899a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block queue.Put(CommandMessage::New(Vector<uint16_t>::empty(), 4900a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block new TestClientData())); 4901a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block queue.Put(CommandMessage::New(Vector<uint16_t>::empty(), 4902a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block new TestClientData())); 4903a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block queue.Put(CommandMessage::New(Vector<uint16_t>::empty(), 4904a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block new TestClientData())); 4905a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(0, TestClientData::destructor_call_counter); 4906a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block queue.Get().Dispose(); 4907a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1, TestClientData::destructor_call_counter); 4908a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block queue.Put(CommandMessage::New(Vector<uint16_t>::empty(), 4909a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block new TestClientData())); 4910a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block queue.Put(CommandMessage::New(Vector<uint16_t>::empty(), 4911a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block new TestClientData())); 4912a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block queue.Put(CommandMessage::New(Vector<uint16_t>::empty(), 4913a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block new TestClientData())); 4914a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block queue.Put(CommandMessage::New(Vector<uint16_t>::empty(), 4915a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block new TestClientData())); 4916a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block queue.Put(CommandMessage::New(Vector<uint16_t>::empty(), 4917a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block new TestClientData())); 4918a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1, TestClientData::destructor_call_counter); 4919a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block queue.Get().Dispose(); 4920a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(2, TestClientData::destructor_call_counter); 4921a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 4922a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // All the client data should be destroyed when the queue is destroyed. 4923a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(TestClientData::destructor_call_counter, 4924a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block TestClientData::destructor_call_counter); 4925a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 4926a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4927a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4928a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic int handled_client_data_instances_count = 0; 4929a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic void MessageHandlerCountingClientData( 4930a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const v8::Debug::Message& message) { 4931a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (message.GetClientData() != NULL) { 4932a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block handled_client_data_instances_count++; 4933a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 4934a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 4935a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4936a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4937a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Tests that all client data passed to the debugger are sent to the handler. 4938a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(SendClientDataToHandler) { 4939a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Create a V8 environment 4940a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::HandleScope scope; 4941a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DebugLocalContext env; 4942a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block TestClientData::ResetCounters(); 4943a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block handled_client_data_instances_count = 0; 4944a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetMessageHandler2(MessageHandlerCountingClientData); 4945a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const char* source_1 = "a = 3; b = 4; c = new Object(); c.d = 5;"; 4946a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const int kBufferSize = 1000; 4947a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block uint16_t buffer[kBufferSize]; 4948a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const char* command_1 = 4949a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "{\"seq\":117," 4950a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "\"type\":\"request\"," 4951a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "\"command\":\"evaluate\"," 4952a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "\"arguments\":{\"expression\":\"1+2\"}}"; 4953a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const char* command_2 = 4954a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "{\"seq\":118," 4955a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "\"type\":\"request\"," 4956a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "\"command\":\"evaluate\"," 4957a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "\"arguments\":{\"expression\":\"1+a\"}}"; 4958a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const char* command_continue = 4959a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "{\"seq\":106," 4960a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "\"type\":\"request\"," 4961a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "\"command\":\"continue\"}"; 4962a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4963a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SendCommand(buffer, AsciiToUtf16(command_1, buffer), 4964a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block new TestClientData()); 4965a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SendCommand(buffer, AsciiToUtf16(command_2, buffer), NULL); 4966a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SendCommand(buffer, AsciiToUtf16(command_2, buffer), 4967a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block new TestClientData()); 4968a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SendCommand(buffer, AsciiToUtf16(command_2, buffer), 4969a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block new TestClientData()); 4970a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // All the messages will be processed on beforeCompile event. 4971a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CompileRun(source_1); 4972a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SendCommand(buffer, AsciiToUtf16(command_continue, buffer)); 4973a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(3, TestClientData::constructor_call_counter); 4974a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(TestClientData::constructor_call_counter, 4975a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block handled_client_data_instances_count); 4976a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(TestClientData::constructor_call_counter, 4977a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block TestClientData::destructor_call_counter); 4978a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 4979a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4980a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4981a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block/* Test ThreadedDebugging */ 4982a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block/* This test interrupts a running infinite loop that is 4983a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block * occupying the v8 thread by a break command from the 4984a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block * debugger thread. It then changes the value of a 4985a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block * global object, to make the loop terminate. 4986a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block */ 4987a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4988a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockBarriers threaded_debugging_barriers; 4989a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4990a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass V8Thread : public v8::internal::Thread { 4991a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 49923fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch V8Thread() : Thread("V8Thread") { } 4993a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void Run(); 4994a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 4995a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4996a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass DebuggerThread : public v8::internal::Thread { 4997a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 49983fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch DebuggerThread() : Thread("DebuggerThread") { } 4999a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void Run(); 5000a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 5001a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5002a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5003a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic v8::Handle<v8::Value> ThreadedAtBarrier1(const v8::Arguments& args) { 5004a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block threaded_debugging_barriers.barrier_1.Wait(); 5005a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return v8::Undefined(); 5006a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 5007a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5008a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5009a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic void ThreadedMessageHandler(const v8::Debug::Message& message) { 5010a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static char print_buffer[1000]; 5011a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::String::Value json(message.GetJSON()); 5012a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Utf16ToAscii(*json, json.length(), print_buffer); 5013a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (IsBreakEventMessage(print_buffer)) { 50149ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick // Check that we are inside the while loop. 50159ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick int source_line = GetSourceLineFromBreakEventMessage(print_buffer); 50169ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick CHECK(8 <= source_line && source_line <= 13); 5017a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block threaded_debugging_barriers.barrier_2.Wait(); 5018a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 5019a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 5020a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5021a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5022a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid V8Thread::Run() { 5023a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const char* source = 5024a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "flag = true;\n" 5025a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "function bar( new_value ) {\n" 5026a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " flag = new_value;\n" 5027a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " return \"Return from bar(\" + new_value + \")\";\n" 5028a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "}\n" 5029a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "\n" 5030a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "function foo() {\n" 5031a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " var x = 1;\n" 5032a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " while ( flag == true ) {\n" 5033a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " if ( x == 1 ) {\n" 5034a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " ThreadedAtBarrier1();\n" 5035a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " }\n" 5036a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " x = x + 1;\n" 5037a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " }\n" 5038a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "}\n" 5039a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "\n" 5040a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "foo();\n"; 5041a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 50423fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch v8::V8::Initialize(); 5043a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::HandleScope scope; 5044a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DebugLocalContext env; 5045a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetMessageHandler2(&ThreadedMessageHandler); 5046a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<v8::ObjectTemplate> global_template = v8::ObjectTemplate::New(); 5047a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block global_template->Set(v8::String::New("ThreadedAtBarrier1"), 5048a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::FunctionTemplate::New(ThreadedAtBarrier1)); 5049a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<v8::Context> context = v8::Context::New(NULL, global_template); 5050a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Context::Scope context_scope(context); 5051a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5052a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CompileRun(source); 5053a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 5054a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5055a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid DebuggerThread::Run() { 5056a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const int kBufSize = 1000; 5057a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block uint16_t buffer[kBufSize]; 5058a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5059a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const char* command_1 = "{\"seq\":102," 5060a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "\"type\":\"request\"," 5061a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "\"command\":\"evaluate\"," 5062a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "\"arguments\":{\"expression\":\"bar(false)\"}}"; 5063a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const char* command_2 = "{\"seq\":103," 5064a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "\"type\":\"request\"," 5065a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "\"command\":\"continue\"}"; 5066a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5067a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block threaded_debugging_barriers.barrier_1.Wait(); 5068a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::DebugBreak(); 5069a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block threaded_debugging_barriers.barrier_2.Wait(); 5070a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SendCommand(buffer, AsciiToUtf16(command_1, buffer)); 5071a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SendCommand(buffer, AsciiToUtf16(command_2, buffer)); 5072a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 5073a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5074a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5075a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(ThreadedDebugging) { 50763fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch DebuggerThread debugger_thread; 50773fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch V8Thread v8_thread; 507844f0eee88ff00398ff7f715fab053374d808c90dSteve Block 5079a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Create a V8 environment 5080a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block threaded_debugging_barriers.Initialize(); 5081a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5082a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8_thread.Start(); 5083a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block debugger_thread.Start(); 5084a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5085a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8_thread.Join(); 5086a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block debugger_thread.Join(); 5087a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 5088a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5089a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block/* Test RecursiveBreakpoints */ 5090a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block/* In this test, the debugger evaluates a function with a breakpoint, after 5091a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block * hitting a breakpoint in another function. We do this with both values 5092a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block * of the flag enabling recursive breakpoints, and verify that the second 5093a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block * breakpoint is hit when enabled, and missed when disabled. 5094a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block */ 5095a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5096a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass BreakpointsV8Thread : public v8::internal::Thread { 5097a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 50983fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch BreakpointsV8Thread() : Thread("BreakpointsV8Thread") { } 5099a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void Run(); 5100a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 5101a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5102a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass BreakpointsDebuggerThread : public v8::internal::Thread { 5103a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 51043fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch explicit BreakpointsDebuggerThread(bool global_evaluate) 51053fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch : Thread("BreakpointsDebuggerThread"), 510644f0eee88ff00398ff7f715fab053374d808c90dSteve Block global_evaluate_(global_evaluate) {} 5107a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void Run(); 5108d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 5109d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke private: 5110d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke bool global_evaluate_; 5111a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 5112a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5113a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5114a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockBarriers* breakpoints_barriers; 51153ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Blockint break_event_breakpoint_id; 51163ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Blockint evaluate_int_result; 5117a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5118a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic void BreakpointsMessageHandler(const v8::Debug::Message& message) { 5119a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static char print_buffer[1000]; 5120a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::String::Value json(message.GetJSON()); 5121a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Utf16ToAscii(*json, json.length(), print_buffer); 5122a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5123a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (IsBreakEventMessage(print_buffer)) { 51243ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block break_event_breakpoint_id = 51253ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block GetBreakpointIdFromBreakEventMessage(print_buffer); 51263ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block breakpoints_barriers->semaphore_1->Signal(); 51273ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block } else if (IsEvaluateResponseMessage(print_buffer)) { 51283ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block evaluate_int_result = GetEvaluateIntResult(print_buffer); 5129a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block breakpoints_barriers->semaphore_1->Signal(); 5130a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 5131a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 5132a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5133a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5134a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid BreakpointsV8Thread::Run() { 5135a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const char* source_1 = "var y_global = 3;\n" 5136a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "function cat( new_value ) {\n" 5137a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " var x = new_value;\n" 51383ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block " y_global = y_global + 4;\n" 5139a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " x = 3 * x + 1;\n" 51403ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block " y_global = y_global + 5;\n" 5141a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " return x;\n" 5142a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "}\n" 5143a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "\n" 5144a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "function dog() {\n" 5145a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " var x = 1;\n" 5146a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " x = y_global;" 5147a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " var z = 3;" 5148a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " x += 100;\n" 5149a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " return x;\n" 5150a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "}\n" 5151a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "\n"; 5152a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const char* source_2 = "cat(17);\n" 5153a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "cat(19);\n"; 5154a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 51553fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch v8::V8::Initialize(); 5156a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::HandleScope scope; 5157a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DebugLocalContext env; 5158a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetMessageHandler2(&BreakpointsMessageHandler); 5159a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5160a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CompileRun(source_1); 5161a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block breakpoints_barriers->barrier_1.Wait(); 5162a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block breakpoints_barriers->barrier_2.Wait(); 5163a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CompileRun(source_2); 5164a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 5165a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5166a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5167a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid BreakpointsDebuggerThread::Run() { 5168a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const int kBufSize = 1000; 5169a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block uint16_t buffer[kBufSize]; 5170a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5171a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const char* command_1 = "{\"seq\":101," 5172a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "\"type\":\"request\"," 5173a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "\"command\":\"setbreakpoint\"," 5174a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "\"arguments\":{\"type\":\"function\",\"target\":\"cat\",\"line\":3}}"; 5175a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const char* command_2 = "{\"seq\":102," 5176a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "\"type\":\"request\"," 5177a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "\"command\":\"setbreakpoint\"," 5178a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "\"arguments\":{\"type\":\"function\",\"target\":\"dog\",\"line\":3}}"; 5179d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke const char* command_3; 5180d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke if (this->global_evaluate_) { 5181d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke command_3 = "{\"seq\":103," 5182d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke "\"type\":\"request\"," 5183d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke "\"command\":\"evaluate\"," 5184d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke "\"arguments\":{\"expression\":\"dog()\",\"disable_break\":false," 5185d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke "\"global\":true}}"; 5186d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } else { 5187d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke command_3 = "{\"seq\":103," 5188d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke "\"type\":\"request\"," 5189d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke "\"command\":\"evaluate\"," 5190d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke "\"arguments\":{\"expression\":\"dog()\",\"disable_break\":false}}"; 5191d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 5192d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke const char* command_4; 5193d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke if (this->global_evaluate_) { 5194d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke command_4 = "{\"seq\":104," 5195d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke "\"type\":\"request\"," 5196d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke "\"command\":\"evaluate\"," 5197d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke "\"arguments\":{\"expression\":\"100 + 8\",\"disable_break\":true," 5198d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke "\"global\":true}}"; 5199d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } else { 5200d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke command_4 = "{\"seq\":104," 5201d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke "\"type\":\"request\"," 5202d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke "\"command\":\"evaluate\"," 5203d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke "\"arguments\":{\"expression\":\"x + 1\",\"disable_break\":true}}"; 5204d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 52053ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block const char* command_5 = "{\"seq\":105," 5206a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "\"type\":\"request\"," 5207a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "\"command\":\"continue\"}"; 52083ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block const char* command_6 = "{\"seq\":106," 5209a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "\"type\":\"request\"," 5210a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "\"command\":\"continue\"}"; 5211d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke const char* command_7; 5212d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke if (this->global_evaluate_) { 5213d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke command_7 = "{\"seq\":107," 5214d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke "\"type\":\"request\"," 5215d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke "\"command\":\"evaluate\"," 5216d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke "\"arguments\":{\"expression\":\"dog()\",\"disable_break\":true," 5217d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke "\"global\":true}}"; 5218d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } else { 5219d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke command_7 = "{\"seq\":107," 5220d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke "\"type\":\"request\"," 5221d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke "\"command\":\"evaluate\"," 5222d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke "\"arguments\":{\"expression\":\"dog()\",\"disable_break\":true}}"; 5223d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 52243ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block const char* command_8 = "{\"seq\":108," 5225a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "\"type\":\"request\"," 5226a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "\"command\":\"continue\"}"; 5227a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5228a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5229a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // v8 thread initializes, runs source_1 5230a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block breakpoints_barriers->barrier_1.Wait(); 52313ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // 1:Set breakpoint in cat() (will get id 1). 5232a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SendCommand(buffer, AsciiToUtf16(command_1, buffer)); 52333ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // 2:Set breakpoint in dog() (will get id 2). 5234a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SendCommand(buffer, AsciiToUtf16(command_2, buffer)); 5235a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block breakpoints_barriers->barrier_2.Wait(); 52363ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // V8 thread starts compiling source_2. 5237a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Automatic break happens, to run queued commands 5238a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // breakpoints_barriers->semaphore_1->Wait(); 5239a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Commands 1 through 3 run, thread continues. 5240a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // v8 thread runs source_2 to breakpoint in cat(). 5241a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // message callback receives break event. 5242a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block breakpoints_barriers->semaphore_1->Wait(); 52433ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // Must have hit breakpoint #1. 52443ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block CHECK_EQ(1, break_event_breakpoint_id); 5245a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // 4:Evaluate dog() (which has a breakpoint). 5246a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SendCommand(buffer, AsciiToUtf16(command_3, buffer)); 52473ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // V8 thread hits breakpoint in dog(). 5248a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block breakpoints_barriers->semaphore_1->Wait(); // wait for break event 52493ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // Must have hit breakpoint #2. 52503ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block CHECK_EQ(2, break_event_breakpoint_id); 52513ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // 5:Evaluate (x + 1). 5252a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SendCommand(buffer, AsciiToUtf16(command_4, buffer)); 52533ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // Evaluate (x + 1) finishes. 52543ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block breakpoints_barriers->semaphore_1->Wait(); 52553ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // Must have result 108. 52563ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block CHECK_EQ(108, evaluate_int_result); 52573ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // 6:Continue evaluation of dog(). 5258a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SendCommand(buffer, AsciiToUtf16(command_5, buffer)); 52593ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // Evaluate dog() finishes. 52603ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block breakpoints_barriers->semaphore_1->Wait(); 52613ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // Must have result 107. 52623ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block CHECK_EQ(107, evaluate_int_result); 5263a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // 7:Continue evaluation of source_2, finish cat(17), hit breakpoint 5264a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // in cat(19). 5265a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SendCommand(buffer, AsciiToUtf16(command_6, buffer)); 52663ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // Message callback gets break event. 5267a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block breakpoints_barriers->semaphore_1->Wait(); // wait for break event 52683ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // Must have hit breakpoint #1. 52693ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block CHECK_EQ(1, break_event_breakpoint_id); 52703ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // 8: Evaluate dog() with breaks disabled. 5271a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SendCommand(buffer, AsciiToUtf16(command_7, buffer)); 52723ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // Evaluate dog() finishes. 52733ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block breakpoints_barriers->semaphore_1->Wait(); 52743ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // Must have result 116. 52753ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block CHECK_EQ(116, evaluate_int_result); 5276a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // 9: Continue evaluation of source2, reach end. 5277a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SendCommand(buffer, AsciiToUtf16(command_8, buffer)); 5278a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 5279a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5280d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid TestRecursiveBreakpointsGeneric(bool global_evaluate) { 5281eab96aab0834f21954b5d6aa6366bcfb348ed811Leon Clarke i::FLAG_debugger_auto_break = true; 5282888f6729be6a6f6fbe246cb5a9f122e2dbe455b7Leon Clarke 52833fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch BreakpointsDebuggerThread breakpoints_debugger_thread(global_evaluate); 52843fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch BreakpointsV8Thread breakpoints_v8_thread; 5285d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 5286a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Create a V8 environment 5287a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Barriers stack_allocated_breakpoints_barriers; 5288a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block stack_allocated_breakpoints_barriers.Initialize(); 5289a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block breakpoints_barriers = &stack_allocated_breakpoints_barriers; 5290a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5291a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block breakpoints_v8_thread.Start(); 5292a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block breakpoints_debugger_thread.Start(); 5293a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5294a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block breakpoints_v8_thread.Join(); 5295a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block breakpoints_debugger_thread.Join(); 5296a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 5297a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5298d91b9f7d46489a9ee00f9cb415630299c76a502bLeon ClarkeTEST(RecursiveBreakpoints) { 5299d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke TestRecursiveBreakpointsGeneric(false); 5300d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 5301d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 5302d91b9f7d46489a9ee00f9cb415630299c76a502bLeon ClarkeTEST(RecursiveBreakpointsGlobal) { 5303d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke TestRecursiveBreakpointsGeneric(true); 5304d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 5305d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 5306a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5307a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic void DummyDebugEventListener(v8::DebugEvent event, 5308a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<v8::Object> exec_state, 5309a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<v8::Object> event_data, 5310a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<v8::Value> data) { 5311a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 5312a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5313a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5314a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(SetDebugEventListenerOnUninitializedVM) { 5315a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetDebugEventListener(DummyDebugEventListener); 5316a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 5317a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5318a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5319a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic void DummyMessageHandler(const v8::Debug::Message& message) { 5320a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 5321a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5322a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5323a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(SetMessageHandlerOnUninitializedVM) { 5324a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetMessageHandler2(DummyMessageHandler); 5325a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 5326a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5327a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5328a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(DebugBreakOnUninitializedVM) { 5329a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::DebugBreak(); 5330a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 5331a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5332a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5333a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(SendCommandToUninitializedVM) { 5334a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const char* dummy_command = "{}"; 5335a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block uint16_t dummy_buffer[80]; 5336a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int dummy_length = AsciiToUtf16(dummy_command, dummy_buffer); 5337a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SendCommand(dummy_buffer, dummy_length); 5338a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 5339a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5340a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5341a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Source for a JavaScript function which returns the data parameter of a 5342a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// function called in the context of the debugger. If no data parameter is 5343a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// passed it throws an exception. 5344a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic const char* debugger_call_with_data_source = 5345a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "function debugger_call_with_data(exec_state, data) {" 5346a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " if (data) return data;" 5347a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " throw 'No data!'" 5348a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "}"; 5349a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockv8::Handle<v8::Function> debugger_call_with_data; 5350a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5351a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5352a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Source for a JavaScript function which returns the data parameter of a 5353a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// function called in the context of the debugger. If no data parameter is 5354a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// passed it throws an exception. 5355a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic const char* debugger_call_with_closure_source = 5356a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "var x = 3;" 5357a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "(function (exec_state) {" 5358a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " if (exec_state.y) return x - 1;" 5359a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " exec_state.y = x;" 5360a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " return exec_state.y" 5361a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "})"; 5362a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockv8::Handle<v8::Function> debugger_call_with_closure; 5363a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5364a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Function to retrieve the number of JavaScript frames by calling a JavaScript 5365a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// in the debugger. 5366a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic v8::Handle<v8::Value> CheckFrameCount(const v8::Arguments& args) { 5367a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(v8::Debug::Call(frame_count)->IsNumber()); 5368a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(args[0]->Int32Value(), 5369a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::Call(frame_count)->Int32Value()); 5370a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return v8::Undefined(); 5371a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 5372a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5373a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5374a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Function to retrieve the source line of the top JavaScript frame by calling a 5375a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// JavaScript function in the debugger. 5376a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic v8::Handle<v8::Value> CheckSourceLine(const v8::Arguments& args) { 5377a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(v8::Debug::Call(frame_source_line)->IsNumber()); 5378a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(args[0]->Int32Value(), 5379a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::Call(frame_source_line)->Int32Value()); 5380a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return v8::Undefined(); 5381a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 5382a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5383a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5384a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Function to test passing an additional parameter to a JavaScript function 5385a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// called in the debugger. It also tests that functions called in the debugger 5386a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// can throw exceptions. 5387a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic v8::Handle<v8::Value> CheckDataParameter(const v8::Arguments& args) { 5388a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<v8::String> data = v8::String::New("Test"); 5389a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(v8::Debug::Call(debugger_call_with_data, data)->IsString()); 5390a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5391a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(v8::Debug::Call(debugger_call_with_data).IsEmpty()); 5392a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(v8::Debug::Call(debugger_call_with_data).IsEmpty()); 5393a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5394a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::TryCatch catcher; 5395a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::Call(debugger_call_with_data); 5396a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(catcher.HasCaught()); 5397a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(catcher.Exception()->IsString()); 5398a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5399a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return v8::Undefined(); 5400a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 5401a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5402a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5403a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Function to test using a JavaScript with closure in the debugger. 5404a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic v8::Handle<v8::Value> CheckClosure(const v8::Arguments& args) { 5405a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(v8::Debug::Call(debugger_call_with_closure)->IsNumber()); 5406a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(3, v8::Debug::Call(debugger_call_with_closure)->Int32Value()); 5407a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return v8::Undefined(); 5408a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 5409a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5410a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5411a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Test functions called through the debugger. 5412a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(CallFunctionInDebugger) { 5413a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Create and enter a context with the functions CheckFrameCount, 5414a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // CheckSourceLine and CheckDataParameter installed. 5415a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::HandleScope scope; 5416a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<v8::ObjectTemplate> global_template = v8::ObjectTemplate::New(); 5417a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block global_template->Set(v8::String::New("CheckFrameCount"), 5418a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::FunctionTemplate::New(CheckFrameCount)); 5419a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block global_template->Set(v8::String::New("CheckSourceLine"), 5420a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::FunctionTemplate::New(CheckSourceLine)); 5421a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block global_template->Set(v8::String::New("CheckDataParameter"), 5422a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::FunctionTemplate::New(CheckDataParameter)); 5423a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block global_template->Set(v8::String::New("CheckClosure"), 5424a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::FunctionTemplate::New(CheckClosure)); 5425a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<v8::Context> context = v8::Context::New(NULL, global_template); 5426a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Context::Scope context_scope(context); 5427a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5428a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Compile a function for checking the number of JavaScript frames. 5429a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Script::Compile(v8::String::New(frame_count_source))->Run(); 5430a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block frame_count = v8::Local<v8::Function>::Cast( 5431a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block context->Global()->Get(v8::String::New("frame_count"))); 5432a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5433a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Compile a function for returning the source line for the top frame. 5434a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Script::Compile(v8::String::New(frame_source_line_source))->Run(); 5435a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block frame_source_line = v8::Local<v8::Function>::Cast( 5436a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block context->Global()->Get(v8::String::New("frame_source_line"))); 5437a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5438a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Compile a function returning the data parameter. 5439a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Script::Compile(v8::String::New(debugger_call_with_data_source))->Run(); 5440a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block debugger_call_with_data = v8::Local<v8::Function>::Cast( 5441a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block context->Global()->Get(v8::String::New("debugger_call_with_data"))); 5442a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5443a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Compile a function capturing closure. 5444a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block debugger_call_with_closure = v8::Local<v8::Function>::Cast( 5445a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Script::Compile( 5446a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::String::New(debugger_call_with_closure_source))->Run()); 5447a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 54486ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // Calling a function through the debugger returns 0 frames if there are 54496ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // no JavaScript frames. 54506ded16be15dd865a9b21ea304d5273c8be299c87Steve Block CHECK_EQ(v8::Integer::New(0), v8::Debug::Call(frame_count)); 5451a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5452a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Test that the number of frames can be retrieved. 5453a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Script::Compile(v8::String::New("CheckFrameCount(1)"))->Run(); 5454a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Script::Compile(v8::String::New("function f() {" 5455a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " CheckFrameCount(2);" 5456a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "}; f()"))->Run(); 5457a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5458a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Test that the source line can be retrieved. 5459a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Script::Compile(v8::String::New("CheckSourceLine(0)"))->Run(); 5460a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Script::Compile(v8::String::New("function f() {\n" 5461a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " CheckSourceLine(1)\n" 5462a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " CheckSourceLine(2)\n" 5463a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " CheckSourceLine(3)\n" 5464a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "}; f()"))->Run(); 5465a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5466a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Test that a parameter can be passed to a function called in the debugger. 5467a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Script::Compile(v8::String::New("CheckDataParameter()"))->Run(); 5468a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5469a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Test that a function with closure can be run in the debugger. 5470a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Script::Compile(v8::String::New("CheckClosure()"))->Run(); 5471a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5472a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5473a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Test that the source line is correct when there is a line offset. 5474a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::ScriptOrigin origin(v8::String::New("test"), 5475a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Integer::New(7)); 5476a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Script::Compile(v8::String::New("CheckSourceLine(7)"), &origin)->Run(); 5477a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Script::Compile(v8::String::New("function f() {\n" 5478a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " CheckSourceLine(8)\n" 5479a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " CheckSourceLine(9)\n" 5480a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " CheckSourceLine(10)\n" 5481a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "}; f()"), &origin)->Run(); 5482a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 5483a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5484a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5485a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Debugger message handler which counts the number of breaks. 5486a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic void SendContinueCommand(); 5487a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic void MessageHandlerBreakPointHitCount( 5488a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const v8::Debug::Message& message) { 5489a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (message.IsEvent() && message.GetEvent() == v8::Break) { 5490a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Count the number of breaks. 5491a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count++; 5492a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5493a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block SendContinueCommand(); 5494a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 5495a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 5496a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5497a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5498a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Test that clearing the debug event listener actually clears all break points 5499a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// and related information. 5500a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(DebuggerUnload) { 5501a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DebugLocalContext env; 5502a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5503a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Check debugger is unloaded before it is used. 5504a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CheckDebuggerUnloaded(); 5505a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5506a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Set a debug event listener. 5507a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 5508a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount, 5509a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Undefined()); 5510a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block { 5511a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::HandleScope scope; 5512a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Create a couple of functions for the test. 5513a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Local<v8::Function> foo = 5514a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CompileFunction(&env, "function foo(){x=1}", "foo"); 5515a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Local<v8::Function> bar = 5516a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CompileFunction(&env, "function bar(){y=2}", "bar"); 5517a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5518a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Set some break points. 5519a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block SetBreakPoint(foo, 0); 5520a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block SetBreakPoint(foo, 4); 5521a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block SetBreakPoint(bar, 0); 5522a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block SetBreakPoint(bar, 4); 5523a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5524a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Make sure that the break points are there. 5525a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 5526a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block foo->Call(env->Global(), 0, NULL); 5527a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(2, break_point_hit_count); 5528a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bar->Call(env->Global(), 0, NULL); 5529a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(4, break_point_hit_count); 5530a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 5531a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5532a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Remove the debug event listener without clearing breakpoints. Do this 5533a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // outside a handle scope. 5534a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetDebugEventListener(NULL); 5535a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CheckDebuggerUnloaded(true); 5536a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5537a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Now set a debug message handler. 5538a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 5539a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetMessageHandler2(MessageHandlerBreakPointHitCount); 5540a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block { 5541a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::HandleScope scope; 5542a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5543a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Get the test functions again. 55443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch v8::Local<v8::Function> foo(v8::Local<v8::Function>::Cast( 55453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch env->Global()->Get(v8::String::New("foo")))); 5546a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5547a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block foo->Call(env->Global(), 0, NULL); 5548a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(0, break_point_hit_count); 5549a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5550a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Set break points and run again. 5551a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block SetBreakPoint(foo, 0); 5552a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block SetBreakPoint(foo, 4); 5553a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block foo->Call(env->Global(), 0, NULL); 5554a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(2, break_point_hit_count); 5555a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 5556a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5557a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Remove the debug message handler without clearing breakpoints. Do this 5558a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // outside a handle scope. 5559a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetMessageHandler2(NULL); 5560a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CheckDebuggerUnloaded(true); 5561a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 5562a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5563a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5564a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Sends continue command to the debugger. 5565a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic void SendContinueCommand() { 5566a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const int kBufferSize = 1000; 5567a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block uint16_t buffer[kBufferSize]; 5568a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const char* command_continue = 5569a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "{\"seq\":0," 5570a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "\"type\":\"request\"," 5571a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "\"command\":\"continue\"}"; 5572a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5573a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SendCommand(buffer, AsciiToUtf16(command_continue, buffer)); 5574a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 5575a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5576a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5577a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Debugger message handler which counts the number of times it is called. 5578a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic int message_handler_hit_count = 0; 5579a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic void MessageHandlerHitCount(const v8::Debug::Message& message) { 5580a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block message_handler_hit_count++; 5581a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 55823ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block static char print_buffer[1000]; 55833ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block v8::String::Value json(message.GetJSON()); 55843ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block Utf16ToAscii(*json, json.length(), print_buffer); 55853ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block if (IsExceptionEventMessage(print_buffer)) { 55863ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // Send a continue command for exception events. 55873ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block SendContinueCommand(); 55883ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block } 5589a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 5590a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5591a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5592a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Test clearing the debug message handler. 5593a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(DebuggerClearMessageHandler) { 5594a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::HandleScope scope; 5595a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DebugLocalContext env; 5596a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5597a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Check debugger is unloaded before it is used. 5598a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CheckDebuggerUnloaded(); 5599a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5600a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Set a debug message handler. 5601a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetMessageHandler2(MessageHandlerHitCount); 5602a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5603a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Run code to throw a unhandled exception. This should end up in the message 5604a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // handler. 5605a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CompileRun("throw 1"); 5606a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5607a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // The message handler should be called. 5608a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_GT(message_handler_hit_count, 0); 5609a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5610a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Clear debug message handler. 5611a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block message_handler_hit_count = 0; 5612a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetMessageHandler(NULL); 5613a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5614a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Run code to throw a unhandled exception. This should end up in the message 5615a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // handler. 5616a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CompileRun("throw 1"); 5617a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5618a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // The message handler should not be called more. 5619a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(0, message_handler_hit_count); 5620a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5621a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CheckDebuggerUnloaded(true); 5622a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 5623a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5624a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5625a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Debugger message handler which clears the message handler while active. 5626a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic void MessageHandlerClearingMessageHandler( 5627a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const v8::Debug::Message& message) { 5628a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block message_handler_hit_count++; 5629a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5630a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Clear debug message handler. 5631a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetMessageHandler(NULL); 5632a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 5633a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5634a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5635a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Test clearing the debug message handler while processing a debug event. 5636a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(DebuggerClearMessageHandlerWhileActive) { 5637a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::HandleScope scope; 5638a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DebugLocalContext env; 5639a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5640a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Check debugger is unloaded before it is used. 5641a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CheckDebuggerUnloaded(); 5642a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5643a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Set a debug message handler. 5644a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetMessageHandler2(MessageHandlerClearingMessageHandler); 5645a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5646a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Run code to throw a unhandled exception. This should end up in the message 5647a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // handler. 5648a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CompileRun("throw 1"); 5649a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5650a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // The message handler should be called. 5651a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1, message_handler_hit_count); 5652a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5653a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CheckDebuggerUnloaded(true); 5654a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 5655a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5656a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5657a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block/* Test DebuggerHostDispatch */ 5658a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block/* In this test, the debugger waits for a command on a breakpoint 5659a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block * and is dispatching host commands while in the infinite loop. 5660a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block */ 5661a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5662a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass HostDispatchV8Thread : public v8::internal::Thread { 5663a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 56643fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch HostDispatchV8Thread() : Thread("HostDispatchV8Thread") { } 5665a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void Run(); 5666a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 5667a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5668a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass HostDispatchDebuggerThread : public v8::internal::Thread { 5669a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 56703fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch HostDispatchDebuggerThread() : Thread("HostDispatchDebuggerThread") { } 5671a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void Run(); 5672a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 5673a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5674a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockBarriers* host_dispatch_barriers; 5675a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5676a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic void HostDispatchMessageHandler(const v8::Debug::Message& message) { 5677a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static char print_buffer[1000]; 5678a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::String::Value json(message.GetJSON()); 5679a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Utf16ToAscii(*json, json.length(), print_buffer); 5680a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 5681a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5682a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5683a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic void HostDispatchDispatchHandler() { 5684a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block host_dispatch_barriers->semaphore_1->Signal(); 5685a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 5686a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5687a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5688a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid HostDispatchV8Thread::Run() { 5689a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const char* source_1 = "var y_global = 3;\n" 5690a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "function cat( new_value ) {\n" 5691a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " var x = new_value;\n" 5692a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " y_global = 4;\n" 5693a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " x = 3 * x + 1;\n" 5694a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " y_global = 5;\n" 5695a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " return x;\n" 5696a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "}\n" 5697a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "\n"; 5698a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const char* source_2 = "cat(17);\n"; 5699a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 57003fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch v8::V8::Initialize(); 5701a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::HandleScope scope; 5702a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DebugLocalContext env; 5703a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 57043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Set up message and host dispatch handlers. 5705a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetMessageHandler2(HostDispatchMessageHandler); 5706a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetHostDispatchHandler(HostDispatchDispatchHandler, 10 /* ms */); 5707a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5708a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CompileRun(source_1); 5709a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block host_dispatch_barriers->barrier_1.Wait(); 5710a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block host_dispatch_barriers->barrier_2.Wait(); 5711a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CompileRun(source_2); 5712a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 5713a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5714a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5715a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid HostDispatchDebuggerThread::Run() { 5716a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const int kBufSize = 1000; 5717a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block uint16_t buffer[kBufSize]; 5718a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5719a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const char* command_1 = "{\"seq\":101," 5720a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "\"type\":\"request\"," 5721a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "\"command\":\"setbreakpoint\"," 5722a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "\"arguments\":{\"type\":\"function\",\"target\":\"cat\",\"line\":3}}"; 5723a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const char* command_2 = "{\"seq\":102," 5724a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "\"type\":\"request\"," 5725a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "\"command\":\"continue\"}"; 5726a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5727a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // v8 thread initializes, runs source_1 5728a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block host_dispatch_barriers->barrier_1.Wait(); 5729a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // 1: Set breakpoint in cat(). 5730a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SendCommand(buffer, AsciiToUtf16(command_1, buffer)); 5731a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5732a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block host_dispatch_barriers->barrier_2.Wait(); 5733a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // v8 thread starts compiling source_2. 5734a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Break happens, to run queued commands and host dispatches. 5735a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Wait for host dispatch to be processed. 5736a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block host_dispatch_barriers->semaphore_1->Wait(); 5737a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // 2: Continue evaluation 5738a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SendCommand(buffer, AsciiToUtf16(command_2, buffer)); 5739a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 5740a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5741a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5742a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(DebuggerHostDispatch) { 57433fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch HostDispatchDebuggerThread host_dispatch_debugger_thread; 57443fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch HostDispatchV8Thread host_dispatch_v8_thread; 5745a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block i::FLAG_debugger_auto_break = true; 5746a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5747a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Create a V8 environment 5748a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Barriers stack_allocated_host_dispatch_barriers; 5749a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block stack_allocated_host_dispatch_barriers.Initialize(); 5750a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block host_dispatch_barriers = &stack_allocated_host_dispatch_barriers; 5751a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5752a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block host_dispatch_v8_thread.Start(); 5753a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block host_dispatch_debugger_thread.Start(); 5754a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5755a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block host_dispatch_v8_thread.Join(); 5756a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block host_dispatch_debugger_thread.Join(); 5757a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 5758a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5759a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5760d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block/* Test DebugMessageDispatch */ 5761d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block/* In this test, the V8 thread waits for a message from the debug thread. 5762d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block * The DebugMessageDispatchHandler is executed from the debugger thread 5763d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block * which signals the V8 thread to wake up. 5764d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block */ 5765d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 5766d0582a6c46733687d045e4188a1bcd0123c758a1Steve Blockclass DebugMessageDispatchV8Thread : public v8::internal::Thread { 5767d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block public: 57683fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch DebugMessageDispatchV8Thread() : Thread("DebugMessageDispatchV8Thread") { } 5769d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block void Run(); 5770d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block}; 5771d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 5772d0582a6c46733687d045e4188a1bcd0123c758a1Steve Blockclass DebugMessageDispatchDebuggerThread : public v8::internal::Thread { 5773d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block public: 57743fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch DebugMessageDispatchDebuggerThread() 57753fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch : Thread("DebugMessageDispatchDebuggerThread") { } 5776d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block void Run(); 5777d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block}; 5778d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 5779d0582a6c46733687d045e4188a1bcd0123c758a1Steve BlockBarriers* debug_message_dispatch_barriers; 5780d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 5781d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 5782d0582a6c46733687d045e4188a1bcd0123c758a1Steve Blockstatic void DebugMessageHandler() { 5783d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block debug_message_dispatch_barriers->semaphore_1->Signal(); 5784d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block} 5785d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 5786d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 5787d0582a6c46733687d045e4188a1bcd0123c758a1Steve Blockvoid DebugMessageDispatchV8Thread::Run() { 57883fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch v8::V8::Initialize(); 5789d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block v8::HandleScope scope; 5790d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block DebugLocalContext env; 5791d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 57923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Set up debug message dispatch handler. 5793d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block v8::Debug::SetDebugMessageDispatchHandler(DebugMessageHandler); 5794d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 5795d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block CompileRun("var y = 1 + 2;\n"); 5796d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block debug_message_dispatch_barriers->barrier_1.Wait(); 5797d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block debug_message_dispatch_barriers->semaphore_1->Wait(); 5798d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block debug_message_dispatch_barriers->barrier_2.Wait(); 5799d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block} 5800d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 5801d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 5802d0582a6c46733687d045e4188a1bcd0123c758a1Steve Blockvoid DebugMessageDispatchDebuggerThread::Run() { 5803d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block debug_message_dispatch_barriers->barrier_1.Wait(); 5804d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block SendContinueCommand(); 5805d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block debug_message_dispatch_barriers->barrier_2.Wait(); 5806d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block} 5807d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 5808d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 5809d0582a6c46733687d045e4188a1bcd0123c758a1Steve BlockTEST(DebuggerDebugMessageDispatch) { 58103fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch DebugMessageDispatchDebuggerThread debug_message_dispatch_debugger_thread; 58113fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch DebugMessageDispatchV8Thread debug_message_dispatch_v8_thread; 581244f0eee88ff00398ff7f715fab053374d808c90dSteve Block 5813d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block i::FLAG_debugger_auto_break = true; 5814d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 5815d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // Create a V8 environment 5816d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block Barriers stack_allocated_debug_message_dispatch_barriers; 5817d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block stack_allocated_debug_message_dispatch_barriers.Initialize(); 5818d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block debug_message_dispatch_barriers = 5819d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block &stack_allocated_debug_message_dispatch_barriers; 5820d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 5821d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block debug_message_dispatch_v8_thread.Start(); 5822d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block debug_message_dispatch_debugger_thread.Start(); 5823d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 5824d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block debug_message_dispatch_v8_thread.Join(); 5825d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block debug_message_dispatch_debugger_thread.Join(); 5826d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block} 5827d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 5828d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 5829a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(DebuggerAgent) { 583069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch v8::V8::Initialize(); 583144f0eee88ff00398ff7f715fab053374d808c90dSteve Block i::Debugger* debugger = i::Isolate::Current()->debugger(); 5832a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Make sure these ports is not used by other tests to allow tests to run in 5833a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // parallel. 5834a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const int kPort1 = 5858; 5835a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const int kPort2 = 5857; 5836a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const int kPort3 = 5856; 5837a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5838a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Make a string with the port2 number. 5839a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const int kPortBufferLen = 6; 5840a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block char port2_str[kPortBufferLen]; 5841a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block OS::SNPrintF(i::Vector<char>(port2_str, kPortBufferLen), "%d", kPort2); 5842a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5843a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool ok; 5844a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5845a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Initialize the socket library. 58463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch i::Socket::SetUp(); 5847a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5848a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Test starting and stopping the agent without any client connection. 584944f0eee88ff00398ff7f715fab053374d808c90dSteve Block debugger->StartAgent("test", kPort1); 585044f0eee88ff00398ff7f715fab053374d808c90dSteve Block debugger->StopAgent(); 5851a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Test starting the agent, connecting a client and shutting down the agent 5852a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // with the client connected. 585344f0eee88ff00398ff7f715fab053374d808c90dSteve Block ok = debugger->StartAgent("test", kPort2); 5854a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(ok); 585544f0eee88ff00398ff7f715fab053374d808c90dSteve Block debugger->WaitForAgent(); 5856a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block i::Socket* client = i::OS::CreateSocket(); 5857a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ok = client->Connect("localhost", port2_str); 5858a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(ok); 58593fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // It is important to wait for a message from the agent. Otherwise, 58603fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // we can close the server socket during "accept" syscall, making it failing 58613fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // (at least on Linux), and the test will work incorrectly. 58623fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch char buf; 58633fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ok = client->Receive(&buf, 1) == 1; 58643fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch CHECK(ok); 586544f0eee88ff00398ff7f715fab053374d808c90dSteve Block debugger->StopAgent(); 5866a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block delete client; 5867a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5868a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Test starting and stopping the agent with the required port already 5869a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // occoupied. 5870a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block i::Socket* server = i::OS::CreateSocket(); 5871a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block server->Bind(kPort3); 5872a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 587344f0eee88ff00398ff7f715fab053374d808c90dSteve Block debugger->StartAgent("test", kPort3); 587444f0eee88ff00398ff7f715fab053374d808c90dSteve Block debugger->StopAgent(); 5875a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5876a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block delete server; 5877a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 5878a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5879a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5880a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass DebuggerAgentProtocolServerThread : public i::Thread { 5881a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 58823fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch explicit DebuggerAgentProtocolServerThread(int port) 58833fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch : Thread("DebuggerAgentProtocolServerThread"), 588444f0eee88ff00398ff7f715fab053374d808c90dSteve Block port_(port), 588544f0eee88ff00398ff7f715fab053374d808c90dSteve Block server_(NULL), 588644f0eee88ff00398ff7f715fab053374d808c90dSteve Block client_(NULL), 5887a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block listening_(OS::CreateSemaphore(0)) { 5888a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 5889a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ~DebuggerAgentProtocolServerThread() { 5890a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Close both sockets. 5891a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block delete client_; 5892a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block delete server_; 5893a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block delete listening_; 5894a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 5895a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5896a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void Run(); 5897a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void WaitForListening() { listening_->Wait(); } 5898a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block char* body() { return *body_; } 5899a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5900a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private: 5901a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int port_; 5902589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch i::SmartArrayPointer<char> body_; 5903a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block i::Socket* server_; // Server socket used for bind/accept. 5904a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block i::Socket* client_; // Single client connection used by the test. 5905a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block i::Semaphore* listening_; // Signalled when the server is in listen mode. 5906a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 5907a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5908a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5909a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid DebuggerAgentProtocolServerThread::Run() { 5910a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool ok; 5911a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5912a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Create the server socket and bind it to the requested port. 5913a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block server_ = i::OS::CreateSocket(); 5914a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(server_ != NULL); 5915a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ok = server_->Bind(port_); 5916a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(ok); 5917a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5918a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Listen for new connections. 5919a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ok = server_->Listen(1); 5920a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(ok); 5921a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block listening_->Signal(); 5922a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5923a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Accept a connection. 5924a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block client_ = server_->Accept(); 5925a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(client_ != NULL); 5926a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5927a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Receive a debugger agent protocol message. 5928a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block i::DebuggerAgentUtil::ReceiveMessage(client_); 5929a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 5930a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5931a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5932a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(DebuggerAgentProtocolOverflowHeader) { 5933a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Make sure this port is not used by other tests to allow tests to run in 5934a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // parallel. 5935a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const int kPort = 5860; 5936a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static const char* kLocalhost = "localhost"; 5937a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5938a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Make a string with the port number. 5939a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const int kPortBufferLen = 6; 5940a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block char port_str[kPortBufferLen]; 5941a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block OS::SNPrintF(i::Vector<char>(port_str, kPortBufferLen), "%d", kPort); 5942a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5943a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Initialize the socket library. 59443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch i::Socket::SetUp(); 5945a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5946a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Create a socket server to receive a debugger agent message. 5947a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DebuggerAgentProtocolServerThread* server = 59483fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch new DebuggerAgentProtocolServerThread(kPort); 5949a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block server->Start(); 5950a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block server->WaitForListening(); 5951a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5952a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Connect. 5953a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block i::Socket* client = i::OS::CreateSocket(); 5954a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(client != NULL); 5955a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool ok = client->Connect(kLocalhost, port_str); 5956a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(ok); 5957a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5958a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Send headers which overflow the receive buffer. 5959a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static const int kBufferSize = 1000; 5960a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block char buffer[kBufferSize]; 5961a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5962a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Long key and short value: XXXX....XXXX:0\r\n. 5963a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (int i = 0; i < kBufferSize - 4; i++) { 5964a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block buffer[i] = 'X'; 5965a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 5966a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block buffer[kBufferSize - 4] = ':'; 5967a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block buffer[kBufferSize - 3] = '0'; 5968a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block buffer[kBufferSize - 2] = '\r'; 5969a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block buffer[kBufferSize - 1] = '\n'; 5970a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block client->Send(buffer, kBufferSize); 5971a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5972a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Short key and long value: X:XXXX....XXXX\r\n. 5973a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block buffer[0] = 'X'; 5974a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block buffer[1] = ':'; 5975a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (int i = 2; i < kBufferSize - 2; i++) { 5976a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block buffer[i] = 'X'; 5977a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 5978a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block buffer[kBufferSize - 2] = '\r'; 5979a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block buffer[kBufferSize - 1] = '\n'; 5980a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block client->Send(buffer, kBufferSize); 5981a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5982a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Add empty body to request. 5983a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const char* content_length_zero_header = "Content-Length:0\r\n"; 5984d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block client->Send(content_length_zero_header, 5985d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block StrLength(content_length_zero_header)); 5986a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block client->Send("\r\n", 2); 5987a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5988a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Wait until data is received. 5989a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block server->Join(); 5990a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5991a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Check for empty body. 5992a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(server->body() == NULL); 5993a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5994a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Close the client before the server to avoid TIME_WAIT issues. 5995a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block client->Shutdown(); 5996a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block delete client; 5997a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block delete server; 5998a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 5999a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6000a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6001a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Test for issue http://code.google.com/p/v8/issues/detail?id=289. 6002a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Make sure that DebugGetLoadedScripts doesn't return scripts 6003a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// with disposed external source. 6004a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass EmptyExternalStringResource : public v8::String::ExternalStringResource { 6005a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 6006a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EmptyExternalStringResource() { empty_[0] = 0; } 6007a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block virtual ~EmptyExternalStringResource() {} 6008a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block virtual size_t length() const { return empty_.length(); } 6009a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block virtual const uint16_t* data() const { return empty_.start(); } 6010a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private: 6011a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ::v8::internal::EmbeddedVector<uint16_t, 1> empty_; 6012a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 6013a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6014a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6015a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(DebugGetLoadedScripts) { 6016a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::HandleScope scope; 6017a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DebugLocalContext env; 6018a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block env.ExposeDebug(); 6019a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6020a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EmptyExternalStringResource source_ext_str; 6021a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Local<v8::String> source = v8::String::NewExternal(&source_ext_str); 60223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch v8::Handle<v8::Script> evil_script(v8::Script::Compile(source)); 60233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // "use" evil_script to make the compiler happy. 60243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch (void) evil_script; 6025a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<i::ExternalTwoByteString> i_source( 6026a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block i::ExternalTwoByteString::cast(*v8::Utils::OpenHandle(*source))); 6027a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // This situation can happen if source was an external string disposed 6028a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // by its owner. 6029a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block i_source->set_resource(0); 6030a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6031a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool allow_natives_syntax = i::FLAG_allow_natives_syntax; 6032a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block i::FLAG_allow_natives_syntax = true; 6033a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CompileRun( 6034a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "var scripts = %DebugGetLoadedScripts();" 6035a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "var count = scripts.length;" 6036a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "for (var i = 0; i < count; ++i) {" 6037a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " scripts[i].line_ends;" 6038a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "}"); 6039a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Must not crash while accessing line_ends. 6040a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block i::FLAG_allow_natives_syntax = allow_natives_syntax; 6041a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6042a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Some scripts are retrieved - at least the number of native scripts. 6043a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_GT((*env)->Global()->Get(v8::String::New("count"))->Int32Value(), 8); 6044a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 6045a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6046a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6047a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Test script break points set on lines. 6048a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(ScriptNameAndData) { 6049a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::HandleScope scope; 6050a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DebugLocalContext env; 6051a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block env.ExposeDebug(); 6052a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6053a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Create functions for retrieving script name and data for the function on 6054a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // the top frame when hitting a break point. 6055a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block frame_script_name = CompileFunction(&env, 6056a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block frame_script_name_source, 6057a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "frame_script_name"); 6058a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block frame_script_data = CompileFunction(&env, 6059a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block frame_script_data_source, 6060a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "frame_script_data"); 6061402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu compiled_script_data = CompileFunction(&env, 6062402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu compiled_script_data_source, 6063402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu "compiled_script_data"); 6064a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6065a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount, 6066a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Undefined()); 6067a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6068a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Test function source. 6069a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Local<v8::String> script = v8::String::New( 6070a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "function f() {\n" 6071a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " debugger;\n" 6072a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "}\n"); 6073a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6074a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::ScriptOrigin origin1 = v8::ScriptOrigin(v8::String::New("name")); 6075a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<v8::Script> script1 = v8::Script::Compile(script, &origin1); 6076a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block script1->SetData(v8::String::New("data")); 6077a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block script1->Run(); 6078a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Local<v8::Function> f; 6079a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block f = v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("f"))); 6080a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6081a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block f->Call(env->Global(), 0, NULL); 6082a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1, break_point_hit_count); 6083a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ("name", last_script_name_hit); 6084a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ("data", last_script_data_hit); 6085a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6086a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Compile the same script again without setting data. As the compilation 6087a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // cache is disabled when debugging expect the data to be missing. 6088a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Script::Compile(script, &origin1)->Run(); 6089a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block f = v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("f"))); 6090a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block f->Call(env->Global(), 0, NULL); 6091a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(2, break_point_hit_count); 6092a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ("name", last_script_name_hit); 6093a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ("", last_script_data_hit); // Undefined results in empty string. 6094a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6095a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Local<v8::String> data_obj_source = v8::String::New( 6096a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "({ a: 'abc',\n" 6097a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " b: 123,\n" 6098a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " toString: function() { return this.a + ' ' + this.b; }\n" 6099a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "})\n"); 6100a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Local<v8::Value> data_obj = v8::Script::Compile(data_obj_source)->Run(); 6101a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::ScriptOrigin origin2 = v8::ScriptOrigin(v8::String::New("new name")); 6102a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<v8::Script> script2 = v8::Script::Compile(script, &origin2); 6103a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block script2->Run(); 6104d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block script2->SetData(data_obj->ToString()); 6105a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block f = v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("f"))); 6106a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block f->Call(env->Global(), 0, NULL); 6107a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(3, break_point_hit_count); 6108a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ("new name", last_script_name_hit); 6109a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ("abc 123", last_script_data_hit); 6110402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu 6111402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu v8::Handle<v8::Script> script3 = 6112402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu v8::Script::Compile(script, &origin2, NULL, 6113402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu v8::String::New("in compile")); 6114402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu CHECK_EQ("in compile", last_script_data_hit); 6115402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu script3->Run(); 6116402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu f = v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("f"))); 6117402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu f->Call(env->Global(), 0, NULL); 6118402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu CHECK_EQ(4, break_point_hit_count); 6119402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu CHECK_EQ("in compile", last_script_data_hit); 6120a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 6121a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6122a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6123a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic v8::Persistent<v8::Context> expected_context; 6124a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic v8::Handle<v8::Value> expected_context_data; 6125a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6126a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6127a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Check that the expected context is the one generating the debug event. 6128a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic void ContextCheckMessageHandler(const v8::Debug::Message& message) { 6129a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(message.GetEventContext() == expected_context); 6130a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(message.GetEventContext()->GetData()->StrictEquals( 6131a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block expected_context_data)); 6132a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block message_handler_hit_count++; 6133a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 61343ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block static char print_buffer[1000]; 61353ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block v8::String::Value json(message.GetJSON()); 61363ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block Utf16ToAscii(*json, json.length(), print_buffer); 61373ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 6138a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Send a continue command for break events. 61393ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block if (IsBreakEventMessage(print_buffer)) { 6140a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block SendContinueCommand(); 6141a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 6142a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 6143a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6144a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6145a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Test which creates two contexts and sets different embedder data on each. 6146a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Checks that this data is set correctly and that when the debug message 6147a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// handler is called the expected context is the one active. 6148a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(ContextData) { 6149a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::HandleScope scope; 6150a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6151a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetMessageHandler2(ContextCheckMessageHandler); 6152a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6153a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Create two contexts. 6154a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Persistent<v8::Context> context_1; 6155a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Persistent<v8::Context> context_2; 6156a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<v8::ObjectTemplate> global_template = 6157a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<v8::ObjectTemplate>(); 6158a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<v8::Value> global_object = v8::Handle<v8::Value>(); 6159a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block context_1 = v8::Context::New(NULL, global_template, global_object); 6160a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block context_2 = v8::Context::New(NULL, global_template, global_object); 6161a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6162a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Default data value is undefined. 6163a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(context_1->GetData()->IsUndefined()); 6164a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(context_2->GetData()->IsUndefined()); 6165a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6166a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Set and check different data values. 6167d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block v8::Handle<v8::String> data_1 = v8::String::New("1"); 6168d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block v8::Handle<v8::String> data_2 = v8::String::New("2"); 6169a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block context_1->SetData(data_1); 6170a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block context_2->SetData(data_2); 6171a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(context_1->GetData()->StrictEquals(data_1)); 6172a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(context_2->GetData()->StrictEquals(data_2)); 6173a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6174a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Simple test function which causes a break. 6175a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const char* source = "function f() { debugger; }"; 6176a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6177a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Enter and run function in the first context. 6178a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block { 6179a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Context::Scope context_scope(context_1); 6180a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block expected_context = context_1; 6181a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block expected_context_data = data_1; 6182a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Local<v8::Function> f = CompileFunction(source, "f"); 6183a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block f->Call(context_1->Global(), 0, NULL); 6184a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 6185a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6186a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6187a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Enter and run function in the second context. 6188a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block { 6189a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Context::Scope context_scope(context_2); 6190a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block expected_context = context_2; 6191a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block expected_context_data = data_2; 6192a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Local<v8::Function> f = CompileFunction(source, "f"); 6193a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block f->Call(context_2->Global(), 0, NULL); 6194a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 6195a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6196a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Two times compile event and two times break event. 6197a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_GT(message_handler_hit_count, 4); 6198a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6199a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetMessageHandler2(NULL); 6200a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CheckDebuggerUnloaded(); 6201a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 6202a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6203a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6204a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Debug message handler which issues a debug break when it hits a break event. 6205a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic int message_handler_break_hit_count = 0; 6206a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic void DebugBreakMessageHandler(const v8::Debug::Message& message) { 6207a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Schedule a debug break for break events. 6208a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (message.IsEvent() && message.GetEvent() == v8::Break) { 6209a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block message_handler_break_hit_count++; 6210a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (message_handler_break_hit_count == 1) { 6211a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::DebugBreak(); 6212a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 6213a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 6214a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6215a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Issue a continue command if this event will not cause the VM to start 6216a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // running. 6217a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!message.WillStartRunning()) { 6218a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block SendContinueCommand(); 6219a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 6220a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 6221a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6222a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6223a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Test that a debug break can be scheduled while in a message handler. 6224a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(DebugBreakInMessageHandler) { 6225a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::HandleScope scope; 6226a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DebugLocalContext env; 6227a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6228a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetMessageHandler2(DebugBreakMessageHandler); 6229a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6230a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Test functions. 6231a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const char* script = "function f() { debugger; g(); } function g() { }"; 6232a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CompileRun(script); 6233a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Local<v8::Function> f = 6234a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("f"))); 6235a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Local<v8::Function> g = 6236a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("g"))); 6237a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6238a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Call f then g. The debugger statement in f will casue a break which will 6239a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // cause another break. 6240a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block f->Call(env->Global(), 0, NULL); 6241a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(2, message_handler_break_hit_count); 6242a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Calling g will not cause any additional breaks. 6243a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block g->Call(env->Global(), 0, NULL); 6244a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(2, message_handler_break_hit_count); 6245a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 6246a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6247a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 62486ded16be15dd865a9b21ea304d5273c8be299c87Steve Block#ifndef V8_INTERPRETED_REGEXP 6249a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Debug event handler which gets the function on the top frame and schedules a 6250a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// break a number of times. 6251a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic void DebugEventDebugBreak( 6252a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::DebugEvent event, 6253a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<v8::Object> exec_state, 6254a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<v8::Object> event_data, 6255a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<v8::Value> data) { 6256a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6257a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (event == v8::Break) { 6258a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count++; 6259a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6260a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Get the name of the top frame function. 6261a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!frame_function_name.IsEmpty()) { 6262a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Get the name of the function. 6263b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch const int argc = 2; 6264b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch v8::Handle<v8::Value> argv[argc] = { exec_state, v8::Integer::New(0) }; 6265a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<v8::Value> result = frame_function_name->Call(exec_state, 6266a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block argc, argv); 6267a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (result->IsUndefined()) { 6268a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_function_hit[0] = '\0'; 6269a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 6270a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(result->IsString()); 6271a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<v8::String> function_name(result->ToString()); 6272a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block function_name->WriteAscii(last_function_hit); 6273a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 6274a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 6275a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6276a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Keep forcing breaks. 6277a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (break_point_hit_count < 20) { 6278a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::DebugBreak(); 6279a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 6280a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 6281a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 6282a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6283a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6284a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(RegExpDebugBreak) { 6285a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // This test only applies to native regexps. 6286a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::HandleScope scope; 6287a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DebugLocalContext env; 6288a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6289a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Create a function for checking the function when hitting a break point. 6290a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block frame_function_name = CompileFunction(&env, 6291a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block frame_function_name_source, 6292a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "frame_function_name"); 6293a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6294a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Test RegExp which matches white spaces and comments at the begining of a 6295a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // source line. 6296a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const char* script = 6297a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "var sourceLineBeginningSkip = /^(?:[ \\v\\h]*(?:\\/\\*.*?\\*\\/)*)*/;\n" 6298a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "function f(s) { return s.match(sourceLineBeginningSkip)[0].length; }"; 6299a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6300a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Local<v8::Function> f = CompileFunction(script, "f"); 6301a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const int argc = 1; 6302a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<v8::Value> argv[argc] = { v8::String::New(" /* xxx */ a=0;") }; 6303a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Local<v8::Value> result = f->Call(env->Global(), argc, argv); 6304a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(12, result->Int32Value()); 6305a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6306a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetDebugEventListener(DebugEventDebugBreak); 6307a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::DebugBreak(); 6308a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block result = f->Call(env->Global(), argc, argv); 6309a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6310a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Check that there was only one break event. Matching RegExp should not 6311a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // cause Break events. 6312a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1, break_point_hit_count); 6313a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ("f", last_function_hit); 6314a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 63156ded16be15dd865a9b21ea304d5273c8be299c87Steve Block#endif // V8_INTERPRETED_REGEXP 6316a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6317a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6318a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Common part of EvalContextData and NestedBreakEventContextData tests. 6319a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic void ExecuteScriptForContextCheck() { 6320a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Create a context. 6321a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Persistent<v8::Context> context_1; 6322a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<v8::ObjectTemplate> global_template = 6323a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<v8::ObjectTemplate>(); 6324257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch context_1 = v8::Context::New(NULL, global_template); 6325a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6326a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Default data value is undefined. 6327a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(context_1->GetData()->IsUndefined()); 6328a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6329a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Set and check a data value. 6330d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block v8::Handle<v8::String> data_1 = v8::String::New("1"); 6331a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block context_1->SetData(data_1); 6332a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(context_1->GetData()->StrictEquals(data_1)); 6333a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6334a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Simple test function with eval that causes a break. 6335a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const char* source = "function f() { eval('debugger;'); }"; 6336a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6337a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Enter and run function in the context. 6338a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block { 6339a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Context::Scope context_scope(context_1); 6340a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block expected_context = context_1; 6341a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block expected_context_data = data_1; 6342a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Local<v8::Function> f = CompileFunction(source, "f"); 6343a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block f->Call(context_1->Global(), 0, NULL); 6344a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 6345a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 6346a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6347a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6348a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Test which creates a context and sets embedder data on it. Checks that this 6349a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// data is set correctly and that when the debug message handler is called for 6350a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// break event in an eval statement the expected context is the one returned by 6351a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Message.GetEventContext. 6352a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(EvalContextData) { 6353a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::HandleScope scope; 6354a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetMessageHandler2(ContextCheckMessageHandler); 6355a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6356a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ExecuteScriptForContextCheck(); 6357a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6358a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // One time compile event and one time break event. 6359a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_GT(message_handler_hit_count, 2); 6360a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetMessageHandler2(NULL); 6361a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CheckDebuggerUnloaded(); 6362a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 6363a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6364a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6365a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic bool sent_eval = false; 6366a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic int break_count = 0; 6367a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic int continue_command_send_count = 0; 6368a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Check that the expected context is the one generating the debug event 6369a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// including the case of nested break event. 6370a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic void DebugEvalContextCheckMessageHandler( 6371a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const v8::Debug::Message& message) { 6372a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(message.GetEventContext() == expected_context); 6373a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(message.GetEventContext()->GetData()->StrictEquals( 6374a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block expected_context_data)); 6375a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block message_handler_hit_count++; 6376a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 63773ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block static char print_buffer[1000]; 63783ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block v8::String::Value json(message.GetJSON()); 63793ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block Utf16ToAscii(*json, json.length(), print_buffer); 63803ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 63813ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block if (IsBreakEventMessage(print_buffer)) { 6382a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_count++; 6383a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!sent_eval) { 6384a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block sent_eval = true; 6385a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6386a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const int kBufferSize = 1000; 6387a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block uint16_t buffer[kBufferSize]; 6388a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const char* eval_command = 6389257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch "{\"seq\":0," 6390257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch "\"type\":\"request\"," 6391257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch "\"command\":\"evaluate\"," 6392257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch "\"arguments\":{\"expression\":\"debugger;\"," 6393257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch "\"global\":true,\"disable_break\":false}}"; 6394a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6395a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Send evaluate command. 6396a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SendCommand(buffer, AsciiToUtf16(eval_command, buffer)); 6397a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return; 6398a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 6399a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // It's a break event caused by the evaluation request above. 6400a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block SendContinueCommand(); 6401a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block continue_command_send_count++; 6402a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 64033ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block } else if (IsEvaluateResponseMessage(print_buffer) && 64043ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block continue_command_send_count < 2) { 6405a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Response to the evaluation request. We're still on the breakpoint so 6406a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // send continue. 6407a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block SendContinueCommand(); 6408a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block continue_command_send_count++; 6409a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 6410a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 6411a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6412a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6413a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Tests that context returned for break event is correct when the event occurs 6414a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// in 'evaluate' debugger request. 6415a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(NestedBreakEventContextData) { 6416a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::HandleScope scope; 6417a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_count = 0; 6418a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block message_handler_hit_count = 0; 6419a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetMessageHandler2(DebugEvalContextCheckMessageHandler); 6420a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6421a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ExecuteScriptForContextCheck(); 6422a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6423a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // One time compile event and two times break event. 6424a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_GT(message_handler_hit_count, 3); 6425a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6426a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // One break from the source and another from the evaluate request. 6427a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(break_count, 2); 6428a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetMessageHandler2(NULL); 6429a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CheckDebuggerUnloaded(); 6430a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 6431a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6432a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6433a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Debug event listener which counts the script collected events. 6434a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockint script_collected_count = 0; 6435a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic void DebugEventScriptCollectedEvent(v8::DebugEvent event, 6436a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<v8::Object> exec_state, 6437a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<v8::Object> event_data, 6438a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<v8::Value> data) { 6439a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Count the number of breaks. 6440a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (event == v8::ScriptCollected) { 6441a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block script_collected_count++; 6442a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 6443a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 6444a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6445a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6446a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Test that scripts collected are reported through the debug event listener. 6447a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(ScriptCollectedEvent) { 644844f0eee88ff00398ff7f715fab053374d808c90dSteve Block v8::internal::Debug* debug = v8::internal::Isolate::Current()->debug(); 6449a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 6450a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block script_collected_count = 0; 6451a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::HandleScope scope; 6452a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DebugLocalContext env; 6453a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6454a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Request the loaded scripts to initialize the debugger script cache. 645544f0eee88ff00398ff7f715fab053374d808c90dSteve Block debug->GetLoadedScripts(); 6456a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6457a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Do garbage collection to ensure that only the script in this test will be 6458a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // collected afterwards. 64593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch HEAP->CollectAllGarbage(Heap::kNoGCFlags); 6460a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6461a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block script_collected_count = 0; 6462a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetDebugEventListener(DebugEventScriptCollectedEvent, 6463a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Undefined()); 6464a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block { 6465a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Script::Compile(v8::String::New("eval('a=1')"))->Run(); 6466a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Script::Compile(v8::String::New("eval('a=2')"))->Run(); 6467a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 6468a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6469a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Do garbage collection to collect the script above which is no longer 6470a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // referenced. 64713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch HEAP->CollectAllGarbage(Heap::kNoGCFlags); 6472a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6473a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(2, script_collected_count); 6474a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6475a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetDebugEventListener(NULL); 6476a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CheckDebuggerUnloaded(); 6477a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 6478a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6479a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6480a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Debug event listener which counts the script collected events. 6481a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockint script_collected_message_count = 0; 6482a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic void ScriptCollectedMessageHandler(const v8::Debug::Message& message) { 6483a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Count the number of scripts collected. 6484a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (message.IsEvent() && message.GetEvent() == v8::ScriptCollected) { 6485a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block script_collected_message_count++; 6486a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<v8::Context> context = message.GetEventContext(); 6487a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(context.IsEmpty()); 6488a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 6489a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 6490a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6491a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6492a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Test that GetEventContext doesn't fail and return empty handle for 6493a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ScriptCollected events. 6494a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(ScriptCollectedEventContext) { 649544f0eee88ff00398ff7f715fab053374d808c90dSteve Block v8::internal::Debug* debug = v8::internal::Isolate::Current()->debug(); 6496a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block script_collected_message_count = 0; 6497a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::HandleScope scope; 6498a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6499a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block { // Scope for the DebugLocalContext. 6500a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DebugLocalContext env; 6501a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6502a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Request the loaded scripts to initialize the debugger script cache. 650344f0eee88ff00398ff7f715fab053374d808c90dSteve Block debug->GetLoadedScripts(); 6504a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6505a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Do garbage collection to ensure that only the script in this test will be 6506a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // collected afterwards. 65073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch HEAP->CollectAllGarbage(Heap::kNoGCFlags); 6508a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6509a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetMessageHandler2(ScriptCollectedMessageHandler); 6510a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block { 6511a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Script::Compile(v8::String::New("eval('a=1')"))->Run(); 6512a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Script::Compile(v8::String::New("eval('a=2')"))->Run(); 6513a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 6514a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 6515a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6516a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Do garbage collection to collect the script above which is no longer 6517a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // referenced. 65183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch HEAP->CollectAllGarbage(Heap::kNoGCFlags); 6519a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6520a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(2, script_collected_message_count); 6521a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6522a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetMessageHandler2(NULL); 6523a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 6524a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6525a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6526a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Debug event listener which counts the after compile events. 6527a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockint after_compile_message_count = 0; 6528a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic void AfterCompileMessageHandler(const v8::Debug::Message& message) { 6529a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Count the number of scripts collected. 6530a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (message.IsEvent()) { 6531a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (message.GetEvent() == v8::AfterCompile) { 6532a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block after_compile_message_count++; 6533a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else if (message.GetEvent() == v8::Break) { 6534a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block SendContinueCommand(); 6535a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 6536a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 6537a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 6538a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6539a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6540a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Tests that after compile event is sent as many times as there are scripts 6541a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// compiled. 6542a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(AfterCompileMessageWhenMessageHandlerIsReset) { 6543a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::HandleScope scope; 6544a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DebugLocalContext env; 6545a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block after_compile_message_count = 0; 6546a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const char* script = "var a=1"; 6547a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6548a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetMessageHandler2(AfterCompileMessageHandler); 6549a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Script::Compile(v8::String::New(script))->Run(); 6550a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetMessageHandler2(NULL); 6551a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6552a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetMessageHandler2(AfterCompileMessageHandler); 6553a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::DebugBreak(); 6554a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Script::Compile(v8::String::New(script))->Run(); 6555a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6556a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Setting listener to NULL should cause debugger unload. 6557a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetMessageHandler2(NULL); 6558a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CheckDebuggerUnloaded(); 6559a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6560a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Compilation cache should be disabled when debugger is active. 6561a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(2, after_compile_message_count); 6562a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 6563a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6564a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6565a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Tests that break event is sent when message handler is reset. 6566a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(BreakMessageWhenMessageHandlerIsReset) { 6567a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::HandleScope scope; 6568a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DebugLocalContext env; 6569a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block after_compile_message_count = 0; 6570a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const char* script = "function f() {};"; 6571a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6572a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetMessageHandler2(AfterCompileMessageHandler); 6573a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Script::Compile(v8::String::New(script))->Run(); 6574a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetMessageHandler2(NULL); 6575a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6576a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetMessageHandler2(AfterCompileMessageHandler); 6577a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::DebugBreak(); 6578a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Local<v8::Function> f = 6579a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("f"))); 6580a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block f->Call(env->Global(), 0, NULL); 6581a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6582a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Setting message handler to NULL should cause debugger unload. 6583a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetMessageHandler2(NULL); 6584a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CheckDebuggerUnloaded(); 6585a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6586a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Compilation cache should be disabled when debugger is active. 6587a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1, after_compile_message_count); 6588a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 6589a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6590a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6591a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic int exception_event_count = 0; 6592a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic void ExceptionMessageHandler(const v8::Debug::Message& message) { 6593a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (message.IsEvent() && message.GetEvent() == v8::Exception) { 6594a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block exception_event_count++; 6595a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block SendContinueCommand(); 6596a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 6597a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 6598a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6599a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6600a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Tests that exception event is sent when message handler is reset. 6601a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(ExceptionMessageWhenMessageHandlerIsReset) { 6602a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::HandleScope scope; 6603a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DebugLocalContext env; 6604086aeeaae12517475c22695a200be45495516549Ben Murdoch 6605086aeeaae12517475c22695a200be45495516549Ben Murdoch // For this test, we want to break on uncaught exceptions: 6606086aeeaae12517475c22695a200be45495516549Ben Murdoch ChangeBreakOnException(false, true); 6607086aeeaae12517475c22695a200be45495516549Ben Murdoch 6608a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block exception_event_count = 0; 6609a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const char* script = "function f() {throw new Error()};"; 6610a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6611a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetMessageHandler2(AfterCompileMessageHandler); 6612a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Script::Compile(v8::String::New(script))->Run(); 6613a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetMessageHandler2(NULL); 6614a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6615a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetMessageHandler2(ExceptionMessageHandler); 6616a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Local<v8::Function> f = 6617a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("f"))); 6618a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block f->Call(env->Global(), 0, NULL); 6619a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6620a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Setting message handler to NULL should cause debugger unload. 6621a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetMessageHandler2(NULL); 6622a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CheckDebuggerUnloaded(); 6623a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6624a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1, exception_event_count); 6625a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 6626a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6627a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6628a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Tests after compile event is sent when there are some provisional 6629a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// breakpoints out of the scripts lines range. 6630a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(ProvisionalBreakpointOnLineOutOfRange) { 6631a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::HandleScope scope; 6632a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DebugLocalContext env; 6633a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block env.ExposeDebug(); 6634a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const char* script = "function f() {};"; 6635a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const char* resource_name = "test_resource"; 6636a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6637a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Set a couple of provisional breakpoint on lines out of the script lines 6638a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // range. 6639a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int sbp1 = SetScriptBreakPointByNameFromJS(resource_name, 3, 6640a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block -1 /* no column */); 6641a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int sbp2 = SetScriptBreakPointByNameFromJS(resource_name, 5, 5); 6642a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6643a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block after_compile_message_count = 0; 6644a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetMessageHandler2(AfterCompileMessageHandler); 6645a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6646a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::ScriptOrigin origin( 6647a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::String::New(resource_name), 6648a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Integer::New(10), 6649a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Integer::New(1)); 6650a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Compile a script whose first line number is greater than the breakpoints' 6651a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // lines. 6652a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Script::Compile(v8::String::New(script), &origin)->Run(); 6653a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6654a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // If the script is compiled successfully there is exactly one after compile 6655a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // event. In case of an exception in debugger code after compile event is not 6656a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // sent. 6657a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1, after_compile_message_count); 6658a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6659a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ClearBreakPointFromJS(sbp1); 6660a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ClearBreakPointFromJS(sbp2); 6661a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetMessageHandler2(NULL); 6662a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 6663a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6664a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6665a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic void BreakMessageHandler(const v8::Debug::Message& message) { 666644f0eee88ff00398ff7f715fab053374d808c90dSteve Block i::Isolate* isolate = i::Isolate::Current(); 6667a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (message.IsEvent() && message.GetEvent() == v8::Break) { 6668a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Count the number of breaks. 6669a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count++; 6670a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6671a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::HandleScope scope; 66723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch message.GetJSON(); 6673a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6674a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block SendContinueCommand(); 6675a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else if (message.IsEvent() && message.GetEvent() == v8::AfterCompile) { 6676a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::HandleScope scope; 6677a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 667844f0eee88ff00398ff7f715fab053374d808c90dSteve Block bool is_debug_break = isolate->stack_guard()->IsDebugBreak(); 6679a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Force DebugBreak flag while serializer is working. 668044f0eee88ff00398ff7f715fab053374d808c90dSteve Block isolate->stack_guard()->DebugBreak(); 6681a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6682a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Force serialization to trigger some internal JS execution. 66833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch message.GetJSON(); 6684a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6685a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Restore previous state. 6686a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (is_debug_break) { 668744f0eee88ff00398ff7f715fab053374d808c90dSteve Block isolate->stack_guard()->DebugBreak(); 6688a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 668944f0eee88ff00398ff7f715fab053374d808c90dSteve Block isolate->stack_guard()->Continue(i::DEBUGBREAK); 6690a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 6691a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 6692a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 6693a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6694a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6695a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Test that if DebugBreak is forced it is ignored when code from 6696a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// debug-delay.js is executed. 6697a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(NoDebugBreakInAfterCompileMessageHandler) { 6698a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::HandleScope scope; 6699a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DebugLocalContext env; 6700a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6701a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Register a debug event listener which sets the break flag and counts. 6702a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetMessageHandler2(BreakMessageHandler); 6703a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6704a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Set the debug break flag. 6705a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::DebugBreak(); 6706a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6707a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Create a function for testing stepping. 6708a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const char* src = "function f() { eval('var x = 10;'); } "; 6709a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Local<v8::Function> f = CompileFunction(&env, src, "f"); 6710a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6711a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // There should be only one break event. 6712a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1, break_point_hit_count); 6713a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6714a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Set the debug break flag again. 6715a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::DebugBreak(); 6716a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block f->Call(env->Global(), 0, NULL); 6717a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // There should be one more break event when the script is evaluated in 'f'. 6718a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(2, break_point_hit_count); 6719a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6720a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Get rid of the debug message handler. 6721a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetMessageHandler2(NULL); 6722a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CheckDebuggerUnloaded(); 6723a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 6724a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6725a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6726e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarkestatic int counting_message_handler_counter; 6727e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 6728e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarkestatic void CountingMessageHandler(const v8::Debug::Message& message) { 6729e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke counting_message_handler_counter++; 6730e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke} 6731e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 6732e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke// Test that debug messages get processed when ProcessDebugMessages is called. 6733e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon ClarkeTEST(ProcessDebugMessages) { 6734e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke v8::HandleScope scope; 6735e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke DebugLocalContext env; 6736e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 6737e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke counting_message_handler_counter = 0; 6738e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 6739e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke v8::Debug::SetMessageHandler2(CountingMessageHandler); 6740e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 6741e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke const int kBufferSize = 1000; 6742e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke uint16_t buffer[kBufferSize]; 6743e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke const char* scripts_command = 6744e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke "{\"seq\":0," 6745e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke "\"type\":\"request\"," 6746e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke "\"command\":\"scripts\"}"; 6747e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 6748e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // Send scripts command. 6749e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke v8::Debug::SendCommand(buffer, AsciiToUtf16(scripts_command, buffer)); 6750e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 6751e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke CHECK_EQ(0, counting_message_handler_counter); 6752e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke v8::Debug::ProcessDebugMessages(); 6753e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // At least one message should come 6754e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke CHECK_GE(counting_message_handler_counter, 1); 6755e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 6756e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke counting_message_handler_counter = 0; 6757e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 6758e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke v8::Debug::SendCommand(buffer, AsciiToUtf16(scripts_command, buffer)); 6759e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke v8::Debug::SendCommand(buffer, AsciiToUtf16(scripts_command, buffer)); 6760e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke CHECK_EQ(0, counting_message_handler_counter); 6761e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke v8::Debug::ProcessDebugMessages(); 6762e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // At least two messages should come 6763e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke CHECK_GE(counting_message_handler_counter, 2); 6764e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 6765e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // Get rid of the debug message handler. 6766e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke v8::Debug::SetMessageHandler2(NULL); 6767e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke CheckDebuggerUnloaded(); 6768e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke} 6769e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 6770e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 67716ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockstruct BacktraceData { 6772d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke static int frame_counter; 6773d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke static void MessageHandler(const v8::Debug::Message& message) { 6774d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke char print_buffer[1000]; 6775d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke v8::String::Value json(message.GetJSON()); 6776d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Utf16ToAscii(*json, json.length(), print_buffer, 1000); 6777d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 6778d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke if (strstr(print_buffer, "backtrace") == NULL) { 6779d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke return; 6780d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 6781d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke frame_counter = GetTotalFramesInt(print_buffer); 6782d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 6783d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke}; 6784d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 67856ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockint BacktraceData::frame_counter; 6786d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 6787d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 6788d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke// Test that debug messages get processed when ProcessDebugMessages is called. 6789d91b9f7d46489a9ee00f9cb415630299c76a502bLeon ClarkeTEST(Backtrace) { 6790d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke v8::HandleScope scope; 6791d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke DebugLocalContext env; 6792d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 67936ded16be15dd865a9b21ea304d5273c8be299c87Steve Block v8::Debug::SetMessageHandler2(BacktraceData::MessageHandler); 6794d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 6795d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke const int kBufferSize = 1000; 6796d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke uint16_t buffer[kBufferSize]; 6797d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke const char* scripts_command = 6798d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke "{\"seq\":0," 6799d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke "\"type\":\"request\"," 6800d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke "\"command\":\"backtrace\"}"; 6801d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 6802d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Check backtrace from ProcessDebugMessages. 68036ded16be15dd865a9b21ea304d5273c8be299c87Steve Block BacktraceData::frame_counter = -10; 6804d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke v8::Debug::SendCommand(buffer, AsciiToUtf16(scripts_command, buffer)); 6805d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke v8::Debug::ProcessDebugMessages(); 68066ded16be15dd865a9b21ea304d5273c8be299c87Steve Block CHECK_EQ(BacktraceData::frame_counter, 0); 6807d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 6808d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke v8::Handle<v8::String> void0 = v8::String::New("void(0)"); 6809d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke v8::Handle<v8::Script> script = v8::Script::Compile(void0, void0); 6810d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 6811d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Check backtrace from "void(0)" script. 68126ded16be15dd865a9b21ea304d5273c8be299c87Steve Block BacktraceData::frame_counter = -10; 6813d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke v8::Debug::SendCommand(buffer, AsciiToUtf16(scripts_command, buffer)); 6814d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke script->Run(); 68156ded16be15dd865a9b21ea304d5273c8be299c87Steve Block CHECK_EQ(BacktraceData::frame_counter, 1); 6816d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 6817d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Get rid of the debug message handler. 6818d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke v8::Debug::SetMessageHandler2(NULL); 6819d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke CheckDebuggerUnloaded(); 6820d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 6821d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 6822d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 6823a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(GetMirror) { 6824a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::HandleScope scope; 6825a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DebugLocalContext env; 6826a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<v8::Value> obj = v8::Debug::GetMirror(v8::String::New("hodja")); 6827a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<v8::Function> run_test = v8::Handle<v8::Function>::Cast( 6828a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Script::New( 6829a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::String::New( 6830a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "function runTest(mirror) {" 6831a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " return mirror.isString() && (mirror.length() == 5);" 6832a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "}" 6833a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "" 6834a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "runTest;"))->Run()); 6835a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<v8::Value> result = run_test->Call(env->Global(), 1, &obj); 6836a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(result->IsTrue()); 6837a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 6838d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 6839d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 6840d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block// Test that the debug break flag works with function.apply. 6841d0582a6c46733687d045e4188a1bcd0123c758a1Steve BlockTEST(DebugBreakFunctionApply) { 6842d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block v8::HandleScope scope; 6843d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block DebugLocalContext env; 6844d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 6845d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // Create a function for testing breaking in apply. 6846d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block v8::Local<v8::Function> foo = CompileFunction( 6847d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block &env, 6848d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block "function baz(x) { }" 6849d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block "function bar(x) { baz(); }" 6850d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block "function foo(){ bar.apply(this, [1]); }", 6851d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block "foo"); 6852d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 6853d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // Register a debug event listener which steps and counts. 6854d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block v8::Debug::SetDebugEventListener(DebugEventBreakMax); 6855d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 6856d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // Set the debug break flag before calling the code using function.apply. 6857d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block v8::Debug::DebugBreak(); 6858d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 6859d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // Limit the number of debug breaks. This is a regression test for issue 493 6860d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // where this test would enter an infinite loop. 6861d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block break_point_hit_count = 0; 6862d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block max_break_point_hit_count = 10000; // 10000 => infinite loop. 6863d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block foo->Call(env->Global(), 0, NULL); 6864d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 6865d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // When keeping the debug break several break will happen. 68663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CHECK_GT(break_point_hit_count, 1); 6867d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 6868d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block v8::Debug::SetDebugEventListener(NULL); 6869d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block CheckDebuggerUnloaded(); 6870d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block} 6871d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 6872d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 6873d0582a6c46733687d045e4188a1bcd0123c758a1Steve Blockv8::Handle<v8::Context> debugee_context; 6874d0582a6c46733687d045e4188a1bcd0123c758a1Steve Blockv8::Handle<v8::Context> debugger_context; 6875d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 6876d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 6877d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block// Property getter that checks that current and calling contexts 6878d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block// are both the debugee contexts. 6879d0582a6c46733687d045e4188a1bcd0123c758a1Steve Blockstatic v8::Handle<v8::Value> NamedGetterWithCallingContextCheck( 6880d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block v8::Local<v8::String> name, 6881d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block const v8::AccessorInfo& info) { 6882d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block CHECK_EQ(0, strcmp(*v8::String::AsciiValue(name), "a")); 6883d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block v8::Handle<v8::Context> current = v8::Context::GetCurrent(); 6884d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block CHECK(current == debugee_context); 6885d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block CHECK(current != debugger_context); 6886d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block v8::Handle<v8::Context> calling = v8::Context::GetCalling(); 6887d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block CHECK(calling == debugee_context); 6888d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block CHECK(calling != debugger_context); 6889d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block return v8::Int32::New(1); 6890d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block} 6891d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 6892d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 6893d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block// Debug event listener that checks if the first argument of a function is 6894d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block// an object with property 'a' == 1. If the property has custom accessor 6895d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block// this handler will eventually invoke it. 6896d0582a6c46733687d045e4188a1bcd0123c758a1Steve Blockstatic void DebugEventGetAtgumentPropertyValue( 6897d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block v8::DebugEvent event, 6898d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block v8::Handle<v8::Object> exec_state, 6899d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block v8::Handle<v8::Object> event_data, 6900d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block v8::Handle<v8::Value> data) { 6901d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block if (event == v8::Break) { 6902d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block break_point_hit_count++; 6903d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block CHECK(debugger_context == v8::Context::GetCurrent()); 6904d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block v8::Handle<v8::Function> func(v8::Function::Cast(*CompileRun( 6905d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block "(function(exec_state) {\n" 6906d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block " return (exec_state.frame(0).argumentValue(0).property('a').\n" 6907d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block " value().value() == 1);\n" 6908d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block "})"))); 6909d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block const int argc = 1; 6910d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block v8::Handle<v8::Value> argv[argc] = { exec_state }; 6911d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block v8::Handle<v8::Value> result = func->Call(exec_state, argc, argv); 6912d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block CHECK(result->IsTrue()); 6913d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block } 6914d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block} 6915d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 6916d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 6917d0582a6c46733687d045e4188a1bcd0123c758a1Steve BlockTEST(CallingContextIsNotDebugContext) { 691844f0eee88ff00398ff7f715fab053374d808c90dSteve Block v8::internal::Debug* debug = v8::internal::Isolate::Current()->debug(); 6919d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // Create and enter a debugee context. 6920d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block v8::HandleScope scope; 6921d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block DebugLocalContext env; 6922d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block env.ExposeDebug(); 6923d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 6924d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // Save handles to the debugger and debugee contexts to be used in 6925d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // NamedGetterWithCallingContextCheck. 6926d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block debugee_context = v8::Local<v8::Context>(*env); 692744f0eee88ff00398ff7f715fab053374d808c90dSteve Block debugger_context = v8::Utils::ToLocal(debug->debug_context()); 6928d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 6929d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // Create object with 'a' property accessor. 6930d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block v8::Handle<v8::ObjectTemplate> named = v8::ObjectTemplate::New(); 6931d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block named->SetAccessor(v8::String::New("a"), 6932d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block NamedGetterWithCallingContextCheck); 6933d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block env->Global()->Set(v8::String::New("obj"), 6934d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block named->NewInstance()); 6935d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 6936d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // Register the debug event listener 6937d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block v8::Debug::SetDebugEventListener(DebugEventGetAtgumentPropertyValue); 6938d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 6939d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // Create a function that invokes debugger. 6940d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block v8::Local<v8::Function> foo = CompileFunction( 6941d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block &env, 6942d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block "function bar(x) { debugger; }" 6943d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block "function foo(){ bar(obj); }", 6944d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block "foo"); 6945d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 6946d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block break_point_hit_count = 0; 6947d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block foo->Call(env->Global(), 0, NULL); 6948d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block CHECK_EQ(1, break_point_hit_count); 6949d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 6950d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block v8::Debug::SetDebugEventListener(NULL); 6951d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block debugee_context = v8::Handle<v8::Context>(); 6952d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block debugger_context = v8::Handle<v8::Context>(); 6953d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block CheckDebuggerUnloaded(); 6954d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block} 69556ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 69566ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 69576ded16be15dd865a9b21ea304d5273c8be299c87Steve BlockTEST(DebugContextIsPreservedBetweenAccesses) { 69586ded16be15dd865a9b21ea304d5273c8be299c87Steve Block v8::HandleScope scope; 69596ded16be15dd865a9b21ea304d5273c8be299c87Steve Block v8::Local<v8::Context> context1 = v8::Debug::GetDebugContext(); 69606ded16be15dd865a9b21ea304d5273c8be299c87Steve Block v8::Local<v8::Context> context2 = v8::Debug::GetDebugContext(); 69616ded16be15dd865a9b21ea304d5273c8be299c87Steve Block CHECK_EQ(*context1, *context2); 6962f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke} 6963f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 6964f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 6965f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarkestatic v8::Handle<v8::Value> expected_callback_data; 6966f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarkestatic void DebugEventContextChecker(const v8::Debug::EventDetails& details) { 6967f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke CHECK(details.GetEventContext() == expected_context); 6968f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke CHECK_EQ(expected_callback_data, details.GetCallbackData()); 6969f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke} 6970f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 6971f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke// Check that event details contain context where debug event occured. 6972f7060e27768c550ace7ec48ad8c093466db52dfaLeon ClarkeTEST(DebugEventContext) { 6973f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke v8::HandleScope scope; 6974f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke expected_callback_data = v8::Int32::New(2010); 6975f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke v8::Debug::SetDebugEventListener2(DebugEventContextChecker, 6976f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke expected_callback_data); 6977f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke expected_context = v8::Context::New(); 6978f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke v8::Context::Scope context_scope(expected_context); 6979f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke v8::Script::Compile(v8::String::New("(function(){debugger;})();"))->Run(); 6980f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke expected_context.Dispose(); 6981f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke expected_context.Clear(); 6982f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke v8::Debug::SetDebugEventListener(NULL); 6983f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke expected_context_data = v8::Handle<v8::Value>(); 69846ded16be15dd865a9b21ea304d5273c8be299c87Steve Block CheckDebuggerUnloaded(); 69856ded16be15dd865a9b21ea304d5273c8be299c87Steve Block} 6986f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 69873bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch 69883bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdochstatic void* expected_break_data; 69893bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdochstatic bool was_debug_break_called; 69903bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdochstatic bool was_debug_event_called; 69913bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdochstatic void DebugEventBreakDataChecker(const v8::Debug::EventDetails& details) { 69923bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch if (details.GetEvent() == v8::BreakForCommand) { 69933bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch CHECK_EQ(expected_break_data, details.GetClientData()); 69943bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch was_debug_event_called = true; 69953bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch } else if (details.GetEvent() == v8::Break) { 69963bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch was_debug_break_called = true; 69973bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch } 69983bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch} 69993bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch 7000b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 70013bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch// Check that event details contain context where debug event occured. 70023bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben MurdochTEST(DebugEventBreakData) { 70033bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch v8::HandleScope scope; 70043bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch DebugLocalContext env; 70053bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch v8::Debug::SetDebugEventListener2(DebugEventBreakDataChecker); 70063bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch 70073bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch TestClientData::constructor_call_counter = 0; 70083bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch TestClientData::destructor_call_counter = 0; 70093bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch 70103bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch expected_break_data = NULL; 70113bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch was_debug_event_called = false; 70123bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch was_debug_break_called = false; 70133bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch v8::Debug::DebugBreakForCommand(); 70143bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch v8::Script::Compile(v8::String::New("(function(x){return x;})(1);"))->Run(); 70153bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch CHECK(was_debug_event_called); 70163bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch CHECK(!was_debug_break_called); 70173bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch 70183bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch TestClientData* data1 = new TestClientData(); 70193bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch expected_break_data = data1; 70203bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch was_debug_event_called = false; 70213bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch was_debug_break_called = false; 70223bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch v8::Debug::DebugBreakForCommand(data1); 70233bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch v8::Script::Compile(v8::String::New("(function(x){return x+1;})(1);"))->Run(); 70243bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch CHECK(was_debug_event_called); 70253bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch CHECK(!was_debug_break_called); 70263bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch 70273bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch expected_break_data = NULL; 70283bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch was_debug_event_called = false; 70293bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch was_debug_break_called = false; 70303bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch v8::Debug::DebugBreak(); 70313bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch v8::Script::Compile(v8::String::New("(function(x){return x+2;})(1);"))->Run(); 70323bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch CHECK(!was_debug_event_called); 70333bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch CHECK(was_debug_break_called); 70343bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch 70353bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch TestClientData* data2 = new TestClientData(); 70363bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch expected_break_data = data2; 70373bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch was_debug_event_called = false; 70383bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch was_debug_break_called = false; 70393bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch v8::Debug::DebugBreak(); 70403bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch v8::Debug::DebugBreakForCommand(data2); 70413bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch v8::Script::Compile(v8::String::New("(function(x){return x+3;})(1);"))->Run(); 70423bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch CHECK(was_debug_event_called); 70433bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch CHECK(was_debug_break_called); 70443bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch 70453bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch CHECK_EQ(2, TestClientData::constructor_call_counter); 70463bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch CHECK_EQ(TestClientData::constructor_call_counter, 70473bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch TestClientData::destructor_call_counter); 70483bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch 70493bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch v8::Debug::SetDebugEventListener(NULL); 70503bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch CheckDebuggerUnloaded(); 70513bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch} 70523bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch 7053b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochstatic bool debug_event_break_deoptimize_done = false; 7054b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 7055b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochstatic void DebugEventBreakDeoptimize(v8::DebugEvent event, 7056b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch v8::Handle<v8::Object> exec_state, 7057b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch v8::Handle<v8::Object> event_data, 7058b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch v8::Handle<v8::Value> data) { 7059b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (event == v8::Break) { 7060b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (!frame_function_name.IsEmpty()) { 7061b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Get the name of the function. 7062b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch const int argc = 2; 7063b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch v8::Handle<v8::Value> argv[argc] = { exec_state, v8::Integer::New(0) }; 7064b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch v8::Handle<v8::Value> result = 7065b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch frame_function_name->Call(exec_state, argc, argv); 7066b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (!result->IsUndefined()) { 7067b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch char fn[80]; 7068b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CHECK(result->IsString()); 7069b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch v8::Handle<v8::String> function_name(result->ToString()); 7070b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch function_name->WriteAscii(fn); 7071b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (strcmp(fn, "bar") == 0) { 7072b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch i::Deoptimizer::DeoptimizeAll(); 7073b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch debug_event_break_deoptimize_done = true; 7074b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 7075b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 7076b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 7077b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 7078b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch v8::Debug::DebugBreak(); 7079b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 7080b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 7081b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 7082b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 7083b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// Test deoptimization when execution is broken using the debug break stack 7084b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// check interrupt. 7085b0fe1620dcb4135ac3ab2d66ff93072373911299Ben MurdochTEST(DeoptimizeDuringDebugBreak) { 7086b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch v8::HandleScope scope; 7087b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch DebugLocalContext env; 7088b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch env.ExposeDebug(); 7089b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 7090b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Create a function for checking the function when hitting a break point. 7091b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch frame_function_name = CompileFunction(&env, 7092b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch frame_function_name_source, 7093b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "frame_function_name"); 7094b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 7095b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 7096b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Set a debug event listener which will keep interrupting execution until 7097b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // debug break. When inside function bar it will deoptimize all functions. 7098b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // This tests lazy deoptimization bailout for the stack check, as the first 7099b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // time in function bar when using debug break and no break points will be at 7100b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // the initial stack check. 7101b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch v8::Debug::SetDebugEventListener(DebugEventBreakDeoptimize, 7102b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch v8::Undefined()); 7103b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 7104b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Compile and run function bar which will optimize it for some flag settings. 7105b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch v8::Script::Compile(v8::String::New("function bar(){}; bar()"))->Run(); 7106b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 7107b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Set debug break and call bar again. 7108b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch v8::Debug::DebugBreak(); 7109b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch v8::Script::Compile(v8::String::New("bar()"))->Run(); 7110b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 7111b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CHECK(debug_event_break_deoptimize_done); 7112b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 7113b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch v8::Debug::SetDebugEventListener(NULL); 7114b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 7115b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 7116b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 7117b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochstatic void DebugEventBreakWithOptimizedStack(v8::DebugEvent event, 7118b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch v8::Handle<v8::Object> exec_state, 7119b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch v8::Handle<v8::Object> event_data, 7120b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch v8::Handle<v8::Value> data) { 7121b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (event == v8::Break) { 7122b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (!frame_function_name.IsEmpty()) { 7123b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch for (int i = 0; i < 2; i++) { 7124b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch const int argc = 2; 7125b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch v8::Handle<v8::Value> argv[argc] = { exec_state, v8::Integer::New(i) }; 7126b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Get the name of the function in frame i. 7127b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch v8::Handle<v8::Value> result = 7128b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch frame_function_name->Call(exec_state, argc, argv); 7129b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CHECK(result->IsString()); 7130b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch v8::Handle<v8::String> function_name(result->ToString()); 7131b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CHECK(function_name->Equals(v8::String::New("loop"))); 7132b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Get the name of the first argument in frame i. 7133b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch result = frame_argument_name->Call(exec_state, argc, argv); 7134b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CHECK(result->IsString()); 7135b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch v8::Handle<v8::String> argument_name(result->ToString()); 7136b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CHECK(argument_name->Equals(v8::String::New("count"))); 7137b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Get the value of the first argument in frame i. If the 7138b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // funtion is optimized the value will be undefined, otherwise 7139b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // the value will be '1 - i'. 7140b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // 7141b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // TODO(3141533): We should be able to get the real value for 7142b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // optimized frames. 7143b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch result = frame_argument_value->Call(exec_state, argc, argv); 7144b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CHECK(result->IsUndefined() || (result->Int32Value() == 1 - i)); 7145b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Get the name of the first local variable. 7146b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch result = frame_local_name->Call(exec_state, argc, argv); 7147b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CHECK(result->IsString()); 7148b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch v8::Handle<v8::String> local_name(result->ToString()); 7149b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CHECK(local_name->Equals(v8::String::New("local"))); 7150b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Get the value of the first local variable. If the function 7151b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // is optimized the value will be undefined, otherwise it will 7152b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // be 42. 7153b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // 7154b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // TODO(3141533): We should be able to get the real value for 7155b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // optimized frames. 7156b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch result = frame_local_value->Call(exec_state, argc, argv); 7157b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CHECK(result->IsUndefined() || (result->Int32Value() == 42)); 7158b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 7159b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 7160b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 7161b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 7162b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 7163b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 7164b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochstatic v8::Handle<v8::Value> ScheduleBreak(const v8::Arguments& args) { 7165b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch v8::Debug::SetDebugEventListener(DebugEventBreakWithOptimizedStack, 7166b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch v8::Undefined()); 7167b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch v8::Debug::DebugBreak(); 7168b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return v8::Undefined(); 7169b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 7170b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 7171b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 7172b0fe1620dcb4135ac3ab2d66ff93072373911299Ben MurdochTEST(DebugBreakStackInspection) { 7173b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch v8::HandleScope scope; 7174b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch DebugLocalContext env; 7175b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 7176b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch frame_function_name = 7177b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CompileFunction(&env, frame_function_name_source, "frame_function_name"); 7178b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch frame_argument_name = 7179b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CompileFunction(&env, frame_argument_name_source, "frame_argument_name"); 7180b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch frame_argument_value = CompileFunction(&env, 7181b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch frame_argument_value_source, 7182b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "frame_argument_value"); 7183b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch frame_local_name = 7184b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CompileFunction(&env, frame_local_name_source, "frame_local_name"); 7185b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch frame_local_value = 7186b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CompileFunction(&env, frame_local_value_source, "frame_local_value"); 7187b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 7188b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch v8::Handle<v8::FunctionTemplate> schedule_break_template = 7189b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch v8::FunctionTemplate::New(ScheduleBreak); 7190b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch v8::Handle<v8::Function> schedule_break = 7191b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch schedule_break_template->GetFunction(); 7192b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch env->Global()->Set(v8_str("scheduleBreak"), schedule_break); 7193b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 7194b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch const char* src = 7195b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "function loop(count) {" 7196b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch " var local = 42;" 7197b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch " if (count < 1) { scheduleBreak(); loop(count + 1); }" 7198b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "}" 7199b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "loop(0);"; 7200b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch v8::Script::Compile(v8::String::New(src))->Run(); 7201b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 7202b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 72033e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu 72043e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu// Test that setting the terminate execution flag during debug break processing. 72058a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wangstatic void TestDebugBreakInLoop(const char* loop_head, 72068a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang const char** loop_bodies, 72078a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang const char* loop_tail) { 72088a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang // Receive 100 breaks for each test and then terminate JavaScript execution. 72093fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch static const int kBreaksPerTest = 100; 72103fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 72113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch for (int i = 0; loop_bodies[i] != NULL; i++) { 72123fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Perform a lazy deoptimization after various numbers of breaks 72133fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // have been hit. 72143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch for (int j = 0; j < 11; j++) { 72153fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch break_point_hit_count_deoptimize = j; 72163fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (j == 10) { 72173fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch break_point_hit_count_deoptimize = kBreaksPerTest; 72183fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 72198a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang 72203fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch break_point_hit_count = 0; 72213fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch max_break_point_hit_count = kBreaksPerTest; 72223fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch terminate_after_max_break_point_hit = true; 72238a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang 72243fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch EmbeddedVector<char, 1024> buffer; 72253fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch OS::SNPrintF(buffer, 72263fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "function f() {%s%s%s}", 72273fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch loop_head, loop_bodies[i], loop_tail); 72288a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang 72293fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Function with infinite loop. 72303fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch CompileRun(buffer.start()); 72318a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang 72323fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Set the debug break to enter the debugger as soon as possible. 72333fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch v8::Debug::DebugBreak(); 72348a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang 72353fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Call function with infinite loop. 72363fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch CompileRun("f();"); 72373fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch CHECK_EQ(kBreaksPerTest, break_point_hit_count); 72388a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang 72393fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch CHECK(!v8::V8::IsExecutionTerminating()); 72403fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 72418a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang } 72428a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang} 72438a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang 72448a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang 72453e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui ZhuTEST(DebugBreakLoop) { 72463e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu v8::HandleScope scope; 72473e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu DebugLocalContext env; 72483e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu 72493e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu // Register a debug event listener which sets the break flag and counts. 72503e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu v8::Debug::SetDebugEventListener(DebugEventBreakMax); 72513e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu 72523fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Create a function for getting the frame count when hitting the break. 72533fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch frame_count = CompileFunction(&env, frame_count_source, "frame_count"); 72543fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 72558a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang CompileRun("var a = 1;"); 72568a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang CompileRun("function g() { }"); 72578a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang CompileRun("function h() { }"); 72588a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang 72598a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang const char* loop_bodies[] = { 72608a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang "", 72618a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang "g()", 72628a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang "if (a == 0) { g() }", 72638a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang "if (a == 1) { g() }", 72648a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang "if (a == 0) { g() } else { h() }", 72658a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang "if (a == 0) { continue }", 72668a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang "if (a == 1) { continue }", 72678a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang "switch (a) { case 1: g(); }", 72688a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang "switch (a) { case 1: continue; }", 72698a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang "switch (a) { case 1: g(); break; default: h() }", 72708a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang "switch (a) { case 1: continue; break; default: h() }", 72718a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang NULL 72728a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang }; 72738a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang 72748a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang TestDebugBreakInLoop("while (true) {", loop_bodies, "}"); 72758a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang TestDebugBreakInLoop("while (a == 1) {", loop_bodies, "}"); 72763e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu 72778a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang TestDebugBreakInLoop("do {", loop_bodies, "} while (true)"); 72788a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang TestDebugBreakInLoop("do {", loop_bodies, "} while (a == 1)"); 72793e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu 72808a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang TestDebugBreakInLoop("for (;;) {", loop_bodies, "}"); 72818a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang TestDebugBreakInLoop("for (;a == 1;) {", loop_bodies, "}"); 72823e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu 72833e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu // Get rid of the debug event listener. 72843e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu v8::Debug::SetDebugEventListener(NULL); 72853e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu CheckDebuggerUnloaded(); 72863e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu} 72873e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu 72883e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu 72893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochv8::Local<v8::Script> inline_script; 72903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 72913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochstatic void DebugBreakInlineListener(v8::DebugEvent event, 72923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch v8::Handle<v8::Object> exec_state, 72933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch v8::Handle<v8::Object> event_data, 72943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch v8::Handle<v8::Value> data) { 72953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (event != v8::Break) return; 72963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 72973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int expected_frame_count = 4; 72983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int expected_line_number[] = {1, 4, 7, 12}; 72993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 73003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch i::Handle<i::Object> compiled_script = v8::Utils::OpenHandle(*inline_script); 73013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch i::Handle<i::Script> source_script = i::Handle<i::Script>(i::Script::cast( 73023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch i::JSFunction::cast(*compiled_script)->shared()->script())); 73033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 73043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int break_id = v8::internal::Isolate::Current()->debug()->break_id(); 73053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch char script[128]; 73063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch i::Vector<char> script_vector(script, sizeof(script)); 73073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch OS::SNPrintF(script_vector, "%%GetFrameCount(%d)", break_id); 73083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch v8::Local<v8::Value> result = CompileRun(script); 73093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 73103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int frame_count = result->Int32Value(); 73113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CHECK_EQ(expected_frame_count, frame_count); 73123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 73133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch for (int i = 0; i < frame_count; i++) { 73143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // The 5. element in the returned array of GetFrameDetails contains the 73153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // source position of that frame. 73163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch OS::SNPrintF(script_vector, "%%GetFrameDetails(%d, %d)[5]", break_id, i); 73173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch v8::Local<v8::Value> result = CompileRun(script); 73183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CHECK_EQ(expected_line_number[i], 73193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch i::GetScriptLineNumber(source_script, result->Int32Value())); 73203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 73213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch v8::Debug::SetDebugEventListener(NULL); 73223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch v8::V8::TerminateExecution(); 73233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 73243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 73253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 73263ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochTEST(DebugBreakInline) { 73273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch i::FLAG_allow_natives_syntax = true; 73283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch v8::HandleScope scope; 73293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DebugLocalContext env; 73303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch const char* source = 73313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch "function debug(b) { \n" 73323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch " if (b) debugger; \n" 73333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch "} \n" 73343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch "function f(b) { \n" 73353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch " debug(b) \n" 73363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch "}; \n" 73373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch "function g(b) { \n" 73383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch " f(b); \n" 73393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch "}; \n" 73403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch "g(false); \n" 73413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch "g(false); \n" 73423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch "%OptimizeFunctionOnNextCall(g); \n" 73433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch "g(true);"; 73443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch v8::Debug::SetDebugEventListener(DebugBreakInlineListener); 73453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch inline_script = v8::Script::Compile(v8::String::New(source)); 73463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch inline_script->Run(); 73473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 73483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 73493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 73509dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen#endif // ENABLE_DEBUGGER_SUPPORT 7351