2017-06-02 15:11:29 +00:00
|
|
|
// Copyright 2016 the V8 project authors. All rights reserved.
|
|
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
|
|
// found in the LICENSE file.
|
|
|
|
|
|
|
|
// MODULE
|
2018-07-06 04:32:58 +00:00
|
|
|
// Flags: --no-always-opt --no-opt
|
2017-06-02 15:11:29 +00:00
|
|
|
|
|
|
|
// The first part of this file is copied over from debug-set-variable-value.js
|
|
|
|
// (a few tests were removed because they make no sense for modules). The second
|
|
|
|
// part is new.
|
|
|
|
|
|
|
|
var Debug = debug.Debug;
|
|
|
|
|
|
|
|
// Accepts a function/closure 'fun' that must have a debugger statement inside.
|
|
|
|
// A variable 'variable_name' must be initialized before debugger statement
|
|
|
|
// and returned after the statement. The test will alter variable value when
|
|
|
|
// on debugger statement and check that returned value reflects the change.
|
|
|
|
function RunPauseTest(scope_number, expected_old_result, variable_name,
|
|
|
|
new_value, expected_new_result, fun) {
|
|
|
|
var actual_old_result = fun();
|
|
|
|
assertEquals(expected_old_result, actual_old_result);
|
|
|
|
|
|
|
|
var listener_delegate;
|
|
|
|
var listener_called = false;
|
|
|
|
var exception = null;
|
|
|
|
|
|
|
|
function listener_delegate(exec_state) {
|
|
|
|
var scope = exec_state.frame(0).scope(scope_number);
|
|
|
|
scope.setVariableValue(variable_name, new_value);
|
|
|
|
}
|
|
|
|
|
|
|
|
function listener(event, exec_state, event_data, data) {
|
|
|
|
try {
|
|
|
|
if (event == Debug.DebugEvent.Break) {
|
|
|
|
listener_called = true;
|
|
|
|
listener_delegate(exec_state);
|
|
|
|
}
|
|
|
|
} catch (e) {
|
|
|
|
exception = e;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Add the debug event listener.
|
|
|
|
Debug.setListener(listener);
|
|
|
|
|
|
|
|
var actual_new_result;
|
|
|
|
try {
|
|
|
|
actual_new_result = fun();
|
|
|
|
} finally {
|
|
|
|
Debug.setListener(null);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (exception != null) {
|
|
|
|
assertUnreachable("Exception in listener\n" + exception.stack);
|
|
|
|
}
|
|
|
|
assertTrue(listener_called);
|
|
|
|
|
|
|
|
assertEquals(expected_new_result, actual_new_result);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function ClosureTestCase(scope_index, old_result, variable_name, new_value,
|
|
|
|
new_result, success_expected, factory) {
|
|
|
|
this.scope_index_ = scope_index;
|
|
|
|
this.old_result_ = old_result;
|
|
|
|
this.variable_name_ = variable_name;
|
|
|
|
this.new_value_ = new_value;
|
|
|
|
this.new_result_ = new_result;
|
|
|
|
this.success_expected_ = success_expected;
|
|
|
|
this.factory_ = factory;
|
|
|
|
}
|
|
|
|
|
|
|
|
ClosureTestCase.prototype.run_pause_test = function() {
|
|
|
|
var th = this;
|
|
|
|
var fun = this.factory_(true);
|
|
|
|
this.run_and_catch_(function() {
|
|
|
|
RunPauseTest(th.scope_index_ + 1, th.old_result_, th.variable_name_,
|
|
|
|
th.new_value_, th.new_result_, fun);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
ClosureTestCase.prototype.run_and_catch_ = function(runnable) {
|
|
|
|
if (this.success_expected_) {
|
|
|
|
runnable();
|
|
|
|
} else {
|
|
|
|
assertThrows(runnable);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Test scopes visible from closures.
|
|
|
|
|
|
|
|
var closure_test_cases = [
|
|
|
|
new ClosureTestCase(0, 'cat', 'v1', 5, 5, true,
|
|
|
|
function Factory(debug_stop) {
|
|
|
|
var v1 = 'cat';
|
|
|
|
return function() {
|
|
|
|
if (debug_stop) debugger;
|
|
|
|
return v1;
|
|
|
|
}
|
|
|
|
}),
|
|
|
|
|
|
|
|
new ClosureTestCase(0, 4, 't', 7, 9, true, function Factory(debug_stop) {
|
|
|
|
var t = 2;
|
|
|
|
var r = eval("t");
|
|
|
|
return function() {
|
|
|
|
if (debug_stop) debugger;
|
|
|
|
return r + t;
|
|
|
|
}
|
|
|
|
}),
|
|
|
|
|
|
|
|
new ClosureTestCase(0, 6, 't', 10, 13, true, function Factory(debug_stop) {
|
|
|
|
var t = 2;
|
|
|
|
var r = eval("t = 3");
|
|
|
|
return function() {
|
|
|
|
if (debug_stop) debugger;
|
|
|
|
return r + t;
|
|
|
|
}
|
|
|
|
}),
|
|
|
|
|
|
|
|
new ClosureTestCase(2, 'capybara', 'foo', 77, 77, true,
|
|
|
|
function Factory(debug_stop) {
|
|
|
|
var foo = "capybara";
|
|
|
|
return (function() {
|
|
|
|
var bar = "fish";
|
|
|
|
try {
|
|
|
|
throw {name: "test exception"};
|
|
|
|
} catch (e) {
|
|
|
|
return function() {
|
|
|
|
if (debug_stop) debugger;
|
|
|
|
bar = "beast";
|
|
|
|
return foo;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
})();
|
|
|
|
}),
|
|
|
|
|
|
|
|
new ClosureTestCase(0, 'AlphaBeta', 'eee', 5, '5Beta', true,
|
|
|
|
function Factory(debug_stop) {
|
|
|
|
var foo = "Beta";
|
|
|
|
return (function() {
|
|
|
|
var bar = "fish";
|
|
|
|
try {
|
|
|
|
throw "Alpha";
|
|
|
|
} catch (eee) {
|
|
|
|
return function() {
|
|
|
|
if (debug_stop) debugger;
|
|
|
|
return eee + foo;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
})();
|
|
|
|
})
|
|
|
|
];
|
|
|
|
|
|
|
|
for (var i = 0; i < closure_test_cases.length; i++) {
|
|
|
|
closure_test_cases[i].run_pause_test();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Test local scope.
|
|
|
|
|
|
|
|
RunPauseTest(0, 'HelloYou', 'u', 'We', 'HelloWe', (function Factory() {
|
|
|
|
return function() {
|
|
|
|
var u = "You";
|
|
|
|
var v = "Hello";
|
|
|
|
debugger;
|
|
|
|
return v + u;
|
|
|
|
}
|
|
|
|
})());
|
|
|
|
|
|
|
|
RunPauseTest(0, 'Helloworld', 'p', 'GoodBye', 'HelloGoodBye',
|
|
|
|
(function Factory() {
|
|
|
|
function H(p) {
|
|
|
|
var v = "Hello";
|
|
|
|
debugger;
|
|
|
|
return v + p;
|
|
|
|
}
|
|
|
|
return function() {
|
|
|
|
return H("world");
|
|
|
|
}
|
|
|
|
})());
|
|
|
|
|
|
|
|
RunPauseTest(0, 'mouse', 'v1', 'dog', 'dog', (function Factory() {
|
|
|
|
return function() {
|
|
|
|
var v1 = 'cat';
|
|
|
|
eval("v1 = 'mouse'");
|
|
|
|
debugger;
|
|
|
|
return v1;
|
|
|
|
}
|
|
|
|
})());
|
|
|
|
|
|
|
|
// Check that we correctly update local variable that
|
|
|
|
// is referenced from an inner closure.
|
|
|
|
RunPauseTest(0, 'Blue', 'v', 'Green', 'Green', (function Factory() {
|
|
|
|
return function() {
|
|
|
|
function A() {
|
|
|
|
var v = "Blue";
|
|
|
|
function Inner() {
|
|
|
|
return void v;
|
|
|
|
}
|
|
|
|
debugger;
|
|
|
|
return v;
|
|
|
|
}
|
|
|
|
return A();
|
|
|
|
}
|
|
|
|
})());
|
|
|
|
|
|
|
|
// Check that we correctly update parameter, that is known to be stored
|
|
|
|
// both on stack and in heap.
|
|
|
|
RunPauseTest(0, 5, 'p', 2012, 2012, (function Factory() {
|
|
|
|
return function() {
|
|
|
|
function A(p) {
|
|
|
|
function Inner() {
|
|
|
|
return void p;
|
|
|
|
}
|
|
|
|
debugger;
|
|
|
|
return p;
|
|
|
|
}
|
|
|
|
return A(5);
|
|
|
|
}
|
|
|
|
})());
|
|
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// From here on we test the module scope.
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
|
|
// Non-existing variable.
|
|
|
|
{
|
|
|
|
let exception;
|
|
|
|
function listener(event, exec_state) {
|
|
|
|
if (event == Debug.DebugEvent.Break) {
|
|
|
|
let module_scope = exec_state.frame().scope(1);
|
|
|
|
assertEquals(debug.ScopeType.Module, module_scope.scopeType());
|
|
|
|
try {
|
|
|
|
module_scope.setVariableValue('spargel', 42);
|
|
|
|
} catch(e) { exception = e; }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Debug.setListener(listener);
|
|
|
|
assertThrows(() => spargel, ReferenceError);
|
|
|
|
debugger;
|
|
|
|
assertThrows(() => spargel, ReferenceError);
|
|
|
|
assertTrue(exception !== undefined);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Local (non-exported) variable.
|
|
|
|
let salat = 12;
|
|
|
|
{
|
|
|
|
function listener(event, exec_state) {
|
|
|
|
if (event == Debug.DebugEvent.Break) {
|
|
|
|
let module_scope = exec_state.frame().scope(1);
|
|
|
|
assertEquals(debug.ScopeType.Module, module_scope.scopeType());
|
|
|
|
module_scope.setVariableValue('salat', 42);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Debug.setListener(listener);
|
|
|
|
assertEquals(12, salat);
|
|
|
|
debugger;
|
|
|
|
assertEquals(42, salat);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-06-14 14:33:58 +00:00
|
|
|
// Local (non-exported) variable, nested access.
|
|
|
|
let salad = 12;
|
|
|
|
{
|
|
|
|
function listener(event, exec_state) {
|
|
|
|
if (event == Debug.DebugEvent.Break) {
|
|
|
|
let scope_count = exec_state.frame().scopeCount();
|
2017-12-07 09:45:45 +00:00
|
|
|
let module_scope = exec_state.frame().scope(1);
|
2017-06-14 14:33:58 +00:00
|
|
|
assertEquals(debug.ScopeType.Module, module_scope.scopeType());
|
|
|
|
module_scope.setVariableValue('salad', 42);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Debug.setListener(listener);
|
|
|
|
function foo() {
|
|
|
|
assertEquals(12, salad);
|
|
|
|
debugger;
|
|
|
|
assertEquals(42, salad);
|
|
|
|
};
|
|
|
|
foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-06-02 15:11:29 +00:00
|
|
|
// Exported variable.
|
|
|
|
export let salami = 1;
|
|
|
|
{
|
|
|
|
function listener(event, exec_state) {
|
|
|
|
if (event == Debug.DebugEvent.Break) {
|
|
|
|
let module_scope = exec_state.frame().scope(1);
|
|
|
|
assertEquals(debug.ScopeType.Module, module_scope.scopeType());
|
|
|
|
module_scope.setVariableValue('salami', 2);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Debug.setListener(listener);
|
|
|
|
assertEquals(1, salami);
|
|
|
|
debugger;
|
|
|
|
assertEquals(2, salami);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-06-14 14:33:58 +00:00
|
|
|
// Exported variable, nested access.
|
|
|
|
export let ham = 1;
|
|
|
|
{
|
|
|
|
function listener(event, exec_state) {
|
|
|
|
if (event == Debug.DebugEvent.Break) {
|
|
|
|
let scope_count = exec_state.frame().scopeCount();
|
2017-12-07 09:45:45 +00:00
|
|
|
let module_scope = exec_state.frame().scope(1);
|
2017-06-14 14:33:58 +00:00
|
|
|
assertEquals(debug.ScopeType.Module, module_scope.scopeType());
|
|
|
|
module_scope.setVariableValue('ham', 2);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Debug.setListener(listener);
|
|
|
|
function foo() {
|
|
|
|
assertEquals(1, ham);
|
|
|
|
debugger;
|
|
|
|
assertEquals(2, ham);
|
|
|
|
};
|
|
|
|
foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-06-02 15:11:29 +00:00
|
|
|
// Imported variable. Setting is currently not supported.
|
|
|
|
import { salami as wurst } from "./debug-modules-set-variable-value.js";
|
|
|
|
{
|
|
|
|
let exception;
|
|
|
|
function listener(event, exec_state) {
|
|
|
|
if (event == Debug.DebugEvent.Break) {
|
|
|
|
let module_scope = exec_state.frame().scope(1);
|
|
|
|
assertEquals(debug.ScopeType.Module, module_scope.scopeType());
|
|
|
|
try {
|
|
|
|
module_scope.setVariableValue('wurst', 3);
|
|
|
|
} catch(e) { exception = e; }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Debug.setListener(listener);
|
|
|
|
assertEquals(2, wurst);
|
|
|
|
debugger;
|
|
|
|
assertEquals(2, wurst);
|
|
|
|
assertTrue(exception !== undefined);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-06-14 14:33:58 +00:00
|
|
|
// Imported variable, nested access. Setting is currently not supported.
|
|
|
|
import { salami as wurstl } from "./debug-modules-set-variable-value.js";
|
|
|
|
{
|
|
|
|
let exception;
|
|
|
|
function listener(event, exec_state) {
|
|
|
|
if (event == Debug.DebugEvent.Break) {
|
|
|
|
let scope_count = exec_state.frame().scopeCount();
|
|
|
|
let module_scope = exec_state.frame().scope(2);
|
|
|
|
assertEquals(debug.ScopeType.Module, module_scope.scopeType());
|
|
|
|
try {
|
|
|
|
module_scope.setVariableValue('wurstl', 3);
|
|
|
|
} catch(e) { exception = e; }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Debug.setListener(listener);
|
|
|
|
function foo() {
|
|
|
|
assertEquals(2, wurstl);
|
|
|
|
debugger;
|
|
|
|
assertEquals(2, wurstl);
|
|
|
|
assertTrue(exception !== undefined);
|
|
|
|
};
|
|
|
|
foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-06-02 15:11:29 +00:00
|
|
|
Debug.setListener(null);
|