Merge commit '6e92d2345e8231a44556ce7d416451f5f3e6c398' as 'engine262'

This commit is contained in:
2026-03-27 10:07:29 +05:30
433 changed files with 90478 additions and 0 deletions
@@ -0,0 +1,149 @@
import { Q } from '../completion.mts';
import { __ts_cast__ } from '../helpers.mts';
import type { DataViewObject } from '../intrinsics/DataView.mts';
import { type TypedArrayTypes, typedArrayInfoByType } from '../intrinsics/TypedArray.mts';
import { Value } from '../value.mts';
import {
Assert,
GetValueFromBuffer,
IsDetachedBuffer,
IsBigIntElementType,
SetValueInBuffer,
ToBoolean,
ToIndex,
ToNumber,
ToBigInt,
RequireInternalSlot,
type ArrayBufferObject,
ArrayBufferByteLength,
IsFixedLengthArrayBuffer,
} from './all.mts';
import { Throw } from '#self';
// This file covers abstract operations defined in
/** https://tc39.es/ecma262/#sec-dataview-objects */
/** https://tc39.es/ecma262/#sec-dataview-with-buffer-witness-records */
export interface DataViewWithBufferWitnessRecord {
readonly Object: DataViewObject;
CachedBufferByteLength: number | 'detached';
}
/** https://tc39.es/ecma262/#sec-makedataviewwithbufferwitnessrecord */
export function MakeDataViewWithBufferWitnessRecord(obj: DataViewObject, order: 'seq-cst' | 'unordered'): DataViewWithBufferWitnessRecord {
const buffer = obj.ViewedArrayBuffer as ArrayBufferObject;
let byteLength: DataViewWithBufferWitnessRecord['CachedBufferByteLength'];
if (IsDetachedBuffer(buffer)) {
byteLength = 'detached';
} else {
byteLength = ArrayBufferByteLength(buffer, order);
}
return { Object: obj, CachedBufferByteLength: byteLength };
}
/** https://tc39.es/ecma262/#sec-getviewbytelength */
export function GetViewByteLength(viewRecord: DataViewWithBufferWitnessRecord): number {
Assert(!IsViewOutOfBounds(viewRecord));
const view = viewRecord.Object;
// @ts-expect-error
if (view.ByteLength !== 'auto') {
return view.ByteLength;
}
Assert(!IsFixedLengthArrayBuffer(view.ViewedArrayBuffer as ArrayBufferObject));
const byteOffset = view.ByteOffset;
const byteLength = viewRecord.CachedBufferByteLength;
Assert(byteLength !== 'detached');
return byteLength - byteOffset;
}
/** https://tc39.es/ecma262/#sec-isviewoutofbounds */
export function IsViewOutOfBounds(viewRecord: DataViewWithBufferWitnessRecord): boolean {
const view = viewRecord.Object;
const bufferByteLength = viewRecord.CachedBufferByteLength;
if (IsDetachedBuffer(view.ViewedArrayBuffer as ArrayBufferObject)) {
Assert(bufferByteLength === 'detached');
return true;
}
Assert(typeof bufferByteLength === 'number' && bufferByteLength >= 0);
const byteOffsetStart = view.ByteOffset;
let byteOffsetEnd;
// @ts-expect-error
if (view.ByteLength === 'auto') {
byteOffsetEnd = bufferByteLength;
} else {
byteOffsetEnd = byteOffsetStart + view.ByteLength;
}
if (byteOffsetStart > bufferByteLength || byteOffsetEnd > bufferByteLength) {
return true;
}
return false;
}
/** https://tc39.es/ecma262/#sec-getviewvalue */
export function* GetViewValue(view: Value, requestIndex: Value, isLittleEndian: Value, type: TypedArrayTypes) {
// 1. Perform ? RequireInternalSlot(view, [[DataView]]).
Q(RequireInternalSlot(view, 'DataView'));
__ts_cast__<DataViewObject>(view);
// 2. Assert: view has a [[ViewedArrayBuffer]] internal slot.
Assert('ViewedArrayBuffer' in view);
// 3. Let getIndex be ? ToIndex(requestIndex).
const getIndex = Q(yield* ToIndex(requestIndex));
// 4. Set isLittleEndian to ToBoolean(isLittleEndian).
isLittleEndian = ToBoolean(isLittleEndian);
// 7. Let viewOffset be view.[[ByteOffset]].
const viewOffset = view.ByteOffset;
const viewRecord = MakeDataViewWithBufferWitnessRecord(view, 'unordered');
if (IsViewOutOfBounds(viewRecord)) {
return Throw.TypeError('Offset is out of bound');
}
const viewSize = GetViewByteLength(viewRecord);
// 9. Let elementSize be the Element Size value specified in Table 61 for Element Type type.
const elementSize = typedArrayInfoByType[type].ElementSize;
// 10. If getIndex + elementSize > viewSize, throw a RangeError exception.
if (getIndex + elementSize > viewSize) {
return Throw.RangeError('Offset is out of bound');
}
// 11. Let bufferIndex be getIndex + viewOffset.
const bufferIndex = getIndex + viewOffset;
// 12. Return GetValueFromBuffer(buffer, bufferIndex, type, false, Unordered, isLittleEndian).
return GetValueFromBuffer(view.ViewedArrayBuffer as ArrayBufferObject, bufferIndex, type, false, 'unordered', isLittleEndian.booleanValue());
}
/** https://tc39.es/ecma262/#sec-setviewvalue */
export function* SetViewValue(view: Value, requestIndex: Value, isLittleEndian: Value, type: TypedArrayTypes, value: Value) {
// 1. Perform ? RequireInternalSlot(view, [[DataView]]).
Q(RequireInternalSlot(view, 'DataView'));
// 2. Assert: view has a [[ViewedArrayBuffer]] internal slot.
Assert('ViewedArrayBuffer' in view);
__ts_cast__<DataViewObject>(view);
// 3. Let getIndex be ? ToIndex(requestIndex).
const getIndex = Q(yield* ToIndex(requestIndex));
// 4. If IsBigIntElementType(type) is true, let numberValue be ? ToBigInt(value).
// 5. Otherwise, let numberValue be ? ToNumber(value).
let numberValue;
if (IsBigIntElementType(type) === Value.true) {
numberValue = Q(yield* ToBigInt(value));
} else {
numberValue = Q(yield* ToNumber(value));
}
// 6. Set isLittleEndian to ToBoolean(isLittleEndian).
isLittleEndian = ToBoolean(isLittleEndian);
// 9. Let viewOffset be view.[[ByteOffset]].
const viewOffset = view.ByteOffset;
const viewRecord = MakeDataViewWithBufferWitnessRecord(view, 'unordered');
if (IsViewOutOfBounds(viewRecord)) {
return Throw.TypeError('Offset is out of bound');
}
const viewSize = GetViewByteLength(viewRecord);
// 11. Let elementSize be the Element Size value specified in Table 61 for Element Type type.
const elementSize = typedArrayInfoByType[type].ElementSize;
// 12. If getIndex + elementSize > viewSize, throw a RangeError exception.
if (getIndex + elementSize > viewSize) {
return Throw.RangeError('Offset is out of bound');
}
// 13. Let bufferIndex be getIndex + viewOffset.
const bufferIndex = getIndex + viewOffset;
// 14. Perform ? SetValueInBuffer(buffer, bufferIndex, type, numberValue, false, Unordered, isLittleEndian).
Q(yield* SetValueInBuffer(view.ViewedArrayBuffer as ArrayBufferObject, bufferIndex, type, numberValue, false, 'unordered', isLittleEndian.booleanValue()));
return Value.undefined;
}