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