13ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Copyright 2012 the V8 project authors. All rights reserved. 2a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Redistribution and use in source and binary forms, with or without 3a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// modification, are permitted provided that the following conditions are 4a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// met: 5a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 6a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// * Redistributions of source code must retain the above copyright 7a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// notice, this list of conditions and the following disclaimer. 8a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// * Redistributions in binary form must reproduce the above 9a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// copyright notice, this list of conditions and the following 10a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// disclaimer in the documentation and/or other materials provided 11a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// with the distribution. 12a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// * Neither the name of Google Inc. nor the names of its 13a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// contributors may be used to endorse or promote products derived 14a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// from this software without specific prior written permission. 15a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 16a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 289dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen#include <stdlib.h> 297f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 30b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/v8.h" 31a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 32b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/api.h" 33b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/base/platform/condition-variable.h" 34b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/base/platform/platform.h" 35b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/compilation-cache.h" 36b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/debug.h" 37b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/deoptimizer.h" 38b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/frames.h" 39b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/utils.h" 40b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "test/cctest/cctest.h" 41a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 42a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 43b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochusing ::v8::base::Mutex; 44b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochusing ::v8::base::LockGuard; 45b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochusing ::v8::base::ConditionVariable; 46b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochusing ::v8::base::OS; 47b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochusing ::v8::base::Semaphore; 48a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockusing ::v8::internal::EmbeddedVector; 49a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockusing ::v8::internal::Object; 50a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockusing ::v8::internal::Handle; 51a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockusing ::v8::internal::Heap; 52a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockusing ::v8::internal::JSGlobalProxy; 53a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockusing ::v8::internal::Code; 54a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockusing ::v8::internal::Debug; 55a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockusing ::v8::internal::Debugger; 56a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockusing ::v8::internal::CommandMessage; 57a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockusing ::v8::internal::CommandMessageQueue; 58b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochusing ::v8::internal::StackFrame; 59a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockusing ::v8::internal::StepAction; 60a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockusing ::v8::internal::StepIn; // From StepAction enum 61a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockusing ::v8::internal::StepNext; // From StepAction enum 62a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockusing ::v8::internal::StepOut; // From StepAction enum 63a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockusing ::v8::internal::Vector; 64d0582a6c46733687d045e4188a1bcd0123c758a1Steve Blockusing ::v8::internal::StrLength; 65a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 66a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Size of temp buffer for formatting small strings. 67a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define SMALL_STRING_BUFFER_SIZE 80 68a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 69a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// --- H e l p e r C l a s s e s 70a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 71a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 72a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Helper class for creating a V8 enviromnent for running tests 73a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass DebugLocalContext { 74a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 75a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline DebugLocalContext( 76b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Isolate* isolate, v8::ExtensionConfiguration* extensions = 0, 77b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Handle<v8::ObjectTemplate> global_template = 78b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Handle<v8::ObjectTemplate>(), 79b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Handle<v8::Value> global_object = v8::Handle<v8::Value>()) 80b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : scope_(isolate), 81b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch context_(v8::Context::New(isolate, extensions, global_template, 82b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch global_object)) { 83b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch context_->Enter(); 84b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 85b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inline DebugLocalContext( 86a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::ExtensionConfiguration* extensions = 0, 87a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<v8::ObjectTemplate> global_template = 88a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<v8::ObjectTemplate>(), 89a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<v8::Value> global_object = v8::Handle<v8::Value>()) 90b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : scope_(CcTest::isolate()), 91b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch context_(v8::Context::New(CcTest::isolate(), extensions, 92b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch global_template, global_object)) { 93a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block context_->Enter(); 94a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 95a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline ~DebugLocalContext() { 96a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block context_->Exit(); 97a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 98b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inline v8::Local<v8::Context> context() { return context_; } 99a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline v8::Context* operator->() { return *context_; } 100a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline v8::Context* operator*() { return *context_; } 101b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inline v8::Isolate* GetIsolate() { return context_->GetIsolate(); } 102a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline bool IsReady() { return !context_.IsEmpty(); } 103a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void ExposeDebug() { 104b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::internal::Isolate* isolate = 105b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch reinterpret_cast<v8::internal::Isolate*>(context_->GetIsolate()); 106b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::internal::Factory* factory = isolate->factory(); 107a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Expose the debug context global object in the global object for testing. 108b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK(isolate->debug()->Load()); 109b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<v8::internal::Context> debug_context = 110b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate->debug()->debug_context(); 111b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch debug_context->set_security_token( 112a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Utils::OpenHandle(*context_)->security_token()); 113a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 114a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<JSGlobalProxy> global(Handle<JSGlobalProxy>::cast( 115a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Utils::OpenHandle(*context_->Global()))); 116a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<v8::internal::String> debug_string = 117b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch factory->InternalizeOneByteString(STATIC_CHAR_VECTOR("debug")); 118b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::internal::Runtime::DefineObjectProperty(global, debug_string, 119b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch handle(debug_context->global_proxy(), isolate), DONT_ENUM).Check(); 120a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 121589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch 122a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private: 123b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope_; 124b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Local<v8::Context> context_; 125a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 126a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 127a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 128a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// --- H e l p e r F u n c t i o n s 129a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 130a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 131a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Compile and run the supplied source and return the fequested function. 132a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic v8::Local<v8::Function> CompileFunction(DebugLocalContext* env, 133a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const char* source, 134a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const char* function_name) { 135b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Script::Compile(v8::String::NewFromUtf8(env->GetIsolate(), source)) 136b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ->Run(); 137b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return v8::Local<v8::Function>::Cast((*env)->Global()->Get( 138b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::String::NewFromUtf8(env->GetIsolate(), function_name))); 139a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 140a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 141a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 142a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Compile and run the supplied source and return the requested function. 143b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic v8::Local<v8::Function> CompileFunction(v8::Isolate* isolate, 144b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const char* source, 145a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const char* function_name) { 146b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Script::Compile(v8::String::NewFromUtf8(isolate, source))->Run(); 147b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Local<v8::Object> global = isolate->GetCurrentContext()->Global(); 148a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return v8::Local<v8::Function>::Cast( 149b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch global->Get(v8::String::NewFromUtf8(isolate, function_name))); 150a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 151a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 152a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 153a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Is there any debug info for the function? 154a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic bool HasDebugInfo(v8::Handle<v8::Function> fun) { 155a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<v8::internal::JSFunction> f = v8::Utils::OpenHandle(*fun); 156a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<v8::internal::SharedFunctionInfo> shared(f->shared()); 157a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return Debug::HasDebugInfo(shared); 158a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 159a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 160a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 161a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Set a break point in a function and return the associated break point 162a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// number. 163a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic int SetBreakPoint(Handle<v8::internal::JSFunction> fun, int position) { 164a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static int break_point = 0; 165b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::internal::Isolate* isolate = fun->GetIsolate(); 166b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::internal::Debug* debug = isolate->debug(); 16744f0eee88ff00398ff7f715fab053374d808c90dSteve Block debug->SetBreakPoint( 168b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch fun, 169b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Object>(v8::internal::Smi::FromInt(++break_point), isolate), 1709dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen &position); 171a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return break_point; 172a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 173a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 174a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 175a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Set a break point in a function and return the associated break point 176a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// number. 177a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic int SetBreakPoint(v8::Handle<v8::Function> fun, int position) { 178a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return SetBreakPoint(v8::Utils::OpenHandle(*fun), position); 179a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 180a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 181a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 182a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Set a break point in a function using the Debug object and return the 183a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// associated break point number. 184b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic int SetBreakPointFromJS(v8::Isolate* isolate, 185b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const char* function_name, 186a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int line, int position) { 187a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EmbeddedVector<char, SMALL_STRING_BUFFER_SIZE> buffer; 188b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SNPrintF(buffer, 189b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "debug.Debug.setBreakPoint(%s,%d,%d)", 190b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch function_name, line, position); 191a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block buffer[SMALL_STRING_BUFFER_SIZE - 1] = '\0'; 192b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Handle<v8::String> str = v8::String::NewFromUtf8(isolate, buffer.start()); 193a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return v8::Script::Compile(str)->Run()->Int32Value(); 194a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 195a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 196a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 197a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Set a break point in a script identified by id using the global Debug object. 198b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic int SetScriptBreakPointByIdFromJS(v8::Isolate* isolate, int script_id, 199b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int line, int column) { 200a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EmbeddedVector<char, SMALL_STRING_BUFFER_SIZE> buffer; 201a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (column >= 0) { 202a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Column specified set script break point on precise location. 203b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SNPrintF(buffer, 204b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "debug.Debug.setScriptBreakPointById(%d,%d,%d)", 205b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch script_id, line, column); 206a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 207a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Column not specified set script break point on line. 208b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SNPrintF(buffer, 209b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "debug.Debug.setScriptBreakPointById(%d,%d)", 210b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch script_id, line); 211a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 212a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block buffer[SMALL_STRING_BUFFER_SIZE - 1] = '\0'; 213a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block { 214a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::TryCatch try_catch; 215b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Handle<v8::String> str = 216b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::String::NewFromUtf8(isolate, buffer.start()); 217a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<v8::Value> value = v8::Script::Compile(str)->Run(); 218a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(!try_catch.HasCaught()); 219a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return value->Int32Value(); 220a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 221a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 222a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 223a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 224a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Set a break point in a script identified by name using the global Debug 225a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// object. 226b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic int SetScriptBreakPointByNameFromJS(v8::Isolate* isolate, 227b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const char* script_name, int line, 228b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int column) { 229a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EmbeddedVector<char, SMALL_STRING_BUFFER_SIZE> buffer; 230a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (column >= 0) { 231a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Column specified set script break point on precise location. 232b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SNPrintF(buffer, 233b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "debug.Debug.setScriptBreakPointByName(\"%s\",%d,%d)", 234b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch script_name, line, column); 235a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 236a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Column not specified set script break point on line. 237b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SNPrintF(buffer, 238b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "debug.Debug.setScriptBreakPointByName(\"%s\",%d)", 239b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch script_name, line); 240a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 241a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block buffer[SMALL_STRING_BUFFER_SIZE - 1] = '\0'; 242a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block { 243a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::TryCatch try_catch; 244b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Handle<v8::String> str = 245b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::String::NewFromUtf8(isolate, buffer.start()); 246a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<v8::Value> value = v8::Script::Compile(str)->Run(); 247a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(!try_catch.HasCaught()); 248a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return value->Int32Value(); 249a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 250a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 251a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 252a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 253a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Clear a break point. 254a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic void ClearBreakPoint(int break_point) { 255b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::internal::Isolate* isolate = CcTest::i_isolate(); 256b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::internal::Debug* debug = isolate->debug(); 25744f0eee88ff00398ff7f715fab053374d808c90dSteve Block debug->ClearBreakPoint( 258b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Object>(v8::internal::Smi::FromInt(break_point), isolate)); 259a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 260a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 261a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 262a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Clear a break point using the global Debug object. 263b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic void ClearBreakPointFromJS(v8::Isolate* isolate, 264b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int break_point_number) { 265a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EmbeddedVector<char, SMALL_STRING_BUFFER_SIZE> buffer; 266b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SNPrintF(buffer, 267b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "debug.Debug.clearBreakPoint(%d)", 268b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break_point_number); 269a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block buffer[SMALL_STRING_BUFFER_SIZE - 1] = '\0'; 270b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Script::Compile(v8::String::NewFromUtf8(isolate, buffer.start()))->Run(); 271a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 272a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 273a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 274b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic void EnableScriptBreakPointFromJS(v8::Isolate* isolate, 275b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int break_point_number) { 276a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EmbeddedVector<char, SMALL_STRING_BUFFER_SIZE> buffer; 277b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SNPrintF(buffer, 278b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "debug.Debug.enableScriptBreakPoint(%d)", 279b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break_point_number); 280a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block buffer[SMALL_STRING_BUFFER_SIZE - 1] = '\0'; 281b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Script::Compile(v8::String::NewFromUtf8(isolate, buffer.start()))->Run(); 282a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 283a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 284a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 285b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic void DisableScriptBreakPointFromJS(v8::Isolate* isolate, 286b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int break_point_number) { 287a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EmbeddedVector<char, SMALL_STRING_BUFFER_SIZE> buffer; 288b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SNPrintF(buffer, 289b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "debug.Debug.disableScriptBreakPoint(%d)", 290b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break_point_number); 291a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block buffer[SMALL_STRING_BUFFER_SIZE - 1] = '\0'; 292b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Script::Compile(v8::String::NewFromUtf8(isolate, buffer.start()))->Run(); 293a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 294a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 295a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 296b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic void ChangeScriptBreakPointConditionFromJS(v8::Isolate* isolate, 297b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int break_point_number, 298a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const char* condition) { 299a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EmbeddedVector<char, SMALL_STRING_BUFFER_SIZE> buffer; 300b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SNPrintF(buffer, 301b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "debug.Debug.changeScriptBreakPointCondition(%d, \"%s\")", 302b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break_point_number, condition); 303a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block buffer[SMALL_STRING_BUFFER_SIZE - 1] = '\0'; 304b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Script::Compile(v8::String::NewFromUtf8(isolate, buffer.start()))->Run(); 305a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 306a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 307a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 308b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic void ChangeScriptBreakPointIgnoreCountFromJS(v8::Isolate* isolate, 309b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int break_point_number, 310a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int ignoreCount) { 311a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EmbeddedVector<char, SMALL_STRING_BUFFER_SIZE> buffer; 312b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SNPrintF(buffer, 313b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "debug.Debug.changeScriptBreakPointIgnoreCount(%d, %d)", 314b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break_point_number, ignoreCount); 315a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block buffer[SMALL_STRING_BUFFER_SIZE - 1] = '\0'; 316b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Script::Compile(v8::String::NewFromUtf8(isolate, buffer.start()))->Run(); 317a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 318a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 319a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 320a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Change break on exception. 321a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic void ChangeBreakOnException(bool caught, bool uncaught) { 322b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::internal::Debug* debug = CcTest::i_isolate()->debug(); 32344f0eee88ff00398ff7f715fab053374d808c90dSteve Block debug->ChangeBreakOnException(v8::internal::BreakException, caught); 32444f0eee88ff00398ff7f715fab053374d808c90dSteve Block debug->ChangeBreakOnException(v8::internal::BreakUncaughtException, uncaught); 325a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 326a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 327a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 328a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Change break on exception using the global Debug object. 329b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic void ChangeBreakOnExceptionFromJS(v8::Isolate* isolate, bool caught, 330b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool uncaught) { 331a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (caught) { 332a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Script::Compile( 333b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::String::NewFromUtf8(isolate, "debug.Debug.setBreakOnException()")) 334b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ->Run(); 335a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 336a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Script::Compile( 337b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::String::NewFromUtf8(isolate, "debug.Debug.clearBreakOnException()")) 338b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ->Run(); 339a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 340a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (uncaught) { 341a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Script::Compile( 342b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::String::NewFromUtf8( 343b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate, "debug.Debug.setBreakOnUncaughtException()"))->Run(); 344a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 345a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Script::Compile( 346b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::String::NewFromUtf8( 347b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate, "debug.Debug.clearBreakOnUncaughtException()"))->Run(); 348a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 349a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 350a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 351a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 352a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Prepare to step to next break location. 353a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic void PrepareStep(StepAction step_action) { 354b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::internal::Debug* debug = CcTest::i_isolate()->debug(); 355b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch debug->PrepareStep(step_action, 1, StackFrame::NO_ID); 356a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 357a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 358a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 359a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// This function is in namespace v8::internal to be friend with class 360a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// v8::internal::Debug. 361a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace v8 { 362a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace internal { 363a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 364a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Collect the currently debugged functions. 365a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<FixedArray> GetDebuggedFunctions() { 366b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Debug* debug = CcTest::i_isolate()->debug(); 36744f0eee88ff00398ff7f715fab053374d808c90dSteve Block 36844f0eee88ff00398ff7f715fab053374d808c90dSteve Block v8::internal::DebugInfoListNode* node = debug->debug_info_list_; 369a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 370a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Find the number of debugged functions. 371a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int count = 0; 372a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block while (node) { 373a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block count++; 374a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block node = node->next(); 375a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 376a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 377a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Allocate array for the debugged functions 378a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<FixedArray> debugged_functions = 379b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CcTest::i_isolate()->factory()->NewFixedArray(count); 380a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 381a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Run through the debug info objects and collect all functions. 382a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block count = 0; 383a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block while (node) { 384a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block debugged_functions->set(count++, *node->debug_info()); 385a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block node = node->next(); 386a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 387a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 388a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return debugged_functions; 389a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 390a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 391a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 392a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Check that the debugger has been fully unloaded. 393a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid CheckDebuggerUnloaded(bool check_functions) { 394a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Check that the debugger context is cleared and that there is no debug 395a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // information stored for the debugger. 396b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK(CcTest::i_isolate()->debug()->debug_context().is_null()); 397b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(NULL, CcTest::i_isolate()->debug()->debug_info_list_); 398a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 399a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Collect garbage to ensure weak handles are cleared. 400b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags); 401b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CcTest::heap()->CollectAllGarbage(Heap::kMakeHeapIterableMask); 402a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 403a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Iterate the head and check that there are no debugger related objects left. 404b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HeapIterator iterator(CcTest::heap()); 405d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke for (HeapObject* obj = iterator.next(); obj != NULL; obj = iterator.next()) { 406a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(!obj->IsDebugInfo()); 407a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(!obj->IsBreakPointInfo()); 408a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 409a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // If deep check of functions is requested check that no debug break code 410a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // is left in all functions. 411a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (check_functions) { 412a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (obj->IsJSFunction()) { 413a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block JSFunction* fun = JSFunction::cast(obj); 414a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (RelocIterator it(fun->shared()->code()); !it.done(); it.next()) { 415a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block RelocInfo::Mode rmode = it.rinfo()->rmode(); 416a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (RelocInfo::IsCodeTarget(rmode)) { 417a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(!Debug::IsDebugBreak(it.rinfo()->target_address())); 418a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else if (RelocInfo::IsJSReturn(rmode)) { 419a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(!Debug::IsDebugBreakAtReturn(it.rinfo())); 420a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 421a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 422a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 423a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 424a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 425a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 426a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 427a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 428a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} } // namespace v8::internal 429a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 430a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 431a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Check that the debugger has been fully unloaded. 432a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic void CheckDebuggerUnloaded(bool check_functions = false) { 433e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // Let debugger to unload itself synchronously 434e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke v8::Debug::ProcessDebugMessages(); 435e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 436a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::internal::CheckDebuggerUnloaded(check_functions); 437a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 438a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 439a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 440a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Inherit from BreakLocationIterator to get access to protected parts for 441a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// testing. 442a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass TestBreakLocationIterator: public v8::internal::BreakLocationIterator { 443a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 444a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block explicit TestBreakLocationIterator(Handle<v8::internal::DebugInfo> debug_info) 445a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : BreakLocationIterator(debug_info, v8::internal::SOURCE_BREAK_LOCATIONS) {} 446a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::internal::RelocIterator* it() { return reloc_iterator_; } 447a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::internal::RelocIterator* it_original() { 448a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return reloc_iterator_original_; 449a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 450a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 451a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 452a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 453a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Compile a function, set a break point and check that the call at the break 454a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// location in the code is the expected debug_break function. 455a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid CheckDebugBreakFunction(DebugLocalContext* env, 456a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const char* source, const char* name, 457a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int position, v8::internal::RelocInfo::Mode mode, 458a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Code* debug_break) { 459b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::internal::Debug* debug = CcTest::i_isolate()->debug(); 46044f0eee88ff00398ff7f715fab053374d808c90dSteve Block 461a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Create function and set the break point. 462a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<v8::internal::JSFunction> fun = v8::Utils::OpenHandle( 463a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block *CompileFunction(env, source, name)); 464a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int bp = SetBreakPoint(fun, position); 465a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 466a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Check that the debug break function is as expected. 467a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<v8::internal::SharedFunctionInfo> shared(fun->shared()); 468a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(Debug::HasDebugInfo(shared)); 469a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block TestBreakLocationIterator it1(Debug::GetDebugInfo(shared)); 470b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch it1.FindBreakLocationFromPosition(position, v8::internal::STATEMENT_ALIGNED); 471257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch v8::internal::RelocInfo::Mode actual_mode = it1.it()->rinfo()->rmode(); 472257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (actual_mode == v8::internal::RelocInfo::CODE_TARGET_WITH_ID) { 473257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch actual_mode = v8::internal::RelocInfo::CODE_TARGET; 474257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 475257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch CHECK_EQ(mode, actual_mode); 476a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (mode != v8::internal::RelocInfo::JS_RETURN) { 477a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(debug_break, 478a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Code::GetCodeFromTargetAddress(it1.it()->rinfo()->target_address())); 479a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 480a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(Debug::IsDebugBreakAtReturn(it1.it()->rinfo())); 481a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 482a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 483a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Clear the break point and check that the debug break function is no longer 484a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // there 485a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ClearBreakPoint(bp); 48644f0eee88ff00398ff7f715fab053374d808c90dSteve Block CHECK(!debug->HasDebugInfo(shared)); 487b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK(debug->EnsureDebugInfo(shared, fun)); 488a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block TestBreakLocationIterator it2(Debug::GetDebugInfo(shared)); 489b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch it2.FindBreakLocationFromPosition(position, v8::internal::STATEMENT_ALIGNED); 490257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch actual_mode = it2.it()->rinfo()->rmode(); 491257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (actual_mode == v8::internal::RelocInfo::CODE_TARGET_WITH_ID) { 492257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch actual_mode = v8::internal::RelocInfo::CODE_TARGET; 493257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 494257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch CHECK_EQ(mode, actual_mode); 495a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (mode == v8::internal::RelocInfo::JS_RETURN) { 496a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(!Debug::IsDebugBreakAtReturn(it2.it()->rinfo())); 497a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 498a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 499a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 500a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 501a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// --- D e b u g E v e n t H a n d l e r s 502a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// --- 503a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// --- The different tests uses a number of debug event handlers. 504a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// --- 505a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 506a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 507b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// Source for the JavaScript function which picks out the function 508b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// name of a frame. 509a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockconst char* frame_function_name_source = 510b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "function frame_function_name(exec_state, frame_number) {" 511b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch " return exec_state.frame(frame_number).func().name();" 512a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "}"; 513a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockv8::Local<v8::Function> frame_function_name; 514a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 515a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 516b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// Source for the JavaScript function which pick out the name of the 517b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// first argument of a frame. 518b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochconst char* frame_argument_name_source = 519b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "function frame_argument_name(exec_state, frame_number) {" 520b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch " return exec_state.frame(frame_number).argumentName(0);" 521b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "}"; 522b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochv8::Local<v8::Function> frame_argument_name; 523b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 524b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 525b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// Source for the JavaScript function which pick out the value of the 526b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// first argument of a frame. 527b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochconst char* frame_argument_value_source = 528b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "function frame_argument_value(exec_state, frame_number) {" 529b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch " return exec_state.frame(frame_number).argumentValue(0).value_;" 530b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "}"; 531b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochv8::Local<v8::Function> frame_argument_value; 532b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 533b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 534b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// Source for the JavaScript function which pick out the name of the 535b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// first argument of a frame. 536b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochconst char* frame_local_name_source = 537b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "function frame_local_name(exec_state, frame_number) {" 538b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch " return exec_state.frame(frame_number).localName(0);" 539b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "}"; 540b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochv8::Local<v8::Function> frame_local_name; 541b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 542b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 543b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// Source for the JavaScript function which pick out the value of the 544b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// first argument of a frame. 545b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochconst char* frame_local_value_source = 546b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "function frame_local_value(exec_state, frame_number) {" 547b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch " return exec_state.frame(frame_number).localValue(0).value_;" 548b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "}"; 549b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochv8::Local<v8::Function> frame_local_value; 550b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 551b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 552b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// Source for the JavaScript function which picks out the source line for the 553a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// top frame. 554a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockconst char* frame_source_line_source = 555a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "function frame_source_line(exec_state) {" 556a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " return exec_state.frame(0).sourceLine();" 557a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "}"; 558a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockv8::Local<v8::Function> frame_source_line; 559a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 560a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 561b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// Source for the JavaScript function which picks out the source column for the 562a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// top frame. 563a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockconst char* frame_source_column_source = 564a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "function frame_source_column(exec_state) {" 565a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " return exec_state.frame(0).sourceColumn();" 566a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "}"; 567a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockv8::Local<v8::Function> frame_source_column; 568a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 569a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 570b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// Source for the JavaScript function which picks out the script name for the 571a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// top frame. 572a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockconst char* frame_script_name_source = 573a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "function frame_script_name(exec_state) {" 574a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " return exec_state.frame(0).func().script().name();" 575a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "}"; 576a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockv8::Local<v8::Function> frame_script_name; 577a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 578a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 579b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// Source for the JavaScript function which returns the number of frames. 580a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic const char* frame_count_source = 581a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "function frame_count(exec_state) {" 582a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " return exec_state.frameCount();" 583a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "}"; 584a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockv8::Handle<v8::Function> frame_count; 585a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 586a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 587a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Global variable to store the last function hit - used by some tests. 588a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockchar last_function_hit[80]; 589a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 590b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Global variable to store the name for last script hit - used by some tests. 591a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockchar last_script_name_hit[80]; 592a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 593a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Global variables to store the last source position - used by some tests. 594a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockint last_source_line = -1; 595a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockint last_source_column = -1; 596a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 597a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Debug event handler which counts the break points which have been hit. 598a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockint break_point_hit_count = 0; 5993fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochint break_point_hit_count_deoptimize = 0; 600b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic void DebugEventBreakPointHitCount( 601b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::Debug::EventDetails& event_details) { 602b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::DebugEvent event = event_details.GetEvent(); 603b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Handle<v8::Object> exec_state = event_details.GetExecutionState(); 604b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::internal::Isolate* isolate = CcTest::i_isolate(); 605b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Debug* debug = isolate->debug(); 606a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // When hitting a debug event listener there must be a break set. 60744f0eee88ff00398ff7f715fab053374d808c90dSteve Block CHECK_NE(debug->break_id(), 0); 608a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 609a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Count the number of breaks. 610a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (event == v8::Break) { 611a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count++; 612a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!frame_function_name.IsEmpty()) { 613a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Get the name of the function. 614b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch const int argc = 2; 615b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Handle<v8::Value> argv[argc] = { 616b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch exec_state, v8::Integer::New(CcTest::isolate(), 0) 617b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch }; 618a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<v8::Value> result = frame_function_name->Call(exec_state, 619a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block argc, argv); 620a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (result->IsUndefined()) { 621a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_function_hit[0] = '\0'; 622a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 623a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(result->IsString()); 624a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<v8::String> function_name(result->ToString()); 625b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch function_name->WriteUtf8(last_function_hit); 626a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 627a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 628a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 629a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!frame_source_line.IsEmpty()) { 630a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Get the source line. 631a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const int argc = 1; 632a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<v8::Value> argv[argc] = { exec_state }; 633a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<v8::Value> result = frame_source_line->Call(exec_state, 634a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block argc, argv); 635a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(result->IsNumber()); 636a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_source_line = result->Int32Value(); 637a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 638a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 639a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!frame_source_column.IsEmpty()) { 640a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Get the source column. 641a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const int argc = 1; 642a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<v8::Value> argv[argc] = { exec_state }; 643a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<v8::Value> result = frame_source_column->Call(exec_state, 644a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block argc, argv); 645a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(result->IsNumber()); 646a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_source_column = result->Int32Value(); 647a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 648a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 649a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!frame_script_name.IsEmpty()) { 650a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Get the script name of the function script. 651a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const int argc = 1; 652a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<v8::Value> argv[argc] = { exec_state }; 653a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<v8::Value> result = frame_script_name->Call(exec_state, 654a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block argc, argv); 655a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (result->IsUndefined()) { 656a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_script_name_hit[0] = '\0'; 657a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 658a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(result->IsString()); 659a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<v8::String> script_name(result->ToString()); 660b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch script_name->WriteUtf8(last_script_name_hit); 661a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 662a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 6633fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 6643fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Perform a full deoptimization when the specified number of 6653fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // breaks have been hit. 6663fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (break_point_hit_count == break_point_hit_count_deoptimize) { 667b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch i::Deoptimizer::DeoptimizeAll(isolate); 668402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu } 669a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 670a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 671a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 672a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 673a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Debug event handler which counts a number of events and collects the stack 674a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// height if there is a function compiled for that. 675a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockint exception_hit_count = 0; 676a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockint uncaught_exception_hit_count = 0; 677a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockint last_js_stack_height = -1; 678b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochv8::Handle<v8::Function> debug_event_listener_callback; 679b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochint debug_event_listener_callback_result; 680a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 681a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic void DebugEventCounterClear() { 682a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 683a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block exception_hit_count = 0; 684a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block uncaught_exception_hit_count = 0; 685a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 686a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 687b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic void DebugEventCounter( 688b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::Debug::EventDetails& event_details) { 689b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::DebugEvent event = event_details.GetEvent(); 690b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Handle<v8::Object> exec_state = event_details.GetExecutionState(); 691b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Handle<v8::Object> event_data = event_details.GetEventData(); 692b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::internal::Debug* debug = CcTest::i_isolate()->debug(); 69344f0eee88ff00398ff7f715fab053374d808c90dSteve Block 694a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // When hitting a debug event listener there must be a break set. 69544f0eee88ff00398ff7f715fab053374d808c90dSteve Block CHECK_NE(debug->break_id(), 0); 696a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 697a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Count the number of breaks. 698a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (event == v8::Break) { 699a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count++; 700a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else if (event == v8::Exception) { 701a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block exception_hit_count++; 702a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 703a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Check whether the exception was uncaught. 704b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Local<v8::String> fun_name = 705b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::String::NewFromUtf8(CcTest::isolate(), "uncaught"); 706a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Local<v8::Function> fun = 707b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Local<v8::Function>::Cast(event_data->Get(fun_name)); 708b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Local<v8::Value> result = fun->Call(event_data, 0, NULL); 709a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (result->IsTrue()) { 710a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block uncaught_exception_hit_count++; 711a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 712a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 713a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 714a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Collect the JavsScript stack height if the function frame_count is 715a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // compiled. 716a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!frame_count.IsEmpty()) { 717a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static const int kArgc = 1; 718a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<v8::Value> argv[kArgc] = { exec_state }; 719a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Using exec_state as receiver is just to have a receiver. 720b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Handle<v8::Value> result = frame_count->Call(exec_state, kArgc, argv); 721a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_js_stack_height = result->Int32Value(); 722a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 723b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 724b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Run callback from DebugEventListener and check the result. 725b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!debug_event_listener_callback.IsEmpty()) { 726b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Handle<v8::Value> result = 727b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch debug_event_listener_callback->Call(event_data, 0, NULL); 728b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK(!result.IsEmpty()); 729b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(debug_event_listener_callback_result, result->Int32Value()); 730b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 731a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 732a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 733a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 734a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Debug event handler which evaluates a number of expressions when a break 735a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// point is hit. Each evaluated expression is compared with an expected value. 736a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// For this debug event handler to work the following two global varaibles 737a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// must be initialized. 738a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// checks: An array of expressions and expected results 739a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// evaluate_check_function: A JavaScript function (see below) 740a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 741a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Structure for holding checks to do. 742a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstruct EvaluateCheck { 743a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const char* expr; // An expression to evaluate when a break point is hit. 744a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<v8::Value> expected; // The expected result. 745a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 746b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 747b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 748a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Array of checks to do. 749a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstruct EvaluateCheck* checks = NULL; 750a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Source for The JavaScript function which can do the evaluation when a break 751a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// point is hit. 752a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockconst char* evaluate_check_source = 753a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "function evaluate_check(exec_state, expr, expected) {" 754a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " return exec_state.frame(0).evaluate(expr).value() === expected;" 755a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "}"; 756a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockv8::Local<v8::Function> evaluate_check_function; 757a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 758a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// The actual debug event described by the longer comment above. 759b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic void DebugEventEvaluate( 760b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::Debug::EventDetails& event_details) { 761b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::DebugEvent event = event_details.GetEvent(); 762b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Handle<v8::Object> exec_state = event_details.GetExecutionState(); 763b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::internal::Debug* debug = CcTest::i_isolate()->debug(); 764a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // When hitting a debug event listener there must be a break set. 76544f0eee88ff00398ff7f715fab053374d808c90dSteve Block CHECK_NE(debug->break_id(), 0); 766a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 767a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (event == v8::Break) { 768b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break_point_hit_count++; 769a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (int i = 0; checks[i].expr != NULL; i++) { 770a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const int argc = 3; 771b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Handle<v8::Value> argv[argc] = { 772b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch exec_state, 773b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::String::NewFromUtf8(CcTest::isolate(), checks[i].expr), 774b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch checks[i].expected}; 775a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<v8::Value> result = 776a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block evaluate_check_function->Call(exec_state, argc, argv); 777a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!result->IsTrue()) { 778b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::String::Utf8Value utf8(checks[i].expected->ToString()); 779b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch V8_Fatal(__FILE__, __LINE__, "%s != %s", checks[i].expr, *utf8); 780a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 781a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 782a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 783a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 784a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 785a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 786a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// This debug event listener removes a breakpoint in a function 787a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockint debug_event_remove_break_point = 0; 788b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic void DebugEventRemoveBreakPoint( 789b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::Debug::EventDetails& event_details) { 790b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::DebugEvent event = event_details.GetEvent(); 791b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Handle<v8::Value> data = event_details.GetCallbackData(); 792b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::internal::Debug* debug = CcTest::i_isolate()->debug(); 793a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // When hitting a debug event listener there must be a break set. 79444f0eee88ff00398ff7f715fab053374d808c90dSteve Block CHECK_NE(debug->break_id(), 0); 795a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 796a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (event == v8::Break) { 797a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count++; 7983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CHECK(data->IsFunction()); 799a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ClearBreakPoint(debug_event_remove_break_point); 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. 806a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockStepAction step_action = StepIn; // Step action to perform when stepping. 807b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic void DebugEventStep( 808b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::Debug::EventDetails& event_details) { 809b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::DebugEvent event = event_details.GetEvent(); 810b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::internal::Debug* debug = CcTest::i_isolate()->debug(); 811a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // When hitting a debug event listener there must be a break set. 81244f0eee88ff00398ff7f715fab053374d808c90dSteve Block CHECK_NE(debug->break_id(), 0); 813a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 814a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (event == v8::Break) { 815a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count++; 816a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block PrepareStep(step_action); 817a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 818a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 819a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 820a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 821a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Debug event handler which counts break points hit and performs a step 822a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// afterwards. For each call the expected function is checked. 823a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// For this debug event handler to work the following two global varaibles 824a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// must be initialized. 825a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// expected_step_sequence: An array of the expected function call sequence. 826a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// frame_function_name: A JavaScript function (see below). 827a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 828a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// String containing the expected function call sequence. Note: this only works 829a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// if functions have name length of one. 830a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockconst char* expected_step_sequence = NULL; 831a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 832a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// The actual debug event described by the longer comment above. 833b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic void DebugEventStepSequence( 834b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::Debug::EventDetails& event_details) { 835b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::DebugEvent event = event_details.GetEvent(); 836b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Handle<v8::Object> exec_state = event_details.GetExecutionState(); 837b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::internal::Debug* debug = CcTest::i_isolate()->debug(); 838a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // When hitting a debug event listener there must be a break set. 83944f0eee88ff00398ff7f715fab053374d808c90dSteve Block CHECK_NE(debug->break_id(), 0); 840a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 841a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (event == v8::Break || event == v8::Exception) { 842a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Check that the current function is the expected. 843a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(break_point_hit_count < 844d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block StrLength(expected_step_sequence)); 845b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch const int argc = 2; 846b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Handle<v8::Value> argv[argc] = { 847b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch exec_state, v8::Integer::New(CcTest::isolate(), 0) 848b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch }; 849a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<v8::Value> result = frame_function_name->Call(exec_state, 850a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block argc, argv); 851a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(result->IsString()); 852b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::String::Utf8Value function_name(result->ToString()); 853d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block CHECK_EQ(1, StrLength(*function_name)); 854a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ((*function_name)[0], 855a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block expected_step_sequence[break_point_hit_count]); 856a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 857a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Perform step. 858a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count++; 859a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block PrepareStep(step_action); 860a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 861a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 862a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 863a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 864a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Debug event handler which performs a garbage collection. 865a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic void DebugEventBreakPointCollectGarbage( 866b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::Debug::EventDetails& event_details) { 867b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::DebugEvent event = event_details.GetEvent(); 868b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::internal::Debug* debug = CcTest::i_isolate()->debug(); 869a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // When hitting a debug event listener there must be a break set. 87044f0eee88ff00398ff7f715fab053374d808c90dSteve Block CHECK_NE(debug->break_id(), 0); 871a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 872a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Perform a garbage collection when break point is hit and continue. Based 873a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // on the number of break points hit either scavenge or mark compact 874a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // collector is used. 875a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (event == v8::Break) { 876a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count++; 877a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (break_point_hit_count % 2 == 0) { 878a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Scavenge. 879b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CcTest::heap()->CollectGarbage(v8::internal::NEW_SPACE); 880a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 88180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // Mark sweep compact. 882b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags); 883a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 884a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 885a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 886a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 887a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 888a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Debug event handler which re-issues a debug break and calls the garbage 889a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// collector to have the heap verified. 890b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic void DebugEventBreak( 891b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::Debug::EventDetails& event_details) { 892b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::DebugEvent event = event_details.GetEvent(); 893b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::internal::Debug* debug = CcTest::i_isolate()->debug(); 894a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // When hitting a debug event listener there must be a break set. 89544f0eee88ff00398ff7f715fab053374d808c90dSteve Block CHECK_NE(debug->break_id(), 0); 896a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 897a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (event == v8::Break) { 898a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Count the number of breaks. 899a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count++; 900a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 901a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Run the garbage collector to enforce heap verification if option 902a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // --verify-heap is set. 903b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CcTest::heap()->CollectGarbage(v8::internal::NEW_SPACE); 904a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 905a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Set the break flag again to come back here as soon as possible. 906b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Debug::DebugBreak(CcTest::isolate()); 907a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 908a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 909a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 910a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 911d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block// Debug event handler which re-issues a debug break until a limit has been 912d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block// reached. 913d0582a6c46733687d045e4188a1bcd0123c758a1Steve Blockint max_break_point_hit_count = 0; 9143e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhubool terminate_after_max_break_point_hit = false; 915b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic void DebugEventBreakMax( 916b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::Debug::EventDetails& event_details) { 917b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::DebugEvent event = event_details.GetEvent(); 918b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Handle<v8::Object> exec_state = event_details.GetExecutionState(); 919b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Isolate* v8_isolate = CcTest::isolate(); 920b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::internal::Isolate* isolate = CcTest::i_isolate(); 921b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::internal::Debug* debug = isolate->debug(); 922d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // When hitting a debug event listener there must be a break set. 92344f0eee88ff00398ff7f715fab053374d808c90dSteve Block CHECK_NE(debug->break_id(), 0); 924d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 9253e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu if (event == v8::Break) { 9263e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu if (break_point_hit_count < max_break_point_hit_count) { 9273e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu // Count the number of breaks. 9283e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu break_point_hit_count++; 929d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 9303fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Collect the JavsScript stack height if the function frame_count is 9313fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // compiled. 9323fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (!frame_count.IsEmpty()) { 9333fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch static const int kArgc = 1; 9343fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch v8::Handle<v8::Value> argv[kArgc] = { exec_state }; 9353fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Using exec_state as receiver is just to have a receiver. 9363fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch v8::Handle<v8::Value> result = 9373fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch frame_count->Call(exec_state, kArgc, argv); 9383fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch last_js_stack_height = result->Int32Value(); 9393fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 9403fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 9413e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu // Set the break flag again to come back here as soon as possible. 942b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Debug::DebugBreak(v8_isolate); 9433fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 9443e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu } else if (terminate_after_max_break_point_hit) { 9453e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu // Terminate execution after the last break if requested. 946b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::V8::TerminateExecution(v8_isolate); 9473e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu } 9483fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 9493fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Perform a full deoptimization when the specified number of 9503fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // breaks have been hit. 9513fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (break_point_hit_count == break_point_hit_count_deoptimize) { 952b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch i::Deoptimizer::DeoptimizeAll(isolate); 9533fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 954d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block } 955d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block} 956d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 957d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 958a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// --- M e s s a g e C a l l b a c k 959a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 960a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 961a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Message callback which counts the number of messages. 962a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockint message_callback_count = 0; 963a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 964a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic void MessageCallbackCountClear() { 965a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block message_callback_count = 0; 966a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 967a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 968a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic void MessageCallbackCount(v8::Handle<v8::Message> message, 969a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<v8::Value> data) { 970a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block message_callback_count++; 971a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 972a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 973a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 974a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// --- T h e A c t u a l T e s t s 975a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 976a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 977a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Test that the debug break function is the expected one for different kinds 978a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// of break locations. 979a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(DebugStub) { 980a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block using ::v8::internal::Builtins; 98144f0eee88ff00398ff7f715fab053374d808c90dSteve Block using ::v8::internal::Isolate; 982a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DebugLocalContext env; 983b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(env->GetIsolate()); 984a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 985a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CheckDebugBreakFunction(&env, 986a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "function f1(){}", "f1", 987a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 0, 988a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::internal::RelocInfo::JS_RETURN, 989a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block NULL); 990a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CheckDebugBreakFunction(&env, 991a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "function f2(){x=1;}", "f2", 992a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 0, 993b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::internal::RelocInfo::CODE_TARGET, 994b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CcTest::i_isolate()->builtins()->builtin( 99544f0eee88ff00398ff7f715fab053374d808c90dSteve Block Builtins::kStoreIC_DebugBreak)); 996a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CheckDebugBreakFunction(&env, 997a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "function f3(){var a=x;}", "f3", 998a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 0, 999b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::internal::RelocInfo::CODE_TARGET, 1000b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CcTest::i_isolate()->builtins()->builtin( 100144f0eee88ff00398ff7f715fab053374d808c90dSteve Block Builtins::kLoadIC_DebugBreak)); 1002a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1003a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// TODO(1240753): Make the test architecture independent or split 1004a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// parts of the debugger into architecture dependent files. This 1005a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// part currently disabled as it is not portable between IA32/ARM. 1006a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Currently on ICs for keyed store/load on ARM. 1007a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#if !defined (__arm__) && !defined(__thumb__) 1008a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CheckDebugBreakFunction( 1009a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block &env, 1010a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "function f4(){var index='propertyName'; var a={}; a[index] = 'x';}", 1011a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "f4", 1012a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 0, 1013a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::internal::RelocInfo::CODE_TARGET, 1014b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CcTest::i_isolate()->builtins()->builtin( 101544f0eee88ff00398ff7f715fab053374d808c90dSteve Block Builtins::kKeyedStoreIC_DebugBreak)); 1016a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CheckDebugBreakFunction( 1017a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block &env, 1018a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "function f5(){var index='propertyName'; var a={}; return a[index];}", 1019a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "f5", 1020a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 0, 1021a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::internal::RelocInfo::CODE_TARGET, 1022b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CcTest::i_isolate()->builtins()->builtin( 102344f0eee88ff00398ff7f715fab053374d808c90dSteve Block Builtins::kKeyedLoadIC_DebugBreak)); 1024a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 1025a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1026b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CheckDebugBreakFunction( 1027b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch &env, 1028b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "function f6(a){return a==null;}", 1029b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "f6", 1030b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 0, 1031b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::internal::RelocInfo::CODE_TARGET, 1032b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CcTest::i_isolate()->builtins()->builtin( 1033b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Builtins::kCompareNilIC_DebugBreak)); 1034b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1035a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Check the debug break code stubs for call ICs with different number of 1036a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // parameters. 1037b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // TODO(verwaest): XXX update test. 1038b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Handle<Code> debug_break_0 = v8::internal::ComputeCallDebugBreak(0); 1039b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Handle<Code> debug_break_1 = v8::internal::ComputeCallDebugBreak(1); 1040b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Handle<Code> debug_break_4 = v8::internal::ComputeCallDebugBreak(4); 1041a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1042b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // CheckDebugBreakFunction(&env, 1043b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // "function f4_0(){x();}", "f4_0", 1044b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // 0, 1045b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // v8::internal::RelocInfo::CODE_TARGET, 1046b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // *debug_break_0); 1047a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1048b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // CheckDebugBreakFunction(&env, 1049b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // "function f4_1(){x(1);}", "f4_1", 1050b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // 0, 1051b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // v8::internal::RelocInfo::CODE_TARGET, 1052b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // *debug_break_1); 1053a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1054b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // CheckDebugBreakFunction(&env, 1055b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // "function f4_4(){x(1,2,3,4);}", "f4_4", 1056b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // 0, 1057b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // v8::internal::RelocInfo::CODE_TARGET, 1058b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // *debug_break_4); 1059a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1060a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1061a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1062a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Test that the debug info in the VM is in sync with the functions being 1063a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// debugged. 1064a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(DebugInfo) { 1065a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DebugLocalContext env; 1066b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(env->GetIsolate()); 1067a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Create a couple of functions for the test. 1068a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Local<v8::Function> foo = 1069a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CompileFunction(&env, "function foo(){}", "foo"); 1070a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Local<v8::Function> bar = 1071a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CompileFunction(&env, "function bar(){}", "bar"); 1072a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Initially no functions are debugged. 1073a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(0, v8::internal::GetDebuggedFunctions()->length()); 1074a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(!HasDebugInfo(foo)); 1075a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(!HasDebugInfo(bar)); 1076a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // One function (foo) is debugged. 1077a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int bp1 = SetBreakPoint(foo, 0); 1078a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1, v8::internal::GetDebuggedFunctions()->length()); 1079a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(HasDebugInfo(foo)); 1080a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(!HasDebugInfo(bar)); 1081a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Two functions are debugged. 1082a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int bp2 = SetBreakPoint(bar, 0); 1083a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(2, v8::internal::GetDebuggedFunctions()->length()); 1084a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(HasDebugInfo(foo)); 1085a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(HasDebugInfo(bar)); 1086a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // One function (bar) is debugged. 1087a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ClearBreakPoint(bp1); 1088a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1, v8::internal::GetDebuggedFunctions()->length()); 1089a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(!HasDebugInfo(foo)); 1090a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(HasDebugInfo(bar)); 1091a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // No functions are debugged. 1092a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ClearBreakPoint(bp2); 1093a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(0, v8::internal::GetDebuggedFunctions()->length()); 1094a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(!HasDebugInfo(foo)); 1095a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(!HasDebugInfo(bar)); 1096a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1097a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1098a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1099a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Test that a break point can be set at an IC store location. 1100a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(BreakPointICStore) { 1101a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 1102a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DebugLocalContext env; 1103b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(env->GetIsolate()); 1104a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1105b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount); 1106b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Script::Compile(v8::String::NewFromUtf8(env->GetIsolate(), 1107b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "function foo(){bar=0;}"))->Run(); 1108b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Local<v8::Function> foo = v8::Local<v8::Function>::Cast( 1109b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "foo"))); 1110a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1111a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Run without breakpoints. 1112a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block foo->Call(env->Global(), 0, NULL); 1113a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(0, break_point_hit_count); 1114a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1115a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Run with breakpoint 1116a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int bp = SetBreakPoint(foo, 0); 1117a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block foo->Call(env->Global(), 0, NULL); 1118a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1, break_point_hit_count); 1119a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block foo->Call(env->Global(), 0, NULL); 1120a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(2, break_point_hit_count); 1121a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1122a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Run without breakpoints. 1123a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ClearBreakPoint(bp); 1124a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block foo->Call(env->Global(), 0, NULL); 1125a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(2, break_point_hit_count); 1126a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1127a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetDebugEventListener(NULL); 1128a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CheckDebuggerUnloaded(); 1129a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1130a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1131a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1132a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Test that a break point can be set at an IC load location. 1133a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(BreakPointICLoad) { 1134a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 1135a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DebugLocalContext env; 1136b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(env->GetIsolate()); 1137b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount); 1138b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Script::Compile(v8::String::NewFromUtf8(env->GetIsolate(), "bar=1")) 1139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ->Run(); 1140b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Script::Compile( 1141b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::String::NewFromUtf8(env->GetIsolate(), "function foo(){var x=bar;}")) 1142b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ->Run(); 1143b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Local<v8::Function> foo = v8::Local<v8::Function>::Cast( 1144b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "foo"))); 1145a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1146a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Run without breakpoints. 1147a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block foo->Call(env->Global(), 0, NULL); 1148a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(0, break_point_hit_count); 1149a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 115044f0eee88ff00398ff7f715fab053374d808c90dSteve Block // Run with breakpoint. 1151a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int bp = SetBreakPoint(foo, 0); 1152a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block foo->Call(env->Global(), 0, NULL); 1153a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1, break_point_hit_count); 1154a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block foo->Call(env->Global(), 0, NULL); 1155a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(2, break_point_hit_count); 1156a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1157a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Run without breakpoints. 1158a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ClearBreakPoint(bp); 1159a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block foo->Call(env->Global(), 0, NULL); 1160a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(2, break_point_hit_count); 1161a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1162a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetDebugEventListener(NULL); 1163a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CheckDebuggerUnloaded(); 1164a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1165a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1166a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1167a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Test that a break point can be set at an IC call location. 1168a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(BreakPointICCall) { 1169a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 1170a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DebugLocalContext env; 1171b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(env->GetIsolate()); 1172b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount); 1173b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Script::Compile( 1174b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::String::NewFromUtf8(env->GetIsolate(), "function bar(){}"))->Run(); 1175b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Script::Compile(v8::String::NewFromUtf8(env->GetIsolate(), 1176b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "function foo(){bar();}"))->Run(); 1177b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Local<v8::Function> foo = v8::Local<v8::Function>::Cast( 1178b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "foo"))); 1179a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1180a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Run without breakpoints. 1181a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block foo->Call(env->Global(), 0, NULL); 1182a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(0, break_point_hit_count); 1183a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 118444f0eee88ff00398ff7f715fab053374d808c90dSteve Block // Run with breakpoint 1185a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int bp = SetBreakPoint(foo, 0); 1186a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block foo->Call(env->Global(), 0, NULL); 1187a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1, break_point_hit_count); 1188a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block foo->Call(env->Global(), 0, NULL); 1189a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(2, break_point_hit_count); 1190a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1191a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Run without breakpoints. 1192a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ClearBreakPoint(bp); 1193a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block foo->Call(env->Global(), 0, NULL); 1194a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(2, break_point_hit_count); 1195a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1196a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetDebugEventListener(NULL); 1197a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CheckDebuggerUnloaded(); 1198a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1199a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1200a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 120180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen// Test that a break point can be set at an IC call location and survive a GC. 120280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian MonsenTEST(BreakPointICCallWithGC) { 120380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen break_point_hit_count = 0; 120480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen DebugLocalContext env; 1205b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(env->GetIsolate()); 1206b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Debug::SetDebugEventListener(DebugEventBreakPointCollectGarbage); 1207b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Script::Compile( 1208b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::String::NewFromUtf8(env->GetIsolate(), "function bar(){return 1;}")) 1209b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ->Run(); 1210b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Script::Compile(v8::String::NewFromUtf8(env->GetIsolate(), 1211b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "function foo(){return bar();}")) 1212b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ->Run(); 1213b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Local<v8::Function> foo = v8::Local<v8::Function>::Cast( 1214b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "foo"))); 121580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 121680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // Run without breakpoints. 121780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen CHECK_EQ(1, foo->Call(env->Global(), 0, NULL)->Int32Value()); 121880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen CHECK_EQ(0, break_point_hit_count); 121980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 122080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // Run with breakpoint. 122180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen int bp = SetBreakPoint(foo, 0); 122280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen CHECK_EQ(1, foo->Call(env->Global(), 0, NULL)->Int32Value()); 122380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen CHECK_EQ(1, break_point_hit_count); 122480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen CHECK_EQ(1, foo->Call(env->Global(), 0, NULL)->Int32Value()); 122580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen CHECK_EQ(2, break_point_hit_count); 122680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 122780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // Run without breakpoints. 122880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen ClearBreakPoint(bp); 122980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen foo->Call(env->Global(), 0, NULL); 123080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen CHECK_EQ(2, break_point_hit_count); 123180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 123280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen v8::Debug::SetDebugEventListener(NULL); 123380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen CheckDebuggerUnloaded(); 123480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen} 123580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 123680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 123780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen// Test that a break point can be set at an IC call location and survive a GC. 123880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian MonsenTEST(BreakPointConstructCallWithGC) { 123980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen break_point_hit_count = 0; 124080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen DebugLocalContext env; 1241b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(env->GetIsolate()); 1242b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Debug::SetDebugEventListener(DebugEventBreakPointCollectGarbage); 1243b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Script::Compile(v8::String::NewFromUtf8(env->GetIsolate(), 1244b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "function bar(){ this.x = 1;}")) 1245b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ->Run(); 1246b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Script::Compile( 1247b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::String::NewFromUtf8(env->GetIsolate(), 1248b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "function foo(){return new bar(1).x;}"))->Run(); 1249b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Local<v8::Function> foo = v8::Local<v8::Function>::Cast( 1250b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "foo"))); 125180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 125280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // Run without breakpoints. 125380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen CHECK_EQ(1, foo->Call(env->Global(), 0, NULL)->Int32Value()); 125480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen CHECK_EQ(0, break_point_hit_count); 125580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 125680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // Run with breakpoint. 125780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen int bp = SetBreakPoint(foo, 0); 125880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen CHECK_EQ(1, foo->Call(env->Global(), 0, NULL)->Int32Value()); 125980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen CHECK_EQ(1, break_point_hit_count); 126080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen CHECK_EQ(1, foo->Call(env->Global(), 0, NULL)->Int32Value()); 126180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen CHECK_EQ(2, break_point_hit_count); 126280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 126380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // Run without breakpoints. 126480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen ClearBreakPoint(bp); 126580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen foo->Call(env->Global(), 0, NULL); 126680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen CHECK_EQ(2, break_point_hit_count); 126780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 126880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen v8::Debug::SetDebugEventListener(NULL); 126980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen CheckDebuggerUnloaded(); 127080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen} 127180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 127280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 1273a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Test that a break point can be set at a return store location. 1274a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(BreakPointReturn) { 1275a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 1276a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DebugLocalContext env; 1277b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(env->GetIsolate()); 1278a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1279a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Create a functions for checking the source line and column when hitting 1280a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // a break point. 1281a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block frame_source_line = CompileFunction(&env, 1282a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block frame_source_line_source, 1283a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "frame_source_line"); 1284a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block frame_source_column = CompileFunction(&env, 1285a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block frame_source_column_source, 1286a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "frame_source_column"); 1287a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1288a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1289b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount); 1290b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Script::Compile( 1291b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::String::NewFromUtf8(env->GetIsolate(), "function foo(){}"))->Run(); 1292b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Local<v8::Function> foo = v8::Local<v8::Function>::Cast( 1293b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "foo"))); 1294a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1295a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Run without breakpoints. 1296a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block foo->Call(env->Global(), 0, NULL); 1297a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(0, break_point_hit_count); 1298a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1299a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Run with breakpoint 1300a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int bp = SetBreakPoint(foo, 0); 1301a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block foo->Call(env->Global(), 0, NULL); 1302a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1, break_point_hit_count); 1303a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(0, last_source_line); 1304bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch CHECK_EQ(15, last_source_column); 1305a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block foo->Call(env->Global(), 0, NULL); 1306a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(2, break_point_hit_count); 1307a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(0, last_source_line); 1308bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch CHECK_EQ(15, last_source_column); 1309a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1310a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Run without breakpoints. 1311a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ClearBreakPoint(bp); 1312a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block foo->Call(env->Global(), 0, NULL); 1313a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(2, break_point_hit_count); 1314a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1315a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetDebugEventListener(NULL); 1316a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CheckDebuggerUnloaded(); 1317a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1318a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1319a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1320a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic void CallWithBreakPoints(v8::Local<v8::Object> recv, 1321a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Local<v8::Function> f, 1322a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int break_point_count, 1323a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int call_count) { 1324a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 1325a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (int i = 0; i < call_count; i++) { 1326a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block f->Call(recv, 0, NULL); 1327a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ((i + 1) * break_point_count, break_point_hit_count); 1328a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1329a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1330a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1331b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1332a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Test GC during break point processing. 1333a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(GCDuringBreakPointProcessing) { 1334a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 1335a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DebugLocalContext env; 1336b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(env->GetIsolate()); 1337a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1338b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Debug::SetDebugEventListener(DebugEventBreakPointCollectGarbage); 1339a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Local<v8::Function> foo; 1340a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1341a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Test IC store break point with garbage collection. 1342a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block foo = CompileFunction(&env, "function foo(){bar=0;}", "foo"); 1343a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block SetBreakPoint(foo, 0); 1344a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CallWithBreakPoints(env->Global(), foo, 1, 10); 1345a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1346a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Test IC load break point with garbage collection. 1347a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block foo = CompileFunction(&env, "bar=1;function foo(){var x=bar;}", "foo"); 1348a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block SetBreakPoint(foo, 0); 1349a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CallWithBreakPoints(env->Global(), foo, 1, 10); 1350a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1351a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Test IC call break point with garbage collection. 1352a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block foo = CompileFunction(&env, "function bar(){};function foo(){bar();}", "foo"); 1353a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block SetBreakPoint(foo, 0); 1354a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CallWithBreakPoints(env->Global(), foo, 1, 10); 1355a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1356a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Test return break point with garbage collection. 1357a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block foo = CompileFunction(&env, "function foo(){}", "foo"); 1358a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block SetBreakPoint(foo, 0); 1359a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CallWithBreakPoints(env->Global(), foo, 1, 25); 1360a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 13617f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Test debug break slot break point with garbage collection. 13627f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch foo = CompileFunction(&env, "function foo(){var a;}", "foo"); 13637f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch SetBreakPoint(foo, 0); 13647f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch CallWithBreakPoints(env->Global(), foo, 1, 25); 13657f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 1366a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetDebugEventListener(NULL); 1367a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CheckDebuggerUnloaded(); 1368a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1369a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1370a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1371a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Call the function three times with different garbage collections in between 1372a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// and make sure that the break point survives. 1373bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdochstatic void CallAndGC(v8::Local<v8::Object> recv, 13743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch v8::Local<v8::Function> f) { 1375a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 1376a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1377a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (int i = 0; i < 3; i++) { 1378a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Call function. 1379a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block f->Call(recv, 0, NULL); 1380a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1 + i * 3, break_point_hit_count); 1381a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1382a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Scavenge and call function. 1383b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CcTest::heap()->CollectGarbage(v8::internal::NEW_SPACE); 1384a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block f->Call(recv, 0, NULL); 1385a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(2 + i * 3, break_point_hit_count); 1386a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1387a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Mark sweep (and perhaps compact) and call function. 1388b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags); 1389a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block f->Call(recv, 0, NULL); 1390a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(3 + i * 3, break_point_hit_count); 1391a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1392a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1393a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1394a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 13953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Test that a break point can be set at a return store location. 13963ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochTEST(BreakPointSurviveGC) { 1397a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 1398a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DebugLocalContext env; 1399b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(env->GetIsolate()); 1400a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1401b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount); 1402a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Local<v8::Function> foo; 1403a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1404a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Test IC store break point with garbage collection. 1405bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch { 14063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CompileFunction(&env, "function foo(){}", "foo"); 1407bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch foo = CompileFunction(&env, "function foo(){bar=0;}", "foo"); 1408bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch SetBreakPoint(foo, 0); 1409bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch } 14103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CallAndGC(env->Global(), foo); 1411a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1412a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Test IC load break point with garbage collection. 1413bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch { 14143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CompileFunction(&env, "function foo(){}", "foo"); 1415bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch foo = CompileFunction(&env, "bar=1;function foo(){var x=bar;}", "foo"); 1416bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch SetBreakPoint(foo, 0); 1417bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch } 14183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CallAndGC(env->Global(), foo); 1419a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1420a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Test IC call break point with garbage collection. 1421bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch { 14223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CompileFunction(&env, "function foo(){}", "foo"); 1423bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch foo = CompileFunction(&env, 1424bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch "function bar(){};function foo(){bar();}", 1425bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch "foo"); 1426bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch SetBreakPoint(foo, 0); 1427bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch } 14283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CallAndGC(env->Global(), foo); 1429a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1430a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Test return break point with garbage collection. 1431bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch { 14323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CompileFunction(&env, "function foo(){}", "foo"); 1433bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch foo = CompileFunction(&env, "function foo(){}", "foo"); 1434bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch SetBreakPoint(foo, 0); 1435bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch } 14363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CallAndGC(env->Global(), foo); 1437bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch 1438bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch // Test non IC break point with garbage collection. 1439bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch { 14403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CompileFunction(&env, "function foo(){}", "foo"); 1441bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch foo = CompileFunction(&env, "function foo(){var bar=0;}", "foo"); 1442bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch SetBreakPoint(foo, 0); 1443bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch } 14443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CallAndGC(env->Global(), foo); 1445bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch 1446a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1447a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetDebugEventListener(NULL); 1448a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CheckDebuggerUnloaded(); 1449a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1450a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1451a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1452a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Test that break points can be set using the global Debug object. 1453a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(BreakPointThroughJavaScript) { 1454a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 1455a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DebugLocalContext env; 1456b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(env->GetIsolate()); 1457a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block env.ExposeDebug(); 1458a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1459b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount); 1460b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Script::Compile( 1461b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::String::NewFromUtf8(env->GetIsolate(), "function bar(){}"))->Run(); 1462b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Script::Compile(v8::String::NewFromUtf8(env->GetIsolate(), 1463b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "function foo(){bar();bar();}")) 1464b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ->Run(); 1465a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // 012345678901234567890 1466a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // 1 2 1467a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Break points are set at position 3 and 9 1468b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Local<v8::Script> foo = 1469b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Script::Compile(v8::String::NewFromUtf8(env->GetIsolate(), "foo()")); 1470a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1471a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Run without breakpoints. 1472a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block foo->Run(); 1473a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(0, break_point_hit_count); 1474a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1475a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Run with one breakpoint 1476b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int bp1 = SetBreakPointFromJS(env->GetIsolate(), "foo", 0, 3); 1477a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block foo->Run(); 1478a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1, break_point_hit_count); 1479a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block foo->Run(); 1480a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(2, break_point_hit_count); 1481a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1482a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Run with two breakpoints 1483b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int bp2 = SetBreakPointFromJS(env->GetIsolate(), "foo", 0, 9); 1484a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block foo->Run(); 1485a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(4, break_point_hit_count); 1486a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block foo->Run(); 1487a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(6, break_point_hit_count); 1488a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1489a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Run with one breakpoint 1490b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ClearBreakPointFromJS(env->GetIsolate(), bp2); 1491a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block foo->Run(); 1492a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(7, break_point_hit_count); 1493a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block foo->Run(); 1494a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(8, break_point_hit_count); 1495a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1496a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Run without breakpoints. 1497b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ClearBreakPointFromJS(env->GetIsolate(), bp1); 1498a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block foo->Run(); 1499a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(8, break_point_hit_count); 1500a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1501a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetDebugEventListener(NULL); 1502a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CheckDebuggerUnloaded(); 1503a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1504a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Make sure that the break point numbers are consecutive. 1505a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1, bp1); 1506a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(2, bp2); 1507a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1508a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1509a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1510a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Test that break points on scripts identified by name can be set using the 1511a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// global Debug object. 1512a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(ScriptBreakPointByNameThroughJavaScript) { 1513a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 1514a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DebugLocalContext env; 1515b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(env->GetIsolate()); 1516a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block env.ExposeDebug(); 1517a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1518b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount); 1519a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1520b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Local<v8::String> script = v8::String::NewFromUtf8( 1521b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch env->GetIsolate(), 1522a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "function f() {\n" 1523a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " function h() {\n" 1524a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " a = 0; // line 2\n" 1525a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " }\n" 1526a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " b = 1; // line 4\n" 1527a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " return h();\n" 1528a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "}\n" 1529a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "\n" 1530a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "function g() {\n" 1531a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " function h() {\n" 1532a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " a = 0;\n" 1533a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " }\n" 1534a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " b = 2; // line 12\n" 1535a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " h();\n" 1536a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " b = 3; // line 14\n" 1537a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " f(); // line 15\n" 1538a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "}"); 1539a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1540a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Compile the script and get the two functions. 1541a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::ScriptOrigin origin = 1542b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::ScriptOrigin(v8::String::NewFromUtf8(env->GetIsolate(), "test")); 1543a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Script::Compile(script, &origin)->Run(); 1544b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Local<v8::Function> f = v8::Local<v8::Function>::Cast( 1545b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "f"))); 1546b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Local<v8::Function> g = v8::Local<v8::Function>::Cast( 1547b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "g"))); 1548a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1549a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Call f and g without break points. 1550a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 1551a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block f->Call(env->Global(), 0, NULL); 1552a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(0, break_point_hit_count); 1553a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block g->Call(env->Global(), 0, NULL); 1554a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(0, break_point_hit_count); 1555a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1556a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Call f and g with break point on line 12. 1557b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int sbp1 = SetScriptBreakPointByNameFromJS(env->GetIsolate(), "test", 12, 0); 1558a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 1559a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block f->Call(env->Global(), 0, NULL); 1560a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(0, break_point_hit_count); 1561a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block g->Call(env->Global(), 0, NULL); 1562a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1, break_point_hit_count); 1563a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1564a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Remove the break point again. 1565a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 1566b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ClearBreakPointFromJS(env->GetIsolate(), sbp1); 1567a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block f->Call(env->Global(), 0, NULL); 1568a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(0, break_point_hit_count); 1569a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block g->Call(env->Global(), 0, NULL); 1570a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(0, break_point_hit_count); 1571a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1572a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Call f and g with break point on line 2. 1573b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int sbp2 = SetScriptBreakPointByNameFromJS(env->GetIsolate(), "test", 2, 0); 1574a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 1575a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block f->Call(env->Global(), 0, NULL); 1576a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1, break_point_hit_count); 1577a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block g->Call(env->Global(), 0, NULL); 1578a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(2, break_point_hit_count); 1579a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1580a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Call f and g with break point on line 2, 4, 12, 14 and 15. 1581b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int sbp3 = SetScriptBreakPointByNameFromJS(env->GetIsolate(), "test", 4, 0); 1582b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int sbp4 = SetScriptBreakPointByNameFromJS(env->GetIsolate(), "test", 12, 0); 1583b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int sbp5 = SetScriptBreakPointByNameFromJS(env->GetIsolate(), "test", 14, 0); 1584b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int sbp6 = SetScriptBreakPointByNameFromJS(env->GetIsolate(), "test", 15, 0); 1585a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 1586a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block f->Call(env->Global(), 0, NULL); 1587a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(2, break_point_hit_count); 1588a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block g->Call(env->Global(), 0, NULL); 1589a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(7, break_point_hit_count); 1590a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1591a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Remove all the break points again. 1592a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 1593b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ClearBreakPointFromJS(env->GetIsolate(), sbp2); 1594b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ClearBreakPointFromJS(env->GetIsolate(), sbp3); 1595b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ClearBreakPointFromJS(env->GetIsolate(), sbp4); 1596b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ClearBreakPointFromJS(env->GetIsolate(), sbp5); 1597b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ClearBreakPointFromJS(env->GetIsolate(), sbp6); 1598a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block f->Call(env->Global(), 0, NULL); 1599a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(0, break_point_hit_count); 1600a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block g->Call(env->Global(), 0, NULL); 1601a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(0, break_point_hit_count); 1602a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1603a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetDebugEventListener(NULL); 1604a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CheckDebuggerUnloaded(); 1605a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1606a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Make sure that the break point numbers are consecutive. 1607a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1, sbp1); 1608a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(2, sbp2); 1609a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(3, sbp3); 1610a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(4, sbp4); 1611a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(5, sbp5); 1612a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(6, sbp6); 1613a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1614a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1615a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1616a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(ScriptBreakPointByIdThroughJavaScript) { 1617a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 1618a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DebugLocalContext env; 1619b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(env->GetIsolate()); 1620a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block env.ExposeDebug(); 1621a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1622b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount); 1623a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1624b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Local<v8::String> source = v8::String::NewFromUtf8( 1625b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch env->GetIsolate(), 1626a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "function f() {\n" 1627a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " function h() {\n" 1628a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " a = 0; // line 2\n" 1629a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " }\n" 1630a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " b = 1; // line 4\n" 1631a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " return h();\n" 1632a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "}\n" 1633a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "\n" 1634a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "function g() {\n" 1635a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " function h() {\n" 1636a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " a = 0;\n" 1637a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " }\n" 1638a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " b = 2; // line 12\n" 1639a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " h();\n" 1640a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " b = 3; // line 14\n" 1641a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " f(); // line 15\n" 1642a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "}"); 1643a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1644a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Compile the script and get the two functions. 1645a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::ScriptOrigin origin = 1646b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::ScriptOrigin(v8::String::NewFromUtf8(env->GetIsolate(), "test")); 1647a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Local<v8::Script> script = v8::Script::Compile(source, &origin); 1648a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block script->Run(); 1649b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Local<v8::Function> f = v8::Local<v8::Function>::Cast( 1650b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "f"))); 1651b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Local<v8::Function> g = v8::Local<v8::Function>::Cast( 1652b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "g"))); 1653a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1654a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Get the script id knowing that internally it is a 32 integer. 1655b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int script_id = script->GetUnboundScript()->GetId(); 1656a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1657a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Call f and g without break points. 1658a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 1659a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block f->Call(env->Global(), 0, NULL); 1660a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(0, break_point_hit_count); 1661a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block g->Call(env->Global(), 0, NULL); 1662a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(0, break_point_hit_count); 1663a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1664a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Call f and g with break point on line 12. 1665b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int sbp1 = SetScriptBreakPointByIdFromJS(env->GetIsolate(), script_id, 12, 0); 1666a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 1667a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block f->Call(env->Global(), 0, NULL); 1668a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(0, break_point_hit_count); 1669a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block g->Call(env->Global(), 0, NULL); 1670a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1, break_point_hit_count); 1671a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1672a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Remove the break point again. 1673a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 1674b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ClearBreakPointFromJS(env->GetIsolate(), sbp1); 1675a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block f->Call(env->Global(), 0, NULL); 1676a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(0, break_point_hit_count); 1677a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block g->Call(env->Global(), 0, NULL); 1678a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(0, break_point_hit_count); 1679a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1680a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Call f and g with break point on line 2. 1681b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int sbp2 = SetScriptBreakPointByIdFromJS(env->GetIsolate(), script_id, 2, 0); 1682a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 1683a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block f->Call(env->Global(), 0, NULL); 1684a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1, break_point_hit_count); 1685a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block g->Call(env->Global(), 0, NULL); 1686a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(2, break_point_hit_count); 1687a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1688a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Call f and g with break point on line 2, 4, 12, 14 and 15. 1689b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int sbp3 = SetScriptBreakPointByIdFromJS(env->GetIsolate(), script_id, 4, 0); 1690b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int sbp4 = SetScriptBreakPointByIdFromJS(env->GetIsolate(), script_id, 12, 0); 1691b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int sbp5 = SetScriptBreakPointByIdFromJS(env->GetIsolate(), script_id, 14, 0); 1692b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int sbp6 = SetScriptBreakPointByIdFromJS(env->GetIsolate(), script_id, 15, 0); 1693a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 1694a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block f->Call(env->Global(), 0, NULL); 1695a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(2, break_point_hit_count); 1696a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block g->Call(env->Global(), 0, NULL); 1697a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(7, break_point_hit_count); 1698a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1699a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Remove all the break points again. 1700a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 1701b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ClearBreakPointFromJS(env->GetIsolate(), sbp2); 1702b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ClearBreakPointFromJS(env->GetIsolate(), sbp3); 1703b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ClearBreakPointFromJS(env->GetIsolate(), sbp4); 1704b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ClearBreakPointFromJS(env->GetIsolate(), sbp5); 1705b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ClearBreakPointFromJS(env->GetIsolate(), sbp6); 1706a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block f->Call(env->Global(), 0, NULL); 1707a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(0, break_point_hit_count); 1708a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block g->Call(env->Global(), 0, NULL); 1709a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(0, break_point_hit_count); 1710a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1711a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetDebugEventListener(NULL); 1712a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CheckDebuggerUnloaded(); 1713a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1714a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Make sure that the break point numbers are consecutive. 1715a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1, sbp1); 1716a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(2, sbp2); 1717a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(3, sbp3); 1718a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(4, sbp4); 1719a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(5, sbp5); 1720a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(6, sbp6); 1721a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1722a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1723a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1724a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Test conditional script break points. 1725a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(EnableDisableScriptBreakPoint) { 1726a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 1727a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DebugLocalContext env; 1728b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(env->GetIsolate()); 1729a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block env.ExposeDebug(); 1730a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1731b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount); 1732a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1733b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Local<v8::String> script = v8::String::NewFromUtf8( 1734b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch env->GetIsolate(), 1735a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "function f() {\n" 1736a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " a = 0; // line 1\n" 1737a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "};"); 1738a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1739a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Compile the script and get function f. 1740a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::ScriptOrigin origin = 1741b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::ScriptOrigin(v8::String::NewFromUtf8(env->GetIsolate(), "test")); 1742a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Script::Compile(script, &origin)->Run(); 1743b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Local<v8::Function> f = v8::Local<v8::Function>::Cast( 1744b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "f"))); 1745a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1746a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Set script break point on line 1 (in function f). 1747b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int sbp = SetScriptBreakPointByNameFromJS(env->GetIsolate(), "test", 1, 0); 1748a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1749a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Call f while enabeling and disabling the script break point. 1750a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 1751a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block f->Call(env->Global(), 0, NULL); 1752a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1, break_point_hit_count); 1753a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1754b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DisableScriptBreakPointFromJS(env->GetIsolate(), sbp); 1755a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block f->Call(env->Global(), 0, NULL); 1756a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1, break_point_hit_count); 1757a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1758b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch EnableScriptBreakPointFromJS(env->GetIsolate(), sbp); 1759a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block f->Call(env->Global(), 0, NULL); 1760a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(2, break_point_hit_count); 1761a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1762b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DisableScriptBreakPointFromJS(env->GetIsolate(), sbp); 1763a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block f->Call(env->Global(), 0, NULL); 1764a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(2, break_point_hit_count); 1765a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1766a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Reload the script and get f again checking that the disabeling survives. 1767a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Script::Compile(script, &origin)->Run(); 1768b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch f = v8::Local<v8::Function>::Cast( 1769b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "f"))); 1770a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block f->Call(env->Global(), 0, NULL); 1771a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(2, break_point_hit_count); 1772a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1773b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch EnableScriptBreakPointFromJS(env->GetIsolate(), sbp); 1774a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block f->Call(env->Global(), 0, NULL); 1775a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(3, break_point_hit_count); 1776a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1777a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetDebugEventListener(NULL); 1778a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CheckDebuggerUnloaded(); 1779a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1780a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1781a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1782a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Test conditional script break points. 1783a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(ConditionalScriptBreakPoint) { 1784a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 1785a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DebugLocalContext env; 1786b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(env->GetIsolate()); 1787a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block env.ExposeDebug(); 1788a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1789b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount); 1790a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1791b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Local<v8::String> script = v8::String::NewFromUtf8( 1792b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch env->GetIsolate(), 1793a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "count = 0;\n" 1794a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "function f() {\n" 1795a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " g(count++); // line 2\n" 1796a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "};\n" 1797a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "function g(x) {\n" 1798a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " var a=x; // line 5\n" 1799a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "};"); 1800a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1801a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Compile the script and get function f. 1802a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::ScriptOrigin origin = 1803b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::ScriptOrigin(v8::String::NewFromUtf8(env->GetIsolate(), "test")); 1804a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Script::Compile(script, &origin)->Run(); 1805b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Local<v8::Function> f = v8::Local<v8::Function>::Cast( 1806b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "f"))); 1807a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1808a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Set script break point on line 5 (in function g). 1809b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int sbp1 = SetScriptBreakPointByNameFromJS(env->GetIsolate(), "test", 5, 0); 1810a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1811a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Call f with different conditions on the script break point. 1812a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 1813b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ChangeScriptBreakPointConditionFromJS(env->GetIsolate(), sbp1, "false"); 1814a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block f->Call(env->Global(), 0, NULL); 1815a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(0, break_point_hit_count); 1816a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1817b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ChangeScriptBreakPointConditionFromJS(env->GetIsolate(), sbp1, "true"); 1818a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 1819a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block f->Call(env->Global(), 0, NULL); 1820a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1, break_point_hit_count); 1821a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1822b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ChangeScriptBreakPointConditionFromJS(env->GetIsolate(), sbp1, "x % 2 == 0"); 1823a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 1824a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (int i = 0; i < 10; i++) { 1825a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block f->Call(env->Global(), 0, NULL); 1826a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1827a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(5, break_point_hit_count); 1828a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1829a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Reload the script and get f again checking that the condition survives. 1830a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Script::Compile(script, &origin)->Run(); 1831b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch f = v8::Local<v8::Function>::Cast( 1832b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "f"))); 1833a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1834a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 1835a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (int i = 0; i < 10; i++) { 1836a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block f->Call(env->Global(), 0, NULL); 1837a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1838a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(5, break_point_hit_count); 1839a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1840a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetDebugEventListener(NULL); 1841a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CheckDebuggerUnloaded(); 1842a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1843a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1844a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1845a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Test ignore count on script break points. 1846a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(ScriptBreakPointIgnoreCount) { 1847a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 1848a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DebugLocalContext env; 1849b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(env->GetIsolate()); 1850a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block env.ExposeDebug(); 1851a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1852b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount); 1853a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1854b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Local<v8::String> script = v8::String::NewFromUtf8( 1855b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch env->GetIsolate(), 1856a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "function f() {\n" 1857a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " a = 0; // line 1\n" 1858a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "};"); 1859a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1860a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Compile the script and get function f. 1861a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::ScriptOrigin origin = 1862b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::ScriptOrigin(v8::String::NewFromUtf8(env->GetIsolate(), "test")); 1863a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Script::Compile(script, &origin)->Run(); 1864b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Local<v8::Function> f = v8::Local<v8::Function>::Cast( 1865b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "f"))); 1866a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1867a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Set script break point on line 1 (in function f). 1868b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int sbp = SetScriptBreakPointByNameFromJS(env->GetIsolate(), "test", 1, 0); 1869a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1870a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Call f with different ignores on the script break point. 1871a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 1872b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ChangeScriptBreakPointIgnoreCountFromJS(env->GetIsolate(), sbp, 1); 1873a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block f->Call(env->Global(), 0, NULL); 1874a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(0, break_point_hit_count); 1875a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block f->Call(env->Global(), 0, NULL); 1876a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1, break_point_hit_count); 1877a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1878b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ChangeScriptBreakPointIgnoreCountFromJS(env->GetIsolate(), sbp, 5); 1879a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 1880a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (int i = 0; i < 10; i++) { 1881a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block f->Call(env->Global(), 0, NULL); 1882a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1883a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(5, break_point_hit_count); 1884a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1885a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Reload the script and get f again checking that the ignore survives. 1886a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Script::Compile(script, &origin)->Run(); 1887b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch f = v8::Local<v8::Function>::Cast( 1888b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "f"))); 1889a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1890a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 1891a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (int i = 0; i < 10; i++) { 1892a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block f->Call(env->Global(), 0, NULL); 1893a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1894a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(5, break_point_hit_count); 1895a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1896a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetDebugEventListener(NULL); 1897a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CheckDebuggerUnloaded(); 1898a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1899a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1900a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1901a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Test that script break points survive when a script is reloaded. 1902a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(ScriptBreakPointReload) { 1903a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 1904a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DebugLocalContext env; 1905b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(env->GetIsolate()); 1906a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block env.ExposeDebug(); 1907a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1908b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount); 1909a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1910a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Local<v8::Function> f; 1911b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Local<v8::String> script = v8::String::NewFromUtf8( 1912b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch env->GetIsolate(), 1913a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "function f() {\n" 1914a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " function h() {\n" 1915a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " a = 0; // line 2\n" 1916a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " }\n" 1917a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " b = 1; // line 4\n" 1918a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " return h();\n" 1919a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "}"); 1920a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1921b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::ScriptOrigin origin_1 = 1922b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::ScriptOrigin(v8::String::NewFromUtf8(env->GetIsolate(), "1")); 1923b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::ScriptOrigin origin_2 = 1924b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::ScriptOrigin(v8::String::NewFromUtf8(env->GetIsolate(), "2")); 1925a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1926a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Set a script break point before the script is loaded. 1927b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SetScriptBreakPointByNameFromJS(env->GetIsolate(), "1", 2, 0); 1928a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1929a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Compile the script and get the function. 1930a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Script::Compile(script, &origin_1)->Run(); 1931b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch f = v8::Local<v8::Function>::Cast( 1932b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "f"))); 1933a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1934a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Call f and check that the script break point is active. 1935a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 1936a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block f->Call(env->Global(), 0, NULL); 1937a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1, break_point_hit_count); 1938a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1939a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Compile the script again with a different script data and get the 1940a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // function. 1941a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Script::Compile(script, &origin_2)->Run(); 1942b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch f = v8::Local<v8::Function>::Cast( 1943b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "f"))); 1944a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1945a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Call f and check that no break points are set. 1946a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 1947a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block f->Call(env->Global(), 0, NULL); 1948a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(0, break_point_hit_count); 1949a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1950a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Compile the script again and get the function. 1951a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Script::Compile(script, &origin_1)->Run(); 1952b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch f = v8::Local<v8::Function>::Cast( 1953b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "f"))); 1954a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1955a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Call f and check that the script break point is active. 1956a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 1957a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block f->Call(env->Global(), 0, NULL); 1958a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1, break_point_hit_count); 1959a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1960a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetDebugEventListener(NULL); 1961a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CheckDebuggerUnloaded(); 1962a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1963a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1964a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1965a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Test when several scripts has the same script data 1966a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(ScriptBreakPointMultiple) { 1967a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 1968a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DebugLocalContext env; 1969b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(env->GetIsolate()); 1970a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block env.ExposeDebug(); 1971a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1972b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount); 1973a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1974a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Local<v8::Function> f; 1975b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Local<v8::String> script_f = 1976b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::String::NewFromUtf8(env->GetIsolate(), 1977b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "function f() {\n" 1978b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch " a = 0; // line 1\n" 1979b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "}"); 1980a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1981a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Local<v8::Function> g; 1982b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Local<v8::String> script_g = 1983b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::String::NewFromUtf8(env->GetIsolate(), 1984b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "function g() {\n" 1985b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch " b = 0; // line 1\n" 1986b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "}"); 1987a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1988a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::ScriptOrigin origin = 1989b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::ScriptOrigin(v8::String::NewFromUtf8(env->GetIsolate(), "test")); 1990a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1991a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Set a script break point before the scripts are loaded. 1992b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int sbp = SetScriptBreakPointByNameFromJS(env->GetIsolate(), "test", 1, 0); 1993a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1994a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Compile the scripts with same script data and get the functions. 1995a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Script::Compile(script_f, &origin)->Run(); 1996b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch f = v8::Local<v8::Function>::Cast( 1997b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "f"))); 1998a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Script::Compile(script_g, &origin)->Run(); 1999b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch g = v8::Local<v8::Function>::Cast( 2000b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "g"))); 2001a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2002a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Call f and g and check that the script break point is active. 2003a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 2004a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block f->Call(env->Global(), 0, NULL); 2005a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1, break_point_hit_count); 2006a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block g->Call(env->Global(), 0, NULL); 2007a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(2, break_point_hit_count); 2008a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2009a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Clear the script break point. 2010b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ClearBreakPointFromJS(env->GetIsolate(), sbp); 2011a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2012a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Call f and g and check that the script break point is no longer active. 2013a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 2014a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block f->Call(env->Global(), 0, NULL); 2015a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(0, break_point_hit_count); 2016a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block g->Call(env->Global(), 0, NULL); 2017a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(0, break_point_hit_count); 2018a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2019a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Set script break point with the scripts loaded. 2020b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch sbp = SetScriptBreakPointByNameFromJS(env->GetIsolate(), "test", 1, 0); 2021a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2022a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Call f and g and check that the script break point is active. 2023a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 2024a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block f->Call(env->Global(), 0, NULL); 2025a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1, break_point_hit_count); 2026a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block g->Call(env->Global(), 0, NULL); 2027a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(2, break_point_hit_count); 2028a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2029a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetDebugEventListener(NULL); 2030a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CheckDebuggerUnloaded(); 2031a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2032a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2033a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2034a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Test the script origin which has both name and line offset. 2035a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(ScriptBreakPointLineOffset) { 2036a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 2037a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DebugLocalContext env; 2038b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(env->GetIsolate()); 2039a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block env.ExposeDebug(); 2040a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2041b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount); 2042a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2043a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Local<v8::Function> f; 2044b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Local<v8::String> script = v8::String::NewFromUtf8( 2045b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch env->GetIsolate(), 2046b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "function f() {\n" 2047b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch " a = 0; // line 8 as this script has line offset 7\n" 2048b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch " b = 0; // line 9 as this script has line offset 7\n" 2049b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "}"); 2050a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2051a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Create script origin both name and line offset. 2052b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::ScriptOrigin origin( 2053b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::String::NewFromUtf8(env->GetIsolate(), "test.html"), 2054b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Integer::New(env->GetIsolate(), 7)); 2055a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2056a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Set two script break points before the script is loaded. 2057b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int sbp1 = 2058b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SetScriptBreakPointByNameFromJS(env->GetIsolate(), "test.html", 8, 0); 2059b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int sbp2 = 2060b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SetScriptBreakPointByNameFromJS(env->GetIsolate(), "test.html", 9, 0); 2061a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2062a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Compile the script and get the function. 2063a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Script::Compile(script, &origin)->Run(); 2064b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch f = v8::Local<v8::Function>::Cast( 2065b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "f"))); 2066a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2067a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Call f and check that the script break point is active. 2068a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 2069a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block f->Call(env->Global(), 0, NULL); 2070a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(2, break_point_hit_count); 2071a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2072a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Clear the script break points. 2073b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ClearBreakPointFromJS(env->GetIsolate(), sbp1); 2074b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ClearBreakPointFromJS(env->GetIsolate(), sbp2); 2075a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2076a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Call f and check that no script break points are active. 2077a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 2078a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block f->Call(env->Global(), 0, NULL); 2079a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(0, break_point_hit_count); 2080a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2081a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Set a script break point with the script loaded. 2082b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch sbp1 = SetScriptBreakPointByNameFromJS(env->GetIsolate(), "test.html", 9, 0); 2083a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2084a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Call f and check that the script break point is active. 2085a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 2086a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block f->Call(env->Global(), 0, NULL); 2087a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1, break_point_hit_count); 2088a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2089a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetDebugEventListener(NULL); 2090a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CheckDebuggerUnloaded(); 2091a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2092a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2093a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2094a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Test script break points set on lines. 2095a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(ScriptBreakPointLine) { 2096a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DebugLocalContext env; 2097b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(env->GetIsolate()); 2098a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block env.ExposeDebug(); 2099a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2100a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Create a function for checking the function when hitting a break point. 2101a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block frame_function_name = CompileFunction(&env, 2102a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block frame_function_name_source, 2103a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "frame_function_name"); 2104a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2105b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount); 2106a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2107a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Local<v8::Function> f; 2108a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Local<v8::Function> g; 2109b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Local<v8::String> script = 2110b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::String::NewFromUtf8(env->GetIsolate(), 2111b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "a = 0 // line 0\n" 2112b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "function f() {\n" 2113b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch " a = 1; // line 2\n" 2114b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "}\n" 2115b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch " a = 2; // line 4\n" 2116b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch " /* xx */ function g() { // line 5\n" 2117b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch " function h() { // line 6\n" 2118b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch " a = 3; // line 7\n" 2119b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch " }\n" 2120b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch " h(); // line 9\n" 2121b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch " a = 4; // line 10\n" 2122b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch " }\n" 2123b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch " a=5; // line 12"); 2124a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2125a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Set a couple script break point before the script is loaded. 2126b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int sbp1 = 2127b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SetScriptBreakPointByNameFromJS(env->GetIsolate(), "test.html", 0, -1); 2128b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int sbp2 = 2129b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SetScriptBreakPointByNameFromJS(env->GetIsolate(), "test.html", 1, -1); 2130b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int sbp3 = 2131b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SetScriptBreakPointByNameFromJS(env->GetIsolate(), "test.html", 5, -1); 2132a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2133a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Compile the script and get the function. 2134a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 2135b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::ScriptOrigin origin( 2136b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::String::NewFromUtf8(env->GetIsolate(), "test.html"), 2137b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Integer::New(env->GetIsolate(), 0)); 2138a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Script::Compile(script, &origin)->Run(); 2139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch f = v8::Local<v8::Function>::Cast( 2140b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "f"))); 2141b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch g = v8::Local<v8::Function>::Cast( 2142b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "g"))); 2143a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 214469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch // Check that a break point was hit when the script was run. 2145a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1, break_point_hit_count); 2146d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block CHECK_EQ(0, StrLength(last_function_hit)); 2147a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2148a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Call f and check that the script break point. 2149a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block f->Call(env->Global(), 0, NULL); 2150a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(2, break_point_hit_count); 2151a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ("f", last_function_hit); 2152a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2153a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Call g and check that the script break point. 2154a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block g->Call(env->Global(), 0, NULL); 2155a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(3, break_point_hit_count); 2156a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ("g", last_function_hit); 2157a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2158a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Clear the script break point on g and set one on h. 2159b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ClearBreakPointFromJS(env->GetIsolate(), sbp3); 2160b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int sbp4 = 2161b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SetScriptBreakPointByNameFromJS(env->GetIsolate(), "test.html", 6, -1); 2162a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2163a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Call g and check that the script break point in h is hit. 2164a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block g->Call(env->Global(), 0, NULL); 2165a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(4, break_point_hit_count); 2166a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ("h", last_function_hit); 2167a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2168a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Clear break points in f and h. Set a new one in the script between 2169a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // functions f and g and test that there is no break points in f and g any 2170a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // more. 2171b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ClearBreakPointFromJS(env->GetIsolate(), sbp2); 2172b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ClearBreakPointFromJS(env->GetIsolate(), sbp4); 2173b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int sbp5 = 2174b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SetScriptBreakPointByNameFromJS(env->GetIsolate(), "test.html", 4, -1); 2175a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 2176a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block f->Call(env->Global(), 0, NULL); 2177a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block g->Call(env->Global(), 0, NULL); 2178a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(0, break_point_hit_count); 2179a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2180a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Reload the script which should hit two break points. 2181a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 2182a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Script::Compile(script, &origin)->Run(); 2183a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(2, break_point_hit_count); 2184d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block CHECK_EQ(0, StrLength(last_function_hit)); 2185a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2186a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Set a break point in the code after the last function decleration. 2187b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int sbp6 = 2188b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SetScriptBreakPointByNameFromJS(env->GetIsolate(), "test.html", 12, -1); 2189a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2190a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Reload the script which should hit three break points. 2191a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 2192a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Script::Compile(script, &origin)->Run(); 2193a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(3, break_point_hit_count); 2194d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block CHECK_EQ(0, StrLength(last_function_hit)); 2195a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2196a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Clear the last break points, and reload the script which should not hit any 2197a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // break points. 2198b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ClearBreakPointFromJS(env->GetIsolate(), sbp1); 2199b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ClearBreakPointFromJS(env->GetIsolate(), sbp5); 2200b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ClearBreakPointFromJS(env->GetIsolate(), sbp6); 2201a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 2202a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Script::Compile(script, &origin)->Run(); 2203a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(0, break_point_hit_count); 2204a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2205a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetDebugEventListener(NULL); 2206a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CheckDebuggerUnloaded(); 2207a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2208a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2209a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 22109dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen// Test top level script break points set on lines. 22119dcf7e2f83591d471e88bf7d230651900b8e424bKristian MonsenTEST(ScriptBreakPointLineTopLevel) { 22129dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen DebugLocalContext env; 2213b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(env->GetIsolate()); 22149dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen env.ExposeDebug(); 22159dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen 2216b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount); 22179dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen 2218b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Local<v8::String> script = 2219b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::String::NewFromUtf8(env->GetIsolate(), 2220b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "function f() {\n" 2221b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch " a = 1; // line 1\n" 2222b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "}\n" 2223b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "a = 2; // line 3\n"); 22249dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen v8::Local<v8::Function> f; 22259dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen { 2226b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(env->GetIsolate()); 2227b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CompileRunWithOrigin(script, "test.html"); 22289dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen } 2229b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch f = v8::Local<v8::Function>::Cast( 2230b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "f"))); 22319dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen 2232b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags); 22339dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen 2234b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SetScriptBreakPointByNameFromJS(env->GetIsolate(), "test.html", 3, -1); 22359dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen 22369dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen // Call f and check that there was no break points. 22379dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen break_point_hit_count = 0; 22389dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen f->Call(env->Global(), 0, NULL); 22399dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen CHECK_EQ(0, break_point_hit_count); 22409dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen 22419dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen // Recompile and run script and check that break point was hit. 22429dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen break_point_hit_count = 0; 2243b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CompileRunWithOrigin(script, "test.html"); 22449dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen CHECK_EQ(1, break_point_hit_count); 22459dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen 22469dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen // Call f and check that there are still no break points. 22479dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen break_point_hit_count = 0; 2248b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch f = v8::Local<v8::Function>::Cast( 2249b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "f"))); 22509dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen CHECK_EQ(0, break_point_hit_count); 22519dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen 22529dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen v8::Debug::SetDebugEventListener(NULL); 22539dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen CheckDebuggerUnloaded(); 22549dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen} 22559dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen 22569dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen 22578defd9ff6930b4e24729971a61cf7469daf119beSteve Block// Test that it is possible to add and remove break points in a top level 22588defd9ff6930b4e24729971a61cf7469daf119beSteve Block// function which has no references but has not been collected yet. 22598defd9ff6930b4e24729971a61cf7469daf119beSteve BlockTEST(ScriptBreakPointTopLevelCrash) { 22608defd9ff6930b4e24729971a61cf7469daf119beSteve Block DebugLocalContext env; 2261b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(env->GetIsolate()); 22628defd9ff6930b4e24729971a61cf7469daf119beSteve Block env.ExposeDebug(); 22638defd9ff6930b4e24729971a61cf7469daf119beSteve Block 2264b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount); 22658defd9ff6930b4e24729971a61cf7469daf119beSteve Block 2266b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Local<v8::String> script_source = 2267b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::String::NewFromUtf8(env->GetIsolate(), 2268b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "function f() {\n" 2269b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch " return 0;\n" 2270b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "}\n" 2271b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "f()"); 22728defd9ff6930b4e24729971a61cf7469daf119beSteve Block 2273b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int sbp1 = 2274b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SetScriptBreakPointByNameFromJS(env->GetIsolate(), "test.html", 3, -1); 22758defd9ff6930b4e24729971a61cf7469daf119beSteve Block { 2276b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(env->GetIsolate()); 22778defd9ff6930b4e24729971a61cf7469daf119beSteve Block break_point_hit_count = 0; 2278b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CompileRunWithOrigin(script_source, "test.html"); 22798defd9ff6930b4e24729971a61cf7469daf119beSteve Block CHECK_EQ(1, break_point_hit_count); 22808defd9ff6930b4e24729971a61cf7469daf119beSteve Block } 22818defd9ff6930b4e24729971a61cf7469daf119beSteve Block 2282b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int sbp2 = 2283b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SetScriptBreakPointByNameFromJS(env->GetIsolate(), "test.html", 3, -1); 2284b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ClearBreakPointFromJS(env->GetIsolate(), sbp1); 2285b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ClearBreakPointFromJS(env->GetIsolate(), sbp2); 22868defd9ff6930b4e24729971a61cf7469daf119beSteve Block 22878defd9ff6930b4e24729971a61cf7469daf119beSteve Block v8::Debug::SetDebugEventListener(NULL); 22888defd9ff6930b4e24729971a61cf7469daf119beSteve Block CheckDebuggerUnloaded(); 22898defd9ff6930b4e24729971a61cf7469daf119beSteve Block} 22908defd9ff6930b4e24729971a61cf7469daf119beSteve Block 22918defd9ff6930b4e24729971a61cf7469daf119beSteve Block 2292a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Test that it is possible to remove the last break point for a function 2293a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// inside the break handling of that break point. 2294a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(RemoveBreakPointInBreak) { 2295a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DebugLocalContext env; 2296b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(env->GetIsolate()); 2297a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2298a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Local<v8::Function> foo = 2299a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CompileFunction(&env, "function foo(){a=1;}", "foo"); 2300a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block debug_event_remove_break_point = SetBreakPoint(foo, 0); 2301a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2302a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Register the debug event listener pasing the function 2303a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetDebugEventListener(DebugEventRemoveBreakPoint, foo); 2304a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2305a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 2306a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block foo->Call(env->Global(), 0, NULL); 2307a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1, break_point_hit_count); 2308a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2309a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 2310a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block foo->Call(env->Global(), 0, NULL); 2311a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(0, break_point_hit_count); 2312a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2313a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetDebugEventListener(NULL); 2314a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CheckDebuggerUnloaded(); 2315a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2316a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2317a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2318a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Test that the debugger statement causes a break. 2319a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(DebuggerStatement) { 2320a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 2321a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DebugLocalContext env; 2322b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(env->GetIsolate()); 2323b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount); 2324b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Script::Compile( 2325b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::String::NewFromUtf8(env->GetIsolate(), "function bar(){debugger}")) 2326b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ->Run(); 2327b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Script::Compile( 2328b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::String::NewFromUtf8(env->GetIsolate(), 2329b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "function foo(){debugger;debugger;}"))->Run(); 2330b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Local<v8::Function> foo = v8::Local<v8::Function>::Cast( 2331b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "foo"))); 2332b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Local<v8::Function> bar = v8::Local<v8::Function>::Cast( 2333b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "bar"))); 2334a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2335a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Run function with debugger statement 2336a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bar->Call(env->Global(), 0, NULL); 2337a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1, break_point_hit_count); 2338a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2339a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Run function with two debugger statement 2340a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block foo->Call(env->Global(), 0, NULL); 2341a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(3, break_point_hit_count); 2342a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2343a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetDebugEventListener(NULL); 2344a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CheckDebuggerUnloaded(); 2345a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2346a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2347a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 23488defd9ff6930b4e24729971a61cf7469daf119beSteve Block// Test setting a breakpoint on the debugger statement. 23494515c472dc3e5ed2448a564600976759e569a0a8Leon ClarkeTEST(DebuggerStatementBreakpoint) { 23504515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke break_point_hit_count = 0; 23514515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke DebugLocalContext env; 2352b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(env->GetIsolate()); 2353b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount); 2354b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Script::Compile( 2355b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::String::NewFromUtf8(env->GetIsolate(), "function foo(){debugger;}")) 2356b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ->Run(); 2357b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Local<v8::Function> foo = v8::Local<v8::Function>::Cast( 2358b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "foo"))); 23594515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke 23604515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke // The debugger statement triggers breakpint hit 23614515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke foo->Call(env->Global(), 0, NULL); 23624515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke CHECK_EQ(1, break_point_hit_count); 23634515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke 23644515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke int bp = SetBreakPoint(foo, 0); 23654515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke 23664515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke // Set breakpoint does not duplicate hits 23674515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke foo->Call(env->Global(), 0, NULL); 23684515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke CHECK_EQ(2, break_point_hit_count); 23694515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke 23704515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke ClearBreakPoint(bp); 23714515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke v8::Debug::SetDebugEventListener(NULL); 23724515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke CheckDebuggerUnloaded(); 23734515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke} 23744515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke 23754515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke 2376b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Test that the evaluation of expressions when a break point is hit generates 2377a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// the correct results. 2378a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(DebugEvaluate) { 2379a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DebugLocalContext env; 2380b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Isolate* isolate = env->GetIsolate(); 2381b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(isolate); 2382a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block env.ExposeDebug(); 2383a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2384a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Create a function for checking the evaluation when hitting a break point. 2385a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block evaluate_check_function = CompileFunction(&env, 2386a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block evaluate_check_source, 2387a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "evaluate_check"); 2388a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Register the debug event listener 2389a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetDebugEventListener(DebugEventEvaluate); 2390a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2391a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Different expected vaules of x and a when in a break point (u = undefined, 2392a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // d = Hello, world!). 2393a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block struct EvaluateCheck checks_uu[] = { 2394b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch {"x", v8::Undefined(isolate)}, 2395b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch {"a", v8::Undefined(isolate)}, 2396a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block {NULL, v8::Handle<v8::Value>()} 2397a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block }; 2398a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block struct EvaluateCheck checks_hu[] = { 2399b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch {"x", v8::String::NewFromUtf8(env->GetIsolate(), "Hello, world!")}, 2400b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch {"a", v8::Undefined(isolate)}, 2401a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block {NULL, v8::Handle<v8::Value>()} 2402a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block }; 2403a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block struct EvaluateCheck checks_hh[] = { 2404b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch {"x", v8::String::NewFromUtf8(env->GetIsolate(), "Hello, world!")}, 2405b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch {"a", v8::String::NewFromUtf8(env->GetIsolate(), "Hello, world!")}, 2406a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block {NULL, v8::Handle<v8::Value>()} 2407a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block }; 2408a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2409a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Simple test function. The "y=0" is in the function foo to provide a break 2410b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // location. For "y=0" the "y" is at position 15 in the foo function 2411a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // therefore setting breakpoint at position 15 will break at "y=0" and 2412a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // setting it higher will break after. 2413a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Local<v8::Function> foo = CompileFunction(&env, 2414a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "function foo(x) {" 2415a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " var a;" 24167f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch " y=0;" // To ensure break location 1. 2417a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " a=x;" 24187f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch " y=0;" // To ensure break location 2. 2419a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "}", 2420a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "foo"); 24217f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch const int foo_break_position_1 = 15; 24227f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch const int foo_break_position_2 = 29; 2423a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2424a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Arguments with one parameter "Hello, world!" 2425b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Handle<v8::Value> argv_foo[1] = { 2426b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::String::NewFromUtf8(env->GetIsolate(), "Hello, world!")}; 2427a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2428a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Call foo with breakpoint set before a=x and undefined as parameter. 24297f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch int bp = SetBreakPoint(foo, foo_break_position_1); 2430a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block checks = checks_uu; 2431a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block foo->Call(env->Global(), 0, NULL); 2432a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2433a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Call foo with breakpoint set before a=x and parameter "Hello, world!". 2434a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block checks = checks_hu; 2435a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block foo->Call(env->Global(), 1, argv_foo); 2436a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2437a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Call foo with breakpoint set after a=x and parameter "Hello, world!". 2438a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ClearBreakPoint(bp); 24397f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch SetBreakPoint(foo, foo_break_position_2); 2440a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block checks = checks_hh; 2441a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block foo->Call(env->Global(), 1, argv_foo); 2442a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2443b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Test that overriding Object.prototype will not interfere into evaluation 2444b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // on call frame. 2445b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Local<v8::Function> zoo = 2446b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CompileFunction(&env, 2447b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "x = undefined;" 2448b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "function zoo(t) {" 2449b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch " var a=x;" 2450b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch " Object.prototype.x = 42;" 2451b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch " x=t;" 2452b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch " y=0;" // To ensure break location. 2453b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch " delete Object.prototype.x;" 2454b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch " x=a;" 2455b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "}", 2456b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "zoo"); 2457b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const int zoo_break_position = 50; 2458b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2459b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Arguments with one parameter "Hello, world!" 2460b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Handle<v8::Value> argv_zoo[1] = { 2461b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::String::NewFromUtf8(env->GetIsolate(), "Hello, world!")}; 2462b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2463b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Call zoo with breakpoint set at y=0. 2464b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DebugEventCounterClear(); 2465b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bp = SetBreakPoint(zoo, zoo_break_position); 2466b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch checks = checks_hu; 2467b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch zoo->Call(env->Global(), 1, argv_zoo); 2468b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(1, break_point_hit_count); 2469b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ClearBreakPoint(bp); 2470b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2471a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Test function with an inner function. The "y=0" is in function barbar 2472a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // to provide a break location. For "y=0" the "y" is at position 8 in the 2473a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // barbar function therefore setting breakpoint at position 8 will break at 2474a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // "y=0" and setting it higher will break after. 2475a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Local<v8::Function> bar = CompileFunction(&env, 2476a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "y = 0;" 2477a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "x = 'Goodbye, world!';" 2478a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "function bar(x, b) {" 2479a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " var a;" 2480a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " function barbar() {" 2481a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " y=0; /* To ensure break location.*/" 2482a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " a=x;" 2483a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " };" 2484a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " debug.Debug.clearAllBreakPoints();" 2485a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " barbar();" 2486a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " y=0;a=x;" 2487a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "}", 2488a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "bar"); 2489a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const int barbar_break_position = 8; 2490a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2491a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Call bar setting breakpoint before a=x in barbar and undefined as 2492a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // parameter. 2493a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block checks = checks_uu; 2494a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<v8::Value> argv_bar_1[2] = { 2495b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Undefined(isolate), 2496b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Number::New(isolate, barbar_break_position) 2497a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block }; 2498a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bar->Call(env->Global(), 2, argv_bar_1); 2499a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2500a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Call bar setting breakpoint before a=x in barbar and parameter 2501a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // "Hello, world!". 2502a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block checks = checks_hu; 2503a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<v8::Value> argv_bar_2[2] = { 2504b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::String::NewFromUtf8(env->GetIsolate(), "Hello, world!"), 2505b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Number::New(env->GetIsolate(), barbar_break_position) 2506a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block }; 2507a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bar->Call(env->Global(), 2, argv_bar_2); 2508a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2509a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Call bar setting breakpoint after a=x in barbar and parameter 2510a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // "Hello, world!". 2511a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block checks = checks_hh; 2512a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<v8::Value> argv_bar_3[2] = { 2513b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::String::NewFromUtf8(env->GetIsolate(), "Hello, world!"), 2514b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Number::New(env->GetIsolate(), barbar_break_position + 1) 2515a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block }; 2516a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bar->Call(env->Global(), 2, argv_bar_3); 2517a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2518a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetDebugEventListener(NULL); 2519a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CheckDebuggerUnloaded(); 2520a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2521a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2522b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2523b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochint debugEventCount = 0; 2524b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic void CheckDebugEvent(const v8::Debug::EventDetails& eventDetails) { 2525b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (eventDetails.GetEvent() == v8::Break) ++debugEventCount; 2526b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2527b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2528b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2529b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Test that the conditional breakpoints work event if code generation from 2530b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// strings is prohibited in the debugee context. 2531b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST(ConditionalBreakpointWithCodeGenerationDisallowed) { 2532b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DebugLocalContext env; 2533b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(env->GetIsolate()); 2534b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch env.ExposeDebug(); 2535b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2536b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Debug::SetDebugEventListener(CheckDebugEvent); 2537b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2538b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Local<v8::Function> foo = CompileFunction(&env, 2539b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "function foo(x) {\n" 2540b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch " var s = 'String value2';\n" 2541b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch " return s + x;\n" 2542b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "}", 2543b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "foo"); 2544b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2545b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Set conditional breakpoint with condition 'true'. 2546b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CompileRun("debug.Debug.setBreakPoint(foo, 2, 0, 'true')"); 2547b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2548b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch debugEventCount = 0; 2549b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch env->AllowCodeGenerationFromStrings(false); 2550b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch foo->Call(env->Global(), 0, NULL); 2551b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(1, debugEventCount); 2552b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2553b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Debug::SetDebugEventListener(NULL); 2554b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CheckDebuggerUnloaded(); 2555b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2556b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2557b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2558b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool checkedDebugEvals = true; 2559b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochv8::Handle<v8::Function> checkGlobalEvalFunction; 2560b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochv8::Handle<v8::Function> checkFrameEvalFunction; 2561b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic void CheckDebugEval(const v8::Debug::EventDetails& eventDetails) { 2562b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (eventDetails.GetEvent() == v8::Break) { 2563b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ++debugEventCount; 2564b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope handleScope(CcTest::isolate()); 2565b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2566b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Handle<v8::Value> args[] = { eventDetails.GetExecutionState() }; 2567b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK(checkGlobalEvalFunction->Call( 2568b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch eventDetails.GetEventContext()->Global(), 1, args)->IsTrue()); 2569b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK(checkFrameEvalFunction->Call( 2570b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch eventDetails.GetEventContext()->Global(), 1, args)->IsTrue()); 2571b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2572b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2573b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2574b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2575b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Test that the evaluation of expressions when a break point is hit generates 2576b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// the correct results in case code generation from strings is disallowed in the 2577b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// debugee context. 2578b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST(DebugEvaluateWithCodeGenerationDisallowed) { 2579b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DebugLocalContext env; 2580b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(env->GetIsolate()); 2581b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch env.ExposeDebug(); 2582b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2583b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Debug::SetDebugEventListener(CheckDebugEval); 2584b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2585b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Local<v8::Function> foo = CompileFunction(&env, 2586b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "var global = 'Global';\n" 2587b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "function foo(x) {\n" 2588b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch " var local = 'Local';\n" 2589b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch " debugger;\n" 2590b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch " return local + x;\n" 2591b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "}", 2592b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "foo"); 2593b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch checkGlobalEvalFunction = CompileFunction(&env, 2594b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "function checkGlobalEval(exec_state) {\n" 2595b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch " return exec_state.evaluateGlobal('global').value() === 'Global';\n" 2596b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "}", 2597b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "checkGlobalEval"); 2598b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2599b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch checkFrameEvalFunction = CompileFunction(&env, 2600b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "function checkFrameEval(exec_state) {\n" 2601b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch " return exec_state.frame(0).evaluate('local').value() === 'Local';\n" 2602b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "}", 2603b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "checkFrameEval"); 2604b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch debugEventCount = 0; 2605b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch env->AllowCodeGenerationFromStrings(false); 2606b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch foo->Call(env->Global(), 0, NULL); 2607b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(1, debugEventCount); 2608b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2609b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch checkGlobalEvalFunction.Clear(); 2610b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch checkFrameEvalFunction.Clear(); 2611b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Debug::SetDebugEventListener(NULL); 2612b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CheckDebuggerUnloaded(); 2613b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2614b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2615b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2616e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke// Copies a C string to a 16-bit string. Does not check for buffer overflow. 2617e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke// Does not use the V8 engine to convert strings, so it can be used 2618e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke// in any thread. Returns the length of the string. 2619e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarkeint AsciiToUtf16(const char* input_buffer, uint16_t* output_buffer) { 2620e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke int i; 2621e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke for (i = 0; input_buffer[i] != '\0'; ++i) { 2622e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // ASCII does not use chars > 127, but be careful anyway. 2623e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke output_buffer[i] = static_cast<unsigned char>(input_buffer[i]); 2624e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke } 2625e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke output_buffer[i] = 0; 2626e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke return i; 2627e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke} 2628e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 2629b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2630e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke// Copies a 16-bit string to a C string by dropping the high byte of 2631e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke// each character. Does not check for buffer overflow. 2632e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke// Can be used in any thread. Requires string length as an input. 2633e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarkeint Utf16ToAscii(const uint16_t* input_buffer, int length, 2634e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke char* output_buffer, int output_len = -1) { 2635e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke if (output_len >= 0) { 2636e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke if (length > output_len - 1) { 2637e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke length = output_len - 1; 2638e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke } 2639e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke } 2640e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 2641e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke for (int i = 0; i < length; ++i) { 2642e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke output_buffer[i] = static_cast<char>(input_buffer[i]); 2643e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke } 2644e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke output_buffer[length] = '\0'; 2645e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke return length; 2646e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke} 2647e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 2648e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 2649e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke// We match parts of the message to get evaluate result int value. 2650e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarkebool GetEvaluateStringResult(char *message, char* buffer, int buffer_size) { 2651d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke if (strstr(message, "\"command\":\"evaluate\"") == NULL) { 2652d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke return false; 2653d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 2654d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke const char* prefix = "\"text\":\""; 2655d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke char* pos1 = strstr(message, prefix); 2656d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke if (pos1 == NULL) { 2657d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke return false; 2658d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 2659d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke pos1 += strlen(prefix); 2660d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke char* pos2 = strchr(pos1, '"'); 2661d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke if (pos2 == NULL) { 2662e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke return false; 2663e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke } 2664e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke Vector<char> buf(buffer, buffer_size); 2665d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke int len = static_cast<int>(pos2 - pos1); 2666d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke if (len > buffer_size - 1) { 2667d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke len = buffer_size - 1; 2668d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 2669b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch StrNCpy(buf, pos1, len); 2670e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke buffer[buffer_size - 1] = '\0'; 2671e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke return true; 2672e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke} 2673e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 2674e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 2675e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarkestruct EvaluateResult { 2676e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke static const int kBufferSize = 20; 2677e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke char buffer[kBufferSize]; 2678e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke}; 2679e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 2680e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarkestruct DebugProcessDebugMessagesData { 2681e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke static const int kArraySize = 5; 2682e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke int counter; 2683e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke EvaluateResult results[kArraySize]; 2684e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 2685e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke void reset() { 2686e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke counter = 0; 2687e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke } 2688e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke EvaluateResult* current() { 2689e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke return &results[counter % kArraySize]; 2690e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke } 2691e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke void next() { 2692e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke counter++; 2693e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke } 2694e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke}; 2695e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 2696e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon ClarkeDebugProcessDebugMessagesData process_debug_messages_data; 2697e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 2698e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarkestatic void DebugProcessDebugMessagesHandler( 2699b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::Debug::Message& message) { 2700b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Handle<v8::String> json = message.GetJSON(); 2701b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::String::Utf8Value utf8(json); 2702e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke EvaluateResult* array_item = process_debug_messages_data.current(); 2703e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 2704b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool res = GetEvaluateStringResult(*utf8, 2705e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke array_item->buffer, 2706e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke EvaluateResult::kBufferSize); 2707e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke if (res) { 2708e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke process_debug_messages_data.next(); 2709e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke } 2710e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke} 2711e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 2712b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2713e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke// Test that the evaluation of expressions works even from ProcessDebugMessages 2714e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke// i.e. with empty stack. 2715e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon ClarkeTEST(DebugEvaluateWithoutStack) { 2716e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke v8::Debug::SetMessageHandler(DebugProcessDebugMessagesHandler); 2717e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 2718e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke DebugLocalContext env; 2719b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(env->GetIsolate()); 2720e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 2721e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke const char* source = 2722e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke "var v1 = 'Pinguin';\n function getAnimal() { return 'Capy' + 'bara'; }"; 2723e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 2724b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Script::Compile(v8::String::NewFromUtf8(env->GetIsolate(), source)) 2725b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ->Run(); 2726e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 2727e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke v8::Debug::ProcessDebugMessages(); 2728e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 2729e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke const int kBufferSize = 1000; 2730e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke uint16_t buffer[kBufferSize]; 2731e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 2732e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke const char* command_111 = "{\"seq\":111," 2733e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke "\"type\":\"request\"," 2734e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke "\"command\":\"evaluate\"," 2735e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke "\"arguments\":{" 2736e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke " \"global\":true," 2737e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke " \"expression\":\"v1\",\"disable_break\":true" 2738e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke "}}"; 2739e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 2740b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Isolate* isolate = CcTest::isolate(); 2741b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Debug::SendCommand(isolate, buffer, AsciiToUtf16(command_111, buffer)); 2742e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 2743e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke const char* command_112 = "{\"seq\":112," 2744e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke "\"type\":\"request\"," 2745e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke "\"command\":\"evaluate\"," 2746e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke "\"arguments\":{" 2747e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke " \"global\":true," 2748e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke " \"expression\":\"getAnimal()\",\"disable_break\":true" 2749e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke "}}"; 2750e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 2751b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Debug::SendCommand(isolate, buffer, AsciiToUtf16(command_112, buffer)); 2752e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 2753e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke const char* command_113 = "{\"seq\":113," 2754e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke "\"type\":\"request\"," 2755e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke "\"command\":\"evaluate\"," 2756e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke "\"arguments\":{" 2757e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke " \"global\":true," 2758e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke " \"expression\":\"239 + 566\",\"disable_break\":true" 2759e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke "}}"; 2760e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 2761b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Debug::SendCommand(isolate, buffer, AsciiToUtf16(command_113, buffer)); 2762e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 2763e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke v8::Debug::ProcessDebugMessages(); 2764e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 2765e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke CHECK_EQ(3, process_debug_messages_data.counter); 2766e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 2767d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke CHECK_EQ(strcmp("Pinguin", process_debug_messages_data.results[0].buffer), 0); 2768d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke CHECK_EQ(strcmp("Capybara", process_debug_messages_data.results[1].buffer), 2769d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 0); 2770d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke CHECK_EQ(strcmp("805", process_debug_messages_data.results[2].buffer), 0); 2771e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 2772e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke v8::Debug::SetMessageHandler(NULL); 2773e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke v8::Debug::SetDebugEventListener(NULL); 2774e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke CheckDebuggerUnloaded(); 2775e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke} 2776e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 2777a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2778a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Simple test of the stepping mechanism using only store ICs. 2779a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(DebugStepLinear) { 2780a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DebugLocalContext env; 2781b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(env->GetIsolate()); 2782a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2783a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Create a function for testing stepping. 2784a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Local<v8::Function> foo = CompileFunction(&env, 2785a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "function foo(){a=1;b=1;c=1;}", 2786a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "foo"); 2787b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 2788b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Run foo to allow it to get optimized. 2789b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CompileRun("a=0; b=0; c=0; foo();"); 2790b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 2791a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block SetBreakPoint(foo, 3); 2792a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2793a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Register a debug event listener which steps and counts. 2794a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetDebugEventListener(DebugEventStep); 2795a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2796a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block step_action = StepIn; 2797a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 2798a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block foo->Call(env->Global(), 0, NULL); 2799a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2800a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // With stepping all break locations are hit. 2801a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(4, break_point_hit_count); 2802a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2803a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetDebugEventListener(NULL); 2804a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CheckDebuggerUnloaded(); 2805a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2806a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Register a debug event listener which just counts. 2807a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount); 2808a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2809a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block SetBreakPoint(foo, 3); 2810a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 2811a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block foo->Call(env->Global(), 0, NULL); 2812a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2813a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Without stepping only active break points are hit. 2814a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1, break_point_hit_count); 2815a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2816a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetDebugEventListener(NULL); 2817a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CheckDebuggerUnloaded(); 2818a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2819a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2820a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2821a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Test of the stepping mechanism for keyed load in a loop. 2822a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(DebugStepKeyedLoadLoop) { 2823a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DebugLocalContext env; 2824b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(env->GetIsolate()); 2825a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 28267f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Register a debug event listener which steps and counts. 28277f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch v8::Debug::SetDebugEventListener(DebugEventStep); 28287f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 2829a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Create a function for testing stepping of keyed load. The statement 'y=1' 2830a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // is there to have more than one breakable statement in the loop, TODO(315). 2831a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Local<v8::Function> foo = CompileFunction( 2832a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block &env, 2833a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "function foo(a) {\n" 2834a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " var x;\n" 2835a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " var len = a.length;\n" 2836a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " for (var i = 0; i < len; i++) {\n" 2837a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " y = 1;\n" 2838a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " x = a[i];\n" 2839a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " }\n" 2840b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "}\n" 2841b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "y=0\n", 2842a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "foo"); 2843a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2844a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Create array [0,1,2,3,4,5,6,7,8,9] 2845b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Local<v8::Array> a = v8::Array::New(env->GetIsolate(), 10); 2846a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (int i = 0; i < 10; i++) { 2847b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch a->Set(v8::Number::New(env->GetIsolate(), i), 2848b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Number::New(env->GetIsolate(), i)); 2849a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2850a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2851a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Call function without any break points to ensure inlining is in place. 2852a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const int kArgc = 1; 2853a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<v8::Value> args[kArgc] = { a }; 2854a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block foo->Call(env->Global(), kArgc, args); 2855a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 28563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Set up break point and step through the function. 2857a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block SetBreakPoint(foo, 3); 2858a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block step_action = StepNext; 2859a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 2860a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block foo->Call(env->Global(), kArgc, args); 2861a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2862a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // With stepping all break locations are hit. 2863b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(35, break_point_hit_count); 2864a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2865a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetDebugEventListener(NULL); 2866a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CheckDebuggerUnloaded(); 2867a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2868a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2869a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2870a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Test of the stepping mechanism for keyed store in a loop. 2871a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(DebugStepKeyedStoreLoop) { 2872a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DebugLocalContext env; 2873b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(env->GetIsolate()); 2874a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 28757f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Register a debug event listener which steps and counts. 28767f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch v8::Debug::SetDebugEventListener(DebugEventStep); 28777f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 2878a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Create a function for testing stepping of keyed store. The statement 'y=1' 2879a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // is there to have more than one breakable statement in the loop, TODO(315). 2880a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Local<v8::Function> foo = CompileFunction( 2881a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block &env, 2882a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "function foo(a) {\n" 2883a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " var len = a.length;\n" 2884a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " for (var i = 0; i < len; i++) {\n" 2885a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " y = 1;\n" 2886a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " a[i] = 42;\n" 2887a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " }\n" 2888b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "}\n" 2889b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "y=0\n", 2890a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "foo"); 2891a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2892a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Create array [0,1,2,3,4,5,6,7,8,9] 2893b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Local<v8::Array> a = v8::Array::New(env->GetIsolate(), 10); 2894a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (int i = 0; i < 10; i++) { 2895b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch a->Set(v8::Number::New(env->GetIsolate(), i), 2896b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Number::New(env->GetIsolate(), i)); 2897a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2898a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2899a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Call function without any break points to ensure inlining is in place. 2900a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const int kArgc = 1; 2901a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<v8::Value> args[kArgc] = { a }; 2902a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block foo->Call(env->Global(), kArgc, args); 2903a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 29043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Set up break point and step through the function. 2905a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block SetBreakPoint(foo, 3); 2906a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block step_action = StepNext; 2907a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 2908a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block foo->Call(env->Global(), kArgc, args); 2909a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2910a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // With stepping all break locations are hit. 2911b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(34, break_point_hit_count); 2912a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2913a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetDebugEventListener(NULL); 2914a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CheckDebuggerUnloaded(); 2915a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2916a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2917a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 291825f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen// Test of the stepping mechanism for named load in a loop. 291925f6136652d8341ed047e7fc1a450af5bd218ea9Kristian MonsenTEST(DebugStepNamedLoadLoop) { 292025f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen DebugLocalContext env; 2921b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(env->GetIsolate()); 292225f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen 29237f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Register a debug event listener which steps and counts. 29247f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch v8::Debug::SetDebugEventListener(DebugEventStep); 29257f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 292625f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen // Create a function for testing stepping of named load. 292725f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen v8::Local<v8::Function> foo = CompileFunction( 292825f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen &env, 292925f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen "function foo() {\n" 293025f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen " var a = [];\n" 293125f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen " var s = \"\";\n" 293225f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen " for (var i = 0; i < 10; i++) {\n" 293325f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen " var v = new V(i, i + 1);\n" 293425f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen " v.y;\n" 293525f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen " a.length;\n" // Special case: array length. 293625f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen " s.length;\n" // Special case: string length. 293725f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen " }\n" 293825f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen "}\n" 293925f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen "function V(x, y) {\n" 294025f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen " this.x = x;\n" 294125f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen " this.y = y;\n" 294225f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen "}\n", 294325f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen "foo"); 294425f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen 294525f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen // Call function without any break points to ensure inlining is in place. 294625f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen foo->Call(env->Global(), 0, NULL); 294725f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen 29483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Set up break point and step through the function. 294925f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen SetBreakPoint(foo, 4); 295025f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen step_action = StepNext; 295125f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen break_point_hit_count = 0; 295225f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen foo->Call(env->Global(), 0, NULL); 295325f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen 295425f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen // With stepping all break locations are hit. 2955b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(55, break_point_hit_count); 295625f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen 295725f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen v8::Debug::SetDebugEventListener(NULL); 295825f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen CheckDebuggerUnloaded(); 295925f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen} 296025f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen 296125f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen 2962b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochstatic void DoDebugStepNamedStoreLoop(int expected) { 2963756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick DebugLocalContext env; 2964b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(env->GetIsolate()); 2965756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 2966b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Register a debug event listener which steps and counts. 2967b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch v8::Debug::SetDebugEventListener(DebugEventStep); 2968756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 2969756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick // Create a function for testing stepping of named store. 2970756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick v8::Local<v8::Function> foo = CompileFunction( 2971756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick &env, 2972756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick "function foo() {\n" 2973756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick " var a = {a:1};\n" 2974756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick " for (var i = 0; i < 10; i++) {\n" 2975756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick " a.a = 2\n" 2976756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick " }\n" 2977756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick "}\n", 2978756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick "foo"); 2979756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 2980756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick // Call function without any break points to ensure inlining is in place. 2981756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick foo->Call(env->Global(), 0, NULL); 2982756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 29833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Set up break point and step through the function. 2984756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick SetBreakPoint(foo, 3); 2985756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick step_action = StepNext; 2986756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick break_point_hit_count = 0; 2987756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick foo->Call(env->Global(), 0, NULL); 2988756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 2989756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick // With stepping all expected break locations are hit. 2990756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick CHECK_EQ(expected, break_point_hit_count); 2991756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 2992756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick v8::Debug::SetDebugEventListener(NULL); 2993756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick CheckDebuggerUnloaded(); 2994756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick} 2995756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 2996756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 2997756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick// Test of the stepping mechanism for named load in a loop. 2998b0fe1620dcb4135ac3ab2d66ff93072373911299Ben MurdochTEST(DebugStepNamedStoreLoop) { 2999b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DoDebugStepNamedStoreLoop(24); 3000756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick} 3001756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 3002756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 3003a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Test the stepping mechanism with different ICs. 3004a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(DebugStepLinearMixedICs) { 3005a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DebugLocalContext env; 3006b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(env->GetIsolate()); 3007a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 30087f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Register a debug event listener which steps and counts. 30097f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch v8::Debug::SetDebugEventListener(DebugEventStep); 30107f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 3011a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Create a function for testing stepping. 3012a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Local<v8::Function> foo = CompileFunction(&env, 3013a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "function bar() {};" 3014a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "function foo() {" 3015a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " var x;" 3016a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " var index='name';" 3017a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " var y = {};" 3018a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " a=1;b=2;x=a;y[index]=3;x=y[index];bar();}", "foo"); 3019b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 3020b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Run functions to allow them to get optimized. 3021b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CompileRun("a=0; b=0; bar(); foo();"); 3022b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 3023a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block SetBreakPoint(foo, 0); 3024a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3025a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block step_action = StepIn; 3026a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 3027a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block foo->Call(env->Global(), 0, NULL); 3028a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3029a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // With stepping all break locations are hit. 30307f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch CHECK_EQ(11, break_point_hit_count); 3031a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3032a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetDebugEventListener(NULL); 3033a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CheckDebuggerUnloaded(); 3034a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3035a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Register a debug event listener which just counts. 3036a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount); 3037a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3038a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block SetBreakPoint(foo, 0); 3039a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 3040a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block foo->Call(env->Global(), 0, NULL); 3041a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3042a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Without stepping only active break points are hit. 3043a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1, break_point_hit_count); 3044a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3045a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetDebugEventListener(NULL); 3046a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CheckDebuggerUnloaded(); 3047a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 3048a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3049a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 30507f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen MurdochTEST(DebugStepDeclarations) { 30517f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch DebugLocalContext env; 3052b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(env->GetIsolate()); 30537f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 30547f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Register a debug event listener which steps and counts. 30557f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch v8::Debug::SetDebugEventListener(DebugEventStep); 30567f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 3057b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Create a function for testing stepping. Run it to allow it to get 3058b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // optimized. 30597f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch const char* src = "function foo() { " 30607f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch " var a;" 30617f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch " var b = 1;" 30627f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch " var c = foo;" 30637f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch " var d = Math.floor;" 30647f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch " var e = b + d(1.2);" 3065b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "}" 3066b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "foo()"; 30677f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch v8::Local<v8::Function> foo = CompileFunction(&env, src, "foo"); 3068b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 30697f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch SetBreakPoint(foo, 0); 30707f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 30717f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Stepping through the declarations. 30727f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch step_action = StepIn; 30737f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch break_point_hit_count = 0; 30747f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch foo->Call(env->Global(), 0, NULL); 30757f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch CHECK_EQ(6, break_point_hit_count); 30767f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 30777f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Get rid of the debug event listener. 30787f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch v8::Debug::SetDebugEventListener(NULL); 30797f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch CheckDebuggerUnloaded(); 30807f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 30817f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 30827f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 30837f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen MurdochTEST(DebugStepLocals) { 30847f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch DebugLocalContext env; 3085b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(env->GetIsolate()); 30867f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 30877f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Register a debug event listener which steps and counts. 30887f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch v8::Debug::SetDebugEventListener(DebugEventStep); 30897f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 3090b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Create a function for testing stepping. Run it to allow it to get 3091b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // optimized. 30927f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch const char* src = "function foo() { " 30937f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch " var a,b;" 30947f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch " a = 1;" 30957f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch " b = a + 2;" 30967f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch " b = 1 + 2 + 3;" 30977f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch " a = Math.floor(b);" 3098b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "}" 3099b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "foo()"; 31007f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch v8::Local<v8::Function> foo = CompileFunction(&env, src, "foo"); 3101b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 31027f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch SetBreakPoint(foo, 0); 31037f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 31047f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Stepping through the declarations. 31057f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch step_action = StepIn; 31067f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch break_point_hit_count = 0; 31077f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch foo->Call(env->Global(), 0, NULL); 31087f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch CHECK_EQ(6, break_point_hit_count); 31097f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 31107f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Get rid of the debug event listener. 31117f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch v8::Debug::SetDebugEventListener(NULL); 31127f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch CheckDebuggerUnloaded(); 31137f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 31147f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 31157f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 3116a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(DebugStepIf) { 3117a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DebugLocalContext env; 3118b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Isolate* isolate = env->GetIsolate(); 3119b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(isolate); 3120a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3121a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Register a debug event listener which steps and counts. 3122a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetDebugEventListener(DebugEventStep); 3123a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3124b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Create a function for testing stepping. Run it to allow it to get 3125b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // optimized. 3126a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const int argc = 1; 3127a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const char* src = "function foo(x) { " 3128a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " a = 1;" 3129a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " if (x) {" 3130a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " b = 1;" 3131a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " } else {" 3132a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " c = 1;" 3133a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " d = 1;" 3134a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " }" 3135b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "}" 3136b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "a=0; b=0; c=0; d=0; foo()"; 3137a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Local<v8::Function> foo = CompileFunction(&env, src, "foo"); 3138a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block SetBreakPoint(foo, 0); 3139a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3140a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Stepping through the true part. 3141a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block step_action = StepIn; 3142a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 3143b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Handle<v8::Value> argv_true[argc] = { v8::True(isolate) }; 3144a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block foo->Call(env->Global(), argc, argv_true); 31457f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch CHECK_EQ(4, break_point_hit_count); 3146a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3147a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Stepping through the false part. 3148a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block step_action = StepIn; 3149a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 3150b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Handle<v8::Value> argv_false[argc] = { v8::False(isolate) }; 3151a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block foo->Call(env->Global(), argc, argv_false); 31527f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch CHECK_EQ(5, break_point_hit_count); 3153a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3154a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Get rid of the debug event listener. 3155a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetDebugEventListener(NULL); 3156a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CheckDebuggerUnloaded(); 3157a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 3158a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3159a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3160a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(DebugStepSwitch) { 3161a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DebugLocalContext env; 3162b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Isolate* isolate = env->GetIsolate(); 3163b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(isolate); 3164a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3165a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Register a debug event listener which steps and counts. 3166a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetDebugEventListener(DebugEventStep); 3167a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3168b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Create a function for testing stepping. Run it to allow it to get 3169b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // optimized. 3170a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const int argc = 1; 3171a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const char* src = "function foo(x) { " 3172a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " a = 1;" 3173a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " switch (x) {" 3174a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " case 1:" 3175a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " b = 1;" 3176a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " case 2:" 3177a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " c = 1;" 3178a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " break;" 3179a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " case 3:" 3180a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " d = 1;" 3181a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " e = 1;" 31827f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch " f = 1;" 3183a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " break;" 3184a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " }" 3185b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "}" 3186b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "a=0; b=0; c=0; d=0; e=0; f=0; foo()"; 3187a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Local<v8::Function> foo = CompileFunction(&env, src, "foo"); 3188a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block SetBreakPoint(foo, 0); 3189a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3190a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // One case with fall-through. 3191a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block step_action = StepIn; 3192a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 3193b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Handle<v8::Value> argv_1[argc] = { v8::Number::New(isolate, 1) }; 3194a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block foo->Call(env->Global(), argc, argv_1); 31957f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch CHECK_EQ(6, break_point_hit_count); 3196a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3197a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Another case. 3198a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block step_action = StepIn; 3199a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 3200b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Handle<v8::Value> argv_2[argc] = { v8::Number::New(isolate, 2) }; 3201a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block foo->Call(env->Global(), argc, argv_2); 32027f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch CHECK_EQ(5, break_point_hit_count); 3203a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3204a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Last case. 3205a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block step_action = StepIn; 3206a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 3207b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Handle<v8::Value> argv_3[argc] = { v8::Number::New(isolate, 3) }; 3208a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block foo->Call(env->Global(), argc, argv_3); 32097f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch CHECK_EQ(7, break_point_hit_count); 32107f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 32117f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Get rid of the debug event listener. 32127f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch v8::Debug::SetDebugEventListener(NULL); 32137f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch CheckDebuggerUnloaded(); 32147f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 32157f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 32167f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 32177f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen MurdochTEST(DebugStepWhile) { 32187f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch DebugLocalContext env; 3219b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Isolate* isolate = env->GetIsolate(); 3220b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(isolate); 32217f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 32227f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Register a debug event listener which steps and counts. 32237f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch v8::Debug::SetDebugEventListener(DebugEventStep); 32247f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 3225b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Create a function for testing stepping. Run it to allow it to get 3226b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // optimized. 32277f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch const int argc = 1; 32287f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch const char* src = "function foo(x) { " 32297f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch " var a = 0;" 32307f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch " while (a < x) {" 32317f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch " a++;" 32327f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch " }" 3233b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "}" 3234b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "foo()"; 32357f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch v8::Local<v8::Function> foo = CompileFunction(&env, src, "foo"); 32367f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch SetBreakPoint(foo, 8); // "var a = 0;" 32377f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 3238b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Looping 0 times. We still should break at the while-condition once. 3239b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch step_action = StepIn; 3240b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break_point_hit_count = 0; 3241b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Handle<v8::Value> argv_0[argc] = { v8::Number::New(isolate, 0) }; 3242b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch foo->Call(env->Global(), argc, argv_0); 3243b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(3, break_point_hit_count); 3244b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 32457f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Looping 10 times. 32467f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch step_action = StepIn; 32477f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch break_point_hit_count = 0; 3248b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Handle<v8::Value> argv_10[argc] = { v8::Number::New(isolate, 10) }; 32497f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch foo->Call(env->Global(), argc, argv_10); 3250b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(23, break_point_hit_count); 32517f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 32527f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Looping 100 times. 32537f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch step_action = StepIn; 32547f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch break_point_hit_count = 0; 3255b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Handle<v8::Value> argv_100[argc] = { v8::Number::New(isolate, 100) }; 32567f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch foo->Call(env->Global(), argc, argv_100); 3257b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(203, break_point_hit_count); 32587f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 32597f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Get rid of the debug event listener. 32607f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch v8::Debug::SetDebugEventListener(NULL); 32617f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch CheckDebuggerUnloaded(); 32627f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 32637f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 32647f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 32657f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen MurdochTEST(DebugStepDoWhile) { 32667f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch DebugLocalContext env; 3267b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Isolate* isolate = env->GetIsolate(); 3268b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(isolate); 32697f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 32707f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Register a debug event listener which steps and counts. 32717f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch v8::Debug::SetDebugEventListener(DebugEventStep); 32727f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 3273b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Create a function for testing stepping. Run it to allow it to get 3274b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // optimized. 32757f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch const int argc = 1; 32767f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch const char* src = "function foo(x) { " 32777f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch " var a = 0;" 32787f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch " do {" 32797f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch " a++;" 32807f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch " } while (a < x)" 3281b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "}" 3282b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "foo()"; 32837f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch v8::Local<v8::Function> foo = CompileFunction(&env, src, "foo"); 32847f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch SetBreakPoint(foo, 8); // "var a = 0;" 32857f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 32867f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Looping 10 times. 32877f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch step_action = StepIn; 32887f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch break_point_hit_count = 0; 3289b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Handle<v8::Value> argv_10[argc] = { v8::Number::New(isolate, 10) }; 32907f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch foo->Call(env->Global(), argc, argv_10); 32917f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch CHECK_EQ(22, break_point_hit_count); 32927f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 32937f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Looping 100 times. 32947f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch step_action = StepIn; 32957f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch break_point_hit_count = 0; 3296b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Handle<v8::Value> argv_100[argc] = { v8::Number::New(isolate, 100) }; 32977f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch foo->Call(env->Global(), argc, argv_100); 32987f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch CHECK_EQ(202, break_point_hit_count); 3299a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3300a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Get rid of the debug event listener. 3301a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetDebugEventListener(NULL); 3302a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CheckDebuggerUnloaded(); 3303a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 3304a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3305a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3306a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(DebugStepFor) { 3307a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DebugLocalContext env; 3308b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Isolate* isolate = env->GetIsolate(); 3309b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(isolate); 3310a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3311a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Register a debug event listener which steps and counts. 3312a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetDebugEventListener(DebugEventStep); 3313a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3314b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Create a function for testing stepping. Run it to allow it to get 3315b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // optimized. 3316a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const int argc = 1; 3317a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const char* src = "function foo(x) { " 3318a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " a = 1;" 3319a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " for (i = 0; i < x; i++) {" 3320a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " b = 1;" 3321a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " }" 3322b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "}" 3323b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "a=0; b=0; i=0; foo()"; 3324a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Local<v8::Function> foo = CompileFunction(&env, src, "foo"); 3325b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 3326a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block SetBreakPoint(foo, 8); // "a = 1;" 3327a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3328a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Looping 10 times. 3329a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block step_action = StepIn; 3330a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 3331b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Handle<v8::Value> argv_10[argc] = { v8::Number::New(isolate, 10) }; 3332a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block foo->Call(env->Global(), argc, argv_10); 3333a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(23, break_point_hit_count); 3334a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3335a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Looping 100 times. 3336a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block step_action = StepIn; 3337a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 3338b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Handle<v8::Value> argv_100[argc] = { v8::Number::New(isolate, 100) }; 3339a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block foo->Call(env->Global(), argc, argv_100); 3340a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(203, break_point_hit_count); 3341a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3342a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Get rid of the debug event listener. 3343a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetDebugEventListener(NULL); 3344a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CheckDebuggerUnloaded(); 3345a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 3346a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3347a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 33487f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen MurdochTEST(DebugStepForContinue) { 33497f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch DebugLocalContext env; 3350b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Isolate* isolate = env->GetIsolate(); 3351b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(isolate); 33527f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 33537f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Register a debug event listener which steps and counts. 33547f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch v8::Debug::SetDebugEventListener(DebugEventStep); 33557f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 3356b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Create a function for testing stepping. Run it to allow it to get 3357b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // optimized. 33587f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch const int argc = 1; 33597f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch const char* src = "function foo(x) { " 33607f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch " var a = 0;" 33617f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch " var b = 0;" 33627f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch " var c = 0;" 33637f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch " for (var i = 0; i < x; i++) {" 33647f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch " a++;" 33657f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch " if (a % 2 == 0) continue;" 33667f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch " b++;" 33677f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch " c++;" 33687f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch " }" 33697f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch " return b;" 3370b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "}" 3371b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "foo()"; 33727f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch v8::Local<v8::Function> foo = CompileFunction(&env, src, "foo"); 33737f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch v8::Handle<v8::Value> result; 33747f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch SetBreakPoint(foo, 8); // "var a = 0;" 33757f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 33767f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Each loop generates 4 or 5 steps depending on whether a is equal. 33777f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 33787f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Looping 10 times. 33797f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch step_action = StepIn; 33807f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch break_point_hit_count = 0; 3381b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Handle<v8::Value> argv_10[argc] = { v8::Number::New(isolate, 10) }; 33827f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch result = foo->Call(env->Global(), argc, argv_10); 33837f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch CHECK_EQ(5, result->Int32Value()); 3384b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(52, break_point_hit_count); 33857f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 33867f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Looping 100 times. 33877f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch step_action = StepIn; 33887f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch break_point_hit_count = 0; 3389b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Handle<v8::Value> argv_100[argc] = { v8::Number::New(isolate, 100) }; 33907f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch result = foo->Call(env->Global(), argc, argv_100); 33917f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch CHECK_EQ(50, result->Int32Value()); 3392b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(457, break_point_hit_count); 33937f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 33947f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Get rid of the debug event listener. 33957f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch v8::Debug::SetDebugEventListener(NULL); 33967f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch CheckDebuggerUnloaded(); 33977f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 33987f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 33997f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 34007f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen MurdochTEST(DebugStepForBreak) { 34017f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch DebugLocalContext env; 3402b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Isolate* isolate = env->GetIsolate(); 3403b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(isolate); 34047f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 34057f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Register a debug event listener which steps and counts. 34067f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch v8::Debug::SetDebugEventListener(DebugEventStep); 34077f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 3408b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Create a function for testing stepping. Run it to allow it to get 3409b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // optimized. 34107f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch const int argc = 1; 34117f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch const char* src = "function foo(x) { " 34127f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch " var a = 0;" 34137f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch " var b = 0;" 34147f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch " var c = 0;" 34157f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch " for (var i = 0; i < 1000; i++) {" 34167f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch " a++;" 34177f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch " if (a == x) break;" 34187f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch " b++;" 34197f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch " c++;" 34207f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch " }" 34217f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch " return b;" 3422b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "}" 3423b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "foo()"; 34247f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch v8::Local<v8::Function> foo = CompileFunction(&env, src, "foo"); 34257f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch v8::Handle<v8::Value> result; 34267f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch SetBreakPoint(foo, 8); // "var a = 0;" 34277f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 34287f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Each loop generates 5 steps except for the last (when break is executed) 34297f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // which only generates 4. 34307f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 34317f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Looping 10 times. 34327f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch step_action = StepIn; 34337f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch break_point_hit_count = 0; 3434b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Handle<v8::Value> argv_10[argc] = { v8::Number::New(isolate, 10) }; 34357f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch result = foo->Call(env->Global(), argc, argv_10); 34367f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch CHECK_EQ(9, result->Int32Value()); 3437b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(55, break_point_hit_count); 34387f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 34397f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Looping 100 times. 34407f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch step_action = StepIn; 34417f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch break_point_hit_count = 0; 3442b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Handle<v8::Value> argv_100[argc] = { v8::Number::New(isolate, 100) }; 34437f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch result = foo->Call(env->Global(), argc, argv_100); 34447f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch CHECK_EQ(99, result->Int32Value()); 3445b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(505, break_point_hit_count); 34467f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 34477f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Get rid of the debug event listener. 34487f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch v8::Debug::SetDebugEventListener(NULL); 34497f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch CheckDebuggerUnloaded(); 34507f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 34517f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 34527f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 34537f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen MurdochTEST(DebugStepForIn) { 34547f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch DebugLocalContext env; 3455b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(env->GetIsolate()); 34567f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 34577f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Register a debug event listener which steps and counts. 34587f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch v8::Debug::SetDebugEventListener(DebugEventStep); 34597f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 3460b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Create a function for testing stepping. Run it to allow it to get 3461b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // optimized. 34627f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch v8::Local<v8::Function> foo; 34637f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch const char* src_1 = "function foo() { " 34647f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch " var a = [1, 2];" 34657f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch " for (x in a) {" 34667f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch " b = 0;" 34677f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch " }" 3468b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "}" 3469b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "foo()"; 34707f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch foo = CompileFunction(&env, src_1, "foo"); 34717f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch SetBreakPoint(foo, 0); // "var a = ..." 34727f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 34737f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch step_action = StepIn; 34747f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch break_point_hit_count = 0; 34757f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch foo->Call(env->Global(), 0, NULL); 34767f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch CHECK_EQ(6, break_point_hit_count); 34777f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 3478b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Create a function for testing stepping. Run it to allow it to get 3479b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // optimized. 34807f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch const char* src_2 = "function foo() { " 34817f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch " var a = {a:[1, 2, 3]};" 34827f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch " for (x in a.a) {" 34837f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch " b = 0;" 34847f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch " }" 3485b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "}" 3486b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "foo()"; 34877f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch foo = CompileFunction(&env, src_2, "foo"); 34887f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch SetBreakPoint(foo, 0); // "var a = ..." 34897f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 34907f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch step_action = StepIn; 34917f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch break_point_hit_count = 0; 34927f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch foo->Call(env->Global(), 0, NULL); 34937f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch CHECK_EQ(8, break_point_hit_count); 34947f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 34957f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Get rid of the debug event listener. 34967f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch v8::Debug::SetDebugEventListener(NULL); 34977f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch CheckDebuggerUnloaded(); 34987f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 34997f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 35007f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 35017f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen MurdochTEST(DebugStepWith) { 35027f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch DebugLocalContext env; 3503b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(env->GetIsolate()); 35047f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 35057f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Register a debug event listener which steps and counts. 35067f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch v8::Debug::SetDebugEventListener(DebugEventStep); 35077f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 3508b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Create a function for testing stepping. Run it to allow it to get 3509b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // optimized. 35107f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch const char* src = "function foo(x) { " 35117f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch " var a = {};" 35127f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch " with (a) {}" 35137f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch " with (b) {}" 3514b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "}" 3515b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "foo()"; 3516b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch env->Global()->Set(v8::String::NewFromUtf8(env->GetIsolate(), "b"), 3517b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Object::New(env->GetIsolate())); 35187f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch v8::Local<v8::Function> foo = CompileFunction(&env, src, "foo"); 35197f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch v8::Handle<v8::Value> result; 35207f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch SetBreakPoint(foo, 8); // "var a = {};" 35217f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 35227f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch step_action = StepIn; 35237f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch break_point_hit_count = 0; 35247f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch foo->Call(env->Global(), 0, NULL); 35257f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch CHECK_EQ(4, break_point_hit_count); 35267f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 35277f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Get rid of the debug event listener. 35287f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch v8::Debug::SetDebugEventListener(NULL); 35297f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch CheckDebuggerUnloaded(); 35307f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 35317f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 35327f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 35337f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen MurdochTEST(DebugConditional) { 35347f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch DebugLocalContext env; 3535b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Isolate* isolate = env->GetIsolate(); 3536b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(isolate); 35377f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 35387f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Register a debug event listener which steps and counts. 35397f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch v8::Debug::SetDebugEventListener(DebugEventStep); 35407f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 3541b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Create a function for testing stepping. Run it to allow it to get 3542b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // optimized. 35437f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch const char* src = "function foo(x) { " 35447f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch " var a;" 35457f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch " a = x ? 1 : 2;" 35467f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch " return a;" 3547b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "}" 3548b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "foo()"; 35497f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch v8::Local<v8::Function> foo = CompileFunction(&env, src, "foo"); 35507f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch SetBreakPoint(foo, 0); // "var a;" 35517f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 35527f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch step_action = StepIn; 35537f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch break_point_hit_count = 0; 35547f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch foo->Call(env->Global(), 0, NULL); 35557f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch CHECK_EQ(5, break_point_hit_count); 35567f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 35577f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch step_action = StepIn; 35587f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch break_point_hit_count = 0; 35597f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch const int argc = 1; 3560b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Handle<v8::Value> argv_true[argc] = { v8::True(isolate) }; 35617f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch foo->Call(env->Global(), argc, argv_true); 35627f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch CHECK_EQ(5, break_point_hit_count); 35637f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 35647f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Get rid of the debug event listener. 35657f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch v8::Debug::SetDebugEventListener(NULL); 35667f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch CheckDebuggerUnloaded(); 35677f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 35687f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 35697f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 3570a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(StepInOutSimple) { 3571a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DebugLocalContext env; 3572b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(env->GetIsolate()); 3573a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3574a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Create a function for checking the function when hitting a break point. 3575a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block frame_function_name = CompileFunction(&env, 3576a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block frame_function_name_source, 3577a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "frame_function_name"); 3578a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3579a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Register a debug event listener which steps and counts. 3580a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetDebugEventListener(DebugEventStepSequence); 3581a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3582b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Create a function for testing stepping. Run it to allow it to get 3583b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // optimized. 3584a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const char* src = "function a() {b();c();}; " 3585a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "function b() {c();}; " 3586b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "function c() {}; " 3587b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "a(); b(); c()"; 3588a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Local<v8::Function> a = CompileFunction(&env, src, "a"); 3589a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block SetBreakPoint(a, 0); 3590a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3591a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Step through invocation of a with step in. 3592a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block step_action = StepIn; 3593a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 3594a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block expected_step_sequence = "abcbaca"; 3595a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block a->Call(env->Global(), 0, NULL); 3596d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block CHECK_EQ(StrLength(expected_step_sequence), 3597d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block break_point_hit_count); 3598a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3599a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Step through invocation of a with step next. 3600a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block step_action = StepNext; 3601a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 3602a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block expected_step_sequence = "aaa"; 3603a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block a->Call(env->Global(), 0, NULL); 3604d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block CHECK_EQ(StrLength(expected_step_sequence), 3605d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block break_point_hit_count); 3606a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3607a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Step through invocation of a with step out. 3608a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block step_action = StepOut; 3609a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 3610a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block expected_step_sequence = "a"; 3611a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block a->Call(env->Global(), 0, NULL); 3612d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block CHECK_EQ(StrLength(expected_step_sequence), 3613d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block break_point_hit_count); 3614a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3615a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Get rid of the debug event listener. 3616a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetDebugEventListener(NULL); 3617a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CheckDebuggerUnloaded(); 3618a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 3619a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3620a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3621a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(StepInOutTree) { 3622a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DebugLocalContext env; 3623b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(env->GetIsolate()); 3624a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3625a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Create a function for checking the function when hitting a break point. 3626a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block frame_function_name = CompileFunction(&env, 3627a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block frame_function_name_source, 3628a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "frame_function_name"); 3629a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3630a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Register a debug event listener which steps and counts. 3631a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetDebugEventListener(DebugEventStepSequence); 3632a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3633b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Create a function for testing stepping. Run it to allow it to get 3634b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // optimized. 3635a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const char* src = "function a() {b(c(d()),d());c(d());d()}; " 3636a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "function b(x,y) {c();}; " 3637a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "function c(x) {}; " 3638b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "function d() {}; " 3639b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "a(); b(); c(); d()"; 3640a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Local<v8::Function> a = CompileFunction(&env, src, "a"); 3641a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block SetBreakPoint(a, 0); 3642a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3643a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Step through invocation of a with step in. 3644a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block step_action = StepIn; 3645a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 3646a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block expected_step_sequence = "adacadabcbadacada"; 3647a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block a->Call(env->Global(), 0, NULL); 3648d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block CHECK_EQ(StrLength(expected_step_sequence), 3649d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block break_point_hit_count); 3650a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3651a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Step through invocation of a with step next. 3652a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block step_action = StepNext; 3653a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 3654a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block expected_step_sequence = "aaaa"; 3655a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block a->Call(env->Global(), 0, NULL); 3656d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block CHECK_EQ(StrLength(expected_step_sequence), 3657d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block break_point_hit_count); 3658a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3659a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Step through invocation of a with step out. 3660a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block step_action = StepOut; 3661a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 3662a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block expected_step_sequence = "a"; 3663a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block a->Call(env->Global(), 0, NULL); 3664d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block CHECK_EQ(StrLength(expected_step_sequence), 3665d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block break_point_hit_count); 3666a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3667a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Get rid of the debug event listener. 3668a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetDebugEventListener(NULL); 3669a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CheckDebuggerUnloaded(true); 3670a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 3671a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3672a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3673a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(StepInOutBranch) { 3674a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DebugLocalContext env; 3675b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(env->GetIsolate()); 3676a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3677a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Create a function for checking the function when hitting a break point. 3678a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block frame_function_name = CompileFunction(&env, 3679a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block frame_function_name_source, 3680a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "frame_function_name"); 3681a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3682a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Register a debug event listener which steps and counts. 3683a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetDebugEventListener(DebugEventStepSequence); 3684a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3685b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Create a function for testing stepping. Run it to allow it to get 3686b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // optimized. 3687a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const char* src = "function a() {b(false);c();}; " 3688a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "function b(x) {if(x){c();};}; " 3689b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "function c() {}; " 3690b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "a(); b(); c()"; 3691a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Local<v8::Function> a = CompileFunction(&env, src, "a"); 3692a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block SetBreakPoint(a, 0); 3693a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3694a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Step through invocation of a. 3695a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block step_action = StepIn; 3696a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 36977f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch expected_step_sequence = "abbaca"; 3698a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block a->Call(env->Global(), 0, NULL); 3699d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block CHECK_EQ(StrLength(expected_step_sequence), 3700d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block break_point_hit_count); 3701a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3702a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Get rid of the debug event listener. 3703a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetDebugEventListener(NULL); 3704a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CheckDebuggerUnloaded(); 3705a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 3706a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3707a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3708a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Test that step in does not step into native functions. 3709a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(DebugStepNatives) { 3710a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DebugLocalContext env; 3711b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(env->GetIsolate()); 3712a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3713a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Create a function for testing stepping. 3714a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Local<v8::Function> foo = CompileFunction( 3715a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block &env, 3716a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "function foo(){debugger;Math.sin(1);}", 3717a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "foo"); 3718a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3719a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Register a debug event listener which steps and counts. 3720a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetDebugEventListener(DebugEventStep); 3721a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3722a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block step_action = StepIn; 3723a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 3724a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block foo->Call(env->Global(), 0, NULL); 3725a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3726a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // With stepping all break locations are hit. 3727a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(3, break_point_hit_count); 3728a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3729a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetDebugEventListener(NULL); 3730a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CheckDebuggerUnloaded(); 3731a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3732a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Register a debug event listener which just counts. 3733a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount); 3734a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3735a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 3736a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block foo->Call(env->Global(), 0, NULL); 3737a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3738a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Without stepping only active break points are hit. 3739a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1, break_point_hit_count); 3740a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3741a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetDebugEventListener(NULL); 3742a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CheckDebuggerUnloaded(); 3743a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 3744a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3745a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3746a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Test that step in works with function.apply. 3747a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(DebugStepFunctionApply) { 3748a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DebugLocalContext env; 3749b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(env->GetIsolate()); 3750a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3751a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Create a function for testing stepping. 3752a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Local<v8::Function> foo = CompileFunction( 3753a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block &env, 3754a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "function bar(x, y, z) { if (x == 1) { a = y; b = z; } }" 3755a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "function foo(){ debugger; bar.apply(this, [1,2,3]); }", 3756a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "foo"); 3757a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3758a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Register a debug event listener which steps and counts. 3759a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetDebugEventListener(DebugEventStep); 3760a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3761a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block step_action = StepIn; 3762a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 3763a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block foo->Call(env->Global(), 0, NULL); 3764a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3765a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // With stepping all break locations are hit. 37667f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch CHECK_EQ(7, break_point_hit_count); 3767a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3768a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetDebugEventListener(NULL); 3769a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CheckDebuggerUnloaded(); 3770a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3771a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Register a debug event listener which just counts. 3772a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount); 3773a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3774a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 3775a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block foo->Call(env->Global(), 0, NULL); 3776a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3777a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Without stepping only the debugger statement is hit. 3778a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1, break_point_hit_count); 3779a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3780a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetDebugEventListener(NULL); 3781a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CheckDebuggerUnloaded(); 3782a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 3783a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3784a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3785a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Test that step in works with function.call. 3786a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(DebugStepFunctionCall) { 3787a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DebugLocalContext env; 3788b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Isolate* isolate = env->GetIsolate(); 3789b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(isolate); 3790a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3791a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Create a function for testing stepping. 3792a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Local<v8::Function> foo = CompileFunction( 3793a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block &env, 3794a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "function bar(x, y, z) { if (x == 1) { a = y; b = z; } }" 3795a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "function foo(a){ debugger;" 3796a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " if (a) {" 3797a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " bar.call(this, 1, 2, 3);" 3798a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " } else {" 3799a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " bar.call(this, 0);" 3800a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " }" 3801a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "}", 3802a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "foo"); 3803a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3804a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Register a debug event listener which steps and counts. 3805a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetDebugEventListener(DebugEventStep); 3806a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block step_action = StepIn; 3807a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3808a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Check stepping where the if condition in bar is false. 3809a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 3810a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block foo->Call(env->Global(), 0, NULL); 38117f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch CHECK_EQ(6, break_point_hit_count); 3812a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3813a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Check stepping where the if condition in bar is true. 3814a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 3815a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const int argc = 1; 3816b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Handle<v8::Value> argv[argc] = { v8::True(isolate) }; 3817a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block foo->Call(env->Global(), argc, argv); 38187f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch CHECK_EQ(8, break_point_hit_count); 3819a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3820a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetDebugEventListener(NULL); 3821a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CheckDebuggerUnloaded(); 3822a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3823a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Register a debug event listener which just counts. 3824a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount); 3825a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3826a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 3827a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block foo->Call(env->Global(), 0, NULL); 3828a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3829a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Without stepping only the debugger statement is hit. 3830a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1, break_point_hit_count); 3831a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3832a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetDebugEventListener(NULL); 3833a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CheckDebuggerUnloaded(); 3834a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 3835a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3836a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3837d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block// Tests that breakpoint will be hit if it's set in script. 3838d0582a6c46733687d045e4188a1bcd0123c758a1Steve BlockTEST(PauseInScript) { 3839d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block DebugLocalContext env; 3840b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(env->GetIsolate()); 3841d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block env.ExposeDebug(); 3842d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 3843d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // Register a debug event listener which counts. 3844d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block v8::Debug::SetDebugEventListener(DebugEventCounter); 3845d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 3846d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // Create a script that returns a function. 3847d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block const char* src = "(function (evt) {})"; 3848d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block const char* script_name = "StepInHandlerTest"; 3849d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 3850d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // Set breakpoint in the script. 3851b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SetScriptBreakPointByNameFromJS(env->GetIsolate(), script_name, 0, -1); 3852d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block break_point_hit_count = 0; 3853d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 3854b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::ScriptOrigin origin( 3855b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::String::NewFromUtf8(env->GetIsolate(), script_name), 3856b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Integer::New(env->GetIsolate(), 0)); 3857b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Handle<v8::Script> script = v8::Script::Compile( 3858b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::String::NewFromUtf8(env->GetIsolate(), src), &origin); 3859d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block v8::Local<v8::Value> r = script->Run(); 3860d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 3861d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block CHECK(r->IsFunction()); 3862d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block CHECK_EQ(1, break_point_hit_count); 3863d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 3864d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // Get rid of the debug event listener. 3865d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block v8::Debug::SetDebugEventListener(NULL); 3866d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block CheckDebuggerUnloaded(); 3867d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block} 3868d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 3869d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 3870a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Test break on exceptions. For each exception break combination the number 3871a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// of debug event exception callbacks and message callbacks are collected. The 3872a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// number of debug event exception callbacks are used to check that the 3873a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// debugger is called correctly and the number of message callbacks is used to 3874a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// check that uncaught exceptions are still returned even if there is a break 3875a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// for them. 3876a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(BreakOnException) { 3877a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DebugLocalContext env; 3878b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(env->GetIsolate()); 3879a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block env.ExposeDebug(); 3880a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3881a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Create functions for testing break on exception. 38823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CompileFunction(&env, "function throws(){throw 1;}", "throws"); 3883a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Local<v8::Function> caught = 3884a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CompileFunction(&env, 3885a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "function caught(){try {throws();} catch(e) {};}", 3886a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "caught"); 3887a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Local<v8::Function> notCaught = 3888a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CompileFunction(&env, "function notCaught(){throws();}", "notCaught"); 3889a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3890a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::V8::AddMessageListener(MessageCallbackCount); 3891a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetDebugEventListener(DebugEventCounter); 3892a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3893086aeeaae12517475c22695a200be45495516549Ben Murdoch // Initial state should be no break on exceptions. 3894a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DebugEventCounterClear(); 3895a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block MessageCallbackCountClear(); 3896a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block caught->Call(env->Global(), 0, NULL); 3897a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(0, exception_hit_count); 3898a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(0, uncaught_exception_hit_count); 3899a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(0, message_callback_count); 3900a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block notCaught->Call(env->Global(), 0, NULL); 3901086aeeaae12517475c22695a200be45495516549Ben Murdoch CHECK_EQ(0, exception_hit_count); 3902086aeeaae12517475c22695a200be45495516549Ben Murdoch CHECK_EQ(0, uncaught_exception_hit_count); 3903a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1, message_callback_count); 3904a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3905a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // No break on exception 3906a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DebugEventCounterClear(); 3907a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block MessageCallbackCountClear(); 3908a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ChangeBreakOnException(false, false); 3909a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block caught->Call(env->Global(), 0, NULL); 3910a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(0, exception_hit_count); 3911a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(0, uncaught_exception_hit_count); 3912a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(0, message_callback_count); 3913a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block notCaught->Call(env->Global(), 0, NULL); 3914a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(0, exception_hit_count); 3915a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(0, uncaught_exception_hit_count); 3916a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1, message_callback_count); 3917a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3918a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Break on uncaught exception 3919a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DebugEventCounterClear(); 3920a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block MessageCallbackCountClear(); 3921a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ChangeBreakOnException(false, true); 3922a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block caught->Call(env->Global(), 0, NULL); 3923a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(0, exception_hit_count); 3924a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(0, uncaught_exception_hit_count); 3925a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(0, message_callback_count); 3926a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block notCaught->Call(env->Global(), 0, NULL); 3927a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1, exception_hit_count); 3928a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1, uncaught_exception_hit_count); 3929a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1, message_callback_count); 3930a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3931a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Break on exception and uncaught exception 3932a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DebugEventCounterClear(); 3933a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block MessageCallbackCountClear(); 3934a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ChangeBreakOnException(true, true); 3935a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block caught->Call(env->Global(), 0, NULL); 3936a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1, exception_hit_count); 3937a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(0, uncaught_exception_hit_count); 3938a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(0, message_callback_count); 3939a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block notCaught->Call(env->Global(), 0, NULL); 3940a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(2, exception_hit_count); 3941a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1, uncaught_exception_hit_count); 3942a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1, message_callback_count); 3943a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3944a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Break on exception 3945a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DebugEventCounterClear(); 3946a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block MessageCallbackCountClear(); 3947a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ChangeBreakOnException(true, false); 3948a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block caught->Call(env->Global(), 0, NULL); 3949a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1, exception_hit_count); 3950a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(0, uncaught_exception_hit_count); 3951a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(0, message_callback_count); 3952a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block notCaught->Call(env->Global(), 0, NULL); 3953a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(2, exception_hit_count); 3954a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1, uncaught_exception_hit_count); 3955a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1, message_callback_count); 3956a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3957a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // No break on exception using JavaScript 3958a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DebugEventCounterClear(); 3959a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block MessageCallbackCountClear(); 3960b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ChangeBreakOnExceptionFromJS(env->GetIsolate(), false, false); 3961a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block caught->Call(env->Global(), 0, NULL); 3962a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(0, exception_hit_count); 3963a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(0, uncaught_exception_hit_count); 3964a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(0, message_callback_count); 3965a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block notCaught->Call(env->Global(), 0, NULL); 3966a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(0, exception_hit_count); 3967a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(0, uncaught_exception_hit_count); 3968a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1, message_callback_count); 3969a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3970a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Break on uncaught exception using JavaScript 3971a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DebugEventCounterClear(); 3972a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block MessageCallbackCountClear(); 3973b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ChangeBreakOnExceptionFromJS(env->GetIsolate(), false, true); 3974a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block caught->Call(env->Global(), 0, NULL); 3975a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(0, exception_hit_count); 3976a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(0, uncaught_exception_hit_count); 3977a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(0, message_callback_count); 3978a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block notCaught->Call(env->Global(), 0, NULL); 3979a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1, exception_hit_count); 3980a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1, uncaught_exception_hit_count); 3981a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1, message_callback_count); 3982a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3983a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Break on exception and uncaught exception using JavaScript 3984a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DebugEventCounterClear(); 3985a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block MessageCallbackCountClear(); 3986b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ChangeBreakOnExceptionFromJS(env->GetIsolate(), true, true); 3987a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block caught->Call(env->Global(), 0, NULL); 3988a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1, exception_hit_count); 3989a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(0, message_callback_count); 3990a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(0, uncaught_exception_hit_count); 3991a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block notCaught->Call(env->Global(), 0, NULL); 3992a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(2, exception_hit_count); 3993a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1, uncaught_exception_hit_count); 3994a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1, message_callback_count); 3995a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3996a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Break on exception using JavaScript 3997a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DebugEventCounterClear(); 3998a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block MessageCallbackCountClear(); 3999b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ChangeBreakOnExceptionFromJS(env->GetIsolate(), true, false); 4000a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block caught->Call(env->Global(), 0, NULL); 4001a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1, exception_hit_count); 4002a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(0, uncaught_exception_hit_count); 4003a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(0, message_callback_count); 4004a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block notCaught->Call(env->Global(), 0, NULL); 4005a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(2, exception_hit_count); 4006a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1, uncaught_exception_hit_count); 4007a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1, message_callback_count); 4008a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4009a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetDebugEventListener(NULL); 4010a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CheckDebuggerUnloaded(); 4011a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::V8::RemoveMessageListeners(MessageCallbackCount); 4012a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 4013a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4014a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4015b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST(EvalJSInDebugEventListenerOnNativeReThrownException) { 4016b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DebugLocalContext env; 4017b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(env->GetIsolate()); 4018b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch env.ExposeDebug(); 4019b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4020b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Create functions for testing break on exception. 4021b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Local<v8::Function> noThrowJS = CompileFunction( 4022b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch &env, "function noThrowJS(){var a=[1]; a.push(2); return a.length;}", 4023b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "noThrowJS"); 4024b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4025b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch debug_event_listener_callback = noThrowJS; 4026b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch debug_event_listener_callback_result = 2; 4027b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4028b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::V8::AddMessageListener(MessageCallbackCount); 4029b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Debug::SetDebugEventListener(DebugEventCounter); 4030b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Break on uncaught exception 4031b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ChangeBreakOnException(false, true); 4032b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DebugEventCounterClear(); 4033b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MessageCallbackCountClear(); 4034b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4035b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // ReThrow native error 4036b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 4037b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::TryCatch tryCatch; 4038b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch env->GetIsolate()->ThrowException(v8::Exception::TypeError( 4039b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::String::NewFromUtf8(env->GetIsolate(), "Type error"))); 4040b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK(tryCatch.HasCaught()); 4041b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch tryCatch.ReThrow(); 4042b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 4043b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(1, exception_hit_count); 4044b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(1, uncaught_exception_hit_count); 4045b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(0, message_callback_count); // FIXME: Should it be 1 ? 4046b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK(!debug_event_listener_callback.IsEmpty()); 4047b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4048b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch debug_event_listener_callback.Clear(); 4049b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 4050b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4051b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4052a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Test break on exception from compiler errors. When compiling using 4053a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// v8::Script::Compile there is no JavaScript stack whereas when compiling using 4054a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// eval there are JavaScript frames. 4055a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(BreakOnCompileException) { 4056a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DebugLocalContext env; 4057b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(env->GetIsolate()); 4058a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4059086aeeaae12517475c22695a200be45495516549Ben Murdoch // For this test, we want to break on uncaught exceptions: 4060086aeeaae12517475c22695a200be45495516549Ben Murdoch ChangeBreakOnException(false, true); 4061086aeeaae12517475c22695a200be45495516549Ben Murdoch 4062a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Create a function for checking the function when hitting a break point. 4063a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block frame_count = CompileFunction(&env, frame_count_source, "frame_count"); 4064a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4065a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::V8::AddMessageListener(MessageCallbackCount); 4066a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetDebugEventListener(DebugEventCounter); 4067a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4068a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DebugEventCounterClear(); 4069a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block MessageCallbackCountClear(); 4070a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4071a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Check initial state. 4072a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(0, exception_hit_count); 4073a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(0, uncaught_exception_hit_count); 4074a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(0, message_callback_count); 4075a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(-1, last_js_stack_height); 4076a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4077a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Throws SyntaxError: Unexpected end of input 4078b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Script::Compile(v8::String::NewFromUtf8(env->GetIsolate(), "+++")); 4079a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1, exception_hit_count); 4080a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1, uncaught_exception_hit_count); 4081a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1, message_callback_count); 4082a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(0, last_js_stack_height); // No JavaScript stack. 4083a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4084a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Throws SyntaxError: Unexpected identifier 4085b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Script::Compile(v8::String::NewFromUtf8(env->GetIsolate(), "x x")); 4086a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(2, exception_hit_count); 4087a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(2, uncaught_exception_hit_count); 4088a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(2, message_callback_count); 4089a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(0, last_js_stack_height); // No JavaScript stack. 4090a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4091a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Throws SyntaxError: Unexpected end of input 4092b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Script::Compile(v8::String::NewFromUtf8(env->GetIsolate(), "eval('+++')")) 4093b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ->Run(); 4094a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(3, exception_hit_count); 4095a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(3, uncaught_exception_hit_count); 4096a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(3, message_callback_count); 4097a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1, last_js_stack_height); 4098a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4099a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Throws SyntaxError: Unexpected identifier 4100b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Script::Compile(v8::String::NewFromUtf8(env->GetIsolate(), "eval('x x')")) 4101b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ->Run(); 4102a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(4, exception_hit_count); 4103a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(4, uncaught_exception_hit_count); 4104a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(4, message_callback_count); 4105a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1, last_js_stack_height); 4106a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 4107a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4108a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4109a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(StepWithException) { 4110a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DebugLocalContext env; 4111b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(env->GetIsolate()); 4112a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4113086aeeaae12517475c22695a200be45495516549Ben Murdoch // For this test, we want to break on uncaught exceptions: 4114086aeeaae12517475c22695a200be45495516549Ben Murdoch ChangeBreakOnException(false, true); 4115086aeeaae12517475c22695a200be45495516549Ben Murdoch 4116a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Create a function for checking the function when hitting a break point. 4117a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block frame_function_name = CompileFunction(&env, 4118a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block frame_function_name_source, 4119a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "frame_function_name"); 4120a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4121a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Register a debug event listener which steps and counts. 4122a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetDebugEventListener(DebugEventStepSequence); 4123a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4124a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Create functions for testing stepping. 4125a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const char* src = "function a() { n(); }; " 4126a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "function b() { c(); }; " 4127a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "function c() { n(); }; " 4128a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "function d() { x = 1; try { e(); } catch(x) { x = 2; } }; " 4129a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "function e() { n(); }; " 4130a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "function f() { x = 1; try { g(); } catch(x) { x = 2; } }; " 4131a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "function g() { h(); }; " 4132a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "function h() { x = 1; throw 1; }; "; 4133a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4134a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Step through invocation of a. 4135a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Local<v8::Function> a = CompileFunction(&env, src, "a"); 4136a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block SetBreakPoint(a, 0); 4137a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block step_action = StepIn; 4138a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 4139a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block expected_step_sequence = "aa"; 4140a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block a->Call(env->Global(), 0, NULL); 4141d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block CHECK_EQ(StrLength(expected_step_sequence), 4142d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block break_point_hit_count); 4143a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4144a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Step through invocation of b + c. 4145a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Local<v8::Function> b = CompileFunction(&env, src, "b"); 4146a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block SetBreakPoint(b, 0); 4147a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block step_action = StepIn; 4148a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 4149a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block expected_step_sequence = "bcc"; 4150a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block b->Call(env->Global(), 0, NULL); 4151d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block CHECK_EQ(StrLength(expected_step_sequence), 4152d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block break_point_hit_count); 4153a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Step through invocation of d + e. 4154a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Local<v8::Function> d = CompileFunction(&env, src, "d"); 4155a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block SetBreakPoint(d, 0); 4156a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ChangeBreakOnException(false, true); 4157a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block step_action = StepIn; 4158a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 41597f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch expected_step_sequence = "ddedd"; 4160a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block d->Call(env->Global(), 0, NULL); 4161d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block CHECK_EQ(StrLength(expected_step_sequence), 4162d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block break_point_hit_count); 4163a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4164a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Step through invocation of d + e now with break on caught exceptions. 4165a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ChangeBreakOnException(true, true); 4166a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block step_action = StepIn; 4167a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 41687f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch expected_step_sequence = "ddeedd"; 4169a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block d->Call(env->Global(), 0, NULL); 4170d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block CHECK_EQ(StrLength(expected_step_sequence), 4171d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block break_point_hit_count); 4172a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4173a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Step through invocation of f + g + h. 4174a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Local<v8::Function> f = CompileFunction(&env, src, "f"); 4175a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block SetBreakPoint(f, 0); 4176a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ChangeBreakOnException(false, true); 4177a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block step_action = StepIn; 4178a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 41797f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch expected_step_sequence = "ffghhff"; 4180a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block f->Call(env->Global(), 0, NULL); 4181d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block CHECK_EQ(StrLength(expected_step_sequence), 4182d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block break_point_hit_count); 4183a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4184a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Step through invocation of f + g + h now with break on caught exceptions. 4185a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ChangeBreakOnException(true, true); 4186a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block step_action = StepIn; 4187a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 41887f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch expected_step_sequence = "ffghhhff"; 4189a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block f->Call(env->Global(), 0, NULL); 4190d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block CHECK_EQ(StrLength(expected_step_sequence), 4191d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block break_point_hit_count); 4192a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4193a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Get rid of the debug event listener. 4194a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetDebugEventListener(NULL); 4195a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CheckDebuggerUnloaded(); 4196a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 4197a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4198a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4199a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(DebugBreak) { 4200b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch i::FLAG_stress_compaction = false; 4201b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef VERIFY_HEAP 4202b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch i::FLAG_verify_heap = true; 4203a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 4204b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DebugLocalContext env; 4205b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Isolate* isolate = env->GetIsolate(); 4206b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(isolate); 4207a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4208a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Register a debug event listener which sets the break flag and counts. 4209a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetDebugEventListener(DebugEventBreak); 4210a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4211a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Create a function for testing stepping. 4212a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const char* src = "function f0() {}" 4213a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "function f1(x1) {}" 4214a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "function f2(x1,x2) {}" 4215a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "function f3(x1,x2,x3) {}"; 4216a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Local<v8::Function> f0 = CompileFunction(&env, src, "f0"); 4217a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Local<v8::Function> f1 = CompileFunction(&env, src, "f1"); 4218a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Local<v8::Function> f2 = CompileFunction(&env, src, "f2"); 4219a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Local<v8::Function> f3 = CompileFunction(&env, src, "f3"); 4220a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4221a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Call the function to make sure it is compiled. 4222b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Handle<v8::Value> argv[] = { v8::Number::New(isolate, 1), 4223b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Number::New(isolate, 1), 4224b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Number::New(isolate, 1), 4225b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Number::New(isolate, 1) }; 4226a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4227a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Call all functions to make sure that they are compiled. 4228a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block f0->Call(env->Global(), 0, NULL); 4229a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block f1->Call(env->Global(), 0, NULL); 4230a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block f2->Call(env->Global(), 0, NULL); 4231a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block f3->Call(env->Global(), 0, NULL); 4232a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4233a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Set the debug break flag. 4234b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Debug::DebugBreak(env->GetIsolate()); 4235b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK(v8::Debug::CheckDebugBreak(env->GetIsolate())); 4236a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4237a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Call all functions with different argument count. 4238a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 4239b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (unsigned int i = 0; i < arraysize(argv); i++) { 4240a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block f0->Call(env->Global(), i, argv); 4241a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block f1->Call(env->Global(), i, argv); 4242a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block f2->Call(env->Global(), i, argv); 4243a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block f3->Call(env->Global(), i, argv); 4244a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 4245a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4246a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // One break for each function called. 4247b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(4 * arraysize(argv), break_point_hit_count); 4248a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4249a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Get rid of the debug event listener. 4250a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetDebugEventListener(NULL); 4251a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CheckDebuggerUnloaded(); 4252a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 4253a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4254a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4255a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Test to ensure that JavaScript code keeps running while the debug break 4256a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// through the stack limit flag is set but breaks are disabled. 4257a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(DisableBreak) { 4258a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DebugLocalContext env; 4259b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(env->GetIsolate()); 4260a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4261a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Register a debug event listener which sets the break flag and counts. 4262a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetDebugEventListener(DebugEventCounter); 4263a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4264a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Create a function for testing stepping. 4265a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const char* src = "function f() {g()};function g(){i=0; while(i<10){i++}}"; 4266a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Local<v8::Function> f = CompileFunction(&env, src, "f"); 4267a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4268b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Set, test and cancel debug break. 4269b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Debug::DebugBreak(env->GetIsolate()); 4270b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK(v8::Debug::CheckDebugBreak(env->GetIsolate())); 4271b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Debug::CancelDebugBreak(env->GetIsolate()); 4272b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK(!v8::Debug::CheckDebugBreak(env->GetIsolate())); 4273b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4274a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Set the debug break flag. 4275b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Debug::DebugBreak(env->GetIsolate()); 4276a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4277a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Call all functions with different argument count. 4278a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 4279a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block f->Call(env->Global(), 0, NULL); 4280a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1, break_point_hit_count); 4281a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4282a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block { 4283b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Debug::DebugBreak(env->GetIsolate()); 4284b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch i::Isolate* isolate = reinterpret_cast<i::Isolate*>(env->GetIsolate()); 4285b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::internal::DisableBreak disable_break(isolate->debug(), true); 4286a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block f->Call(env->Global(), 0, NULL); 4287a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1, break_point_hit_count); 4288a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 4289a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4290a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block f->Call(env->Global(), 0, NULL); 4291a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(2, break_point_hit_count); 4292a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4293a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Get rid of the debug event listener. 4294a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetDebugEventListener(NULL); 4295a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CheckDebuggerUnloaded(); 4296a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 4297a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4298e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarkestatic const char* kSimpleExtensionSource = 4299e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke "(function Foo() {" 4300e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke " return 4;" 4301e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke "})() "; 4302e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 4303e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke// http://crbug.com/28933 4304e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke// Test that debug break is disabled when bootstrapper is active. 4305e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon ClarkeTEST(NoBreakWhenBootstrapping) { 4306b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Isolate* isolate = CcTest::isolate(); 4307b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(isolate); 4308e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 4309e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // Register a debug event listener which sets the break flag and counts. 4310e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke v8::Debug::SetDebugEventListener(DebugEventCounter); 4311e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 4312e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // Set the debug break flag. 4313b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Debug::DebugBreak(isolate); 4314e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke break_point_hit_count = 0; 4315e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke { 4316e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // Create a context with an extension to make sure that some JavaScript 4317e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // code is executed during bootstrapping. 4318e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke v8::RegisterExtension(new v8::Extension("simpletest", 4319e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke kSimpleExtensionSource)); 4320e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke const char* extension_names[] = { "simpletest" }; 4321e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke v8::ExtensionConfiguration extensions(1, extension_names); 4322b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope handle_scope(isolate); 4323b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Context::New(isolate, &extensions); 4324e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke } 4325e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // Check that no DebugBreak events occured during the context creation. 4326e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke CHECK_EQ(0, break_point_hit_count); 4327e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 4328e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // Get rid of the debug event listener. 4329e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke v8::Debug::SetDebugEventListener(NULL); 4330e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke CheckDebuggerUnloaded(); 4331e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke} 4332a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4333b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4334b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic void NamedEnum(const v8::PropertyCallbackInfo<v8::Array>& info) { 4335b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Handle<v8::Array> result = v8::Array::New(info.GetIsolate(), 3); 4336b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch result->Set(v8::Integer::New(info.GetIsolate(), 0), 4337b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::String::NewFromUtf8(info.GetIsolate(), "a")); 4338b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch result->Set(v8::Integer::New(info.GetIsolate(), 1), 4339b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::String::NewFromUtf8(info.GetIsolate(), "b")); 4340b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch result->Set(v8::Integer::New(info.GetIsolate(), 2), 4341b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::String::NewFromUtf8(info.GetIsolate(), "c")); 4342b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch info.GetReturnValue().Set(result); 4343a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 4344a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4345a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4346b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic void IndexedEnum(const v8::PropertyCallbackInfo<v8::Array>& info) { 4347b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Isolate* isolate = info.GetIsolate(); 4348b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Handle<v8::Array> result = v8::Array::New(isolate, 2); 4349b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch result->Set(v8::Integer::New(isolate, 0), v8::Number::New(isolate, 1)); 4350b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch result->Set(v8::Integer::New(isolate, 1), v8::Number::New(isolate, 10)); 4351b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch info.GetReturnValue().Set(result); 4352a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 4353a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4354a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4355b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic void NamedGetter(v8::Local<v8::String> name, 4356b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::PropertyCallbackInfo<v8::Value>& info) { 4357b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::String::Utf8Value n(name); 4358a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (strcmp(*n, "a") == 0) { 4359b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch info.GetReturnValue().Set(v8::String::NewFromUtf8(info.GetIsolate(), "AA")); 4360b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return; 4361a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else if (strcmp(*n, "b") == 0) { 4362b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch info.GetReturnValue().Set(v8::String::NewFromUtf8(info.GetIsolate(), "BB")); 4363b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return; 4364a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else if (strcmp(*n, "c") == 0) { 4365b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch info.GetReturnValue().Set(v8::String::NewFromUtf8(info.GetIsolate(), "CC")); 4366b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return; 4367a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 4368b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch info.GetReturnValue().SetUndefined(); 4369b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return; 4370a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 4371b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch info.GetReturnValue().Set(name); 4372a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 4373a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4374a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4375b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic void IndexedGetter(uint32_t index, 4376b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::PropertyCallbackInfo<v8::Value>& info) { 4377b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch info.GetReturnValue().Set(static_cast<double>(index + 1)); 4378a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 4379a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4380a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4381a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(InterceptorPropertyMirror) { 4382a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Create a V8 environment with debug access. 4383a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DebugLocalContext env; 4384b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Isolate* isolate = env->GetIsolate(); 4385b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(isolate); 4386a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block env.ExposeDebug(); 4387a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4388a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Create object with named interceptor. 4389b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Handle<v8::ObjectTemplate> named = v8::ObjectTemplate::New(isolate); 4390a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block named->SetNamedPropertyHandler(NamedGetter, NULL, NULL, NULL, NamedEnum); 4391b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch env->Global()->Set( 4392b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::String::NewFromUtf8(isolate, "intercepted_named"), 4393b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch named->NewInstance()); 4394a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4395a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Create object with indexed interceptor. 4396b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Handle<v8::ObjectTemplate> indexed = v8::ObjectTemplate::New(isolate); 4397a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block indexed->SetIndexedPropertyHandler(IndexedGetter, 4398a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block NULL, 4399a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block NULL, 4400a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block NULL, 4401a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block IndexedEnum); 4402b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch env->Global()->Set( 4403b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::String::NewFromUtf8(isolate, "intercepted_indexed"), 4404b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch indexed->NewInstance()); 4405a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4406a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Create object with both named and indexed interceptor. 4407b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Handle<v8::ObjectTemplate> both = v8::ObjectTemplate::New(isolate); 4408a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block both->SetNamedPropertyHandler(NamedGetter, NULL, NULL, NULL, NamedEnum); 4409a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block both->SetIndexedPropertyHandler(IndexedGetter, NULL, NULL, NULL, IndexedEnum); 4410b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch env->Global()->Set( 4411b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::String::NewFromUtf8(isolate, "intercepted_both"), 4412b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch both->NewInstance()); 4413a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4414a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Get mirrors for the three objects with interceptor. 4415a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CompileRun( 44163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch "var named_mirror = debug.MakeMirror(intercepted_named);" 44173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch "var indexed_mirror = debug.MakeMirror(intercepted_indexed);" 44183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch "var both_mirror = debug.MakeMirror(intercepted_both)"); 4419a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(CompileRun( 4420a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "named_mirror instanceof debug.ObjectMirror")->BooleanValue()); 4421a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(CompileRun( 4422a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "indexed_mirror instanceof debug.ObjectMirror")->BooleanValue()); 4423a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(CompileRun( 4424a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "both_mirror instanceof debug.ObjectMirror")->BooleanValue()); 4425a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4426a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Get the property names from the interceptors 4427a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CompileRun( 4428a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "named_names = named_mirror.propertyNames();" 4429a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "indexed_names = indexed_mirror.propertyNames();" 4430a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "both_names = both_mirror.propertyNames()"); 4431a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(3, CompileRun("named_names.length")->Int32Value()); 4432a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(2, CompileRun("indexed_names.length")->Int32Value()); 4433a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(5, CompileRun("both_names.length")->Int32Value()); 4434a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4435a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Check the expected number of properties. 4436a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const char* source; 4437a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block source = "named_mirror.properties().length"; 4438a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(3, CompileRun(source)->Int32Value()); 4439a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4440a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block source = "indexed_mirror.properties().length"; 4441a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(2, CompileRun(source)->Int32Value()); 4442a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4443a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block source = "both_mirror.properties().length"; 4444a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(5, CompileRun(source)->Int32Value()); 4445a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4446a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // 1 is PropertyKind.Named; 4447a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block source = "both_mirror.properties(1).length"; 4448a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(3, CompileRun(source)->Int32Value()); 4449a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4450a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // 2 is PropertyKind.Indexed; 4451a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block source = "both_mirror.properties(2).length"; 4452a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(2, CompileRun(source)->Int32Value()); 4453a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4454a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // 3 is PropertyKind.Named | PropertyKind.Indexed; 4455a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block source = "both_mirror.properties(3).length"; 4456a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(5, CompileRun(source)->Int32Value()); 4457a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4458a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Get the interceptor properties for the object with only named interceptor. 44593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CompileRun("var named_values = named_mirror.properties()"); 4460a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4461a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Check that the properties are interceptor properties. 4462a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (int i = 0; i < 3; i++) { 4463a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EmbeddedVector<char, SMALL_STRING_BUFFER_SIZE> buffer; 4464b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SNPrintF(buffer, 4465b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "named_values[%d] instanceof debug.PropertyMirror", i); 4466a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(CompileRun(buffer.start())->BooleanValue()); 4467a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4468b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SNPrintF(buffer, "named_values[%d].isNative()", i); 4469a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(CompileRun(buffer.start())->BooleanValue()); 4470a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 4471a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4472a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Get the interceptor properties for the object with only indexed 4473a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // interceptor. 44743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CompileRun("var indexed_values = indexed_mirror.properties()"); 4475a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4476a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Check that the properties are interceptor properties. 4477a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (int i = 0; i < 2; i++) { 4478a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EmbeddedVector<char, SMALL_STRING_BUFFER_SIZE> buffer; 4479b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SNPrintF(buffer, 4480b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "indexed_values[%d] instanceof debug.PropertyMirror", i); 4481a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(CompileRun(buffer.start())->BooleanValue()); 4482a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 4483a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4484a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Get the interceptor properties for the object with both types of 4485a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // interceptors. 44863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CompileRun("var both_values = both_mirror.properties()"); 4487a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4488a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Check that the properties are interceptor properties. 4489a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (int i = 0; i < 5; i++) { 4490a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EmbeddedVector<char, SMALL_STRING_BUFFER_SIZE> buffer; 4491b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SNPrintF(buffer, "both_values[%d] instanceof debug.PropertyMirror", i); 4492a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(CompileRun(buffer.start())->BooleanValue()); 4493a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 4494a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4495a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Check the property names. 4496a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block source = "both_values[0].name() == 'a'"; 4497a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(CompileRun(source)->BooleanValue()); 4498a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4499a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block source = "both_values[1].name() == 'b'"; 4500a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(CompileRun(source)->BooleanValue()); 4501a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4502a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block source = "both_values[2].name() == 'c'"; 4503a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(CompileRun(source)->BooleanValue()); 4504a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4505a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block source = "both_values[3].name() == 1"; 4506a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(CompileRun(source)->BooleanValue()); 4507a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4508a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block source = "both_values[4].name() == 10"; 4509a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(CompileRun(source)->BooleanValue()); 4510a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 4511a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4512a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4513a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(HiddenPrototypePropertyMirror) { 4514a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Create a V8 environment with debug access. 4515a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DebugLocalContext env; 4516b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Isolate* isolate = env->GetIsolate(); 4517b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(isolate); 4518a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block env.ExposeDebug(); 4519a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4520b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Handle<v8::FunctionTemplate> t0 = v8::FunctionTemplate::New(isolate); 4521b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch t0->InstanceTemplate()->Set(v8::String::NewFromUtf8(isolate, "x"), 4522b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Number::New(isolate, 0)); 4523b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Handle<v8::FunctionTemplate> t1 = v8::FunctionTemplate::New(isolate); 4524a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block t1->SetHiddenPrototype(true); 4525b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch t1->InstanceTemplate()->Set(v8::String::NewFromUtf8(isolate, "y"), 4526b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Number::New(isolate, 1)); 4527b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Handle<v8::FunctionTemplate> t2 = v8::FunctionTemplate::New(isolate); 4528a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block t2->SetHiddenPrototype(true); 4529b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch t2->InstanceTemplate()->Set(v8::String::NewFromUtf8(isolate, "z"), 4530b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Number::New(isolate, 2)); 4531b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Handle<v8::FunctionTemplate> t3 = v8::FunctionTemplate::New(isolate); 4532b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch t3->InstanceTemplate()->Set(v8::String::NewFromUtf8(isolate, "u"), 4533b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Number::New(isolate, 3)); 4534a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4535a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Create object and set them on the global object. 4536a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<v8::Object> o0 = t0->GetFunction()->NewInstance(); 4537b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch env->Global()->Set(v8::String::NewFromUtf8(isolate, "o0"), o0); 4538a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<v8::Object> o1 = t1->GetFunction()->NewInstance(); 4539b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch env->Global()->Set(v8::String::NewFromUtf8(isolate, "o1"), o1); 4540a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<v8::Object> o2 = t2->GetFunction()->NewInstance(); 4541b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch env->Global()->Set(v8::String::NewFromUtf8(isolate, "o2"), o2); 4542a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<v8::Object> o3 = t3->GetFunction()->NewInstance(); 4543b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch env->Global()->Set(v8::String::NewFromUtf8(isolate, "o3"), o3); 4544a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4545a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Get mirrors for the four objects. 4546a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CompileRun( 45473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch "var o0_mirror = debug.MakeMirror(o0);" 45483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch "var o1_mirror = debug.MakeMirror(o1);" 45493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch "var o2_mirror = debug.MakeMirror(o2);" 45503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch "var o3_mirror = debug.MakeMirror(o3)"); 4551a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(CompileRun("o0_mirror instanceof debug.ObjectMirror")->BooleanValue()); 4552a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(CompileRun("o1_mirror instanceof debug.ObjectMirror")->BooleanValue()); 4553a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(CompileRun("o2_mirror instanceof debug.ObjectMirror")->BooleanValue()); 4554a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(CompileRun("o3_mirror instanceof debug.ObjectMirror")->BooleanValue()); 4555a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4556a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Check that each object has one property. 4557a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1, CompileRun( 4558a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "o0_mirror.propertyNames().length")->Int32Value()); 4559a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1, CompileRun( 4560a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "o1_mirror.propertyNames().length")->Int32Value()); 4561a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1, CompileRun( 4562a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "o2_mirror.propertyNames().length")->Int32Value()); 4563a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1, CompileRun( 4564a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "o3_mirror.propertyNames().length")->Int32Value()); 4565a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4566a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Set o1 as prototype for o0. o1 has the hidden prototype flag so all 4567a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // properties on o1 should be seen on o0. 4568b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch o0->Set(v8::String::NewFromUtf8(isolate, "__proto__"), o1); 4569a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(2, CompileRun( 4570a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "o0_mirror.propertyNames().length")->Int32Value()); 4571a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(0, CompileRun( 4572a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "o0_mirror.property('x').value().value()")->Int32Value()); 4573a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1, CompileRun( 4574a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "o0_mirror.property('y').value().value()")->Int32Value()); 4575a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4576a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Set o2 as prototype for o0 (it will end up after o1 as o1 has the hidden 4577a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // prototype flag. o2 also has the hidden prototype flag so all properties 4578a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // on o2 should be seen on o0 as well as properties on o1. 4579b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch o0->Set(v8::String::NewFromUtf8(isolate, "__proto__"), o2); 4580a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(3, CompileRun( 4581a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "o0_mirror.propertyNames().length")->Int32Value()); 4582a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(0, CompileRun( 4583a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "o0_mirror.property('x').value().value()")->Int32Value()); 4584a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1, CompileRun( 4585a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "o0_mirror.property('y').value().value()")->Int32Value()); 4586a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(2, CompileRun( 4587a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "o0_mirror.property('z').value().value()")->Int32Value()); 4588a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4589a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Set o3 as prototype for o0 (it will end up after o1 and o2 as both o1 and 4590a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // o2 has the hidden prototype flag. o3 does not have the hidden prototype 4591a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // flag so properties on o3 should not be seen on o0 whereas the properties 4592a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // from o1 and o2 should still be seen on o0. 4593a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Final prototype chain: o0 -> o1 -> o2 -> o3 4594a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Hidden prototypes: ^^ ^^ 4595b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch o0->Set(v8::String::NewFromUtf8(isolate, "__proto__"), o3); 4596a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(3, CompileRun( 4597a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "o0_mirror.propertyNames().length")->Int32Value()); 4598a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1, CompileRun( 4599a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "o3_mirror.propertyNames().length")->Int32Value()); 4600a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(0, CompileRun( 4601a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "o0_mirror.property('x').value().value()")->Int32Value()); 4602a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1, CompileRun( 4603a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "o0_mirror.property('y').value().value()")->Int32Value()); 4604a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(2, CompileRun( 4605a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "o0_mirror.property('z').value().value()")->Int32Value()); 4606a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(CompileRun("o0_mirror.property('u').isUndefined()")->BooleanValue()); 4607a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4608a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // The prototype (__proto__) for o0 should be o3 as o1 and o2 are hidden. 4609a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(CompileRun("o0_mirror.protoObject() == o3_mirror")->BooleanValue()); 4610a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 4611a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4612a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4613b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic void ProtperyXNativeGetter( 4614b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Local<v8::String> property, 4615b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::PropertyCallbackInfo<v8::Value>& info) { 4616b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch info.GetReturnValue().Set(10); 4617a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 4618a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4619a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4620a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(NativeGetterPropertyMirror) { 4621a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Create a V8 environment with debug access. 4622a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DebugLocalContext env; 4623b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Isolate* isolate = env->GetIsolate(); 4624b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(isolate); 4625a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block env.ExposeDebug(); 4626a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4627b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Handle<v8::String> name = v8::String::NewFromUtf8(isolate, "x"); 4628a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Create object with named accessor. 4629b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Handle<v8::ObjectTemplate> named = v8::ObjectTemplate::New(isolate); 4630a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block named->SetAccessor(name, &ProtperyXNativeGetter, NULL, 4631a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<v8::Value>(), v8::DEFAULT, v8::None); 4632a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4633a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Create object with named property getter. 4634b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch env->Global()->Set(v8::String::NewFromUtf8(isolate, "instance"), 4635b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch named->NewInstance()); 4636a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(10, CompileRun("instance.x")->Int32Value()); 4637a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4638a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Get mirror for the object with property getter. 46393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CompileRun("var instance_mirror = debug.MakeMirror(instance);"); 4640a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(CompileRun( 4641a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "instance_mirror instanceof debug.ObjectMirror")->BooleanValue()); 4642a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 46433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CompileRun("var named_names = instance_mirror.propertyNames();"); 4644a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1, CompileRun("named_names.length")->Int32Value()); 4645a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(CompileRun("named_names[0] == 'x'")->BooleanValue()); 4646a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(CompileRun( 4647a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "instance_mirror.property('x').value().isNumber()")->BooleanValue()); 4648a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(CompileRun( 4649a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "instance_mirror.property('x').value().value() == 10")->BooleanValue()); 4650a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 4651a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4652a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4653b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic void ProtperyXNativeGetterThrowingError( 4654b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Local<v8::String> property, 4655b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::PropertyCallbackInfo<v8::Value>& info) { 4656b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CompileRun("throw new Error('Error message');"); 4657a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 4658a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4659a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4660a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(NativeGetterThrowingErrorPropertyMirror) { 4661a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Create a V8 environment with debug access. 4662a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DebugLocalContext env; 4663b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Isolate* isolate = env->GetIsolate(); 4664b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(isolate); 4665a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block env.ExposeDebug(); 4666a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4667b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Handle<v8::String> name = v8::String::NewFromUtf8(isolate, "x"); 4668a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Create object with named accessor. 4669b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Handle<v8::ObjectTemplate> named = v8::ObjectTemplate::New(isolate); 4670a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block named->SetAccessor(name, &ProtperyXNativeGetterThrowingError, NULL, 4671a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<v8::Value>(), v8::DEFAULT, v8::None); 4672a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4673a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Create object with named property getter. 4674b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch env->Global()->Set(v8::String::NewFromUtf8(isolate, "instance"), 4675b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch named->NewInstance()); 4676a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4677a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Get mirror for the object with property getter. 46783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CompileRun("var instance_mirror = debug.MakeMirror(instance);"); 4679a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(CompileRun( 4680a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "instance_mirror instanceof debug.ObjectMirror")->BooleanValue()); 4681a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CompileRun("named_names = instance_mirror.propertyNames();"); 4682a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1, CompileRun("named_names.length")->Int32Value()); 4683a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(CompileRun("named_names[0] == 'x'")->BooleanValue()); 4684a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(CompileRun( 4685a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "instance_mirror.property('x').value().isError()")->BooleanValue()); 4686a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4687a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Check that the message is that passed to the Error constructor. 4688a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(CompileRun( 4689a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "instance_mirror.property('x').value().message() == 'Error message'")-> 4690a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block BooleanValue()); 4691a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 4692a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4693a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4694d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block// Test that hidden properties object is not returned as an unnamed property 4695d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block// among regular properties. 4696d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block// See http://crbug.com/26491 4697d0582a6c46733687d045e4188a1bcd0123c758a1Steve BlockTEST(NoHiddenProperties) { 4698d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // Create a V8 environment with debug access. 4699d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block DebugLocalContext env; 4700b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Isolate* isolate = env->GetIsolate(); 4701b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(isolate); 4702d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block env.ExposeDebug(); 4703d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 4704d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // Create an object in the global scope. 4705d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block const char* source = "var obj = {a: 1};"; 4706b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Script::Compile(v8::String::NewFromUtf8(isolate, source)) 4707b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ->Run(); 4708d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block v8::Local<v8::Object> obj = v8::Local<v8::Object>::Cast( 4709b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch env->Global()->Get(v8::String::NewFromUtf8(isolate, "obj"))); 4710d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // Set a hidden property on the object. 4711b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch obj->SetHiddenValue( 4712b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::String::NewFromUtf8(isolate, "v8::test-debug::a"), 4713b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Int32::New(isolate, 11)); 4714d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 4715d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // Get mirror for the object with property getter. 4716d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block CompileRun("var obj_mirror = debug.MakeMirror(obj);"); 4717d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block CHECK(CompileRun( 4718d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block "obj_mirror instanceof debug.ObjectMirror")->BooleanValue()); 4719d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block CompileRun("var named_names = obj_mirror.propertyNames();"); 4720d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // There should be exactly one property. But there is also an unnamed 4721d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // property whose value is hidden properties dictionary. The latter 4722d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // property should not be in the list of reguar properties. 4723d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block CHECK_EQ(1, CompileRun("named_names.length")->Int32Value()); 4724d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block CHECK(CompileRun("named_names[0] == 'a'")->BooleanValue()); 4725d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block CHECK(CompileRun( 4726d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block "obj_mirror.property('a').value().value() == 1")->BooleanValue()); 4727d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 4728d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // Object created by t0 will become hidden prototype of object 'obj'. 4729b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Handle<v8::FunctionTemplate> t0 = v8::FunctionTemplate::New(isolate); 4730b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch t0->InstanceTemplate()->Set(v8::String::NewFromUtf8(isolate, "b"), 4731b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Number::New(isolate, 2)); 4732d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block t0->SetHiddenPrototype(true); 4733b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Handle<v8::FunctionTemplate> t1 = v8::FunctionTemplate::New(isolate); 4734b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch t1->InstanceTemplate()->Set(v8::String::NewFromUtf8(isolate, "c"), 4735b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Number::New(isolate, 3)); 4736d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 4737d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // Create proto objects, add hidden properties to them and set them on 4738d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // the global object. 4739d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block v8::Handle<v8::Object> protoObj = t0->GetFunction()->NewInstance(); 4740b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch protoObj->SetHiddenValue( 4741b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::String::NewFromUtf8(isolate, "v8::test-debug::b"), 4742b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Int32::New(isolate, 12)); 4743b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch env->Global()->Set(v8::String::NewFromUtf8(isolate, "protoObj"), 4744b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch protoObj); 4745d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block v8::Handle<v8::Object> grandProtoObj = t1->GetFunction()->NewInstance(); 4746b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch grandProtoObj->SetHiddenValue( 4747b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::String::NewFromUtf8(isolate, "v8::test-debug::c"), 4748b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Int32::New(isolate, 13)); 4749b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch env->Global()->Set( 4750b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::String::NewFromUtf8(isolate, "grandProtoObj"), 4751b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch grandProtoObj); 4752d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 4753d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // Setting prototypes: obj->protoObj->grandProtoObj 4754b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch protoObj->Set(v8::String::NewFromUtf8(isolate, "__proto__"), 4755b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch grandProtoObj); 4756b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch obj->Set(v8::String::NewFromUtf8(isolate, "__proto__"), protoObj); 4757d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 4758d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // Get mirror for the object with property getter. 4759d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block CompileRun("var obj_mirror = debug.MakeMirror(obj);"); 4760d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block CHECK(CompileRun( 4761d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block "obj_mirror instanceof debug.ObjectMirror")->BooleanValue()); 4762d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block CompileRun("var named_names = obj_mirror.propertyNames();"); 4763d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // There should be exactly two properties - one from the object itself and 4764d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // another from its hidden prototype. 4765d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block CHECK_EQ(2, CompileRun("named_names.length")->Int32Value()); 4766d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block CHECK(CompileRun("named_names.sort(); named_names[0] == 'a' &&" 4767d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block "named_names[1] == 'b'")->BooleanValue()); 4768d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block CHECK(CompileRun( 4769d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block "obj_mirror.property('a').value().value() == 1")->BooleanValue()); 4770d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block CHECK(CompileRun( 4771d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block "obj_mirror.property('b').value().value() == 2")->BooleanValue()); 4772d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block} 4773d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 4774a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4775a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Multithreaded tests of JSON debugger protocol 4776a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4777a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Support classes 4778a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4779b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Provides synchronization between N threads, where N is a template parameter. 4780b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// The Wait() call blocks a thread until it is called for the Nth time, then all 4781b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// calls return. Each ThreadBarrier object can only be used once. 4782b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtemplate <int N> 4783b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass ThreadBarrier FINAL { 4784a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 4785b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ThreadBarrier() : num_blocked_(0) {} 4786b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4787b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ~ThreadBarrier() { 4788b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LockGuard<Mutex> lock_guard(&mutex_); 4789b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (num_blocked_ != 0) { 4790b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(N, num_blocked_); 4791b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 4792b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 4793b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4794b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void Wait() { 4795b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LockGuard<Mutex> lock_guard(&mutex_); 4796b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_LT(num_blocked_, N); 4797b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch num_blocked_++; 4798b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (N == num_blocked_) { 4799b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Signal and unblock all waiting threads. 4800b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cv_.NotifyAll(); 4801b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch printf("BARRIER\n\n"); 4802b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch fflush(stdout); 4803b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { // Wait for the semaphore. 4804b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch while (num_blocked_ < N) { 4805b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cv_.Wait(&mutex_); 4806b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 4807b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 4808b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(N, num_blocked_); 4809b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 4810b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4811a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private: 4812b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ConditionVariable cv_; 4813b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Mutex mutex_; 4814a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int num_blocked_; 4815a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4816b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch STATIC_ASSERT(N > 0); 4817a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4818b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DISALLOW_COPY_AND_ASSIGN(ThreadBarrier); 4819b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}; 4820a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4821a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4822a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// A set containing enough barriers and semaphores for any of the tests. 4823a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass Barriers { 4824a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 4825b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Barriers() : semaphore_1(0), semaphore_2(0) {} 4826b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ThreadBarrier<2> barrier_1; 4827b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ThreadBarrier<2> barrier_2; 4828b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ThreadBarrier<2> barrier_3; 4829b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ThreadBarrier<2> barrier_4; 4830b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ThreadBarrier<2> barrier_5; 4831b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::base::Semaphore semaphore_1; 4832b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::base::Semaphore semaphore_2; 4833a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 4834a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4835a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4836a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// We match parts of the message to decide if it is a break message. 4837a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockbool IsBreakEventMessage(char *message) { 4838a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const char* type_event = "\"type\":\"event\""; 4839a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const char* event_break = "\"event\":\"break\""; 4840a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Does the message contain both type:event and event:break? 4841a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return strstr(message, type_event) != NULL && 4842a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block strstr(message, event_break) != NULL; 4843a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 4844a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4845a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 48463ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block// We match parts of the message to decide if it is a exception message. 48473ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Blockbool IsExceptionEventMessage(char *message) { 48483ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block const char* type_event = "\"type\":\"event\""; 48493ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block const char* event_exception = "\"event\":\"exception\""; 48503ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // Does the message contain both type:event and event:exception? 48513ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block return strstr(message, type_event) != NULL && 48523ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block strstr(message, event_exception) != NULL; 48533ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block} 48543ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 48553ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 48563ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block// We match the message wether it is an evaluate response message. 48573ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Blockbool IsEvaluateResponseMessage(char* message) { 48583ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block const char* type_response = "\"type\":\"response\""; 48593ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block const char* command_evaluate = "\"command\":\"evaluate\""; 48603ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // Does the message contain both type:response and command:evaluate? 48613ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block return strstr(message, type_response) != NULL && 48623ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block strstr(message, command_evaluate) != NULL; 48633ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block} 48643ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 48653ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 4866402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescustatic int StringToInt(const char* s) { 4867402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu return atoi(s); // NOLINT 4868402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu} 4869402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu 4870402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu 48713ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block// We match parts of the message to get evaluate result int value. 48723ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Blockint GetEvaluateIntResult(char *message) { 48733ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block const char* value = "\"value\":"; 48743ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block char* pos = strstr(message, value); 48753ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block if (pos == NULL) { 48763ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block return -1; 48773ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block } 48783ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block int res = -1; 4879402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu res = StringToInt(pos + strlen(value)); 48803ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block return res; 48813ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block} 48823ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 48833ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 48843ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block// We match parts of the message to get hit breakpoint id. 48853ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Blockint GetBreakpointIdFromBreakEventMessage(char *message) { 48863ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block const char* breakpoints = "\"breakpoints\":["; 48873ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block char* pos = strstr(message, breakpoints); 48883ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block if (pos == NULL) { 48893ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block return -1; 48903ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block } 48913ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block int res = -1; 4892402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu res = StringToInt(pos + strlen(breakpoints)); 48933ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block return res; 48943ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block} 48953ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 48963ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 4897d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke// We match parts of the message to get total frames number. 4898d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkeint GetTotalFramesInt(char *message) { 4899d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke const char* prefix = "\"totalFrames\":"; 4900d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke char* pos = strstr(message, prefix); 4901d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke if (pos == NULL) { 4902d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke return -1; 4903d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 4904d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke pos += strlen(prefix); 4905402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu int res = StringToInt(pos); 4906d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke return res; 4907d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 4908d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 4909d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 49109ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick// We match parts of the message to get source line. 49119ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrickint GetSourceLineFromBreakEventMessage(char *message) { 49129ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick const char* source_line = "\"sourceLine\":"; 49139ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick char* pos = strstr(message, source_line); 49149ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick if (pos == NULL) { 49159ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick return -1; 49169ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick } 49179ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick int res = -1; 49189ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick res = StringToInt(pos + strlen(source_line)); 49199ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick return res; 49209ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick} 49219ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick 4922b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4923a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block/* Test MessageQueues */ 4924a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block/* Tests the message queues that hold debugger commands and 4925a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block * response messages to the debugger. Fills queues and makes 4926a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block * them grow. 4927a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block */ 4928a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockBarriers message_queue_barriers; 4929a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4930a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// This is the debugger thread, that executes no v8 calls except 4931a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// placing JSON debugger commands in the queue. 4932b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass MessageQueueDebuggerThread : public v8::base::Thread { 4933a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 49343fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch MessageQueueDebuggerThread() 4935b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : Thread(Options("MessageQueueDebuggerThread")) {} 4936a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void Run(); 4937a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 4938a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4939b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4940b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic void MessageHandler(const v8::Debug::Message& message) { 4941b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Handle<v8::String> json = message.GetJSON(); 4942b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::String::Utf8Value utf8(json); 4943b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (IsBreakEventMessage(*utf8)) { 4944a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Lets test script wait until break occurs to send commands. 4945a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Signals when a break is reported. 4946b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch message_queue_barriers.semaphore_2.Signal(); 4947a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 4948a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4949a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Allow message handler to block on a semaphore, to test queueing of 4950a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // messages while blocked. 4951b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch message_queue_barriers.semaphore_1.Wait(); 4952a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 4953a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4954b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4955a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid MessageQueueDebuggerThread::Run() { 4956a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const int kBufferSize = 1000; 4957a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block uint16_t buffer_1[kBufferSize]; 4958a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block uint16_t buffer_2[kBufferSize]; 4959a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const char* command_1 = 4960a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "{\"seq\":117," 4961a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "\"type\":\"request\"," 4962a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "\"command\":\"evaluate\"," 4963a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "\"arguments\":{\"expression\":\"1+2\"}}"; 4964a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const char* command_2 = 4965a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "{\"seq\":118," 4966a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "\"type\":\"request\"," 4967a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "\"command\":\"evaluate\"," 4968a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "\"arguments\":{\"expression\":\"1+a\"}}"; 4969a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const char* command_3 = 4970a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "{\"seq\":119," 4971a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "\"type\":\"request\"," 4972a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "\"command\":\"evaluate\"," 4973a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "\"arguments\":{\"expression\":\"c.d * b\"}}"; 4974a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const char* command_continue = 4975a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "{\"seq\":106," 4976a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "\"type\":\"request\"," 4977a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "\"command\":\"continue\"}"; 4978a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const char* command_single_step = 4979a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "{\"seq\":107," 4980a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "\"type\":\"request\"," 4981a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "\"command\":\"continue\"," 4982a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "\"arguments\":{\"stepaction\":\"next\"}}"; 4983a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4984a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block /* Interleaved sequence of actions by the two threads:*/ 4985a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Main thread compiles and runs source_1 4986b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch message_queue_barriers.semaphore_1.Signal(); 4987a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block message_queue_barriers.barrier_1.Wait(); 4988a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Post 6 commands, filling the command queue and making it expand. 4989a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // These calls return immediately, but the commands stay on the queue 4990a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // until the execution of source_2. 4991a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Note: AsciiToUtf16 executes before SendCommand, so command is copied 4992a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // to buffer before buffer is sent to SendCommand. 4993b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Isolate* isolate = CcTest::isolate(); 4994b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Debug::SendCommand(isolate, buffer_1, AsciiToUtf16(command_1, buffer_1)); 4995b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Debug::SendCommand(isolate, buffer_2, AsciiToUtf16(command_2, buffer_2)); 4996b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Debug::SendCommand(isolate, buffer_2, AsciiToUtf16(command_3, buffer_2)); 4997b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Debug::SendCommand(isolate, buffer_2, AsciiToUtf16(command_3, buffer_2)); 4998b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Debug::SendCommand(isolate, buffer_2, AsciiToUtf16(command_3, buffer_2)); 4999a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block message_queue_barriers.barrier_2.Wait(); 5000a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Main thread compiles and runs source_2. 5001a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Queued commands are executed at the start of compilation of source_2( 5002a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // beforeCompile event). 5003a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Free the message handler to process all the messages from the queue. 7 5004a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // messages are expected: 2 afterCompile events and 5 responses. 5005a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // All the commands added so far will fail to execute as long as call stack 5006a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // is empty on beforeCompile event. 5007a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (int i = 0; i < 6 ; ++i) { 5008b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch message_queue_barriers.semaphore_1.Signal(); 5009a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 5010a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block message_queue_barriers.barrier_3.Wait(); 5011a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Main thread compiles and runs source_3. 5012a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Don't stop in the afterCompile handler. 5013b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch message_queue_barriers.semaphore_1.Signal(); 5014a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // source_3 includes a debugger statement, which causes a break event. 5015a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Wait on break event from hitting "debugger" statement 5016b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch message_queue_barriers.semaphore_2.Wait(); 5017a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // These should execute after the "debugger" statement in source_2 5018b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Debug::SendCommand(isolate, buffer_1, AsciiToUtf16(command_1, buffer_1)); 5019b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Debug::SendCommand(isolate, buffer_2, AsciiToUtf16(command_2, buffer_2)); 5020b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Debug::SendCommand(isolate, buffer_2, AsciiToUtf16(command_3, buffer_2)); 5021b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Debug::SendCommand( 5022b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate, buffer_2, AsciiToUtf16(command_single_step, buffer_2)); 5023a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Run after 2 break events, 4 responses. 5024a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (int i = 0; i < 6 ; ++i) { 5025b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch message_queue_barriers.semaphore_1.Signal(); 5026a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 5027a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Wait on break event after a single step executes. 5028b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch message_queue_barriers.semaphore_2.Wait(); 5029b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Debug::SendCommand(isolate, buffer_1, AsciiToUtf16(command_2, buffer_1)); 5030b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Debug::SendCommand( 5031b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate, buffer_2, AsciiToUtf16(command_continue, buffer_2)); 5032a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Run after 2 responses. 5033a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (int i = 0; i < 2 ; ++i) { 5034b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch message_queue_barriers.semaphore_1.Signal(); 5035a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 5036a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Main thread continues running source_3 to end, waits for this thread. 5037a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 5038a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5039a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5040a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// This thread runs the v8 engine. 5041a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(MessageQueues) { 50423fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch MessageQueueDebuggerThread message_queue_debugger_thread; 504344f0eee88ff00398ff7f715fab053374d808c90dSteve Block 5044a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Create a V8 environment 5045a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DebugLocalContext env; 5046b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(env->GetIsolate()); 5047a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetMessageHandler(MessageHandler); 5048a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block message_queue_debugger_thread.Start(); 5049a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5050a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const char* source_1 = "a = 3; b = 4; c = new Object(); c.d = 5;"; 5051a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const char* source_2 = "e = 17;"; 5052a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const char* source_3 = "a = 4; debugger; a = 5; a = 6; a = 7;"; 5053a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5054a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // See MessageQueueDebuggerThread::Run for interleaved sequence of 5055a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // API calls and events in the two threads. 5056a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CompileRun(source_1); 5057a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block message_queue_barriers.barrier_1.Wait(); 5058a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block message_queue_barriers.barrier_2.Wait(); 5059a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CompileRun(source_2); 5060a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block message_queue_barriers.barrier_3.Wait(); 5061a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CompileRun(source_3); 5062a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block message_queue_debugger_thread.Join(); 5063a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block fflush(stdout); 5064a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 5065a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5066a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5067a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass TestClientData : public v8::Debug::ClientData { 5068a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 5069a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block TestClientData() { 5070a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block constructor_call_counter++; 5071a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 5072a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block virtual ~TestClientData() { 5073a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block destructor_call_counter++; 5074a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 5075a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5076a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static void ResetCounters() { 5077a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block constructor_call_counter = 0; 5078a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block destructor_call_counter = 0; 5079a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 5080a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5081a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static int constructor_call_counter; 5082a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static int destructor_call_counter; 5083a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 5084a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5085a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockint TestClientData::constructor_call_counter = 0; 5086a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockint TestClientData::destructor_call_counter = 0; 5087a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5088a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5089a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Tests that MessageQueue doesn't destroy client data when expands and 5090a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// does destroy when it dies. 5091a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(MessageQueueExpandAndDestroy) { 5092a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block TestClientData::ResetCounters(); 5093a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block { // Create a scope for the queue. 5094a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CommandMessageQueue queue(1); 5095a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block queue.Put(CommandMessage::New(Vector<uint16_t>::empty(), 5096a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block new TestClientData())); 5097a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block queue.Put(CommandMessage::New(Vector<uint16_t>::empty(), 5098a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block new TestClientData())); 5099a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block queue.Put(CommandMessage::New(Vector<uint16_t>::empty(), 5100a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block new TestClientData())); 5101a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(0, TestClientData::destructor_call_counter); 5102a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block queue.Get().Dispose(); 5103a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1, TestClientData::destructor_call_counter); 5104a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block queue.Put(CommandMessage::New(Vector<uint16_t>::empty(), 5105a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block new TestClientData())); 5106a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block queue.Put(CommandMessage::New(Vector<uint16_t>::empty(), 5107a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block new TestClientData())); 5108a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block queue.Put(CommandMessage::New(Vector<uint16_t>::empty(), 5109a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block new TestClientData())); 5110a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block queue.Put(CommandMessage::New(Vector<uint16_t>::empty(), 5111a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block new TestClientData())); 5112a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block queue.Put(CommandMessage::New(Vector<uint16_t>::empty(), 5113a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block new TestClientData())); 5114a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1, TestClientData::destructor_call_counter); 5115a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block queue.Get().Dispose(); 5116a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(2, TestClientData::destructor_call_counter); 5117a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 5118a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // All the client data should be destroyed when the queue is destroyed. 5119a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(TestClientData::destructor_call_counter, 5120a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block TestClientData::destructor_call_counter); 5121a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 5122a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5123a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5124a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic int handled_client_data_instances_count = 0; 5125a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic void MessageHandlerCountingClientData( 5126a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const v8::Debug::Message& message) { 5127a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (message.GetClientData() != NULL) { 5128a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block handled_client_data_instances_count++; 5129a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 5130a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 5131a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5132a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5133a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Tests that all client data passed to the debugger are sent to the handler. 5134a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(SendClientDataToHandler) { 5135a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Create a V8 environment 5136a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DebugLocalContext env; 5137b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Isolate* isolate = env->GetIsolate(); 5138b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(isolate); 5139a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block TestClientData::ResetCounters(); 5140a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block handled_client_data_instances_count = 0; 5141b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Debug::SetMessageHandler(MessageHandlerCountingClientData); 5142a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const char* source_1 = "a = 3; b = 4; c = new Object(); c.d = 5;"; 5143a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const int kBufferSize = 1000; 5144a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block uint16_t buffer[kBufferSize]; 5145a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const char* command_1 = 5146a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "{\"seq\":117," 5147a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "\"type\":\"request\"," 5148a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "\"command\":\"evaluate\"," 5149a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "\"arguments\":{\"expression\":\"1+2\"}}"; 5150a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const char* command_2 = 5151a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "{\"seq\":118," 5152a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "\"type\":\"request\"," 5153a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "\"command\":\"evaluate\"," 5154a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "\"arguments\":{\"expression\":\"1+a\"}}"; 5155a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const char* command_continue = 5156a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "{\"seq\":106," 5157a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "\"type\":\"request\"," 5158a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "\"command\":\"continue\"}"; 5159a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5160b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Debug::SendCommand(isolate, buffer, AsciiToUtf16(command_1, buffer), 5161a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block new TestClientData()); 5162b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Debug::SendCommand( 5163b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate, buffer, AsciiToUtf16(command_2, buffer), NULL); 5164b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Debug::SendCommand(isolate, buffer, AsciiToUtf16(command_2, buffer), 5165a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block new TestClientData()); 5166b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Debug::SendCommand(isolate, buffer, AsciiToUtf16(command_2, buffer), 5167a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block new TestClientData()); 5168a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // All the messages will be processed on beforeCompile event. 5169a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CompileRun(source_1); 5170b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Debug::SendCommand( 5171b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate, buffer, AsciiToUtf16(command_continue, buffer)); 5172a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(3, TestClientData::constructor_call_counter); 5173a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(TestClientData::constructor_call_counter, 5174a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block handled_client_data_instances_count); 5175a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(TestClientData::constructor_call_counter, 5176a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block TestClientData::destructor_call_counter); 5177a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 5178a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5179a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5180a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block/* Test ThreadedDebugging */ 5181a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block/* This test interrupts a running infinite loop that is 5182a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block * occupying the v8 thread by a break command from the 5183a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block * debugger thread. It then changes the value of a 5184a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block * global object, to make the loop terminate. 5185a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block */ 5186a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5187a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockBarriers threaded_debugging_barriers; 5188a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5189b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass V8Thread : public v8::base::Thread { 5190a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 5191b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch V8Thread() : Thread(Options("V8Thread")) {} 5192a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void Run(); 5193b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Isolate* isolate() { return isolate_; } 5194b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5195b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private: 5196b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Isolate* isolate_; 5197a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 5198a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5199b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass DebuggerThread : public v8::base::Thread { 5200a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 5201b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch explicit DebuggerThread(v8::Isolate* isolate) 5202b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : Thread(Options("DebuggerThread")), isolate_(isolate) {} 5203a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void Run(); 5204b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5205b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private: 5206b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Isolate* isolate_; 5207a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 5208a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5209a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5210b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic void ThreadedAtBarrier1( 5211b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::FunctionCallbackInfo<v8::Value>& args) { 5212a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block threaded_debugging_barriers.barrier_1.Wait(); 5213a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 5214a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5215a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5216a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic void ThreadedMessageHandler(const v8::Debug::Message& message) { 5217a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static char print_buffer[1000]; 5218a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::String::Value json(message.GetJSON()); 5219a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Utf16ToAscii(*json, json.length(), print_buffer); 5220a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (IsBreakEventMessage(print_buffer)) { 52219ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick // Check that we are inside the while loop. 52229ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick int source_line = GetSourceLineFromBreakEventMessage(print_buffer); 52239ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick CHECK(8 <= source_line && source_line <= 13); 5224a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block threaded_debugging_barriers.barrier_2.Wait(); 5225a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 5226a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 5227a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5228a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5229a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid V8Thread::Run() { 5230a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const char* source = 5231a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "flag = true;\n" 5232a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "function bar( new_value ) {\n" 5233a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " flag = new_value;\n" 5234a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " return \"Return from bar(\" + new_value + \")\";\n" 5235a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "}\n" 5236a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "\n" 5237a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "function foo() {\n" 5238a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " var x = 1;\n" 5239a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " while ( flag == true ) {\n" 5240a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " if ( x == 1 ) {\n" 5241a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " ThreadedAtBarrier1();\n" 5242a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " }\n" 5243a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " x = x + 1;\n" 5244a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " }\n" 5245a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "}\n" 5246a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "\n" 5247a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "foo();\n"; 5248a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5249b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate_ = v8::Isolate::New(); 5250b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch threaded_debugging_barriers.barrier_3.Wait(); 5251b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 5252b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Isolate::Scope isolate_scope(isolate_); 5253b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DebugLocalContext env(isolate_); 5254b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(isolate_); 5255b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Debug::SetMessageHandler(&ThreadedMessageHandler); 5256b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Handle<v8::ObjectTemplate> global_template = 5257b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::ObjectTemplate::New(env->GetIsolate()); 5258b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch global_template->Set( 5259b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::String::NewFromUtf8(env->GetIsolate(), "ThreadedAtBarrier1"), 5260b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::FunctionTemplate::New(isolate_, ThreadedAtBarrier1)); 5261b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Handle<v8::Context> context = 5262b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Context::New(isolate_, NULL, global_template); 5263b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Context::Scope context_scope(context); 5264b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5265b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CompileRun(source); 5266b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5267b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate_->Dispose(); 5268a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 5269a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5270b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5271a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid DebuggerThread::Run() { 5272a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const int kBufSize = 1000; 5273a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block uint16_t buffer[kBufSize]; 5274a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5275a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const char* command_1 = "{\"seq\":102," 5276a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "\"type\":\"request\"," 5277a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "\"command\":\"evaluate\"," 5278a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "\"arguments\":{\"expression\":\"bar(false)\"}}"; 5279a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const char* command_2 = "{\"seq\":103," 5280a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "\"type\":\"request\"," 5281a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "\"command\":\"continue\"}"; 5282a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5283a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block threaded_debugging_barriers.barrier_1.Wait(); 5284b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Debug::DebugBreak(isolate_); 5285a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block threaded_debugging_barriers.barrier_2.Wait(); 5286b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Debug::SendCommand(isolate_, buffer, AsciiToUtf16(command_1, buffer)); 5287b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Debug::SendCommand(isolate_, buffer, AsciiToUtf16(command_2, buffer)); 5288a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 5289a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5290a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5291a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(ThreadedDebugging) { 52923fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch V8Thread v8_thread; 529344f0eee88ff00398ff7f715fab053374d808c90dSteve Block 5294a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Create a V8 environment 5295a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8_thread.Start(); 5296b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch threaded_debugging_barriers.barrier_3.Wait(); 5297b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DebuggerThread debugger_thread(v8_thread.isolate()); 5298a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block debugger_thread.Start(); 5299a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5300a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8_thread.Join(); 5301a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block debugger_thread.Join(); 5302a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 5303a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5304b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5305a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block/* Test RecursiveBreakpoints */ 5306a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block/* In this test, the debugger evaluates a function with a breakpoint, after 5307a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block * hitting a breakpoint in another function. We do this with both values 5308a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block * of the flag enabling recursive breakpoints, and verify that the second 5309a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block * breakpoint is hit when enabled, and missed when disabled. 5310a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block */ 5311a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5312b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass BreakpointsV8Thread : public v8::base::Thread { 5313a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 5314b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BreakpointsV8Thread() : Thread(Options("BreakpointsV8Thread")) {} 5315a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void Run(); 5316b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5317b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Isolate* isolate() { return isolate_; } 5318b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5319b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private: 5320b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Isolate* isolate_; 5321a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 5322a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5323b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass BreakpointsDebuggerThread : public v8::base::Thread { 5324a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 5325b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BreakpointsDebuggerThread(bool global_evaluate, v8::Isolate* isolate) 5326b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : Thread(Options("BreakpointsDebuggerThread")), 5327b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch global_evaluate_(global_evaluate), 5328b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate_(isolate) {} 5329a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void Run(); 5330d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 5331d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke private: 5332d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke bool global_evaluate_; 5333b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Isolate* isolate_; 5334a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 5335a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5336a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5337a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockBarriers* breakpoints_barriers; 53383ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Blockint break_event_breakpoint_id; 53393ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Blockint evaluate_int_result; 5340a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5341a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic void BreakpointsMessageHandler(const v8::Debug::Message& message) { 5342a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static char print_buffer[1000]; 5343a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::String::Value json(message.GetJSON()); 5344a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Utf16ToAscii(*json, json.length(), print_buffer); 5345a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5346a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (IsBreakEventMessage(print_buffer)) { 53473ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block break_event_breakpoint_id = 53483ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block GetBreakpointIdFromBreakEventMessage(print_buffer); 5349b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch breakpoints_barriers->semaphore_1.Signal(); 53503ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block } else if (IsEvaluateResponseMessage(print_buffer)) { 53513ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block evaluate_int_result = GetEvaluateIntResult(print_buffer); 5352b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch breakpoints_barriers->semaphore_1.Signal(); 5353a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 5354a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 5355a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5356a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5357a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid BreakpointsV8Thread::Run() { 5358a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const char* source_1 = "var y_global = 3;\n" 5359a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "function cat( new_value ) {\n" 5360a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " var x = new_value;\n" 53613ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block " y_global = y_global + 4;\n" 5362a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " x = 3 * x + 1;\n" 53633ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block " y_global = y_global + 5;\n" 5364a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " return x;\n" 5365a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "}\n" 5366a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "\n" 5367a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "function dog() {\n" 5368a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " var x = 1;\n" 5369a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " x = y_global;" 5370a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " var z = 3;" 5371a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " x += 100;\n" 5372a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " return x;\n" 5373a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "}\n" 5374a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "\n"; 5375a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const char* source_2 = "cat(17);\n" 5376a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "cat(19);\n"; 5377a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5378b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate_ = v8::Isolate::New(); 5379b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch breakpoints_barriers->barrier_3.Wait(); 5380b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 5381b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Isolate::Scope isolate_scope(isolate_); 5382b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DebugLocalContext env(isolate_); 5383b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(isolate_); 5384b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Debug::SetMessageHandler(&BreakpointsMessageHandler); 5385b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5386b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CompileRun(source_1); 5387b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch breakpoints_barriers->barrier_1.Wait(); 5388b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch breakpoints_barriers->barrier_2.Wait(); 5389b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CompileRun(source_2); 5390b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5391b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate_->Dispose(); 5392a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 5393a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5394a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5395a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid BreakpointsDebuggerThread::Run() { 5396a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const int kBufSize = 1000; 5397a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block uint16_t buffer[kBufSize]; 5398a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5399a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const char* command_1 = "{\"seq\":101," 5400a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "\"type\":\"request\"," 5401a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "\"command\":\"setbreakpoint\"," 5402a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "\"arguments\":{\"type\":\"function\",\"target\":\"cat\",\"line\":3}}"; 5403a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const char* command_2 = "{\"seq\":102," 5404a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "\"type\":\"request\"," 5405a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "\"command\":\"setbreakpoint\"," 5406a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "\"arguments\":{\"type\":\"function\",\"target\":\"dog\",\"line\":3}}"; 5407d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke const char* command_3; 5408d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke if (this->global_evaluate_) { 5409d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke command_3 = "{\"seq\":103," 5410d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke "\"type\":\"request\"," 5411d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke "\"command\":\"evaluate\"," 5412d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke "\"arguments\":{\"expression\":\"dog()\",\"disable_break\":false," 5413d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke "\"global\":true}}"; 5414d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } else { 5415d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke command_3 = "{\"seq\":103," 5416d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke "\"type\":\"request\"," 5417d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke "\"command\":\"evaluate\"," 5418d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke "\"arguments\":{\"expression\":\"dog()\",\"disable_break\":false}}"; 5419d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 5420d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke const char* command_4; 5421d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke if (this->global_evaluate_) { 5422d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke command_4 = "{\"seq\":104," 5423d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke "\"type\":\"request\"," 5424d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke "\"command\":\"evaluate\"," 5425d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke "\"arguments\":{\"expression\":\"100 + 8\",\"disable_break\":true," 5426d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke "\"global\":true}}"; 5427d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } else { 5428d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke command_4 = "{\"seq\":104," 5429d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke "\"type\":\"request\"," 5430d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke "\"command\":\"evaluate\"," 5431d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke "\"arguments\":{\"expression\":\"x + 1\",\"disable_break\":true}}"; 5432d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 54333ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block const char* command_5 = "{\"seq\":105," 5434a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "\"type\":\"request\"," 5435a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "\"command\":\"continue\"}"; 54363ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block const char* command_6 = "{\"seq\":106," 5437a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "\"type\":\"request\"," 5438a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "\"command\":\"continue\"}"; 5439d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke const char* command_7; 5440d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke if (this->global_evaluate_) { 5441d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke command_7 = "{\"seq\":107," 5442d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke "\"type\":\"request\"," 5443d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke "\"command\":\"evaluate\"," 5444d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke "\"arguments\":{\"expression\":\"dog()\",\"disable_break\":true," 5445d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke "\"global\":true}}"; 5446d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } else { 5447d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke command_7 = "{\"seq\":107," 5448d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke "\"type\":\"request\"," 5449d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke "\"command\":\"evaluate\"," 5450d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke "\"arguments\":{\"expression\":\"dog()\",\"disable_break\":true}}"; 5451d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 54523ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block const char* command_8 = "{\"seq\":108," 5453a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "\"type\":\"request\"," 5454a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "\"command\":\"continue\"}"; 5455a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5456a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5457a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // v8 thread initializes, runs source_1 5458a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block breakpoints_barriers->barrier_1.Wait(); 54593ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // 1:Set breakpoint in cat() (will get id 1). 5460b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Debug::SendCommand(isolate_, buffer, AsciiToUtf16(command_1, buffer)); 54613ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // 2:Set breakpoint in dog() (will get id 2). 5462b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Debug::SendCommand(isolate_, buffer, AsciiToUtf16(command_2, buffer)); 5463a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block breakpoints_barriers->barrier_2.Wait(); 54643ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // V8 thread starts compiling source_2. 5465a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Automatic break happens, to run queued commands 5466b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // breakpoints_barriers->semaphore_1.Wait(); 5467a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Commands 1 through 3 run, thread continues. 5468a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // v8 thread runs source_2 to breakpoint in cat(). 5469a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // message callback receives break event. 5470b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch breakpoints_barriers->semaphore_1.Wait(); 54713ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // Must have hit breakpoint #1. 54723ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block CHECK_EQ(1, break_event_breakpoint_id); 5473a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // 4:Evaluate dog() (which has a breakpoint). 5474b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Debug::SendCommand(isolate_, buffer, AsciiToUtf16(command_3, buffer)); 54753ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // V8 thread hits breakpoint in dog(). 5476b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch breakpoints_barriers->semaphore_1.Wait(); // wait for break event 54773ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // Must have hit breakpoint #2. 54783ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block CHECK_EQ(2, break_event_breakpoint_id); 54793ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // 5:Evaluate (x + 1). 5480b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Debug::SendCommand(isolate_, buffer, AsciiToUtf16(command_4, buffer)); 54813ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // Evaluate (x + 1) finishes. 5482b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch breakpoints_barriers->semaphore_1.Wait(); 54833ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // Must have result 108. 54843ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block CHECK_EQ(108, evaluate_int_result); 54853ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // 6:Continue evaluation of dog(). 5486b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Debug::SendCommand(isolate_, buffer, AsciiToUtf16(command_5, buffer)); 54873ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // Evaluate dog() finishes. 5488b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch breakpoints_barriers->semaphore_1.Wait(); 54893ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // Must have result 107. 54903ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block CHECK_EQ(107, evaluate_int_result); 5491a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // 7:Continue evaluation of source_2, finish cat(17), hit breakpoint 5492a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // in cat(19). 5493b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Debug::SendCommand(isolate_, buffer, AsciiToUtf16(command_6, buffer)); 54943ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // Message callback gets break event. 5495b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch breakpoints_barriers->semaphore_1.Wait(); // wait for break event 54963ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // Must have hit breakpoint #1. 54973ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block CHECK_EQ(1, break_event_breakpoint_id); 54983ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // 8: Evaluate dog() with breaks disabled. 5499b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Debug::SendCommand(isolate_, buffer, AsciiToUtf16(command_7, buffer)); 55003ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // Evaluate dog() finishes. 5501b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch breakpoints_barriers->semaphore_1.Wait(); 55023ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // Must have result 116. 55033ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block CHECK_EQ(116, evaluate_int_result); 5504a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // 9: Continue evaluation of source2, reach end. 5505b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Debug::SendCommand(isolate_, buffer, AsciiToUtf16(command_8, buffer)); 5506a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 5507a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5508888f6729be6a6f6fbe246cb5a9f122e2dbe455b7Leon Clarke 5509b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid TestRecursiveBreakpointsGeneric(bool global_evaluate) { 55103fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch BreakpointsV8Thread breakpoints_v8_thread; 5511d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 5512a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Create a V8 environment 5513a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Barriers stack_allocated_breakpoints_barriers; 5514a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block breakpoints_barriers = &stack_allocated_breakpoints_barriers; 5515a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5516a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block breakpoints_v8_thread.Start(); 5517b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch breakpoints_barriers->barrier_3.Wait(); 5518b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BreakpointsDebuggerThread breakpoints_debugger_thread( 5519b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch global_evaluate, breakpoints_v8_thread.isolate()); 5520a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block breakpoints_debugger_thread.Start(); 5521a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5522a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block breakpoints_v8_thread.Join(); 5523a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block breakpoints_debugger_thread.Join(); 5524a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 5525a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5526b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5527d91b9f7d46489a9ee00f9cb415630299c76a502bLeon ClarkeTEST(RecursiveBreakpoints) { 5528d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke TestRecursiveBreakpointsGeneric(false); 5529d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 5530d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 5531b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5532d91b9f7d46489a9ee00f9cb415630299c76a502bLeon ClarkeTEST(RecursiveBreakpointsGlobal) { 5533d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke TestRecursiveBreakpointsGeneric(true); 5534d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 5535d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 5536a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5537b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic void DummyDebugEventListener( 5538b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::Debug::EventDetails& event_details) { 5539a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 5540a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5541a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5542a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(SetDebugEventListenerOnUninitializedVM) { 5543a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetDebugEventListener(DummyDebugEventListener); 5544a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 5545a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5546a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5547a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic void DummyMessageHandler(const v8::Debug::Message& message) { 5548a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 5549a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5550a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5551a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(SetMessageHandlerOnUninitializedVM) { 5552b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Debug::SetMessageHandler(DummyMessageHandler); 5553a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 5554a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5555a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5556a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Source for a JavaScript function which returns the data parameter of a 5557a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// function called in the context of the debugger. If no data parameter is 5558a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// passed it throws an exception. 5559a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic const char* debugger_call_with_data_source = 5560a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "function debugger_call_with_data(exec_state, data) {" 5561a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " if (data) return data;" 5562a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " throw 'No data!'" 5563a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "}"; 5564a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockv8::Handle<v8::Function> debugger_call_with_data; 5565a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5566a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5567a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Source for a JavaScript function which returns the data parameter of a 5568a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// function called in the context of the debugger. If no data parameter is 5569a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// passed it throws an exception. 5570a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic const char* debugger_call_with_closure_source = 5571a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "var x = 3;" 5572a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "(function (exec_state) {" 5573a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " if (exec_state.y) return x - 1;" 5574a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " exec_state.y = x;" 5575a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " return exec_state.y" 5576a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "})"; 5577a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockv8::Handle<v8::Function> debugger_call_with_closure; 5578a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5579a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Function to retrieve the number of JavaScript frames by calling a JavaScript 5580a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// in the debugger. 5581b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic void CheckFrameCount(const v8::FunctionCallbackInfo<v8::Value>& args) { 5582a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(v8::Debug::Call(frame_count)->IsNumber()); 5583a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(args[0]->Int32Value(), 5584a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::Call(frame_count)->Int32Value()); 5585a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 5586a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5587a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5588a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Function to retrieve the source line of the top JavaScript frame by calling a 5589a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// JavaScript function in the debugger. 5590b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic void CheckSourceLine(const v8::FunctionCallbackInfo<v8::Value>& args) { 5591a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(v8::Debug::Call(frame_source_line)->IsNumber()); 5592a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(args[0]->Int32Value(), 5593a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::Call(frame_source_line)->Int32Value()); 5594a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 5595a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5596a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5597a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Function to test passing an additional parameter to a JavaScript function 5598a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// called in the debugger. It also tests that functions called in the debugger 5599a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// can throw exceptions. 5600b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic void CheckDataParameter( 5601b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::FunctionCallbackInfo<v8::Value>& args) { 5602b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Handle<v8::String> data = 5603b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::String::NewFromUtf8(args.GetIsolate(), "Test"); 5604a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(v8::Debug::Call(debugger_call_with_data, data)->IsString()); 5605a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5606b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < 3; i++) { 5607b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::TryCatch catcher; 5608b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK(v8::Debug::Call(debugger_call_with_data).IsEmpty()); 5609b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK(catcher.HasCaught()); 5610b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK(catcher.Exception()->IsString()); 5611b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5612a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 5613a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5614a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5615a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Function to test using a JavaScript with closure in the debugger. 5616b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic void CheckClosure(const v8::FunctionCallbackInfo<v8::Value>& args) { 5617a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(v8::Debug::Call(debugger_call_with_closure)->IsNumber()); 5618a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(3, v8::Debug::Call(debugger_call_with_closure)->Int32Value()); 5619a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 5620a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5621a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5622a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Test functions called through the debugger. 5623a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(CallFunctionInDebugger) { 5624a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Create and enter a context with the functions CheckFrameCount, 5625a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // CheckSourceLine and CheckDataParameter installed. 5626b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Isolate* isolate = CcTest::isolate(); 5627b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(isolate); 5628b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Handle<v8::ObjectTemplate> global_template = 5629b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::ObjectTemplate::New(isolate); 5630b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch global_template->Set( 5631b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::String::NewFromUtf8(isolate, "CheckFrameCount"), 5632b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::FunctionTemplate::New(isolate, CheckFrameCount)); 5633b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch global_template->Set( 5634b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::String::NewFromUtf8(isolate, "CheckSourceLine"), 5635b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::FunctionTemplate::New(isolate, CheckSourceLine)); 5636b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch global_template->Set( 5637b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::String::NewFromUtf8(isolate, "CheckDataParameter"), 5638b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::FunctionTemplate::New(isolate, CheckDataParameter)); 5639b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch global_template->Set( 5640b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::String::NewFromUtf8(isolate, "CheckClosure"), 5641b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::FunctionTemplate::New(isolate, CheckClosure)); 5642b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Handle<v8::Context> context = v8::Context::New(isolate, 5643b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch NULL, 5644b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch global_template); 5645a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Context::Scope context_scope(context); 5646a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5647a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Compile a function for checking the number of JavaScript frames. 5648b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Script::Compile( 5649b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::String::NewFromUtf8(isolate, frame_count_source))->Run(); 5650b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch frame_count = v8::Local<v8::Function>::Cast(context->Global()->Get( 5651b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::String::NewFromUtf8(isolate, "frame_count"))); 5652a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5653a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Compile a function for returning the source line for the top frame. 5654b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Script::Compile(v8::String::NewFromUtf8(isolate, 5655b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch frame_source_line_source))->Run(); 5656b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch frame_source_line = v8::Local<v8::Function>::Cast(context->Global()->Get( 5657b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::String::NewFromUtf8(isolate, "frame_source_line"))); 5658a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5659a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Compile a function returning the data parameter. 5660b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Script::Compile(v8::String::NewFromUtf8(isolate, 5661b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch debugger_call_with_data_source)) 5662b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ->Run(); 5663a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block debugger_call_with_data = v8::Local<v8::Function>::Cast( 5664b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch context->Global()->Get(v8::String::NewFromUtf8( 5665b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate, "debugger_call_with_data"))); 5666a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5667a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Compile a function capturing closure. 5668b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch debugger_call_with_closure = 5669b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Local<v8::Function>::Cast(v8::Script::Compile( 5670b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::String::NewFromUtf8(isolate, 5671b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch debugger_call_with_closure_source))->Run()); 5672a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 56736ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // Calling a function through the debugger returns 0 frames if there are 56746ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // no JavaScript frames. 5675b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(v8::Integer::New(isolate, 0), 5676b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Debug::Call(frame_count)); 5677a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5678a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Test that the number of frames can be retrieved. 5679b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Script::Compile( 5680b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::String::NewFromUtf8(isolate, "CheckFrameCount(1)"))->Run(); 5681b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Script::Compile(v8::String::NewFromUtf8(isolate, 5682b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "function f() {" 5683b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch " CheckFrameCount(2);" 5684b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "}; f()"))->Run(); 5685a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5686a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Test that the source line can be retrieved. 5687b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Script::Compile( 5688b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::String::NewFromUtf8(isolate, "CheckSourceLine(0)"))->Run(); 5689b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Script::Compile(v8::String::NewFromUtf8(isolate, 5690b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "function f() {\n" 5691b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch " CheckSourceLine(1)\n" 5692b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch " CheckSourceLine(2)\n" 5693b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch " CheckSourceLine(3)\n" 5694b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "}; f()"))->Run(); 5695a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5696a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Test that a parameter can be passed to a function called in the debugger. 5697b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Script::Compile(v8::String::NewFromUtf8(isolate, 5698b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "CheckDataParameter()"))->Run(); 5699a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5700a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Test that a function with closure can be run in the debugger. 5701b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Script::Compile( 5702b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::String::NewFromUtf8(isolate, "CheckClosure()"))->Run(); 5703a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5704a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Test that the source line is correct when there is a line offset. 5705b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::ScriptOrigin origin(v8::String::NewFromUtf8(isolate, "test"), 5706b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Integer::New(isolate, 7)); 5707b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Script::Compile( 5708b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::String::NewFromUtf8(isolate, "CheckSourceLine(7)"), &origin) 5709b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ->Run(); 5710b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Script::Compile(v8::String::NewFromUtf8(isolate, 5711b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "function f() {\n" 5712b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch " CheckSourceLine(8)\n" 5713b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch " CheckSourceLine(9)\n" 5714b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch " CheckSourceLine(10)\n" 5715b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "}; f()"), 5716b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch &origin)->Run(); 5717a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 5718a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5719a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5720a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Debugger message handler which counts the number of breaks. 5721a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic void SendContinueCommand(); 5722a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic void MessageHandlerBreakPointHitCount( 5723a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const v8::Debug::Message& message) { 5724a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (message.IsEvent() && message.GetEvent() == v8::Break) { 5725a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Count the number of breaks. 5726a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count++; 5727a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5728a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block SendContinueCommand(); 5729a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 5730a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 5731a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5732a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5733a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Test that clearing the debug event listener actually clears all break points 5734a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// and related information. 5735a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(DebuggerUnload) { 5736a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DebugLocalContext env; 5737a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5738a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Check debugger is unloaded before it is used. 5739a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CheckDebuggerUnloaded(); 5740a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5741a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Set a debug event listener. 5742a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 5743b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount); 5744a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block { 5745b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(env->GetIsolate()); 5746a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Create a couple of functions for the test. 5747a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Local<v8::Function> foo = 5748a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CompileFunction(&env, "function foo(){x=1}", "foo"); 5749a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Local<v8::Function> bar = 5750a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CompileFunction(&env, "function bar(){y=2}", "bar"); 5751a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5752a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Set some break points. 5753a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block SetBreakPoint(foo, 0); 5754a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block SetBreakPoint(foo, 4); 5755a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block SetBreakPoint(bar, 0); 5756a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block SetBreakPoint(bar, 4); 5757a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5758a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Make sure that the break points are there. 5759a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 5760a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block foo->Call(env->Global(), 0, NULL); 5761a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(2, break_point_hit_count); 5762a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bar->Call(env->Global(), 0, NULL); 5763a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(4, break_point_hit_count); 5764a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 5765a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5766a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Remove the debug event listener without clearing breakpoints. Do this 5767a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // outside a handle scope. 5768a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetDebugEventListener(NULL); 5769a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CheckDebuggerUnloaded(true); 5770a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5771a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Now set a debug message handler. 5772a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count = 0; 5773b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Debug::SetMessageHandler(MessageHandlerBreakPointHitCount); 5774a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block { 5775b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(env->GetIsolate()); 5776a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5777a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Get the test functions again. 57783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch v8::Local<v8::Function> foo(v8::Local<v8::Function>::Cast( 5779b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "foo")))); 5780a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5781a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block foo->Call(env->Global(), 0, NULL); 5782a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(0, break_point_hit_count); 5783a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5784a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Set break points and run again. 5785a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block SetBreakPoint(foo, 0); 5786a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block SetBreakPoint(foo, 4); 5787a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block foo->Call(env->Global(), 0, NULL); 5788a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(2, break_point_hit_count); 5789a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 5790a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5791a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Remove the debug message handler without clearing breakpoints. Do this 5792a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // outside a handle scope. 5793b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Debug::SetMessageHandler(NULL); 5794a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CheckDebuggerUnloaded(true); 5795a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 5796a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5797a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5798a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Sends continue command to the debugger. 5799a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic void SendContinueCommand() { 5800a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const int kBufferSize = 1000; 5801a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block uint16_t buffer[kBufferSize]; 5802a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const char* command_continue = 5803a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "{\"seq\":0," 5804a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "\"type\":\"request\"," 5805a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "\"command\":\"continue\"}"; 5806a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5807b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Debug::SendCommand( 5808b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CcTest::isolate(), buffer, AsciiToUtf16(command_continue, buffer)); 5809a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 5810a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5811a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5812a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Debugger message handler which counts the number of times it is called. 5813a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic int message_handler_hit_count = 0; 5814a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic void MessageHandlerHitCount(const v8::Debug::Message& message) { 5815a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block message_handler_hit_count++; 5816a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 58173ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block static char print_buffer[1000]; 58183ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block v8::String::Value json(message.GetJSON()); 58193ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block Utf16ToAscii(*json, json.length(), print_buffer); 58203ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block if (IsExceptionEventMessage(print_buffer)) { 58213ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // Send a continue command for exception events. 58223ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block SendContinueCommand(); 58233ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block } 5824a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 5825a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5826a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5827a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Test clearing the debug message handler. 5828a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(DebuggerClearMessageHandler) { 5829a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DebugLocalContext env; 5830b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(env->GetIsolate()); 5831a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5832a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Check debugger is unloaded before it is used. 5833a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CheckDebuggerUnloaded(); 5834a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5835a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Set a debug message handler. 5836b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Debug::SetMessageHandler(MessageHandlerHitCount); 5837a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5838a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Run code to throw a unhandled exception. This should end up in the message 5839a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // handler. 5840a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CompileRun("throw 1"); 5841a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5842a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // The message handler should be called. 5843a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_GT(message_handler_hit_count, 0); 5844a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5845a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Clear debug message handler. 5846a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block message_handler_hit_count = 0; 5847a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetMessageHandler(NULL); 5848a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5849a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Run code to throw a unhandled exception. This should end up in the message 5850a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // handler. 5851a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CompileRun("throw 1"); 5852a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5853a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // The message handler should not be called more. 5854a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(0, message_handler_hit_count); 5855a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5856a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CheckDebuggerUnloaded(true); 5857a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 5858a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5859a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5860a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Debugger message handler which clears the message handler while active. 5861a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic void MessageHandlerClearingMessageHandler( 5862a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const v8::Debug::Message& message) { 5863a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block message_handler_hit_count++; 5864a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5865a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Clear debug message handler. 5866a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetMessageHandler(NULL); 5867a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 5868a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5869a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5870a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Test clearing the debug message handler while processing a debug event. 5871a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(DebuggerClearMessageHandlerWhileActive) { 5872a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DebugLocalContext env; 5873b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(env->GetIsolate()); 5874a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5875a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Check debugger is unloaded before it is used. 5876a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CheckDebuggerUnloaded(); 5877a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5878a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Set a debug message handler. 5879b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Debug::SetMessageHandler(MessageHandlerClearingMessageHandler); 5880a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5881a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Run code to throw a unhandled exception. This should end up in the message 5882a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // handler. 5883a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CompileRun("throw 1"); 5884a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5885a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // The message handler should be called. 5886a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1, message_handler_hit_count); 5887a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5888a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CheckDebuggerUnloaded(true); 5889a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 5890a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5891a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5892a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Test for issue http://code.google.com/p/v8/issues/detail?id=289. 5893a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Make sure that DebugGetLoadedScripts doesn't return scripts 5894a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// with disposed external source. 5895a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass EmptyExternalStringResource : public v8::String::ExternalStringResource { 5896a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 5897a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EmptyExternalStringResource() { empty_[0] = 0; } 5898a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block virtual ~EmptyExternalStringResource() {} 5899a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block virtual size_t length() const { return empty_.length(); } 5900a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block virtual const uint16_t* data() const { return empty_.start(); } 5901a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private: 5902a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ::v8::internal::EmbeddedVector<uint16_t, 1> empty_; 5903a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 5904a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5905a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5906a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(DebugGetLoadedScripts) { 5907a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DebugLocalContext env; 5908b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(env->GetIsolate()); 5909a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block env.ExposeDebug(); 5910a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5911a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EmptyExternalStringResource source_ext_str; 5912b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Local<v8::String> source = 5913b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::String::NewExternal(env->GetIsolate(), &source_ext_str); 59143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch v8::Handle<v8::Script> evil_script(v8::Script::Compile(source)); 59153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // "use" evil_script to make the compiler happy. 59163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch (void) evil_script; 5917a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<i::ExternalTwoByteString> i_source( 5918a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block i::ExternalTwoByteString::cast(*v8::Utils::OpenHandle(*source))); 5919a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // This situation can happen if source was an external string disposed 5920a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // by its owner. 5921a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block i_source->set_resource(0); 5922a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5923a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool allow_natives_syntax = i::FLAG_allow_natives_syntax; 5924a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block i::FLAG_allow_natives_syntax = true; 5925a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CompileRun( 5926a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "var scripts = %DebugGetLoadedScripts();" 5927a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "var count = scripts.length;" 5928a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "for (var i = 0; i < count; ++i) {" 5929a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block " scripts[i].line_ends;" 5930a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "}"); 5931a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Must not crash while accessing line_ends. 5932a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block i::FLAG_allow_natives_syntax = allow_natives_syntax; 5933a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5934a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Some scripts are retrieved - at least the number of native scripts. 5935b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_GT((*env) 5936b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ->Global() 5937b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ->Get(v8::String::NewFromUtf8(env->GetIsolate(), "count")) 5938b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ->Int32Value(), 5939b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 8); 5940a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 5941a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5942a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5943a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Test script break points set on lines. 5944a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(ScriptNameAndData) { 5945a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DebugLocalContext env; 5946b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(env->GetIsolate()); 5947a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block env.ExposeDebug(); 5948a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5949a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Create functions for retrieving script name and data for the function on 5950a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // the top frame when hitting a break point. 5951a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block frame_script_name = CompileFunction(&env, 5952a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block frame_script_name_source, 5953a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "frame_script_name"); 5954a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5955b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount); 5956a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5957a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Test function source. 5958b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Local<v8::String> script = v8::String::NewFromUtf8(env->GetIsolate(), 5959b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "function f() {\n" 5960b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch " debugger;\n" 5961b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "}\n"); 5962a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5963b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::ScriptOrigin origin1 = 5964b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::ScriptOrigin(v8::String::NewFromUtf8(env->GetIsolate(), "name")); 5965a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<v8::Script> script1 = v8::Script::Compile(script, &origin1); 5966a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block script1->Run(); 5967a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Local<v8::Function> f; 5968b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch f = v8::Local<v8::Function>::Cast( 5969b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "f"))); 5970a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5971a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block f->Call(env->Global(), 0, NULL); 5972a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1, break_point_hit_count); 5973a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ("name", last_script_name_hit); 5974a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5975a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Compile the same script again without setting data. As the compilation 5976a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // cache is disabled when debugging expect the data to be missing. 5977a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Script::Compile(script, &origin1)->Run(); 5978b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch f = v8::Local<v8::Function>::Cast( 5979b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "f"))); 5980a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block f->Call(env->Global(), 0, NULL); 5981a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(2, break_point_hit_count); 5982a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ("name", last_script_name_hit); 5983b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5984b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Local<v8::String> data_obj_source = v8::String::NewFromUtf8( 5985b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch env->GetIsolate(), 5986b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "({ a: 'abc',\n" 5987b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch " b: 123,\n" 5988b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch " toString: function() { return this.a + ' ' + this.b; }\n" 5989b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "})\n"); 5990b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Script::Compile(data_obj_source)->Run(); 5991b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::ScriptOrigin origin2 = 5992b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::ScriptOrigin(v8::String::NewFromUtf8(env->GetIsolate(), "new name")); 5993a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<v8::Script> script2 = v8::Script::Compile(script, &origin2); 5994a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block script2->Run(); 5995b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch f = v8::Local<v8::Function>::Cast( 5996b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "f"))); 5997a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block f->Call(env->Global(), 0, NULL); 5998a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(3, break_point_hit_count); 5999a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ("new name", last_script_name_hit); 6000402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu 6001b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Handle<v8::Script> script3 = v8::Script::Compile(script, &origin2); 6002402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu script3->Run(); 6003b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch f = v8::Local<v8::Function>::Cast( 6004b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "f"))); 6005402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu f->Call(env->Global(), 0, NULL); 6006402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu CHECK_EQ(4, break_point_hit_count); 6007a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 6008a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6009a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6010b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic v8::Handle<v8::Context> expected_context; 6011a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic v8::Handle<v8::Value> expected_context_data; 6012a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6013a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6014a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Check that the expected context is the one generating the debug event. 6015a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic void ContextCheckMessageHandler(const v8::Debug::Message& message) { 6016a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(message.GetEventContext() == expected_context); 6017b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK(message.GetEventContext()->GetEmbedderData(0)->StrictEquals( 6018a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block expected_context_data)); 6019a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block message_handler_hit_count++; 6020a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 60213ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block static char print_buffer[1000]; 60223ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block v8::String::Value json(message.GetJSON()); 60233ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block Utf16ToAscii(*json, json.length(), print_buffer); 60243ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 6025a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Send a continue command for break events. 60263ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block if (IsBreakEventMessage(print_buffer)) { 6027a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block SendContinueCommand(); 6028a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 6029a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 6030a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6031a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6032a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Test which creates two contexts and sets different embedder data on each. 6033a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Checks that this data is set correctly and that when the debug message 6034a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// handler is called the expected context is the one active. 6035a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(ContextData) { 6036b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Isolate* isolate = CcTest::isolate(); 6037b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(isolate); 6038a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6039a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Create two contexts. 6040b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Handle<v8::Context> context_1; 6041b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Handle<v8::Context> context_2; 6042a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<v8::ObjectTemplate> global_template = 6043a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<v8::ObjectTemplate>(); 6044a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<v8::Value> global_object = v8::Handle<v8::Value>(); 6045b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch context_1 = v8::Context::New(isolate, NULL, global_template, global_object); 6046b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch context_2 = v8::Context::New(isolate, NULL, global_template, global_object); 6047b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6048b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Debug::SetMessageHandler(ContextCheckMessageHandler); 6049a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6050a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Default data value is undefined. 6051b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK(context_1->GetEmbedderData(0)->IsUndefined()); 6052b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK(context_2->GetEmbedderData(0)->IsUndefined()); 6053a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6054a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Set and check different data values. 6055b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Handle<v8::String> data_1 = v8::String::NewFromUtf8(isolate, "1"); 6056b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Handle<v8::String> data_2 = v8::String::NewFromUtf8(isolate, "2"); 6057b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch context_1->SetEmbedderData(0, data_1); 6058b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch context_2->SetEmbedderData(0, data_2); 6059b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK(context_1->GetEmbedderData(0)->StrictEquals(data_1)); 6060b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK(context_2->GetEmbedderData(0)->StrictEquals(data_2)); 6061a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6062a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Simple test function which causes a break. 6063a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const char* source = "function f() { debugger; }"; 6064a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6065a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Enter and run function in the first context. 6066a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block { 6067a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Context::Scope context_scope(context_1); 6068a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block expected_context = context_1; 6069a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block expected_context_data = data_1; 6070b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Local<v8::Function> f = CompileFunction(isolate, source, "f"); 6071a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block f->Call(context_1->Global(), 0, NULL); 6072a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 6073a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6074a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6075a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Enter and run function in the second context. 6076a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block { 6077a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Context::Scope context_scope(context_2); 6078a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block expected_context = context_2; 6079a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block expected_context_data = data_2; 6080b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Local<v8::Function> f = CompileFunction(isolate, source, "f"); 6081a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block f->Call(context_2->Global(), 0, NULL); 6082a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 6083a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6084a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Two times compile event and two times break event. 6085a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_GT(message_handler_hit_count, 4); 6086a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6087b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Debug::SetMessageHandler(NULL); 6088a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CheckDebuggerUnloaded(); 6089a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 6090a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6091a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6092a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Debug message handler which issues a debug break when it hits a break event. 6093a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic int message_handler_break_hit_count = 0; 6094a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic void DebugBreakMessageHandler(const v8::Debug::Message& message) { 6095a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Schedule a debug break for break events. 6096a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (message.IsEvent() && message.GetEvent() == v8::Break) { 6097a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block message_handler_break_hit_count++; 6098a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (message_handler_break_hit_count == 1) { 6099b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Debug::DebugBreak(message.GetIsolate()); 6100a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 6101a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 6102a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6103a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Issue a continue command if this event will not cause the VM to start 6104a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // running. 6105a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!message.WillStartRunning()) { 6106a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block SendContinueCommand(); 6107a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 6108a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 6109a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6110a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6111a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Test that a debug break can be scheduled while in a message handler. 6112a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(DebugBreakInMessageHandler) { 6113a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DebugLocalContext env; 6114b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(env->GetIsolate()); 6115a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6116b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Debug::SetMessageHandler(DebugBreakMessageHandler); 6117a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6118a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Test functions. 6119a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const char* script = "function f() { debugger; g(); } function g() { }"; 6120a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CompileRun(script); 6121b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Local<v8::Function> f = v8::Local<v8::Function>::Cast( 6122b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "f"))); 6123b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Local<v8::Function> g = v8::Local<v8::Function>::Cast( 6124b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "g"))); 6125a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6126a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Call f then g. The debugger statement in f will casue a break which will 6127a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // cause another break. 6128a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block f->Call(env->Global(), 0, NULL); 6129a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(2, message_handler_break_hit_count); 6130a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Calling g will not cause any additional breaks. 6131a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block g->Call(env->Global(), 0, NULL); 6132a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(2, message_handler_break_hit_count); 6133a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 6134a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6135a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 61366ded16be15dd865a9b21ea304d5273c8be299c87Steve Block#ifndef V8_INTERPRETED_REGEXP 6137a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Debug event handler which gets the function on the top frame and schedules a 6138a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// break a number of times. 6139a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic void DebugEventDebugBreak( 6140b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::Debug::EventDetails& event_details) { 6141b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::DebugEvent event = event_details.GetEvent(); 6142b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Handle<v8::Object> exec_state = event_details.GetExecutionState(); 6143a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6144a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (event == v8::Break) { 6145a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count++; 6146a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6147a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Get the name of the top frame function. 6148a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!frame_function_name.IsEmpty()) { 6149a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Get the name of the function. 6150b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch const int argc = 2; 6151b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Handle<v8::Value> argv[argc] = { 6152b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch exec_state, v8::Integer::New(CcTest::isolate(), 0) 6153b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch }; 6154a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<v8::Value> result = frame_function_name->Call(exec_state, 6155a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block argc, argv); 6156a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (result->IsUndefined()) { 6157a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_function_hit[0] = '\0'; 6158a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 6159a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(result->IsString()); 6160a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<v8::String> function_name(result->ToString()); 6161b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch function_name->WriteUtf8(last_function_hit); 6162a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 6163a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 6164a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6165a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Keep forcing breaks. 6166a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (break_point_hit_count < 20) { 6167b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Debug::DebugBreak(CcTest::isolate()); 6168a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 6169a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 6170a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 6171a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6172a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6173a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(RegExpDebugBreak) { 6174a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // This test only applies to native regexps. 6175a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DebugLocalContext env; 6176b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(env->GetIsolate()); 6177a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6178a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Create a function for checking the function when hitting a break point. 6179a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block frame_function_name = CompileFunction(&env, 6180a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block frame_function_name_source, 6181a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "frame_function_name"); 6182a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6183a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Test RegExp which matches white spaces and comments at the begining of a 6184a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // source line. 6185a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const char* script = 6186a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "var sourceLineBeginningSkip = /^(?:[ \\v\\h]*(?:\\/\\*.*?\\*\\/)*)*/;\n" 6187a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block "function f(s) { return s.match(sourceLineBeginningSkip)[0].length; }"; 6188a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6189b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Local<v8::Function> f = CompileFunction(env->GetIsolate(), script, "f"); 6190a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const int argc = 1; 6191b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Handle<v8::Value> argv[argc] = { 6192b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::String::NewFromUtf8(env->GetIsolate(), " /* xxx */ a=0;")}; 6193a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Local<v8::Value> result = f->Call(env->Global(), argc, argv); 6194a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(12, result->Int32Value()); 6195a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6196a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Debug::SetDebugEventListener(DebugEventDebugBreak); 6197b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Debug::DebugBreak(env->GetIsolate()); 6198a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block result = f->Call(env->Global(), argc, argv); 6199a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6200a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Check that there was only one break event. Matching RegExp should not 6201a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // cause Break events. 6202a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1, break_point_hit_count); 6203a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ("f", last_function_hit); 6204a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 62056ded16be15dd865a9b21ea304d5273c8be299c87Steve Block#endif // V8_INTERPRETED_REGEXP 6206a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6207a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6208a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Common part of EvalContextData and NestedBreakEventContextData tests. 6209b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic void ExecuteScriptForContextCheck( 6210b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Debug::MessageHandler message_handler) { 6211a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Create a context. 6212b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Handle<v8::Context> context_1; 6213a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<v8::ObjectTemplate> global_template = 6214a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<v8::ObjectTemplate>(); 6215b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch context_1 = 6216b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Context::New(CcTest::isolate(), NULL, global_template); 6217b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6218b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Debug::SetMessageHandler(message_handler); 6219a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6220a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Default data value is undefined. 6221b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK(context_1->GetEmbedderData(0)->IsUndefined()); 6222a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6223a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Set and check a data value. 6224b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Handle<v8::String> data_1 = 6225b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::String::NewFromUtf8(CcTest::isolate(), "1"); 6226b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch context_1->SetEmbedderData(0, data_1); 6227b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK(context_1->GetEmbedderData(0)->StrictEquals(data_1)); 6228a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6229a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Simple test function with eval that causes a break. 6230a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const char* source = "function f() { eval('debugger;'); }"; 6231a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6232a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Enter and run function in the context. 6233a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block { 6234a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Context::Scope context_scope(context_1); 6235a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block expected_context = context_1; 6236a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block expected_context_data = data_1; 6237b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Local<v8::Function> f = CompileFunction(CcTest::isolate(), source, "f"); 6238a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block f->Call(context_1->Global(), 0, NULL); 6239a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 6240b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6241b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Debug::SetMessageHandler(NULL); 6242a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 6243a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6244a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6245a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Test which creates a context and sets embedder data on it. Checks that this 6246a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// data is set correctly and that when the debug message handler is called for 6247a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// break event in an eval statement the expected context is the one returned by 6248a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Message.GetEventContext. 6249a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(EvalContextData) { 6250b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(CcTest::isolate()); 6251a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6252b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ExecuteScriptForContextCheck(ContextCheckMessageHandler); 6253a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6254a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // One time compile event and one time break event. 6255a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_GT(message_handler_hit_count, 2); 6256a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CheckDebuggerUnloaded(); 6257a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 6258a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6259a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6260a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic bool sent_eval = false; 6261a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic int break_count = 0; 6262a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic int continue_command_send_count = 0; 6263a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Check that the expected context is the one generating the debug event 6264a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// including the case of nested break event. 6265a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic void DebugEvalContextCheckMessageHandler( 6266a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const v8::Debug::Message& message) { 6267a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(message.GetEventContext() == expected_context); 6268b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK(message.GetEventContext()->GetEmbedderData(0)->StrictEquals( 6269a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block expected_context_data)); 6270a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block message_handler_hit_count++; 6271a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 62723ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block static char print_buffer[1000]; 62733ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block v8::String::Value json(message.GetJSON()); 62743ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block Utf16ToAscii(*json, json.length(), print_buffer); 62753ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 6276b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Isolate* isolate = message.GetIsolate(); 62773ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block if (IsBreakEventMessage(print_buffer)) { 6278a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_count++; 6279a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!sent_eval) { 6280a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block sent_eval = true; 6281a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6282a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const int kBufferSize = 1000; 6283a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block uint16_t buffer[kBufferSize]; 6284a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const char* eval_command = 6285257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch "{\"seq\":0," 6286257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch "\"type\":\"request\"," 6287257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch "\"command\":\"evaluate\"," 6288257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch "\"arguments\":{\"expression\":\"debugger;\"," 6289257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch "\"global\":true,\"disable_break\":false}}"; 6290a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6291a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Send evaluate command. 6292b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Debug::SendCommand( 6293b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate, buffer, AsciiToUtf16(eval_command, buffer)); 6294a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return; 6295a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 6296a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // It's a break event caused by the evaluation request above. 6297a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block SendContinueCommand(); 6298a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block continue_command_send_count++; 6299a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 63003ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block } else if (IsEvaluateResponseMessage(print_buffer) && 63013ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block continue_command_send_count < 2) { 6302a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Response to the evaluation request. We're still on the breakpoint so 6303a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // send continue. 6304a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block SendContinueCommand(); 6305a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block continue_command_send_count++; 6306a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 6307a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 6308a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6309a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6310a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Tests that context returned for break event is correct when the event occurs 6311a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// in 'evaluate' debugger request. 6312a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(NestedBreakEventContextData) { 6313b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(CcTest::isolate()); 6314a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_count = 0; 6315a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block message_handler_hit_count = 0; 6316a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6317b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ExecuteScriptForContextCheck(DebugEvalContextCheckMessageHandler); 6318a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6319a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // One time compile event and two times break event. 6320a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_GT(message_handler_hit_count, 3); 6321a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6322a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // One break from the source and another from the evaluate request. 6323a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(break_count, 2); 6324a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CheckDebuggerUnloaded(); 6325a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 6326a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6327a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6328a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Debug event listener which counts the after compile events. 6329a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockint after_compile_message_count = 0; 6330a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic void AfterCompileMessageHandler(const v8::Debug::Message& message) { 6331a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Count the number of scripts collected. 6332a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (message.IsEvent()) { 6333a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (message.GetEvent() == v8::AfterCompile) { 6334a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block after_compile_message_count++; 6335a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else if (message.GetEvent() == v8::Break) { 6336a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block SendContinueCommand(); 6337a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 6338a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 6339a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 6340a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6341a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6342a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Tests that after compile event is sent as many times as there are scripts 6343a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// compiled. 6344a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(AfterCompileMessageWhenMessageHandlerIsReset) { 6345a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DebugLocalContext env; 6346b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(env->GetIsolate()); 6347a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block after_compile_message_count = 0; 6348a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const char* script = "var a=1"; 6349a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6350b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Debug::SetMessageHandler(AfterCompileMessageHandler); 6351b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Script::Compile(v8::String::NewFromUtf8(env->GetIsolate(), script)) 6352b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ->Run(); 6353b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Debug::SetMessageHandler(NULL); 6354a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6355b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Debug::SetMessageHandler(AfterCompileMessageHandler); 6356b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Debug::DebugBreak(env->GetIsolate()); 6357b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Script::Compile(v8::String::NewFromUtf8(env->GetIsolate(), script)) 6358b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ->Run(); 6359a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6360a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Setting listener to NULL should cause debugger unload. 6361b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Debug::SetMessageHandler(NULL); 6362a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CheckDebuggerUnloaded(); 6363a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6364a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Compilation cache should be disabled when debugger is active. 6365a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(2, after_compile_message_count); 6366a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 6367a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6368a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6369b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Syntax error event handler which counts a number of events. 6370b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochint compile_error_event_count = 0; 6371b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6372b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic void CompileErrorEventCounterClear() { 6373b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch compile_error_event_count = 0; 6374b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 6375b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6376b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic void CompileErrorEventCounter( 6377b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::Debug::EventDetails& event_details) { 6378b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::DebugEvent event = event_details.GetEvent(); 6379b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6380b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (event == v8::CompileError) { 6381b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch compile_error_event_count++; 6382b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6383b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 6384b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6385b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6386b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Tests that syntax error event is sent as many times as there are scripts 6387b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// with syntax error compiled. 6388b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST(SyntaxErrorMessageOnSyntaxException) { 6389b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DebugLocalContext env; 6390b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(env->GetIsolate()); 6391b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6392b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // For this test, we want to break on uncaught exceptions: 6393b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ChangeBreakOnException(false, true); 6394b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6395b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Debug::SetDebugEventListener(CompileErrorEventCounter); 6396b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6397b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CompileErrorEventCounterClear(); 6398b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6399b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Check initial state. 6400b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(0, compile_error_event_count); 6401b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6402b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Throws SyntaxError: Unexpected end of input 6403b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Script::Compile(v8::String::NewFromUtf8(env->GetIsolate(), "+++")); 6404b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(1, compile_error_event_count); 6405b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6406b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Script::Compile( 6407b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::String::NewFromUtf8(env->GetIsolate(), "/sel\\/: \\")); 6408b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(2, compile_error_event_count); 6409b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6410b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Script::Compile( 6411b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::String::NewFromUtf8(env->GetIsolate(), "JSON.parse('1234:')")); 6412b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(2, compile_error_event_count); 6413b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6414b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Script::Compile( 6415b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::String::NewFromUtf8(env->GetIsolate(), "new RegExp('/\\/\\\\');")); 6416b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(2, compile_error_event_count); 6417b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6418b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Script::Compile(v8::String::NewFromUtf8(env->GetIsolate(), "throw 1;")); 6419b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(2, compile_error_event_count); 6420b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 6421b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6422b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6423a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Tests that break event is sent when message handler is reset. 6424a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(BreakMessageWhenMessageHandlerIsReset) { 6425a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DebugLocalContext env; 6426b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(env->GetIsolate()); 6427a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block after_compile_message_count = 0; 6428a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const char* script = "function f() {};"; 6429a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6430b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Debug::SetMessageHandler(AfterCompileMessageHandler); 6431b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Script::Compile(v8::String::NewFromUtf8(env->GetIsolate(), script)) 6432b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ->Run(); 6433b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Debug::SetMessageHandler(NULL); 6434a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6435b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Debug::SetMessageHandler(AfterCompileMessageHandler); 6436b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Debug::DebugBreak(env->GetIsolate()); 6437b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Local<v8::Function> f = v8::Local<v8::Function>::Cast( 6438b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "f"))); 6439a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block f->Call(env->Global(), 0, NULL); 6440a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6441a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Setting message handler to NULL should cause debugger unload. 6442b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Debug::SetMessageHandler(NULL); 6443a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CheckDebuggerUnloaded(); 6444a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6445a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Compilation cache should be disabled when debugger is active. 6446a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1, after_compile_message_count); 6447a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 6448a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6449a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6450a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic int exception_event_count = 0; 6451a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic void ExceptionMessageHandler(const v8::Debug::Message& message) { 6452a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (message.IsEvent() && message.GetEvent() == v8::Exception) { 6453a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block exception_event_count++; 6454a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block SendContinueCommand(); 6455a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 6456a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 6457a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6458a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6459a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Tests that exception event is sent when message handler is reset. 6460a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(ExceptionMessageWhenMessageHandlerIsReset) { 6461a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DebugLocalContext env; 6462b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(env->GetIsolate()); 6463086aeeaae12517475c22695a200be45495516549Ben Murdoch 6464086aeeaae12517475c22695a200be45495516549Ben Murdoch // For this test, we want to break on uncaught exceptions: 6465086aeeaae12517475c22695a200be45495516549Ben Murdoch ChangeBreakOnException(false, true); 6466086aeeaae12517475c22695a200be45495516549Ben Murdoch 6467a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block exception_event_count = 0; 6468a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const char* script = "function f() {throw new Error()};"; 6469a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6470b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Debug::SetMessageHandler(AfterCompileMessageHandler); 6471b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Script::Compile(v8::String::NewFromUtf8(env->GetIsolate(), script)) 6472b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ->Run(); 6473b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Debug::SetMessageHandler(NULL); 6474a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6475b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Debug::SetMessageHandler(ExceptionMessageHandler); 6476b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Local<v8::Function> f = v8::Local<v8::Function>::Cast( 6477b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "f"))); 6478a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block f->Call(env->Global(), 0, NULL); 6479a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6480a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Setting message handler to NULL should cause debugger unload. 6481b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Debug::SetMessageHandler(NULL); 6482a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CheckDebuggerUnloaded(); 6483a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6484a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1, exception_event_count); 6485a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 6486a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6487a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6488a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Tests after compile event is sent when there are some provisional 6489a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// breakpoints out of the scripts lines range. 6490a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(ProvisionalBreakpointOnLineOutOfRange) { 6491a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DebugLocalContext env; 6492b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(env->GetIsolate()); 6493a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block env.ExposeDebug(); 6494a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const char* script = "function f() {};"; 6495a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const char* resource_name = "test_resource"; 6496a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6497a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Set a couple of provisional breakpoint on lines out of the script lines 6498a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // range. 6499b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int sbp1 = SetScriptBreakPointByNameFromJS(env->GetIsolate(), resource_name, 6500b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3, -1 /* no column */); 6501b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int sbp2 = 6502b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SetScriptBreakPointByNameFromJS(env->GetIsolate(), resource_name, 5, 5); 6503a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6504a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block after_compile_message_count = 0; 6505b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Debug::SetMessageHandler(AfterCompileMessageHandler); 6506a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6507a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::ScriptOrigin origin( 6508b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::String::NewFromUtf8(env->GetIsolate(), resource_name), 6509b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Integer::New(env->GetIsolate(), 10), 6510b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Integer::New(env->GetIsolate(), 1)); 6511a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Compile a script whose first line number is greater than the breakpoints' 6512a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // lines. 6513b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Script::Compile(v8::String::NewFromUtf8(env->GetIsolate(), script), 6514b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch &origin)->Run(); 6515a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6516a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // If the script is compiled successfully there is exactly one after compile 6517a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // event. In case of an exception in debugger code after compile event is not 6518a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // sent. 6519a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1, after_compile_message_count); 6520a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6521b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ClearBreakPointFromJS(env->GetIsolate(), sbp1); 6522b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ClearBreakPointFromJS(env->GetIsolate(), sbp2); 6523b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Debug::SetMessageHandler(NULL); 6524a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 6525a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6526a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6527a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic void BreakMessageHandler(const v8::Debug::Message& message) { 6528b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch i::Isolate* isolate = CcTest::i_isolate(); 6529a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (message.IsEvent() && message.GetEvent() == v8::Break) { 6530a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Count the number of breaks. 6531a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break_point_hit_count++; 6532a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6533b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch i::HandleScope scope(isolate); 65343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch message.GetJSON(); 6535a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6536a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block SendContinueCommand(); 6537a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else if (message.IsEvent() && message.GetEvent() == v8::AfterCompile) { 6538b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch i::HandleScope scope(isolate); 6539a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6540b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int current_count = break_point_hit_count; 6541a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6542a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Force serialization to trigger some internal JS execution. 65433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch message.GetJSON(); 6544a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6545b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(current_count, break_point_hit_count); 6546a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 6547a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 6548a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6549a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6550a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Test that if DebugBreak is forced it is ignored when code from 6551a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// debug-delay.js is executed. 6552a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(NoDebugBreakInAfterCompileMessageHandler) { 6553a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DebugLocalContext env; 6554b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(env->GetIsolate()); 6555a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6556a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Register a debug event listener which sets the break flag and counts. 6557b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Debug::SetMessageHandler(BreakMessageHandler); 6558a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6559a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Set the debug break flag. 6560b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Debug::DebugBreak(env->GetIsolate()); 6561a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6562a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Create a function for testing stepping. 6563a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const char* src = "function f() { eval('var x = 10;'); } "; 6564a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Local<v8::Function> f = CompileFunction(&env, src, "f"); 6565a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6566a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // There should be only one break event. 6567a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1, break_point_hit_count); 6568a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6569a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Set the debug break flag again. 6570b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Debug::DebugBreak(env->GetIsolate()); 6571a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block f->Call(env->Global(), 0, NULL); 6572a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // There should be one more break event when the script is evaluated in 'f'. 6573a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(2, break_point_hit_count); 6574a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6575a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Get rid of the debug message handler. 6576b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Debug::SetMessageHandler(NULL); 6577a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CheckDebuggerUnloaded(); 6578a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 6579a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6580a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6581e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarkestatic int counting_message_handler_counter; 6582e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 6583e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarkestatic void CountingMessageHandler(const v8::Debug::Message& message) { 6584b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (message.IsResponse()) counting_message_handler_counter++; 6585e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke} 6586e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 6587b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6588e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke// Test that debug messages get processed when ProcessDebugMessages is called. 6589e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon ClarkeTEST(ProcessDebugMessages) { 6590e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke DebugLocalContext env; 6591b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Isolate* isolate = env->GetIsolate(); 6592b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(isolate); 6593e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 6594e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke counting_message_handler_counter = 0; 6595e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 6596b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Debug::SetMessageHandler(CountingMessageHandler); 6597e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 6598e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke const int kBufferSize = 1000; 6599e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke uint16_t buffer[kBufferSize]; 6600e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke const char* scripts_command = 6601e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke "{\"seq\":0," 6602e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke "\"type\":\"request\"," 6603e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke "\"command\":\"scripts\"}"; 6604e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 6605e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // Send scripts command. 6606b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Debug::SendCommand( 6607b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate, buffer, AsciiToUtf16(scripts_command, buffer)); 6608e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 6609e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke CHECK_EQ(0, counting_message_handler_counter); 6610e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke v8::Debug::ProcessDebugMessages(); 6611e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // At least one message should come 6612e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke CHECK_GE(counting_message_handler_counter, 1); 6613e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 6614e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke counting_message_handler_counter = 0; 6615e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 6616b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Debug::SendCommand( 6617b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate, buffer, AsciiToUtf16(scripts_command, buffer)); 6618b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Debug::SendCommand( 6619b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate, buffer, AsciiToUtf16(scripts_command, buffer)); 6620e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke CHECK_EQ(0, counting_message_handler_counter); 6621e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke v8::Debug::ProcessDebugMessages(); 6622e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // At least two messages should come 6623e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke CHECK_GE(counting_message_handler_counter, 2); 6624e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 6625e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // Get rid of the debug message handler. 6626b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Debug::SetMessageHandler(NULL); 6627b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CheckDebuggerUnloaded(); 6628b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 6629b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6630b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6631b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass SendCommandThread; 6632b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic SendCommandThread* send_command_thread_ = NULL; 6633b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6634b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6635b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass SendCommandThread : public v8::base::Thread { 6636b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public: 6637b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch explicit SendCommandThread(v8::Isolate* isolate) 6638b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : Thread(Options("SendCommandThread")), 6639b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch semaphore_(0), 6640b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate_(isolate) {} 6641b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6642b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static void CountingAndSignallingMessageHandler( 6643b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::Debug::Message& message) { 6644b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (message.IsResponse()) { 6645b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch counting_message_handler_counter++; 6646b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch send_command_thread_->semaphore_.Signal(); 6647b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6648b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6649b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6650b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch virtual void Run() { 6651b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch semaphore_.Wait(); 6652b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const int kBufferSize = 1000; 6653b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uint16_t buffer[kBufferSize]; 6654b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const char* scripts_command = 6655b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "{\"seq\":0," 6656b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "\"type\":\"request\"," 6657b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "\"command\":\"scripts\"}"; 6658b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int length = AsciiToUtf16(scripts_command, buffer); 6659b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Send scripts command. 6660b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6661b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < 20; i++) { 6662b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::base::ElapsedTimer timer; 6663b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch timer.Start(); 6664b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(i, counting_message_handler_counter); 6665b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Queue debug message. 6666b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Debug::SendCommand(isolate_, buffer, length); 6667b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Wait for the message handler to pick up the response. 6668b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch semaphore_.Wait(); 6669b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch i::PrintF("iteration %d took %f ms\n", i, 6670b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch timer.Elapsed().InMillisecondsF()); 6671b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6672b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6673b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::V8::TerminateExecution(isolate_); 6674b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6675b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6676b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void StartSending() { semaphore_.Signal(); } 6677b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6678b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private: 6679b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::base::Semaphore semaphore_; 6680b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Isolate* isolate_; 6681b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}; 6682b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6683b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6684b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic void StartSendingCommands( 6685b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::FunctionCallbackInfo<v8::Value>& info) { 6686b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch send_command_thread_->StartSending(); 6687b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 6688b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6689b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6690b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST(ProcessDebugMessagesThreaded) { 6691b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DebugLocalContext env; 6692b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Isolate* isolate = env->GetIsolate(); 6693b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(isolate); 6694b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6695b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch counting_message_handler_counter = 0; 6696b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6697b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Debug::SetMessageHandler( 6698b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SendCommandThread::CountingAndSignallingMessageHandler); 6699b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch send_command_thread_ = new SendCommandThread(isolate); 6700b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch send_command_thread_->Start(); 6701b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6702b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Handle<v8::FunctionTemplate> start = 6703b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::FunctionTemplate::New(isolate, StartSendingCommands); 6704b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch env->Global()->Set(v8_str("start"), start->GetFunction()); 6705b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6706b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CompileRun("start(); while (true) { }"); 6707b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6708b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(20, counting_message_handler_counter); 6709b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6710b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Debug::SetMessageHandler(NULL); 6711e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke CheckDebuggerUnloaded(); 6712e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke} 6713e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 6714e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 67156ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockstruct BacktraceData { 6716d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke static int frame_counter; 6717d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke static void MessageHandler(const v8::Debug::Message& message) { 6718d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke char print_buffer[1000]; 6719d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke v8::String::Value json(message.GetJSON()); 6720d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Utf16ToAscii(*json, json.length(), print_buffer, 1000); 6721d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 6722d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke if (strstr(print_buffer, "backtrace") == NULL) { 6723d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke return; 6724d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 6725d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke frame_counter = GetTotalFramesInt(print_buffer); 6726d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 6727d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke}; 6728d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 67296ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockint BacktraceData::frame_counter; 6730d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 6731d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 6732d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke// Test that debug messages get processed when ProcessDebugMessages is called. 6733d91b9f7d46489a9ee00f9cb415630299c76a502bLeon ClarkeTEST(Backtrace) { 6734d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke DebugLocalContext env; 6735b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Isolate* isolate = env->GetIsolate(); 6736b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(isolate); 6737d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 6738b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Debug::SetMessageHandler(BacktraceData::MessageHandler); 6739d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 6740d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke const int kBufferSize = 1000; 6741d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke uint16_t buffer[kBufferSize]; 6742d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke const char* scripts_command = 6743d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke "{\"seq\":0," 6744d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke "\"type\":\"request\"," 6745d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke "\"command\":\"backtrace\"}"; 6746d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 6747d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Check backtrace from ProcessDebugMessages. 67486ded16be15dd865a9b21ea304d5273c8be299c87Steve Block BacktraceData::frame_counter = -10; 6749b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Debug::SendCommand( 6750b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate, 6751b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch buffer, 6752b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AsciiToUtf16(scripts_command, buffer), 6753b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch NULL); 6754d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke v8::Debug::ProcessDebugMessages(); 67556ded16be15dd865a9b21ea304d5273c8be299c87Steve Block CHECK_EQ(BacktraceData::frame_counter, 0); 6756d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 6757b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Handle<v8::String> void0 = 6758b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::String::NewFromUtf8(env->GetIsolate(), "void(0)"); 6759b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Handle<v8::Script> script = CompileWithOrigin(void0, void0); 6760d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 6761d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Check backtrace from "void(0)" script. 67626ded16be15dd865a9b21ea304d5273c8be299c87Steve Block BacktraceData::frame_counter = -10; 6763b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Debug::SendCommand( 6764b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate, 6765b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch buffer, 6766b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AsciiToUtf16(scripts_command, buffer), 6767b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch NULL); 6768d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke script->Run(); 67696ded16be15dd865a9b21ea304d5273c8be299c87Steve Block CHECK_EQ(BacktraceData::frame_counter, 1); 6770d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 6771d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Get rid of the debug message handler. 6772b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Debug::SetMessageHandler(NULL); 6773d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke CheckDebuggerUnloaded(); 6774d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 6775d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 6776d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 6777a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(GetMirror) { 6778a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DebugLocalContext env; 6779b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Isolate* isolate = env->GetIsolate(); 6780b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(isolate); 6781b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Handle<v8::Value> obj = 6782b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Debug::GetMirror(v8::String::NewFromUtf8(isolate, "hodja")); 6783b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::ScriptCompiler::Source source(v8_str( 6784b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "function runTest(mirror) {" 6785b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch " return mirror.isString() && (mirror.length() == 5);" 6786b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "}" 6787b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "" 6788b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "runTest;")); 6789a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<v8::Function> run_test = v8::Handle<v8::Function>::Cast( 6790b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::ScriptCompiler::CompileUnbound(isolate, &source) 6791b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ->BindToCurrentContext() 6792b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ->Run()); 6793a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<v8::Value> result = run_test->Call(env->Global(), 1, &obj); 6794a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(result->IsTrue()); 6795a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 6796d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 6797d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 6798d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block// Test that the debug break flag works with function.apply. 6799d0582a6c46733687d045e4188a1bcd0123c758a1Steve BlockTEST(DebugBreakFunctionApply) { 6800d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block DebugLocalContext env; 6801b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(env->GetIsolate()); 6802d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 6803d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // Create a function for testing breaking in apply. 6804d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block v8::Local<v8::Function> foo = CompileFunction( 6805d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block &env, 6806d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block "function baz(x) { }" 6807d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block "function bar(x) { baz(); }" 6808d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block "function foo(){ bar.apply(this, [1]); }", 6809d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block "foo"); 6810d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 6811d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // Register a debug event listener which steps and counts. 6812d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block v8::Debug::SetDebugEventListener(DebugEventBreakMax); 6813d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 6814d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // Set the debug break flag before calling the code using function.apply. 6815b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Debug::DebugBreak(env->GetIsolate()); 6816d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 6817d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // Limit the number of debug breaks. This is a regression test for issue 493 6818d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // where this test would enter an infinite loop. 6819d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block break_point_hit_count = 0; 6820d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block max_break_point_hit_count = 10000; // 10000 => infinite loop. 6821d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block foo->Call(env->Global(), 0, NULL); 6822d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 6823d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // When keeping the debug break several break will happen. 68243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CHECK_GT(break_point_hit_count, 1); 6825d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 6826d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block v8::Debug::SetDebugEventListener(NULL); 6827d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block CheckDebuggerUnloaded(); 6828d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block} 6829d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 6830d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 6831d0582a6c46733687d045e4188a1bcd0123c758a1Steve Blockv8::Handle<v8::Context> debugee_context; 6832d0582a6c46733687d045e4188a1bcd0123c758a1Steve Blockv8::Handle<v8::Context> debugger_context; 6833d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 6834d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 6835d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block// Property getter that checks that current and calling contexts 6836d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block// are both the debugee contexts. 6837b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic void NamedGetterWithCallingContextCheck( 6838d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block v8::Local<v8::String> name, 6839b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::PropertyCallbackInfo<v8::Value>& info) { 6840b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(0, strcmp(*v8::String::Utf8Value(name), "a")); 6841b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Handle<v8::Context> current = info.GetIsolate()->GetCurrentContext(); 6842d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block CHECK(current == debugee_context); 6843d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block CHECK(current != debugger_context); 6844b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Handle<v8::Context> calling = info.GetIsolate()->GetCallingContext(); 6845d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block CHECK(calling == debugee_context); 6846d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block CHECK(calling != debugger_context); 6847b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch info.GetReturnValue().Set(1); 6848d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block} 6849d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 6850d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 6851d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block// Debug event listener that checks if the first argument of a function is 6852d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block// an object with property 'a' == 1. If the property has custom accessor 6853d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block// this handler will eventually invoke it. 6854d0582a6c46733687d045e4188a1bcd0123c758a1Steve Blockstatic void DebugEventGetAtgumentPropertyValue( 6855b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::Debug::EventDetails& event_details) { 6856b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::DebugEvent event = event_details.GetEvent(); 6857b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Handle<v8::Object> exec_state = event_details.GetExecutionState(); 6858d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block if (event == v8::Break) { 6859d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block break_point_hit_count++; 6860b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK(debugger_context == CcTest::isolate()->GetCurrentContext()); 6861b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Handle<v8::Function> func = v8::Handle<v8::Function>::Cast(CompileRun( 6862d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block "(function(exec_state) {\n" 6863d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block " return (exec_state.frame(0).argumentValue(0).property('a').\n" 6864d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block " value().value() == 1);\n" 6865b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "})")); 6866d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block const int argc = 1; 6867d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block v8::Handle<v8::Value> argv[argc] = { exec_state }; 6868d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block v8::Handle<v8::Value> result = func->Call(exec_state, argc, argv); 6869d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block CHECK(result->IsTrue()); 6870d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block } 6871d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block} 6872d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 6873d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 6874d0582a6c46733687d045e4188a1bcd0123c758a1Steve BlockTEST(CallingContextIsNotDebugContext) { 6875b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::internal::Debug* debug = CcTest::i_isolate()->debug(); 6876d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // Create and enter a debugee context. 6877d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block DebugLocalContext env; 6878b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Isolate* isolate = env->GetIsolate(); 6879b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(isolate); 6880d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block env.ExposeDebug(); 6881d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 6882d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // Save handles to the debugger and debugee contexts to be used in 6883d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // NamedGetterWithCallingContextCheck. 6884b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch debugee_context = env.context(); 688544f0eee88ff00398ff7f715fab053374d808c90dSteve Block debugger_context = v8::Utils::ToLocal(debug->debug_context()); 6886d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 6887d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // Create object with 'a' property accessor. 6888b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Handle<v8::ObjectTemplate> named = v8::ObjectTemplate::New(isolate); 6889b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch named->SetAccessor(v8::String::NewFromUtf8(isolate, "a"), 6890d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block NamedGetterWithCallingContextCheck); 6891b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch env->Global()->Set(v8::String::NewFromUtf8(isolate, "obj"), 6892d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block named->NewInstance()); 6893d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 6894d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // Register the debug event listener 6895d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block v8::Debug::SetDebugEventListener(DebugEventGetAtgumentPropertyValue); 6896d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 6897d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // Create a function that invokes debugger. 6898d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block v8::Local<v8::Function> foo = CompileFunction( 6899d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block &env, 6900d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block "function bar(x) { debugger; }" 6901d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block "function foo(){ bar(obj); }", 6902d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block "foo"); 6903d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 6904d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block break_point_hit_count = 0; 6905d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block foo->Call(env->Global(), 0, NULL); 6906d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block CHECK_EQ(1, break_point_hit_count); 6907d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 6908d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block v8::Debug::SetDebugEventListener(NULL); 6909d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block debugee_context = v8::Handle<v8::Context>(); 6910d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block debugger_context = v8::Handle<v8::Context>(); 6911d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block CheckDebuggerUnloaded(); 6912d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block} 69136ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 69146ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 69156ded16be15dd865a9b21ea304d5273c8be299c87Steve BlockTEST(DebugContextIsPreservedBetweenAccesses) { 6916b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(CcTest::isolate()); 6917b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount); 69186ded16be15dd865a9b21ea304d5273c8be299c87Steve Block v8::Local<v8::Context> context1 = v8::Debug::GetDebugContext(); 69196ded16be15dd865a9b21ea304d5273c8be299c87Steve Block v8::Local<v8::Context> context2 = v8::Debug::GetDebugContext(); 6920b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK(v8::Utils::OpenHandle(*context1).is_identical_to( 6921b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Utils::OpenHandle(*context2))); 6922b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Debug::SetDebugEventListener(NULL); 6923f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke} 6924f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 6925f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 6926f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarkestatic v8::Handle<v8::Value> expected_callback_data; 6927f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarkestatic void DebugEventContextChecker(const v8::Debug::EventDetails& details) { 6928f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke CHECK(details.GetEventContext() == expected_context); 6929f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke CHECK_EQ(expected_callback_data, details.GetCallbackData()); 6930f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke} 6931f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 6932b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 6933f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke// Check that event details contain context where debug event occured. 6934f7060e27768c550ace7ec48ad8c093466db52dfaLeon ClarkeTEST(DebugEventContext) { 6935b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Isolate* isolate = CcTest::isolate(); 6936b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(isolate); 6937b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch expected_context = v8::Context::New(isolate); 6938b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch expected_callback_data = v8::Int32::New(isolate, 2010); 6939b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Debug::SetDebugEventListener(DebugEventContextChecker, 6940f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke expected_callback_data); 6941f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke v8::Context::Scope context_scope(expected_context); 6942b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Script::Compile( 6943b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::String::NewFromUtf8(isolate, "(function(){debugger;})();"))->Run(); 6944f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke expected_context.Clear(); 6945f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke v8::Debug::SetDebugEventListener(NULL); 6946f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke expected_context_data = v8::Handle<v8::Value>(); 69476ded16be15dd865a9b21ea304d5273c8be299c87Steve Block CheckDebuggerUnloaded(); 69486ded16be15dd865a9b21ea304d5273c8be299c87Steve Block} 6949f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 69503bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch 69513bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdochstatic void* expected_break_data; 69523bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdochstatic bool was_debug_break_called; 69533bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdochstatic bool was_debug_event_called; 69543bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdochstatic void DebugEventBreakDataChecker(const v8::Debug::EventDetails& details) { 69553bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch if (details.GetEvent() == v8::BreakForCommand) { 69563bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch CHECK_EQ(expected_break_data, details.GetClientData()); 69573bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch was_debug_event_called = true; 69583bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch } else if (details.GetEvent() == v8::Break) { 69593bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch was_debug_break_called = true; 69603bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch } 69613bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch} 69623bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch 6963b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 69643bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch// Check that event details contain context where debug event occured. 69653bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben MurdochTEST(DebugEventBreakData) { 69663bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch DebugLocalContext env; 6967b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Isolate* isolate = env->GetIsolate(); 6968b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(isolate); 6969b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Debug::SetDebugEventListener(DebugEventBreakDataChecker); 69703bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch 69713bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch TestClientData::constructor_call_counter = 0; 69723bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch TestClientData::destructor_call_counter = 0; 69733bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch 69743bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch expected_break_data = NULL; 69753bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch was_debug_event_called = false; 69763bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch was_debug_break_called = false; 6977b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Debug::DebugBreakForCommand(isolate, NULL); 6978b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Script::Compile(v8::String::NewFromUtf8(env->GetIsolate(), 6979b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "(function(x){return x;})(1);")) 6980b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ->Run(); 69813bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch CHECK(was_debug_event_called); 69823bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch CHECK(!was_debug_break_called); 69833bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch 69843bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch TestClientData* data1 = new TestClientData(); 69853bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch expected_break_data = data1; 69863bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch was_debug_event_called = false; 69873bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch was_debug_break_called = false; 6988b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Debug::DebugBreakForCommand(isolate, data1); 6989b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Script::Compile(v8::String::NewFromUtf8(env->GetIsolate(), 6990b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "(function(x){return x+1;})(1);")) 6991b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ->Run(); 69923bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch CHECK(was_debug_event_called); 69933bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch CHECK(!was_debug_break_called); 69943bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch 69953bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch expected_break_data = NULL; 69963bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch was_debug_event_called = false; 69973bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch was_debug_break_called = false; 6998b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Debug::DebugBreak(isolate); 6999b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Script::Compile(v8::String::NewFromUtf8(env->GetIsolate(), 7000b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "(function(x){return x+2;})(1);")) 7001b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ->Run(); 70023bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch CHECK(!was_debug_event_called); 70033bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch CHECK(was_debug_break_called); 70043bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch 70053bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch TestClientData* data2 = new TestClientData(); 70063bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch expected_break_data = data2; 70073bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch was_debug_event_called = false; 70083bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch was_debug_break_called = false; 7009b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Debug::DebugBreak(isolate); 7010b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Debug::DebugBreakForCommand(isolate, data2); 7011b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Script::Compile(v8::String::NewFromUtf8(env->GetIsolate(), 7012b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "(function(x){return x+3;})(1);")) 7013b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ->Run(); 70143bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch CHECK(was_debug_event_called); 70153bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch CHECK(was_debug_break_called); 70163bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch 70173bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch CHECK_EQ(2, TestClientData::constructor_call_counter); 70183bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch CHECK_EQ(TestClientData::constructor_call_counter, 70193bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch TestClientData::destructor_call_counter); 70203bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch 70213bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch v8::Debug::SetDebugEventListener(NULL); 70223bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch CheckDebuggerUnloaded(); 70233bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch} 70243bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch 7025b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochstatic bool debug_event_break_deoptimize_done = false; 7026b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 7027b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic void DebugEventBreakDeoptimize( 7028b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::Debug::EventDetails& event_details) { 7029b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::DebugEvent event = event_details.GetEvent(); 7030b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Handle<v8::Object> exec_state = event_details.GetExecutionState(); 7031b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (event == v8::Break) { 7032b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (!frame_function_name.IsEmpty()) { 7033b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Get the name of the function. 7034b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch const int argc = 2; 7035b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Handle<v8::Value> argv[argc] = { 7036b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch exec_state, v8::Integer::New(CcTest::isolate(), 0) 7037b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch }; 7038b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch v8::Handle<v8::Value> result = 7039b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch frame_function_name->Call(exec_state, argc, argv); 7040b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (!result->IsUndefined()) { 7041b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch char fn[80]; 7042b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CHECK(result->IsString()); 7043b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch v8::Handle<v8::String> function_name(result->ToString()); 7044b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch function_name->WriteUtf8(fn); 7045b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (strcmp(fn, "bar") == 0) { 7046b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch i::Deoptimizer::DeoptimizeAll(CcTest::i_isolate()); 7047b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch debug_event_break_deoptimize_done = true; 7048b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 7049b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 7050b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 7051b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 7052b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Debug::DebugBreak(CcTest::isolate()); 7053b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 7054b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 7055b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 7056b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 7057b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// Test deoptimization when execution is broken using the debug break stack 7058b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// check interrupt. 7059b0fe1620dcb4135ac3ab2d66ff93072373911299Ben MurdochTEST(DeoptimizeDuringDebugBreak) { 7060b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch DebugLocalContext env; 7061b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(env->GetIsolate()); 7062b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch env.ExposeDebug(); 7063b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 7064b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Create a function for checking the function when hitting a break point. 7065b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch frame_function_name = CompileFunction(&env, 7066b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch frame_function_name_source, 7067b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "frame_function_name"); 7068b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 7069b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 7070b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Set a debug event listener which will keep interrupting execution until 7071b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // debug break. When inside function bar it will deoptimize all functions. 7072b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // This tests lazy deoptimization bailout for the stack check, as the first 7073b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // time in function bar when using debug break and no break points will be at 7074b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // the initial stack check. 7075b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Debug::SetDebugEventListener(DebugEventBreakDeoptimize); 7076b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 7077b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Compile and run function bar which will optimize it for some flag settings. 7078b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Script::Compile(v8::String::NewFromUtf8( 7079b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch env->GetIsolate(), "function bar(){}; bar()"))->Run(); 7080b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 7081b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Set debug break and call bar again. 7082b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Debug::DebugBreak(env->GetIsolate()); 7083b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Script::Compile(v8::String::NewFromUtf8(env->GetIsolate(), "bar()")) 7084b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ->Run(); 7085b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 7086b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CHECK(debug_event_break_deoptimize_done); 7087b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 7088b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch v8::Debug::SetDebugEventListener(NULL); 7089b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 7090b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 7091b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 7092b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic void DebugEventBreakWithOptimizedStack( 7093b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::Debug::EventDetails& event_details) { 7094b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Isolate* isolate = event_details.GetEventContext()->GetIsolate(); 7095b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::DebugEvent event = event_details.GetEvent(); 7096b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Handle<v8::Object> exec_state = event_details.GetExecutionState(); 7097b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (event == v8::Break) { 7098b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (!frame_function_name.IsEmpty()) { 7099b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch for (int i = 0; i < 2; i++) { 7100b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch const int argc = 2; 7101b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Handle<v8::Value> argv[argc] = { 7102b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch exec_state, v8::Integer::New(isolate, i) 7103b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch }; 7104b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Get the name of the function in frame i. 7105b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch v8::Handle<v8::Value> result = 7106b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch frame_function_name->Call(exec_state, argc, argv); 7107b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CHECK(result->IsString()); 7108b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch v8::Handle<v8::String> function_name(result->ToString()); 7109b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK(function_name->Equals(v8::String::NewFromUtf8(isolate, "loop"))); 7110b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Get the name of the first argument in frame i. 7111b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch result = frame_argument_name->Call(exec_state, argc, argv); 7112b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CHECK(result->IsString()); 7113b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch v8::Handle<v8::String> argument_name(result->ToString()); 7114b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK(argument_name->Equals(v8::String::NewFromUtf8(isolate, "count"))); 7115b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Get the value of the first argument in frame i. If the 7116b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // funtion is optimized the value will be undefined, otherwise 7117b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // the value will be '1 - i'. 7118b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // 7119b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // TODO(3141533): We should be able to get the real value for 7120b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // optimized frames. 7121b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch result = frame_argument_value->Call(exec_state, argc, argv); 7122b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CHECK(result->IsUndefined() || (result->Int32Value() == 1 - i)); 7123b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Get the name of the first local variable. 7124b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch result = frame_local_name->Call(exec_state, argc, argv); 7125b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CHECK(result->IsString()); 7126b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch v8::Handle<v8::String> local_name(result->ToString()); 7127b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK(local_name->Equals(v8::String::NewFromUtf8(isolate, "local"))); 7128b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Get the value of the first local variable. If the function 7129b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // is optimized the value will be undefined, otherwise it will 7130b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // be 42. 7131b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // 7132b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // TODO(3141533): We should be able to get the real value for 7133b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // optimized frames. 7134b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch result = frame_local_value->Call(exec_state, argc, argv); 7135b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CHECK(result->IsUndefined() || (result->Int32Value() == 42)); 7136b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 7137b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 7138b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 7139b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 7140b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 7141b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 7142b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic void ScheduleBreak(const v8::FunctionCallbackInfo<v8::Value>& args) { 7143b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Debug::SetDebugEventListener(DebugEventBreakWithOptimizedStack); 7144b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Debug::DebugBreak(args.GetIsolate()); 7145b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 7146b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 7147b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 7148b0fe1620dcb4135ac3ab2d66ff93072373911299Ben MurdochTEST(DebugBreakStackInspection) { 7149b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch DebugLocalContext env; 7150b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(env->GetIsolate()); 7151b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 7152b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch frame_function_name = 7153b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CompileFunction(&env, frame_function_name_source, "frame_function_name"); 7154b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch frame_argument_name = 7155b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CompileFunction(&env, frame_argument_name_source, "frame_argument_name"); 7156b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch frame_argument_value = CompileFunction(&env, 7157b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch frame_argument_value_source, 7158b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "frame_argument_value"); 7159b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch frame_local_name = 7160b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CompileFunction(&env, frame_local_name_source, "frame_local_name"); 7161b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch frame_local_value = 7162b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CompileFunction(&env, frame_local_value_source, "frame_local_value"); 7163b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 7164b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch v8::Handle<v8::FunctionTemplate> schedule_break_template = 7165b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::FunctionTemplate::New(env->GetIsolate(), ScheduleBreak); 7166b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch v8::Handle<v8::Function> schedule_break = 7167b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch schedule_break_template->GetFunction(); 7168b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch env->Global()->Set(v8_str("scheduleBreak"), schedule_break); 7169b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 7170b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch const char* src = 7171b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "function loop(count) {" 7172b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch " var local = 42;" 7173b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch " if (count < 1) { scheduleBreak(); loop(count + 1); }" 7174b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "}" 7175b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch "loop(0);"; 7176b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Script::Compile(v8::String::NewFromUtf8(env->GetIsolate(), src))->Run(); 7177b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 7178b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 71793e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu 71803e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu// Test that setting the terminate execution flag during debug break processing. 71818a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wangstatic void TestDebugBreakInLoop(const char* loop_head, 71828a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang const char** loop_bodies, 71838a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang const char* loop_tail) { 71848a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang // Receive 100 breaks for each test and then terminate JavaScript execution. 71853fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch static const int kBreaksPerTest = 100; 71863fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 71873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch for (int i = 0; loop_bodies[i] != NULL; i++) { 71883fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Perform a lazy deoptimization after various numbers of breaks 71893fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // have been hit. 7190b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int j = 0; j < 7; j++) { 71913fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch break_point_hit_count_deoptimize = j; 7192b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (j == 6) { 71933fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch break_point_hit_count_deoptimize = kBreaksPerTest; 71943fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 71958a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang 71963fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch break_point_hit_count = 0; 71973fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch max_break_point_hit_count = kBreaksPerTest; 71983fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch terminate_after_max_break_point_hit = true; 71998a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang 72003fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch EmbeddedVector<char, 1024> buffer; 7201b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SNPrintF(buffer, 7202b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "function f() {%s%s%s}", 7203b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch loop_head, loop_bodies[i], loop_tail); 72048a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang 72053fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Function with infinite loop. 72063fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch CompileRun(buffer.start()); 72078a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang 72083fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Set the debug break to enter the debugger as soon as possible. 7209b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Debug::DebugBreak(CcTest::isolate()); 72108a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang 72113fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Call function with infinite loop. 72123fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch CompileRun("f();"); 72133fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch CHECK_EQ(kBreaksPerTest, break_point_hit_count); 72148a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang 72153fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch CHECK(!v8::V8::IsExecutionTerminating()); 72163fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 72178a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang } 72188a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang} 72198a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang 72208a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang 72213e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui ZhuTEST(DebugBreakLoop) { 72223e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu DebugLocalContext env; 7223b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(env->GetIsolate()); 72243e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu 72253e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu // Register a debug event listener which sets the break flag and counts. 72263e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu v8::Debug::SetDebugEventListener(DebugEventBreakMax); 72273e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu 72283fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Create a function for getting the frame count when hitting the break. 72293fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch frame_count = CompileFunction(&env, frame_count_source, "frame_count"); 72303fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 72318a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang CompileRun("var a = 1;"); 72328a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang CompileRun("function g() { }"); 72338a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang CompileRun("function h() { }"); 72348a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang 72358a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang const char* loop_bodies[] = { 72368a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang "", 72378a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang "g()", 72388a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang "if (a == 0) { g() }", 72398a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang "if (a == 1) { g() }", 72408a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang "if (a == 0) { g() } else { h() }", 72418a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang "if (a == 0) { continue }", 72428a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang "if (a == 1) { continue }", 72438a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang "switch (a) { case 1: g(); }", 72448a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang "switch (a) { case 1: continue; }", 72458a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang "switch (a) { case 1: g(); break; default: h() }", 72468a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang "switch (a) { case 1: continue; break; default: h() }", 72478a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang NULL 72488a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang }; 72498a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang 72508a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang TestDebugBreakInLoop("while (true) {", loop_bodies, "}"); 72518a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang TestDebugBreakInLoop("while (a == 1) {", loop_bodies, "}"); 72523e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu 72538a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang TestDebugBreakInLoop("do {", loop_bodies, "} while (true)"); 72548a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang TestDebugBreakInLoop("do {", loop_bodies, "} while (a == 1)"); 72553e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu 72568a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang TestDebugBreakInLoop("for (;;) {", loop_bodies, "}"); 72578a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang TestDebugBreakInLoop("for (;a == 1;) {", loop_bodies, "}"); 72583e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu 72593e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu // Get rid of the debug event listener. 72603e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu v8::Debug::SetDebugEventListener(NULL); 72613e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu CheckDebuggerUnloaded(); 72623e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu} 72633e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu 72643e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu 72653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochv8::Local<v8::Script> inline_script; 72663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 7267b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic void DebugBreakInlineListener( 7268b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::Debug::EventDetails& event_details) { 7269b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::DebugEvent event = event_details.GetEvent(); 72703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (event != v8::Break) return; 72713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 72723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int expected_frame_count = 4; 72733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int expected_line_number[] = {1, 4, 7, 12}; 72743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 72753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch i::Handle<i::Object> compiled_script = v8::Utils::OpenHandle(*inline_script); 72763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch i::Handle<i::Script> source_script = i::Handle<i::Script>(i::Script::cast( 72773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch i::JSFunction::cast(*compiled_script)->shared()->script())); 72783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 7279b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int break_id = CcTest::i_isolate()->debug()->break_id(); 72803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch char script[128]; 72813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch i::Vector<char> script_vector(script, sizeof(script)); 7282b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SNPrintF(script_vector, "%%GetFrameCount(%d)", break_id); 72833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch v8::Local<v8::Value> result = CompileRun(script); 72843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 72853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int frame_count = result->Int32Value(); 72863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CHECK_EQ(expected_frame_count, frame_count); 72873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 72883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch for (int i = 0; i < frame_count; i++) { 72893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // The 5. element in the returned array of GetFrameDetails contains the 72903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // source position of that frame. 7291b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SNPrintF(script_vector, "%%GetFrameDetails(%d, %d)[5]", break_id, i); 72923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch v8::Local<v8::Value> result = CompileRun(script); 72933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CHECK_EQ(expected_line_number[i], 7294b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch i::Script::GetLineNumber(source_script, result->Int32Value())); 72953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 72963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch v8::Debug::SetDebugEventListener(NULL); 7297b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::V8::TerminateExecution(CcTest::isolate()); 72983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 72993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 73003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 73013ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochTEST(DebugBreakInline) { 73023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch i::FLAG_allow_natives_syntax = true; 73033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DebugLocalContext env; 7304b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(env->GetIsolate()); 73053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch const char* source = 73063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch "function debug(b) { \n" 73073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch " if (b) debugger; \n" 73083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch "} \n" 73093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch "function f(b) { \n" 73103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch " debug(b) \n" 73113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch "}; \n" 73123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch "function g(b) { \n" 73133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch " f(b); \n" 73143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch "}; \n" 73153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch "g(false); \n" 73163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch "g(false); \n" 73173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch "%OptimizeFunctionOnNextCall(g); \n" 73183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch "g(true);"; 73193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch v8::Debug::SetDebugEventListener(DebugBreakInlineListener); 7320b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inline_script = 7321b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Script::Compile(v8::String::NewFromUtf8(env->GetIsolate(), source)); 73223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch inline_script->Run(); 73233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 73243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 73253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 7326b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic void DebugEventStepNext( 7327b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::Debug::EventDetails& event_details) { 7328b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::DebugEvent event = event_details.GetEvent(); 7329b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (event == v8::Break) { 7330b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PrepareStep(StepNext); 7331b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 7332b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 7333b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7334b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7335b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic void RunScriptInANewCFrame(const char* source) { 7336b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::TryCatch try_catch; 7337b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CompileRun(source); 7338b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK(try_catch.HasCaught()); 7339b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 7340b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7341b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7342b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST(Regress131642) { 7343b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Bug description: 7344b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // When doing StepNext through the first script, the debugger is not reset 7345b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // after exiting through exception. A flawed implementation enabling the 7346b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // debugger to step into Array.prototype.forEach breaks inside the callback 7347b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // for forEach in the second script under the assumption that we are in a 7348b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // recursive call. In an attempt to step out, we crawl the stack using the 7349b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // recorded frame pointer from the first script and fail when not finding it 7350b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // on the stack. 7351b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DebugLocalContext env; 7352b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(env->GetIsolate()); 7353b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Debug::SetDebugEventListener(DebugEventStepNext); 7354b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7355b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // We step through the first script. It exits through an exception. We run 7356b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // this inside a new frame to record a different FP than the second script 7357b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // would expect. 7358b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const char* script_1 = "debugger; throw new Error();"; 7359b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch RunScriptInANewCFrame(script_1); 7360b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7361b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The second script uses forEach. 7362b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const char* script_2 = "[0].forEach(function() { });"; 7363b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CompileRun(script_2); 7364b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7365b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Debug::SetDebugEventListener(NULL); 7366b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 7367b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7368b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7369b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Import from test-heap.cc 7370b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochint CountNativeContexts(); 7371b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7372b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7373b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic void NopListener(const v8::Debug::EventDetails& event_details) { 7374b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 7375b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7376b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7377b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST(DebuggerCreatesContextIffActive) { 7378b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DebugLocalContext env; 7379b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(env->GetIsolate()); 7380b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(1, CountNativeContexts()); 7381b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7382b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Debug::SetDebugEventListener(NULL); 7383b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CompileRun("debugger;"); 7384b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(1, CountNativeContexts()); 7385b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7386b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Debug::SetDebugEventListener(NopListener); 7387b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CompileRun("debugger;"); 7388b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(2, CountNativeContexts()); 7389b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7390b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Debug::SetDebugEventListener(NULL); 7391b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 7392b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7393b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7394b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST(LiveEditEnabled) { 7395b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::internal::FLAG_allow_natives_syntax = true; 7396b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LocalContext env; 7397b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(env->GetIsolate()); 7398b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Debug::SetLiveEditEnabled(env->GetIsolate(), true); 7399b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CompileRun("%LiveEditCompareStrings('', '')"); 7400b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 7401b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7402b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7403b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST(LiveEditDisabled) { 7404b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::internal::FLAG_allow_natives_syntax = true; 7405b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LocalContext env; 7406b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(env->GetIsolate()); 7407b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Debug::SetLiveEditEnabled(env->GetIsolate(), false); 7408b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CompileRun("%LiveEditCompareStrings('', '')"); 7409b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 7410b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7411b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7412b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST(PrecompiledFunction) { 7413b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Regression test for crbug.com/346207. If we have preparse data, parsing the 7414b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // function in the presence of the debugger (and breakpoints) should still 7415b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // succeed. The bug was that preparsing was done lazily and parsing was done 7416b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // eagerly, so, the symbol streams didn't match. 7417b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DebugLocalContext env; 7418b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(env->GetIsolate()); 7419b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch env.ExposeDebug(); 7420b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Debug::SetDebugEventListener(DebugBreakInlineListener); 7421b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7422b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Local<v8::Function> break_here = 7423b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CompileFunction(&env, "function break_here(){}", "break_here"); 7424b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SetBreakPoint(break_here, 0); 7425b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7426b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const char* source = 7427b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "var a = b = c = 1; \n" 7428b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "function this_is_lazy() { \n" 7429b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // This symbol won't appear in the preparse data. 7430b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch " var a; \n" 7431b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "} \n" 7432b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "function bar() { \n" 7433b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch " return \"bar\"; \n" 7434b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "}; \n" 7435b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "a = b = c = 2; \n" 7436b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "bar(); \n"; 7437b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Local<v8::Value> result = ParserCacheCompileRun(source); 7438b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK(result->IsString()); 7439b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::String::Utf8Value utf8(result); 7440b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ("bar", *utf8); 7441b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7442b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Debug::SetDebugEventListener(NULL); 7443b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CheckDebuggerUnloaded(); 7444b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 7445b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7446b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7447b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic void DebugBreakStackTraceListener( 7448b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::Debug::EventDetails& event_details) { 7449b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::StackTrace::CurrentStackTrace(CcTest::isolate(), 10); 7450b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 7451b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7452b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7453b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic void AddDebugBreak(const v8::FunctionCallbackInfo<v8::Value>& args) { 7454b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Debug::DebugBreak(args.GetIsolate()); 7455b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 7456b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7457b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7458b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST(DebugBreakStackTrace) { 7459b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DebugLocalContext env; 7460b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(env->GetIsolate()); 7461b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Debug::SetDebugEventListener(DebugBreakStackTraceListener); 7462b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Handle<v8::FunctionTemplate> add_debug_break_template = 7463b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::FunctionTemplate::New(env->GetIsolate(), AddDebugBreak); 7464b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Handle<v8::Function> add_debug_break = 7465b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch add_debug_break_template->GetFunction(); 7466b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch env->Global()->Set(v8_str("add_debug_break"), add_debug_break); 7467b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7468b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CompileRun("(function loop() {" 7469b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch " for (var j = 0; j < 1000; j++) {" 7470b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch " for (var i = 0; i < 1000; i++) {" 7471b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch " if (i == 999) add_debug_break();" 7472b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch " }" 7473b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch " }" 7474b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "})()"); 7475b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 7476b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7477b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7478b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochv8::base::Semaphore terminate_requested_semaphore(0); 7479b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochv8::base::Semaphore terminate_fired_semaphore(0); 7480b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool terminate_already_fired = false; 7481b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7482b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7483b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic void DebugBreakTriggerTerminate( 7484b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::Debug::EventDetails& event_details) { 7485b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (event_details.GetEvent() != v8::Break || terminate_already_fired) return; 7486b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch terminate_requested_semaphore.Signal(); 7487b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Wait for at most 2 seconds for the terminate request. 7488b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK(terminate_fired_semaphore.WaitFor(v8::base::TimeDelta::FromSeconds(2))); 7489b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch terminate_already_fired = true; 7490b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 7491b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7492b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7493b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass TerminationThread : public v8::base::Thread { 7494b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public: 7495b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch explicit TerminationThread(v8::Isolate* isolate) 7496b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : Thread(Options("terminator")), isolate_(isolate) {} 7497b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7498b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch virtual void Run() { 7499b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch terminate_requested_semaphore.Wait(); 7500b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::V8::TerminateExecution(isolate_); 7501b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch terminate_fired_semaphore.Signal(); 7502b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 7503b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7504b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private: 7505b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Isolate* isolate_; 7506b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}; 7507b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7508b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7509b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST(DebugBreakOffThreadTerminate) { 7510b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DebugLocalContext env; 7511b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Isolate* isolate = env->GetIsolate(); 7512b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(isolate); 7513b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Debug::SetDebugEventListener(DebugBreakTriggerTerminate); 7514b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TerminationThread terminator(isolate); 7515b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch terminator.Start(); 7516b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::TryCatch try_catch; 7517b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Debug::DebugBreak(isolate); 7518b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CompileRun("while (true);"); 7519b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK(try_catch.HasTerminated()); 7520b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 7521