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