mirror of
https://github.com/bendtherules/completion-viz.git
synced 2026-08-19 00:31:34 +00:00
Clone engine262 in /engine262
This commit is contained in:
@@ -0,0 +1,314 @@
|
||||
import { surroundingAgent } from '../engine.mjs';
|
||||
import { Value, Type, Descriptor } from '../value.mjs';
|
||||
import { Q, X } from '../completion.mjs';
|
||||
import {
|
||||
Assert,
|
||||
CanonicalNumericIndexString,
|
||||
IsAccessorDescriptor,
|
||||
IsDetachedBuffer,
|
||||
IsPropertyKey,
|
||||
IsValidIntegerIndex,
|
||||
MakeBasicObject,
|
||||
OrdinaryGetOwnProperty,
|
||||
OrdinaryHasProperty,
|
||||
OrdinaryDefineOwnProperty,
|
||||
OrdinaryGet,
|
||||
OrdinarySet,
|
||||
GetValueFromBuffer,
|
||||
SetValueInBuffer,
|
||||
ToString,
|
||||
ToNumber,
|
||||
ToBigInt,
|
||||
isIntegerIndex,
|
||||
typedArrayInfoByName,
|
||||
} from './all.mjs';
|
||||
|
||||
export function isIntegerIndexedExoticObject(O) {
|
||||
return O.GetOwnProperty === IntegerIndexedGetOwnProperty;
|
||||
}
|
||||
|
||||
// 9.4.5.1 #sec-integer-indexed-exotic-objects-getownproperty-p
|
||||
export function IntegerIndexedGetOwnProperty(P) {
|
||||
const O = this;
|
||||
// 1. Assert: IsPropertyKey(P) is true.
|
||||
Assert(IsPropertyKey(P));
|
||||
// 2. Assert: O is an Integer-Indexed exotic object.
|
||||
Assert(isIntegerIndexedExoticObject(O));
|
||||
// 3. If Type(P) is String, then
|
||||
if (Type(P) === 'String') {
|
||||
// a. Let numericIndex be ! CanonicalNumericIndexString(P).
|
||||
const numericIndex = X(CanonicalNumericIndexString(P));
|
||||
// b. If numericIndex is not undefined, then
|
||||
if (numericIndex !== Value.undefined) {
|
||||
// i. Let value be ? IntegerIndexedElementGet(O, numericIndex).
|
||||
const value = Q(IntegerIndexedElementGet(O, numericIndex));
|
||||
// ii. If value is undefined, return undefined.
|
||||
if (value === Value.undefined) {
|
||||
return Value.undefined;
|
||||
}
|
||||
// iii. Return the PropertyDescriptor { [[Value]]: value, [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: false }.
|
||||
return Descriptor({
|
||||
Value: value,
|
||||
Writable: Value.true,
|
||||
Enumerable: Value.true,
|
||||
Configurable: Value.false,
|
||||
});
|
||||
}
|
||||
}
|
||||
// 4. Return OrdinaryGetOwnProperty(O, P).
|
||||
return OrdinaryGetOwnProperty(O, P);
|
||||
}
|
||||
|
||||
// 9.4.5.2 #sec-integer-indexed-exotic-objects-hasproperty-p
|
||||
export function IntegerIndexedHasProperty(P) {
|
||||
const O = this;
|
||||
// 1. Assert: IsPropertyKey(P) is true.
|
||||
Assert(IsPropertyKey(P));
|
||||
// 2. Assert: O is an Integer-Indexed exotic object.
|
||||
Assert(isIntegerIndexedExoticObject(O));
|
||||
// 3. If Type(P) is String, then
|
||||
if (Type(P) === 'String') {
|
||||
// a. Let numericIndex be ! CanonicalNumericIndexString(P).
|
||||
const numericIndex = X(CanonicalNumericIndexString(P));
|
||||
// b. If numericIndex is not undefined, then
|
||||
if (numericIndex !== Value.undefined) {
|
||||
// i. Let buffer be O.[[ViewedArrayBuffer]].
|
||||
const buffer = O.ViewedArrayBuffer;
|
||||
// ii. If IsDetachedBuffer(buffer) is true, throw a TypeError exception.
|
||||
if (IsDetachedBuffer(buffer) === Value.true) {
|
||||
return surroundingAgent.Throw('TypeError', 'ArrayBufferDetached');
|
||||
}
|
||||
// iii. If ! IsValidIntegerIndex(O, numericIndex) is false, return false.
|
||||
if (IsValidIntegerIndex(O, numericIndex) === Value.false) {
|
||||
return Value.false;
|
||||
}
|
||||
// iv. Return true.
|
||||
return Value.true;
|
||||
}
|
||||
}
|
||||
// 4. Return ? OrdinaryHasProperty(O, P)
|
||||
return Q(OrdinaryHasProperty(O, P));
|
||||
}
|
||||
|
||||
// #sec-integer-indexed-exotic-objects-defineownproperty-p-desc
|
||||
export function IntegerIndexedDefineOwnProperty(P, Desc) {
|
||||
const O = this;
|
||||
// 1. Assert: IsPropertyKey(P) is true.
|
||||
Assert(IsPropertyKey(P));
|
||||
// 2. Assert: O is an Integer-Indexed exotic object.
|
||||
Assert(isIntegerIndexedExoticObject(O));
|
||||
// 3. If Type(P) is String, then
|
||||
if (Type(P) === 'String') {
|
||||
// a. Let numericIndex be ! CanonicalNumericIndexString(P).
|
||||
const numericIndex = X(CanonicalNumericIndexString(P));
|
||||
// b. If numericIndex is not undefined, then
|
||||
if (numericIndex !== Value.undefined) {
|
||||
// i. If ! IsValidIntegerIndex(O, numericIndex) is false, return false.
|
||||
if (IsValidIntegerIndex(O, numericIndex) === Value.false) {
|
||||
return Value.false;
|
||||
}
|
||||
// ii. If IsAccessorDescriptor(Desc) is true, return false.
|
||||
if (IsAccessorDescriptor(Desc)) {
|
||||
return Value.false;
|
||||
}
|
||||
// iii. If Desc has a [[Configurable]] field and if Desc.[[Configurable]] is true, return false.
|
||||
if (Desc.Configurable === Value.true) {
|
||||
return Value.false;
|
||||
}
|
||||
// iv. If Desc has an [[Enumerable]] field and if Desc.[[Enumerable]] is false, return false.
|
||||
if (Desc.Enumerable === Value.false) {
|
||||
return Value.false;
|
||||
}
|
||||
// v. If Desc has a [[Writable]] field and if Desc.[[Writable]] is false, return false.
|
||||
if (Desc.Writable === Value.false) {
|
||||
return Value.false;
|
||||
}
|
||||
// vi. If Desc has a [[Value]] field, then
|
||||
if (Desc.Value !== undefined) {
|
||||
// 1. Let value be Desc.[[Value]].
|
||||
const value = Desc.Value;
|
||||
// 2. Return ? IntegerIndexedElementSet(O, numericIndex, value).
|
||||
return Q(IntegerIndexedElementSet(O, numericIndex, value));
|
||||
}
|
||||
// vii. Return true.
|
||||
return Value.true;
|
||||
}
|
||||
}
|
||||
// 4. Return ! OrdinaryDefineOwnProperty(O, P, Desc).
|
||||
return Q(OrdinaryDefineOwnProperty(O, P, Desc));
|
||||
}
|
||||
|
||||
// 9.4.5.4 #sec-integer-indexed-exotic-objects-get-p-receiver
|
||||
export function IntegerIndexedGet(P, Receiver) {
|
||||
const O = this;
|
||||
// 1. Assert: IsPropertykey(P) is true.
|
||||
Assert(IsPropertyKey(P));
|
||||
// 2. If Type(P) is String, then
|
||||
if (Type(P) === 'String') {
|
||||
// a. Let numericIndex be ! CanonicalNumericIndexString(P).
|
||||
const numericIndex = X(CanonicalNumericIndexString(P));
|
||||
// b. If numericIndex is not undefined, then
|
||||
if (numericIndex !== Value.undefined) {
|
||||
// i. Return ? IntegerIndexedElementGet(O, numericIndex).
|
||||
return Q(IntegerIndexedElementGet(O, numericIndex));
|
||||
}
|
||||
}
|
||||
// 3. Return ? OrdinaryGet(O, P, Receiver).
|
||||
return Q(OrdinaryGet(O, P, Receiver));
|
||||
}
|
||||
|
||||
// 9.4.5.5 #sec-integer-indexed-exotic-objects-set-p-v-receiver
|
||||
export function IntegerIndexedSet(P, V, Receiver) {
|
||||
const O = this;
|
||||
// 1. Assert: IsPropertyKey(P) is true.
|
||||
Assert(IsPropertyKey(P));
|
||||
// 2. If Type(P) is String, then
|
||||
if (Type(P) === 'String') {
|
||||
// a. Let numericIndex be ! CanonicalNumericIndexString(P).
|
||||
const numericIndex = X(CanonicalNumericIndexString(P));
|
||||
// b. If numericIndex is not undefined, then
|
||||
if (numericIndex !== Value.undefined) {
|
||||
// i. Return ? IntegerIndexedElementSet(O, numericIndex, V).
|
||||
return Q(IntegerIndexedElementSet(O, numericIndex, V));
|
||||
}
|
||||
}
|
||||
// 3. Return ? OrdinarySet(O, P, V, Receiver).
|
||||
return Q(OrdinarySet(O, P, V, Receiver));
|
||||
}
|
||||
|
||||
// 9.4.5.6 #sec-integer-indexed-exotic-objects-ownpropertykeys
|
||||
export function IntegerIndexedOwnPropertyKeys() {
|
||||
const O = this;
|
||||
// 1. Let keys be a new empty List.
|
||||
const keys = [];
|
||||
// 2. Assert: O is an Integer-Indexed exotic object.
|
||||
Assert(isIntegerIndexedExoticObject(O));
|
||||
// 3. Let len be O.[[ArrayLength]].
|
||||
const len = O.ArrayLength.numberValue();
|
||||
// 4. For each integer i starting with 0 such that i < len, in ascending order, do
|
||||
for (let i = 0; i < len; i += 1) {
|
||||
// a. Add ! ToString(i) as the last element of keys.
|
||||
keys.push(X(ToString(new Value(i))));
|
||||
}
|
||||
// 5. For each own property key P of O such that Type(P) is String and P is not an integer index, in ascending chronological order of property creation, do
|
||||
for (const P of O.properties.keys()) {
|
||||
if (Type(P) === 'String') {
|
||||
if (!isIntegerIndex(P)) {
|
||||
// a. Add P as the last element of keys.
|
||||
keys.push(P);
|
||||
}
|
||||
}
|
||||
}
|
||||
// 6. For each own property key P of O such that Type(P) is Symbol, in ascending chronological order of property creation, do
|
||||
for (const P of O.properties.keys()) {
|
||||
if (Type(P) === 'Symbol') {
|
||||
// a. Add P as the last element of keys.
|
||||
keys.push(P);
|
||||
}
|
||||
}
|
||||
// 7. Return keys.
|
||||
return keys;
|
||||
}
|
||||
|
||||
// #sec-integerindexedelementget
|
||||
export function IntegerIndexedElementGet(O, index) {
|
||||
// 1. Assert: O is an Integer-Indexed exotic object.
|
||||
Assert(isIntegerIndexedExoticObject(O));
|
||||
// 2. Assert: Type(index) is Number.
|
||||
Assert(Type(index) === 'Number');
|
||||
// 3. Let buffer be O.[[ViewedArrayBuffer]].
|
||||
const buffer = O.ViewedArrayBuffer;
|
||||
// 4. If IsDetachedBuffer(buffer) is true, throw a TypeError exception.
|
||||
if (IsDetachedBuffer(buffer) === Value.true) {
|
||||
return surroundingAgent.Throw('TypeError', 'ArrayBufferDetached');
|
||||
}
|
||||
// 5. If ! IsValidIntegerIndex(O, index) is false, return undefined.
|
||||
if (IsValidIntegerIndex(O, index) === Value.false) {
|
||||
return Value.undefined;
|
||||
}
|
||||
// 6. Let offset be O.[[ByteOffset]].
|
||||
const offset = O.ByteOffset;
|
||||
// 7. Let arrayTypeName be the String value of O.[[TypedArrayName]].
|
||||
const arrayTypeName = O.TypedArrayName.stringValue();
|
||||
// 8. Let elementSize be the Element Size value specified in Table 61 for arrayTypeName.
|
||||
const elementSize = typedArrayInfoByName[arrayTypeName].ElementSize;
|
||||
// 9. Let indexedPosition be (index × elementSize) + offset.
|
||||
const indexedPosition = new Value((index.numberValue() * elementSize) + offset.numberValue());
|
||||
// 10. Let elementType be the Element Type value in Table 61 for arrayTypeName.
|
||||
const elementType = typedArrayInfoByName[arrayTypeName].ElementType;
|
||||
// 11. Return GetValueFromBuffer(buffer, indexedPosition, elementType, true, Unordered).
|
||||
return GetValueFromBuffer(buffer, indexedPosition, elementType, Value.true, 'Unordered');
|
||||
}
|
||||
|
||||
// #sec-integerindexedelementset
|
||||
export function IntegerIndexedElementSet(O, index, value) {
|
||||
// 1. Assert: O is an Integer-Indexed exotic object.
|
||||
Assert(isIntegerIndexedExoticObject(O));
|
||||
// 2. Assert: Type(index) is Number.
|
||||
Assert(Type(index) === 'Number');
|
||||
// 3. If O.[[ContentType]] is BigInt, let numValue be ? ToBigInt(value).
|
||||
// 4. Otherwise, let numValue be ? ToNumber(value).
|
||||
let numValue;
|
||||
if (O.ContentType === 'BigInt') {
|
||||
numValue = Q(ToBigInt(value));
|
||||
} else {
|
||||
numValue = Q(ToNumber(value));
|
||||
}
|
||||
// 5. Let buffer be O.[[ViewedArrayBuffer]].
|
||||
const buffer = O.ViewedArrayBuffer;
|
||||
// 6. If IsDetachedBuffer(buffer) is true, throw a TypeError exception.
|
||||
if (IsDetachedBuffer(buffer) === Value.true) {
|
||||
return surroundingAgent.Throw('TypeError', 'ArrayBufferDetached');
|
||||
}
|
||||
// 7. If ! IsValidIntegerIndex(O, index) is false, return false.
|
||||
if (IsValidIntegerIndex(O, index) === Value.false) {
|
||||
return Value.false;
|
||||
}
|
||||
// 8. Let offset be O.[[ByteOffset]].
|
||||
const offset = O.ByteOffset;
|
||||
// 9. Let arrayTypeName be the String value of O.[[TypedArrayName]].
|
||||
const arrayTypeName = O.TypedArrayName.stringValue();
|
||||
// 10. Let elementSize be the Element Size value specified in Table 61 for arrayTypeName.
|
||||
const elementSize = typedArrayInfoByName[arrayTypeName].ElementSize;
|
||||
// 11. Let indexedPosition be (index × elementSize) + offset.
|
||||
const indexedPosition = new Value((index.numberValue() * elementSize) + offset.numberValue());
|
||||
// 12. Let elementType be the Element Type value in Table 61 for arrayTypeName.
|
||||
const elementType = typedArrayInfoByName[arrayTypeName].ElementType;
|
||||
// 13. Perform SetValueInBuffer(buffer, indexedPosition, elementType, numValue, true, Unordered).
|
||||
X(SetValueInBuffer(buffer, indexedPosition, elementType, numValue, Value.true, 'Unordered'));
|
||||
// 14. Return true.
|
||||
return Value.true;
|
||||
}
|
||||
|
||||
// #sec-integerindexedobjectcreate
|
||||
export function IntegerIndexedObjectCreate(prototype) {
|
||||
// 1. Let internalSlotsList be « [[Prototype]], [[Extensible]], [[ViewedArrayBuffer]], [[TypedArrayName]], [[ContentType]], [[ByteLength]], [[ByteOffset]], [[ArrayLength]] ».
|
||||
const internalSlotsList = [
|
||||
'Prototype',
|
||||
'Extensible',
|
||||
'ViewedArrayBuffer',
|
||||
'TypedArrayName',
|
||||
'ContentType',
|
||||
'ByteLength',
|
||||
'ByteOffset',
|
||||
'ArrayLength',
|
||||
];
|
||||
// 2. Let A be ! MakeBasicObject(internalSlotsList).
|
||||
const A = X(MakeBasicObject(internalSlotsList));
|
||||
// 3. Set A.[[GetOwnProperty]] as specified in 9.4.5.1.
|
||||
A.GetOwnProperty = IntegerIndexedGetOwnProperty;
|
||||
// 4. Set A.[[HasProperty]] as specified in 9.4.5.2.
|
||||
A.HasProperty = IntegerIndexedHasProperty;
|
||||
// 5. Set A.[[DefineOwnProperty]] as specified in 9.4.5.3.
|
||||
A.DefineOwnProperty = IntegerIndexedDefineOwnProperty;
|
||||
// 6. Set A.[[Get]] as specified in 9.4.5.4.
|
||||
A.Get = IntegerIndexedGet;
|
||||
// 7. Set A.[[Set]] as specified in 9.4.5.5.
|
||||
A.Set = IntegerIndexedSet;
|
||||
// 8. Set A.[[OwnPropertyKeys]] as specified in 9.4.5.6.
|
||||
A.OwnPropertyKeys = IntegerIndexedOwnPropertyKeys;
|
||||
// 9. Set A.[[Prototype]] to prototype.
|
||||
A.Prototype = prototype;
|
||||
// 10. Return A.
|
||||
return A;
|
||||
}
|
||||
Reference in New Issue
Block a user