3f88d2dab4
This adds tests for the mock logic used in differential fuzzing. The tests uncovered a couple of issues in the mock files that are also fixed. This also does some minor code clean up in the mock code. Bug: chromium:1044942 Change-Id: I5b67f70f8b104bb681548f742ab863395a88360f Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2043843 Commit-Queue: Michael Achenbach <machenbach@chromium.org> Reviewed-by: Mathias Bynens <mathias@chromium.org> Cr-Commit-Position: refs/heads/master@{#66304}
92 lines
3.2 KiB
JavaScript
92 lines
3.2 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.
|
|
|
|
// This is intended for permanent JS behavior changes for mocking out
|
|
// non-deterministic behavior. For temporary suppressions, please refer to
|
|
// v8_suppressions.js.
|
|
// This mocks only architecture specific differences. Refer to v8_mocks.js
|
|
// for the general case.
|
|
// This file is loaded before each correctness test cases and won't get
|
|
// minimized.
|
|
|
|
// Mock maximum typed-array buffer and limit to 1MiB. Otherwise we might
|
|
// get range errors. We ignore those by crashing, but that reduces coverage,
|
|
// hence, let's reduce the range-error rate.
|
|
(function() {
|
|
// Math.min might be manipulated in test cases.
|
|
const min = Math.min;
|
|
const maxBytes = 1048576;
|
|
const mock = function(type) {
|
|
const maxLength = maxBytes / (type.BYTES_PER_ELEMENT || 1);
|
|
const handler = {
|
|
construct: function(target, args) {
|
|
if (args[0] && typeof args[0] != "object") {
|
|
// Length used as first argument.
|
|
args[0] = min(maxLength, Number(args[0]));
|
|
} else if (args[0] instanceof ArrayBuffer && args.length > 1) {
|
|
// Buffer used as first argument.
|
|
const buffer = args[0];
|
|
args[1] = Number(args[1]);
|
|
// Ensure offset is multiple of bytes per element.
|
|
args[1] = args[1] - (args[1] % type.BYTES_PER_ELEMENT);
|
|
// Limit offset to length of buffer.
|
|
args[1] = min(args[1], buffer.byteLength || 0);
|
|
if (args.length > 2) {
|
|
// If also length is given, limit it to the maximum that's possible
|
|
// given buffer and offset.
|
|
const maxBytesLeft = buffer.byteLength - args[1];
|
|
const maxLengthLeft = maxBytesLeft / type.BYTES_PER_ELEMENT;
|
|
args[2] = min(Number(args[2]), maxLengthLeft);
|
|
}
|
|
}
|
|
return new (Function.prototype.bind.apply(type, [null].concat(args)));
|
|
},
|
|
};
|
|
return new Proxy(type, handler);
|
|
}
|
|
|
|
ArrayBuffer = mock(ArrayBuffer);
|
|
SharedArrayBuffer = mock(SharedArrayBuffer);
|
|
Int8Array = mock(Int8Array);
|
|
Uint8Array = mock(Uint8Array);
|
|
Uint8ClampedArray = mock(Uint8ClampedArray);
|
|
Int16Array = mock(Int16Array);
|
|
Uint16Array = mock(Uint16Array);
|
|
Int32Array = mock(Int32Array);
|
|
Uint32Array = mock(Uint32Array);
|
|
BigInt64Array = mock(BigInt64Array);
|
|
BigUint64Array = mock(BigUint64Array);
|
|
Float32Array = mock(Float32Array);
|
|
Float64Array = mock(Float64Array);
|
|
})();
|
|
|
|
// Mock typed array set function and cap offset to not throw a range error.
|
|
(function() {
|
|
// Math.min might be manipulated in test cases.
|
|
const min = Math.min;
|
|
const types = [
|
|
Int8Array,
|
|
Uint8Array,
|
|
Uint8ClampedArray,
|
|
Int16Array,
|
|
Uint16Array,
|
|
Int32Array,
|
|
Uint32Array,
|
|
BigInt64Array,
|
|
BigUint64Array,
|
|
Float32Array,
|
|
Float64Array,
|
|
];
|
|
for (const type of types) {
|
|
const set = type.prototype.set;
|
|
type.prototype.set = function(array, offset) {
|
|
if (Array.isArray(array)) {
|
|
offset = Number(offset);
|
|
offset = min(offset, this.length - array.length);
|
|
}
|
|
set.call(this, array, offset);
|
|
};
|
|
}
|
|
})();
|