7101881269
This is a reland of 7a2c371383
Original change's description:
> [debug] introduced runtime side effect check
>
> This CL demonstrates minimum valuable addition to existing debug evaluate
> without side effects mechanism.
> With this CL user can evaluate expressions like:
> [a,b] // create any kind of temporary array literals
> [a,b].reduce((x,y) => x + y, 0); // use reduce method
> [1,2,3].fill(2); // change temporary arrays
>
> The core idea: any change of the object created during evaluation without
> side effects is side effect free. As soon as we try to store this temporary
> object to object existed before evaluation we will terminate execution.
>
> Implementation:
> - track all objects allocated during evaluation and mark them as temporary,
> - patch all bytecodes which change objects.
>
> A little more details (including performance analysis): [1].
>
> [1] https://docs.google.com/document/d/10qqAtZADspPnpYa6SEdYRxrddfKIZJIzbLtGpsZQkRo/edit#
>
> Bug: v8:7588
> Change-Id: I69f7b96e1ebd7ad0022219e8213211c7be72a111
> Reviewed-on: https://chromium-review.googlesource.com/972615
> Commit-Queue: Aleksey Kozyatinskiy <kozyatinskiy@chromium.org>
> Reviewed-by: Yang Guo <yangguo@chromium.org>
> Reviewed-by: Ulan Degenbaev <ulan@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#52370}
Bug: v8:7588
Change-Id: Ibc92bf19155f2ddaedae39b0c576b994e84afcf8
Reviewed-on: https://chromium-review.googlesource.com/996760
Reviewed-by: Aleksey Kozyatinskiy <kozyatinskiy@chromium.org>
Commit-Queue: Aleksey Kozyatinskiy <kozyatinskiy@chromium.org>
Cr-Commit-Position: refs/heads/master@{#52373}
98 lines
2.4 KiB
JavaScript
98 lines
2.4 KiB
JavaScript
// Copyright 2017 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.
|
|
|
|
Debug = debug.Debug
|
|
|
|
var exception = null;
|
|
var date = new Date();
|
|
var T = true;
|
|
var F = false;
|
|
var one = 1;
|
|
var two = 2;
|
|
var string = "s";
|
|
var array = [1, 2, 3];
|
|
function max(...rest) {
|
|
return Math.max(...rest);
|
|
}
|
|
|
|
function def(a = 1) {
|
|
return a;
|
|
}
|
|
|
|
function d1([a, b = 'b']) {
|
|
return a + b;
|
|
}
|
|
|
|
function d2({ x: c, y, z = 'z' } = {x: 'x', y: 'y' }) {
|
|
return c + y + z;
|
|
}
|
|
|
|
function listener(event, exec_state, event_data, data) {
|
|
if (event != Debug.DebugEvent.Break) return;
|
|
try {
|
|
function success(expectation, source) {
|
|
var result = exec_state.frame(0).evaluate(source, true).value();
|
|
if (expectation !== undefined) assertEquals(expectation, result);
|
|
}
|
|
function fail(source) {
|
|
assertThrows(() => exec_state.frame(0).evaluate(source, true),
|
|
EvalError);
|
|
}
|
|
success(false, `Object == {}`);
|
|
success(false, `Object === {}`);
|
|
success(true, `Object != {}`);
|
|
success(true, `Object !== {}`);
|
|
success(true, `'s' == string`);
|
|
success(true, `'s' === string`);
|
|
success(true, `1 < Math.cos(0) * 2`);
|
|
success(false, `1 < string`);
|
|
success(true, `'a' < string`);
|
|
success("s", `string[0]`);
|
|
success(0, `[0][0]`);
|
|
success(1, `T^F`);
|
|
success(0, `T&F`);
|
|
success(1, `T|F`);
|
|
success(false, `T&&F`);
|
|
success(true, `T||F`);
|
|
success(false, `T?F:T`);
|
|
success(false, `!T`);
|
|
success(1, `+one`);
|
|
success(-1, `-one`);
|
|
success(-2, `~one`);
|
|
success(4, `one << two`);
|
|
success(1, `two >> one`);
|
|
success(1, `two >>> one`);
|
|
success(3, `two + one`);
|
|
success(2, `two * one`);
|
|
success(0.5, `one / two`);
|
|
success(0, `(one / two) | 0`);
|
|
success(1, `one ** two`);
|
|
success(NaN, `string * two`);
|
|
success("s2", `string + two`);
|
|
success("s2", `string + two`);
|
|
fail(`[...array]`);
|
|
success(3, `max(...array)`);
|
|
success({s:1}, `({[string]:1})`);
|
|
fail(`[a, b] = [1, 2]`);
|
|
success(2, `def(2)`);
|
|
success(1, `def()`);
|
|
fail(`d1(['a'])`); // Iterator.prototype.next performs stores.
|
|
success("XYz", `d2({x:'X', y:'Y'})`);
|
|
} catch (e) {
|
|
exception = e;
|
|
print(e, e.stack);
|
|
};
|
|
};
|
|
|
|
// Add the debug event listener.
|
|
Debug.setListener(listener);
|
|
|
|
function f() {
|
|
debugger;
|
|
};
|
|
|
|
f();
|
|
|
|
assertNull(exception);
|