Commit d131ecf3 authored by sgjesse@chromium.org's avatar sgjesse@chromium.org

Changed the debugger API to allow only one debug event listener to be...

Changed the debugger API to allow only one debug event listener to be registered. The public API now only has SetDebugEventListener instead of AddDebugEventListener and RemoveDebugEventListener.

Moved the registrered debug event listener from the context to a global handle in the Debugger class. Storing it in the context did not make much sense.

Changed a lot of tests to handle the API change.

BUG=1242707
Review URL: http://codereview.chromium.org/19753

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@1212 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 4bd3d3d1
......@@ -86,7 +86,7 @@ enum DebugEvent {
* (enum DebugEvent)
* \param exec_state execution state (JavaScript object)
* \param event_data event specific data (JavaScript object)
* \param data value passed by the user to AddDebugEventListener
* \param data value passed by the user to SetDebugEventListener
*/
typedef void (*DebugEventCallback)(DebugEvent event,
Handle<Object> exec_state,
......@@ -108,20 +108,14 @@ typedef void (*DebugMessageHandler)(const uint16_t* message, int length,
class EXPORT Debug {
public:
// Add a C debug event listener.
static bool AddDebugEventListener(DebugEventCallback that,
// Set a C debug event listener.
static bool SetDebugEventListener(DebugEventCallback that,
Handle<Value> data = Handle<Value>());
// Add a JavaScript debug event listener.
static bool AddDebugEventListener(v8::Handle<v8::Function> that,
// Set a JavaScript debug event listener.
static bool SetDebugEventListener(v8::Handle<v8::Object> that,
Handle<Value> data = Handle<Value>());
// Remove a C debug event listener.
static void RemoveDebugEventListener(DebugEventCallback that);
// Remove a JavaScript debug event listener.
static void RemoveDebugEventListener(v8::Handle<v8::Function> that);
// Break execution of JavaScript.
static void DebugBreak();
......
......@@ -2816,81 +2816,25 @@ Local<Value> Exception::Error(v8::Handle<v8::String> raw_message) {
// --- D e b u g S u p p o r t ---
bool Debug::AddDebugEventListener(DebugEventCallback that, Handle<Value> data) {
EnsureInitialized("v8::Debug::AddDebugEventListener()");
ON_BAILOUT("v8::Debug::AddDebugEventListener()", return false);
bool Debug::SetDebugEventListener(DebugEventCallback that, Handle<Value> data) {
EnsureInitialized("v8::Debug::SetDebugEventListener()");
ON_BAILOUT("v8::Debug::SetDebugEventListener()", return false);
HandleScope scope;
NeanderArray listeners(i::Factory::debug_event_listeners());
NeanderObject obj(2);
obj.set(0, *i::Factory::NewProxy(FUNCTION_ADDR(that)));
obj.set(1, data.IsEmpty() ?
i::Heap::undefined_value() :
*Utils::OpenHandle(*data));
listeners.add(obj.value());
i::Debugger::UpdateActiveDebugger();
i::Debugger::SetEventListener(i::Factory::NewProxy(FUNCTION_ADDR(that)),
Utils::OpenHandle(*data));
return true;
}
bool Debug::AddDebugEventListener(v8::Handle<v8::Function> that,
bool Debug::SetDebugEventListener(v8::Handle<v8::Object> that,
Handle<Value> data) {
ON_BAILOUT("v8::Debug::AddDebugEventListener()", return false);
HandleScope scope;
NeanderArray listeners(i::Factory::debug_event_listeners());
NeanderObject obj(2);
obj.set(0, *Utils::OpenHandle(*that));
obj.set(1, data.IsEmpty() ?
i::Heap::undefined_value() :
*Utils::OpenHandle(*data));
listeners.add(obj.value());
i::Debugger::UpdateActiveDebugger();
ON_BAILOUT("v8::Debug::SetDebugEventListener()", return false);
i::Debugger::SetEventListener(Utils::OpenHandle(*that),
Utils::OpenHandle(*data));
return true;
}
void Debug::RemoveDebugEventListener(DebugEventCallback that) {
EnsureInitialized("v8::Debug::RemoveDebugEventListener()");
ON_BAILOUT("v8::Debug::RemoveDebugEventListener()", return);
HandleScope scope;
NeanderArray listeners(i::Factory::debug_event_listeners());
for (int i = 0; i < listeners.length(); i++) {
if (listeners.get(i)->IsUndefined()) continue; // skip deleted ones
NeanderObject listener(i::JSObject::cast(listeners.get(i)));
// When removing a C debug event listener only consider proxy objects.
if (listener.get(0)->IsProxy()) {
i::Handle<i::Proxy> callback_obj(i::Proxy::cast(listener.get(0)));
if (callback_obj->proxy() == FUNCTION_ADDR(that)) {
listeners.set(i, i::Heap::undefined_value());
}
}
}
i::Debugger::UpdateActiveDebugger();
}
void Debug::RemoveDebugEventListener(v8::Handle<v8::Function> that) {
ON_BAILOUT("v8::Debug::RemoveDebugEventListener()", return);
HandleScope scope;
NeanderArray listeners(i::Factory::debug_event_listeners());
for (int i = 0; i < listeners.length(); i++) {
if (listeners.get(i)->IsUndefined()) continue; // skip deleted ones
NeanderObject listener(i::JSObject::cast(listeners.get(i)));
// When removing a JavaScript debug event listener only consider JavaScript
// function objects.
if (listener.get(0)->IsJSFunction()) {
i::JSFunction* callback = i::JSFunction::cast(listener.get(0));
i::Handle<i::JSFunction> callback_fun(callback);
if (callback_fun.is_identical_to(Utils::OpenHandle(*that))) {
listeners.set(i, i::Heap::undefined_value());
}
}
}
i::Debugger::UpdateActiveDebugger();
}
void Debug::DebugBreak() {
if (!i::V8::HasBeenSetup()) return;
i::StackGuard::DebugBreak();
......
......@@ -472,10 +472,6 @@ void Genesis::CreateRoots(v8::Handle<v8::ObjectTemplate> global_template,
v8::NeanderArray listeners;
global_context()->set_message_listeners(*listeners.value());
// Allocate the debug event listeners object.
v8::NeanderArray debug_event_listeners;
global_context()->set_debug_event_listeners(*debug_event_listeners.value());
// Allocate the map for function instances.
Handle<Map> fm = Factory::NewMap(JS_FUNCTION_TYPE, JSFunction::kSize);
global_context()->set_function_instance_map(*fm);
......
......@@ -83,7 +83,6 @@ enum ContextLookupFlags {
V(SPECIAL_FUNCTION_TABLE_INDEX, FixedArray, special_function_table) \
V(ARGUMENTS_BOILERPLATE_INDEX, JSObject, arguments_boilerplate) \
V(MESSAGE_LISTENERS_INDEX, JSObject, message_listeners) \
V(DEBUG_EVENT_LISTENERS_INDEX, JSObject, debug_event_listeners) \
V(MAKE_MESSAGE_FUN_INDEX, JSFunction, make_message_fun) \
V(GET_STACK_TRACE_LINE_INDEX, JSFunction, get_stack_trace_line_fun) \
V(CONFIGURE_GLOBAL_INDEX, JSFunction, configure_global_fun) \
......@@ -201,7 +200,6 @@ class Context: public FixedArray {
CONFIGURE_INSTANCE_FUN_INDEX,
SPECIAL_FUNCTION_TABLE_INDEX,
MESSAGE_LISTENERS_INDEX,
DEBUG_EVENT_LISTENERS_INDEX,
MAKE_MESSAGE_FUN_INDEX,
GET_STACK_TRACE_LINE_INDEX,
CONFIGURE_GLOBAL_INDEX,
......
......@@ -542,7 +542,7 @@ int Shell::Main(int argc, char* argv[]) {
}
}
if (i::FLAG_debugger)
v8::Debug::AddDebugEventListener(HandleDebugEvent);
v8::Debug::SetDebugEventListener(HandleDebugEvent);
}
if (run_shell)
RunShell();
......
......@@ -363,15 +363,13 @@ function UpdateScriptBreakPoints(script) {
}
Debug.addListener = function(listener, opt_data) {
if (!IS_FUNCTION(listener)) throw new Error('Parameters have wrong types.');
%AddDebugEventListener(listener, opt_data);
Debug.setListener = function(listener, opt_data) {
if (!IS_FUNCTION(listener) && !IS_UNDEFINED(listener) && !IS_NULL(listener)) {
throw new Error('Parameters have wrong types.');
}
%SetDebugEventListener(listener, opt_data);
};
Debug.removeListener = function(listener) {
if (!IS_FUNCTION(listener)) throw new Error('Parameters have wrong types.');
%RemoveDebugEventListener(listener);
};
Debug.breakExecution = function(f) {
%Break();
......
......@@ -609,10 +609,8 @@ void Debug::Unload() {
void Debug::Iterate(ObjectVisitor* v) {
#define VISIT(field) v->VisitPointer(bit_cast<Object**, Code**>(&(field)));
VISIT(debug_break_return_entry_);
VISIT(debug_break_return_);
#undef VISIT
v->VisitPointer(bit_cast<Object**, Code**>(&(debug_break_return_entry_)));
v->VisitPointer(bit_cast<Object**, Code**>(&(debug_break_return_)));
}
......@@ -1319,6 +1317,8 @@ void Debug::ClearMirrorCache() {
}
Handle<Object> Debugger::event_listener_ = Handle<Object>();
Handle<Object> Debugger::event_listener_data_ = Handle<Object>();
bool Debugger::debugger_active_ = false;
bool Debugger::compiling_natives_ = false;
bool Debugger::is_loading_debugger_ = false;
......@@ -1609,34 +1609,29 @@ void Debugger::ProcessDebugEvent(v8::DebugEvent event,
if (message_thread_ != NULL) {
message_thread_->DebugEvent(event, exec_state, event_data);
}
// Notify registered debug event listeners. The list can contain both C and
// JavaScript functions.
v8::NeanderArray listeners(Factory::debug_event_listeners());
int length = listeners.length();
for (int i = 0; i < length; i++) {
if (listeners.get(i)->IsUndefined()) continue; // Skip deleted ones.
v8::NeanderObject listener(JSObject::cast(listeners.get(i)));
Handle<Object> callback_data(listener.get(1));
if (listener.get(0)->IsProxy()) {
// Notify registered debug event listener. This can be either a C or a
// JavaScript function.
if (!event_listener_.is_null()) {
if (event_listener_->IsProxy()) {
// C debug event listener.
Handle<Proxy> callback_obj(Proxy::cast(listener.get(0)));
Handle<Proxy> callback_obj(Handle<Proxy>::cast(event_listener_));
v8::DebugEventCallback callback =
FUNCTION_CAST<v8::DebugEventCallback>(callback_obj->proxy());
callback(event,
v8::Utils::ToLocal(Handle<JSObject>::cast(exec_state)),
v8::Utils::ToLocal(Handle<JSObject>::cast(event_data)),
v8::Utils::ToLocal(callback_data));
v8::Utils::ToLocal(Handle<Object>::cast(event_listener_data_)));
} else {
// JavaScript debug event listener.
ASSERT(listener.get(0)->IsJSFunction());
Handle<JSFunction> fun(JSFunction::cast(listener.get(0)));
ASSERT(event_listener_->IsJSFunction());
Handle<JSFunction> fun(Handle<JSFunction>::cast(event_listener_));
// Invoke the JavaScript debug event listener.
const int argc = 4;
Object** argv[argc] = { Handle<Object>(Smi::FromInt(event)).location(),
exec_state.location(),
event_data.location(),
callback_data.location() };
event_listener_data_.location() };
Handle<Object> result = Execution::TryCall(fun, Top::global(),
argc, argv, &caught_exception);
if (caught_exception) {
......@@ -1650,11 +1645,42 @@ void Debugger::ProcessDebugEvent(v8::DebugEvent event,
}
void Debugger::SetEventListener(Handle<Object> callback,
Handle<Object> data) {
HandleScope scope;
// Clear the global handles for the event listener and the event listener data
// object.
if (!event_listener_.is_null()) {
GlobalHandles::Destroy(
reinterpret_cast<Object**>(event_listener_.location()));
event_listener_ = Handle<Object>();
}
if (!event_listener_data_.is_null()) {
GlobalHandles::Destroy(
reinterpret_cast<Object**>(event_listener_data_.location()));
event_listener_data_ = Handle<Object>();
}
// If there is a new debug event listener register it together with its data
// object.
if (!callback->IsUndefined() && !callback->IsNull()) {
event_listener_ = Handle<Object>::cast(GlobalHandles::Create(*callback));
if (data.is_null()) {
data = Factory::undefined_value();
}
event_listener_data_ = Handle<Object>::cast(GlobalHandles::Create(*data));
}
UpdateActiveDebugger();
}
void Debugger::SetMessageHandler(v8::DebugMessageHandler handler, void* data) {
debug_message_handler_ = handler;
debug_message_handler_data_ = data;
if (!message_thread_) {
message_thread_ = new DebugMessageThread();
message_thread_ = new DebugMessageThread();
message_thread_->Start();
}
UpdateActiveDebugger();
......@@ -1683,17 +1709,12 @@ void Debugger::ProcessCommand(Vector<const uint16_t> command) {
void Debugger::UpdateActiveDebugger() {
v8::NeanderArray listeners(Factory::debug_event_listeners());
int length = listeners.length();
bool active_listener = false;
for (int i = 0; i < length && !active_listener; i++) {
active_listener = !listeners.get(i)->IsUndefined();
}
set_debugger_active((Debugger::message_thread_ != NULL &&
Debugger::debug_message_handler_ != NULL) ||
active_listener);
if (!debugger_active() && message_thread_)
set_debugger_active((message_thread_ != NULL &&
debug_message_handler_ != NULL) ||
!event_listener_.is_null());
if (!debugger_active() && message_thread_) {
message_thread_->OnDebuggerInactive();
}
}
......
......@@ -372,6 +372,7 @@ class Debugger {
static void OnNewFunction(Handle<JSFunction> fun);
static void ProcessDebugEvent(v8::DebugEvent event,
Handle<Object> event_data);
static void SetEventListener(Handle<Object> callback, Handle<Object> data);
static void SetMessageHandler(v8::DebugMessageHandler handler, void* data);
static void SendMessage(Vector<uint16_t> message);
static void ProcessCommand(Vector<const uint16_t> command);
......@@ -397,6 +398,8 @@ class Debugger {
static bool is_loading_debugger() { return Debugger::is_loading_debugger_; }
private:
static Handle<Object> event_listener_; // Global handle to listener
static Handle<Object> event_listener_data_;
static bool debugger_active_; // Are there any active debugger?
static bool compiling_natives_; // Are we compiling natives?
static bool is_loading_debugger_; // Are we loading the debugger?
......
......@@ -1089,14 +1089,6 @@ bool Heap::CreateApiObjects() {
JSObject::cast(obj)->set_elements(FixedArray::cast(elements));
message_listeners_ = JSObject::cast(obj);
obj = Heap::AllocateJSObjectFromMap(neander_map_);
if (obj->IsFailure()) return false;
elements = AllocateFixedArray(2);
if (elements->IsFailure()) return false;
FixedArray::cast(elements)->set(0, Smi::FromInt(0));
JSObject::cast(obj)->set_elements(FixedArray::cast(elements));
debug_event_listeners_ = JSObject::cast(obj);
return true;
}
......
......@@ -114,7 +114,6 @@ namespace v8 { namespace internal {
V(Map, neander_map) \
V(JSObject, message_listeners) \
V(Proxy, prototype_accessors) \
V(JSObject, debug_event_listeners) \
V(Dictionary, code_stubs) \
V(Dictionary, non_monomorphic_cache) \
V(Code, js_entry_code) \
......
......@@ -4557,30 +4557,17 @@ static StackFrame::Id UnwrapFrameId(Smi* wrapped) {
// Adds a JavaScript function as a debug event listener.
// args[0]: debug event listener function
// args[0]: debug event listener function to set or null or undefined for
// clearing the event listener function
// args[1]: object supplied during callback
static Object* Runtime_AddDebugEventListener(Arguments args) {
static Object* Runtime_SetDebugEventListener(Arguments args) {
ASSERT(args.length() == 2);
// Convert the parameters to API objects to call the API function for adding
// a JavaScript function as debug event listener.
CONVERT_ARG_CHECKED(JSFunction, raw_fun, 0);
v8::Handle<v8::Function> fun(ToApi<v8::Function>(raw_fun));
v8::Handle<v8::Value> data(ToApi<v8::Value>(args.at<Object>(0)));
v8::Debug::AddDebugEventListener(fun, data);
return Heap::undefined_value();
}
// Removes a JavaScript function debug event listener.
// args[0]: debug event listener function
static Object* Runtime_RemoveDebugEventListener(Arguments args) {
ASSERT(args.length() == 1);
// Convert the parameter to an API object to call the API function for
// removing a JavaScript function debug event listener.
CONVERT_ARG_CHECKED(JSFunction, raw_fun, 0);
v8::Handle<v8::Function> fun(ToApi<v8::Function>(raw_fun));
v8::Debug::RemoveDebugEventListener(fun);
RUNTIME_ASSERT(args[0]->IsJSFunction() ||
args[0]->IsUndefined() ||
args[0]->IsNull());
Handle<Object> callback = args.at<Object>(0);
Handle<Object> data = args.at<Object>(1);
Debugger::SetEventListener(callback, data);
return Heap::undefined_value();
}
......
......@@ -213,8 +213,7 @@ namespace v8 { namespace internal {
F(LookupAccessor, 3) \
\
/* Debugging */ \
F(AddDebugEventListener, 2) \
F(RemoveDebugEventListener, 1) \
F(SetDebugEventListener, 2) \
F(Break, 0) \
F(DebugGetPropertyDetails, 2) \
F(DebugGetProperty, 2) \
......
......@@ -102,7 +102,7 @@ function listener(event, exec_state, event_data, data) {
};
// Add the debug event listener.
Debug.addListener(listener);
Debug.setListener(listener);
// Set a break point and call to invoke the debug event listener.
a[2](p1, p2)
......
......@@ -215,7 +215,7 @@ function listener(event, exec_state, event_data, data) {
};
// Add the debug event listener.
Debug.addListener(listener);
Debug.setListener(listener);
// Set a break point and call to invoke the debug event listener.
Debug.setBreakPoint(f, 0, 0);
......
......@@ -94,7 +94,7 @@ function listener(event, exec_state, event_data, data) {
};
// Add the debug event listener.
Debug.addListener(listener);
Debug.setListener(listener);
function g() {};
......
......@@ -87,7 +87,7 @@ function listener(event, exec_state, event_data, data) {
};
// Add the debug event listener.
Debug.addListener(listener);
Debug.setListener(listener);
function g() {};
......
......@@ -39,7 +39,7 @@ function listener(event, exec_state, event_data, data) {
};
// Add the debug event listener.
Debug.addListener(listener);
Debug.setListener(listener);
// Test functions.
count = 0;
......
......@@ -40,7 +40,7 @@ function listener(event, exec_state, event_data, data) {
};
// Add the debug event listener.
Debug.addListener(listener);
Debug.setListener(listener);
// Test debug event for constructor.
function a() {
......@@ -75,4 +75,4 @@ Debug.clearStepping(); // Clear stepping as the listener leaves it on.
assertEquals("bbccdcb", call_graph);
// Get rid of the debug event listener.
Debug.removeListener(listener);
\ No newline at end of file
Debug.setListener(null);
\ No newline at end of file
......@@ -94,7 +94,7 @@ function listener(event, exec_state, event_data, data) {
};
// Add the debug event listener.
Debug.addListener(listener);
Debug.setListener(listener);
function f() {
a=1
......
......@@ -39,7 +39,7 @@ function listener(event, exec_state, event_data, data) {
};
// Add the debug event listener.
Debug.addListener(listener);
Debug.setListener(listener);
// Test function.
function f() {a=1;b=2;};
......
......@@ -72,7 +72,7 @@ function listener(event, exec_state, event_data, data) {
};
// Add the debug event listener.
Debug.addListener(listener);
Debug.setListener(listener);
function h(x, y) {
debugger; // Breakpoint.
......
......@@ -103,7 +103,7 @@ function listener(event, exec_state, event_data, data) {
};
// Add the debug event listener.
Debug.addListener(listener);
Debug.setListener(listener);
function h() {
var a = 1;
......
......@@ -129,7 +129,7 @@ function listener_recurse(event, exec_state, event_data, data) {
};
// Add the debug event listener.
Debug.addListener(listener);
Debug.setListener(listener);
// Test functions - one with break point and one with debugger statement.
function f() {
......@@ -151,11 +151,11 @@ assertTrue(listenerComplete);
assertFalse(exception, "exception in listener")
// Remove the debug event listener.
Debug.removeListener(listener);
Debug.setListener(null);
// Add debug event listener wich uses recursive breaks.
listenerComplete = false;
Debug.addListener(listener_recurse);
Debug.setListener(listener_recurse);
debugger;
......
......@@ -57,7 +57,7 @@ function listener(event, exec_state, event_data, data) {
};
// Add the debug event listener.
Debug.addListener(listener);
Debug.setListener(listener);
function f() {
var a = 1;
......
......@@ -95,7 +95,7 @@ function listener(event, exec_state, event_data, data) {
};
// Add the debug event listener.
Debug.addListener(listener);
Debug.setListener(listener);
function f() {
var a = 3;
......
......@@ -42,7 +42,7 @@ function listener(event, exec_state, event_data, data) {
};
// Add the debug event listener.
Debug.addListener(listener);
Debug.setListener(listener);
// Get events from handled exceptions.
Debug.setBreakOnException();
......@@ -70,4 +70,4 @@ a();
assertTrue(lastDebugEvent.event == Debug.DebugEvent.Break);
assertEquals(lastDebugEvent.frameFuncName, "a");
Debug.removeListener(listener);
Debug.setListener(null);
......@@ -174,7 +174,7 @@ function listener(event, exec_state, event_data, data) {
};
// Add the debug event listener.
Debug.addListener(listener);
Debug.setListener(listener);
function f(a) {
debugger;
......
......@@ -39,7 +39,7 @@ function listener(event, exec_state, event_data, data) {
};
// Add the debug event listener.
Debug.addListener(listener);
Debug.setListener(listener);
// Test function.
function f() {};
......
......@@ -73,7 +73,7 @@ function listener(event, exec_state, event_data, data) {
};
// Add the debug event listener.
Debug.addListener(listener);
Debug.setListener(listener);
// Enter the debugger twice.
debugger;
......
......@@ -39,7 +39,7 @@ function listener(event, exec_state, event_data, data) {
};
// Add the debug event listener.
Debug.addListener(listener);
Debug.setListener(listener);
// Test functions
function f() {a=1;b=2;};
......
......@@ -85,7 +85,7 @@ function listener(event, exec_state, event_data, data) {
};
// Add the debug event listener.
Debug.addListener(listener);
Debug.setListener(listener);
// Call debugger to invoke the debug event listener.
debugger;
......
......@@ -101,7 +101,7 @@ function listener(event, exec_state, event_data, data) {
};
// Add the debug event listener.
Debug.addListener(listener);
Debug.setListener(listener);
function f() {
a=1
......
......@@ -42,7 +42,7 @@ function listener(event, exec_state, event_data, data) {
};
// Add the debug event listener.
Debug.addListener(listener);
Debug.setListener(listener);
// Use 'eval' to ensure that the call to print is through CodeStub CallFunction.
// See Ia32CodeGenerator::VisitCall and Ia32CodeGenerator::CallWithArguments.
......@@ -70,4 +70,4 @@ g();
assertEquals(4, break_break_point_hit_count);
// Get rid of the debug event listener.
Debug.removeListener(listener);
Debug.setListener(null);
......@@ -52,7 +52,7 @@ function listener(event, exec_state, event_data, data) {
};
// Add the debug event listener.
Debug.addListener(listener);
Debug.setListener(listener);
// Test debug event for break point.
function f() {
......@@ -81,4 +81,4 @@ f();
assertEquals(0, result);
// Get rid of the debug event listener.
Debug.removeListener(listener);
\ No newline at end of file
Debug.setListener(null);
\ No newline at end of file
......@@ -45,7 +45,7 @@ function listener(event, exec_state, event_data, data) {
};
// Add the debug event listener.
Debug.addListener(listener);
Debug.setListener(listener);
// Test step into constructor with simple constructor.
function X() {
......@@ -71,4 +71,4 @@ g();
assertEquals(4, break_break_point_hit_count);
// Get rid of the debug event listener.
Debug.removeListener(listener);
Debug.setListener(null);
......@@ -90,7 +90,7 @@ function listener(event, exec_state, event_data, data) {
};
// Add the debug event listener.
Debug.addListener(listener);
Debug.setListener(listener);
// Call method on undefined.
function g() {
......
......@@ -69,7 +69,7 @@ function listener(event, exec_state, event_data, data) {
};
// Add the debug event listener.
Debug.addListener(listener);
Debug.setListener(listener);
// Call a function with local variables passing a different number parameters
// that the number of arguments.
......
......@@ -37,7 +37,7 @@ function listener(event, exec_state, event_data, data) {
};
// Add the debug event listener.
Debug.addListener(listener);
Debug.setListener(listener);
function f() {
a=1
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment