// 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); }; } })();