7a2c371383
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}
65 lines
1.4 KiB
JavaScript
65 lines
1.4 KiB
JavaScript
// Copyright 2018 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;
|
|
|
|
// StaNamedProperty
|
|
var a = {name: 'foo'};
|
|
function set_name(a) {
|
|
a.name = 'bar';
|
|
return a.name;
|
|
}
|
|
|
|
fail(`set_name(a)`);
|
|
success('bar', `set_name({name: 'foo'})`);
|
|
|
|
// StaNamedOwnProperty
|
|
var name_value = 'value';
|
|
function create_object_literal() {
|
|
var obj = {name: name_value};
|
|
return obj.name;
|
|
};
|
|
|
|
success('value', `create_object_literal()`);
|
|
|
|
// StaKeyedProperty
|
|
var arrayValue = 1;
|
|
function create_array_literal() {
|
|
return [arrayValue];
|
|
}
|
|
var b = { 1: 2 };
|
|
|
|
success([arrayValue], `create_array_literal()`)
|
|
fail(`b[1] ^= 2`);
|
|
|
|
// StaInArrayLiteral
|
|
function return_array_use_spread(a) {
|
|
return [...a];
|
|
}
|
|
|
|
fail(`return_array_use_spread([1])`);
|
|
|
|
// CallAccessorSetter
|
|
var array = [1,2,3];
|
|
fail(`array.length = 2`);
|
|
// TODO(7515): this one should be side effect free
|
|
fail(`[1,2,3].length = 2`);
|
|
|
|
// StaDataPropertyInLiteral
|
|
function return_literal_with_data_property(a) {
|
|
return {[a] : 1};
|
|
}
|
|
|
|
success({foo: 1}, `return_literal_with_data_property('foo')`);
|
|
|
|
function success(expectation, source) {
|
|
const result = Debug.evaluateGlobal(source, true).value();
|
|
if (expectation !== undefined) assertEquals(expectation, result);
|
|
}
|
|
|
|
function fail(source) {
|
|
assertThrows(() => Debug.evaluateGlobal(source, true),
|
|
EvalError);
|
|
}
|