mirror of
https://github.com/bendtherules/ask262.git
synced 2026-08-19 00:31:06 +00:00
466 lines
18 KiB
TypeScript
466 lines
18 KiB
TypeScript
import {
|
|
NullValue,
|
|
ObjectValue,
|
|
Value,
|
|
type Arguments,
|
|
type FunctionCallContext,
|
|
UndefinedValue,
|
|
type PropertyKeyValue,
|
|
Descriptor,
|
|
SymbolValue,
|
|
JSStringValue,
|
|
} from '../value.mts';
|
|
import {
|
|
surroundingAgent,
|
|
} from '../host-defined/engine.mts';
|
|
import { Q, X, type ValueEvaluator } from '../completion.mts';
|
|
import { AddEntriesFromIterable } from './Map.mts';
|
|
import { bootstrapConstructor } from './bootstrap.mts';
|
|
import {
|
|
Assert,
|
|
CreateArrayFromList,
|
|
CreateDataProperty,
|
|
DefinePropertyOrThrow,
|
|
CreateDataPropertyOrThrow,
|
|
EnumerableOwnProperties,
|
|
FromPropertyDescriptor,
|
|
Get,
|
|
HasOwnProperty,
|
|
IsExtensible,
|
|
OrdinaryObjectCreate,
|
|
OrdinaryCreateFromConstructor,
|
|
RequireObjectCoercible,
|
|
SameValue,
|
|
Set,
|
|
SetIntegrityLevel,
|
|
TestIntegrityLevel,
|
|
ToObject,
|
|
ToPropertyDescriptor,
|
|
ToPropertyKey,
|
|
CreateBuiltinFunction,
|
|
Realm,
|
|
type FunctionObject,
|
|
GroupBy,
|
|
type KeyedGroupRecord,
|
|
} from '#self';
|
|
|
|
/** https://tc39.es/ecma262/#sec-object-value */
|
|
function* ObjectConstructor([value = Value.undefined]: Arguments, { NewTarget }: FunctionCallContext): ValueEvaluator {
|
|
// 1. If NewTarget is neither undefined nor the active function, then
|
|
if (NewTarget !== Value.undefined && NewTarget !== surroundingAgent.activeFunctionObject) {
|
|
// a. Return ? OrdinaryCreateFromConstructor(NewTarget, "%Object.prototype%").
|
|
return yield* OrdinaryCreateFromConstructor(NewTarget as FunctionObject, '%Object.prototype%');
|
|
}
|
|
// 2. If value is undefined or null, return OrdinaryObjectCreate(%Object.prototype%).
|
|
if (value === Value.null || value === Value.undefined) {
|
|
return OrdinaryObjectCreate(surroundingAgent.intrinsic('%Object.prototype%'));
|
|
}
|
|
// 3. Return ! ToObject(value).
|
|
return X(ToObject(value));
|
|
}
|
|
|
|
/** https://tc39.es/ecma262/#sec-object.assign */
|
|
function* Object_assign([target = Value.undefined, ...sources]: Arguments): ValueEvaluator {
|
|
// 1. Let to be ? ToObject(target).
|
|
const to = Q(ToObject(target));
|
|
// 2. If only one argument was passed, return to.
|
|
if (sources.length === 0) {
|
|
return to;
|
|
}
|
|
// 3. Let sources be the List of argument values starting with the second argument.
|
|
// 4. For each element nextSource of sources, in ascending index order, do
|
|
for (const nextSource of (sources as Arguments).values()) {
|
|
// a. If nextSource is neither undefined nor null, then
|
|
if (nextSource !== Value.undefined && nextSource !== Value.null) {
|
|
// i. Let from be ! ToObject(nextSource).
|
|
const from = X(ToObject(nextSource));
|
|
// ii. Let keys be ? from.[[OwnPropertyKeys]]().
|
|
const keys = Q(yield* from.OwnPropertyKeys());
|
|
// iii. For each element nextKey of keys in List order, do
|
|
for (const nextKey of keys) {
|
|
// 1. Let desc be ? from.[[GetOwnProperty]](nextKey).
|
|
const desc = Q(yield* from.GetOwnProperty(nextKey));
|
|
// 2. If desc is not undefined and desc.[[Enumerable]] is true, then
|
|
if (!(desc instanceof UndefinedValue) && desc.Enumerable === Value.true) {
|
|
// a. Let propValue be ? Get(from, nextKey).
|
|
const propValue = Q(yield* Get(from, nextKey));
|
|
// b. Perform ? Set(to, nextKey, propValue, true).
|
|
Q(yield* Set(to, nextKey, propValue, Value.true));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
// 5. Return to.
|
|
return to;
|
|
}
|
|
|
|
/** https://tc39.es/ecma262/#sec-object.create */
|
|
function* Object_create([O = Value.undefined, Properties = Value.undefined]: Arguments) {
|
|
// 1. If Type(O) is neither Object nor Null, throw a TypeError exception.
|
|
if (!(O instanceof ObjectValue) && !(O instanceof NullValue)) {
|
|
return surroundingAgent.Throw('TypeError', 'ObjectPrototypeType');
|
|
}
|
|
// 2. Let obj be OrdinaryObjectCreate(O).
|
|
const obj = OrdinaryObjectCreate(O);
|
|
// 3. If Properties is not undefined, then
|
|
if (Properties !== Value.undefined) {
|
|
// a. Return ? ObjectDefineProperties(obj, Properties).
|
|
return Q(yield* ObjectDefineProperties(obj, Properties));
|
|
}
|
|
// 4. Return obj.
|
|
return obj;
|
|
}
|
|
|
|
/** https://tc39.es/ecma262/#sec-object.defineproperties */
|
|
function* Object_defineProperties([O = Value.undefined, Properties = Value.undefined]: Arguments): ValueEvaluator {
|
|
// 1. Return ? ObjectDefineProperties(O, Properties).
|
|
return Q(yield* ObjectDefineProperties(O, Properties));
|
|
}
|
|
|
|
/** https://tc39.es/ecma262/#sec-objectdefineproperties ObjectDefineProperties */
|
|
function* ObjectDefineProperties(O: Value, Properties: Value) {
|
|
// 1. If Type(O) is not Object, throw a TypeError exception.
|
|
if (!(O instanceof ObjectValue)) {
|
|
return surroundingAgent.Throw('TypeError', 'NotAnObject', O);
|
|
}
|
|
// 2. Let props be ? ToObject(Properties).
|
|
const props = Q(ToObject(Properties));
|
|
// 3. Let keys be ? props.[[OwnPropertyKeys]]().
|
|
const keys = Q(yield* props.OwnPropertyKeys());
|
|
// 4. Let descriptors be a new empty List.
|
|
const descriptors: [PropertyKeyValue, Descriptor][] = [];
|
|
// 5. For each element nextKey of keys in List order, do
|
|
for (const nextKey of keys) {
|
|
// a. Let propDesc be ? props.[[GetOwnProperty]](nextKey).
|
|
const propDesc = Q(yield* props.GetOwnProperty(nextKey));
|
|
// b. If propDesc is not undefined and propDesc.[[Enumerable]] is true, then
|
|
if (!(propDesc instanceof UndefinedValue) && propDesc.Enumerable === Value.true) {
|
|
// i. Let descObj be ? Get(props, nextKey).
|
|
const descObj = Q(yield* Get(props, nextKey));
|
|
// ii. Let desc be ? ToPropertyDescriptor(descObj).
|
|
const desc = Q(yield* ToPropertyDescriptor(descObj));
|
|
// iii. Append the pair (a two element List) consisting of nextKey and desc to the end of descriptors.
|
|
descriptors.push([nextKey, desc]);
|
|
}
|
|
}
|
|
// 6. For each pair from descriptors in list order, do
|
|
for (const pair of descriptors) {
|
|
// a. Let P be the first element of pair.
|
|
const P = pair[0];
|
|
// b. Let desc be the second element of pair.
|
|
const desc = pair[1];
|
|
// c. Perform ? DefinePropertyOrThrow(O, P, desc).
|
|
Q(yield* DefinePropertyOrThrow(O, P, desc));
|
|
}
|
|
// 7. Return O.
|
|
return O;
|
|
}
|
|
|
|
/** https://tc39.es/ecma262/#sec-object.defineproperty */
|
|
function* Object_defineProperty([O = Value.undefined, P = Value.undefined, Attributes = Value.undefined]: Arguments) {
|
|
// 1. If Type(O) is not Object, throw a TypeError exception.
|
|
if (!(O instanceof ObjectValue)) {
|
|
return surroundingAgent.Throw('TypeError', 'NotAnObject', O);
|
|
}
|
|
// 2. Let key be ? ToPropertyKey(P).
|
|
const key = Q(yield* ToPropertyKey(P));
|
|
// 3. Let desc be ? ToPropertyDescriptor(Attributes).
|
|
const desc = Q(yield* ToPropertyDescriptor(Attributes));
|
|
// 4. Perform ? DefinePropertyOrThrow(O, key, desc).
|
|
Q(yield* DefinePropertyOrThrow(O, key, desc));
|
|
// 5. Return O.
|
|
return O;
|
|
}
|
|
|
|
/** https://tc39.es/ecma262/#sec-object.entries */
|
|
function* Object_entries([O = Value.undefined]: Arguments): ValueEvaluator {
|
|
// 1. Let obj be ? ToObject(O).
|
|
const obj = Q(ToObject(O));
|
|
// 2. Let nameList be ? EnumerableOwnPropertyNames(obj, key+value).
|
|
const nameList = Q(yield* EnumerableOwnProperties(obj, 'key+value'));
|
|
// 3. Return CreateArrayFromList(nameList).
|
|
return CreateArrayFromList(nameList);
|
|
}
|
|
|
|
/** https://tc39.es/ecma262/#sec-object.freeze */
|
|
function* Object_freeze([O = Value.undefined]: Arguments) {
|
|
// 1. If Type(O) is not Object, return O.
|
|
if (!(O instanceof ObjectValue)) {
|
|
return O;
|
|
}
|
|
// 2. Let status be ? SetIntegrityLevel(O, frozen).
|
|
const status = Q(yield* SetIntegrityLevel(O, 'frozen'));
|
|
// 3. If status is false, throw a TypeError exception.
|
|
if (status === Value.false) {
|
|
return surroundingAgent.Throw('TypeError', 'UnableToFreeze', O);
|
|
}
|
|
// 4. Return O.
|
|
return O;
|
|
}
|
|
|
|
/** https://tc39.es/ecma262/#sec-object.fromentries */
|
|
function* Object_fromEntries([iterable = Value.undefined]: Arguments): ValueEvaluator {
|
|
// 1. Perform ? RequireObjectCoercible(iterable).
|
|
Q(RequireObjectCoercible(iterable));
|
|
// 2. Let obj be ! OrdinaryObjectCreate(%Object.prototype%).
|
|
const obj = X(OrdinaryObjectCreate(surroundingAgent.intrinsic('%Object.prototype%')));
|
|
// 3. Assert: obj is an extensible ordinary object with no own properties.
|
|
Assert(obj.Extensible === Value.true && obj.properties.size === 0);
|
|
// 4. Let closure be a new Abstract Closure with parameters (key, value) that captures obj and performs the following steps when called:
|
|
function* closure([key = Value.undefined, value = Value.undefined]: Arguments): ValueEvaluator {
|
|
// a. Let propertyKey be ? ToPropertyKey(key).
|
|
const propertyKey = Q(yield* ToPropertyKey(key));
|
|
// b. Perform ! CreateDataPropertyOrThrow(obj, propertyKey, value).
|
|
X(CreateDataPropertyOrThrow(obj, propertyKey, value));
|
|
// c. Return undefined.
|
|
return Value.undefined;
|
|
}
|
|
// 5. Let adder be ! CreateBuiltinFunction(closure, 2, "", « »).
|
|
const adder = X(CreateBuiltinFunction(closure, 2, Value(''), []));
|
|
// 6. Return ? AddEntriesFromIterable(obj, iterable, adder).
|
|
return Q(yield* AddEntriesFromIterable(obj, iterable, adder));
|
|
}
|
|
|
|
/** https://tc39.es/ecma262/#sec-object.getownpropertydescriptor */
|
|
function* Object_getOwnPropertyDescriptor([O = Value.undefined, P = Value.undefined]: Arguments): ValueEvaluator {
|
|
// 1. Let obj be ? ToObject(O).
|
|
const obj = Q(ToObject(O));
|
|
// 2. Let key be ? ToPropertyKey(P).
|
|
const key = Q(yield* ToPropertyKey(P));
|
|
// 3. Let desc be ? obj.[[GetOwnProperty]](key).
|
|
const desc = Q(yield* obj.GetOwnProperty(key));
|
|
// 4. Return FromPropertyDescriptor(desc).
|
|
return FromPropertyDescriptor(desc);
|
|
}
|
|
|
|
/** https://tc39.es/ecma262/#sec-object.getownpropertydescriptors */
|
|
function* Object_getOwnPropertyDescriptors([O = Value.undefined]: Arguments): ValueEvaluator {
|
|
// 1. Let obj be ? ToObject(O).
|
|
const obj = Q(ToObject(O));
|
|
// 2. Let ownKeys be ? obj.[[OwnPropertyKeys]]().
|
|
const ownKeys = Q(yield* obj.OwnPropertyKeys());
|
|
// 3. Let descriptors be ! OrdinaryObjectCreate(%Object.prototype%).
|
|
const descriptors = X(OrdinaryObjectCreate(surroundingAgent.intrinsic('%Object.prototype%')));
|
|
// 4. For each element key of ownKeys in List order, do
|
|
for (const key of ownKeys) {
|
|
// a. Let desc be ? obj.[[GetOwnProperty]](key).
|
|
const desc = Q(yield* obj.GetOwnProperty(key));
|
|
// b. Let descriptor be ! FromPropertyDescriptor(desc).
|
|
const descriptor = X(FromPropertyDescriptor(desc));
|
|
// c. If descriptor is not undefined, perform ! CreateDataPropertyOrThrow(descriptors, key, descriptor).
|
|
if (descriptor !== Value.undefined) {
|
|
X(CreateDataProperty(descriptors, key, descriptor));
|
|
}
|
|
}
|
|
// 5. Return descriptors.
|
|
return descriptors;
|
|
}
|
|
|
|
/** https://tc39.es/ecma262/#sec-getownpropertykeys */
|
|
function* GetOwnPropertyKeys(O: Value, type: 'String' | 'Symbol'): ValueEvaluator {
|
|
// 1. Let obj be ? ToObject(O).
|
|
const obj = Q(ToObject(O));
|
|
// 2. Let keys be ? obj.[[OwnPropertyKeys]]().
|
|
const keys = Q(yield* obj.OwnPropertyKeys());
|
|
// 3. Let nameList be a new empty List.
|
|
const nameList: PropertyKeyValue[] = [];
|
|
// 4. For each element nextKey of keys in List order, do
|
|
keys.forEach((nextKey) => {
|
|
// a. If nextKey is a Symbol and type is symbol, or if nextKey is a String and type is string, then
|
|
if ((type === 'Symbol' && nextKey instanceof SymbolValue) || (type === 'String' && nextKey instanceof JSStringValue)) {
|
|
// i. Append nextKey as the last element of nameList.
|
|
nameList.push(nextKey);
|
|
}
|
|
});
|
|
return CreateArrayFromList(nameList);
|
|
}
|
|
|
|
/** https://tc39.es/ecma262/#sec-object.getownpropertynames */
|
|
function* Object_getOwnPropertyNames([O = Value.undefined]: Arguments): ValueEvaluator {
|
|
// 1. Return ? GetOwnPropertyKeys(O, string).
|
|
return Q(yield* GetOwnPropertyKeys(O, 'String'));
|
|
}
|
|
|
|
/** https://tc39.es/ecma262/#sec-object.getownpropertysymbols */
|
|
function* Object_getOwnPropertySymbols([O = Value.undefined]: Arguments): ValueEvaluator {
|
|
// 1. Return ? GetOwnPropertyKeys(O, symbol).
|
|
return Q(yield* GetOwnPropertyKeys(O, 'Symbol'));
|
|
}
|
|
|
|
/** https://tc39.es/ecma262/#sec-object.getprototypeof */
|
|
function* Object_getPrototypeOf([O = Value.undefined]: Arguments): ValueEvaluator {
|
|
// 1. Let obj be ? ToObject(O).
|
|
const obj = Q(ToObject(O));
|
|
// 2. Return ? obj.[[GetPrototypeOf]]().
|
|
return Q(yield* obj.GetPrototypeOf());
|
|
}
|
|
|
|
/** https://tc39.es/ecma262/#sec-object.groupby */
|
|
function* Object_groupBy([items = Value.undefined, callback = Value.undefined]: Arguments): ValueEvaluator {
|
|
/*
|
|
1. Let groups be ? GroupBy(items, callback, property).
|
|
2. Let obj be OrdinaryObjectCreate(null).
|
|
3. For each Record { [[Key]], [[Elements]] } g of groups, do
|
|
a. Let elements be CreateArrayFromList(g.[[Elements]]).
|
|
b. Perform ! CreateDataPropertyOrThrow(obj, g.[[Key]], elements).
|
|
4. Return obj.
|
|
*/
|
|
const groups: KeyedGroupRecord[] = Q(yield* GroupBy(items, callback, 'property'));
|
|
const obj = OrdinaryObjectCreate(Value.null);
|
|
for (const g of groups) {
|
|
const elements = CreateArrayFromList(g.Elements);
|
|
X(CreateDataPropertyOrThrow(obj, g.Key, elements));
|
|
}
|
|
return obj;
|
|
}
|
|
|
|
/** https://tc39.es/ecma262/#sec-object.hasown */
|
|
function* Object_hasOwn([O = Value.undefined, P = Value.undefined]: Arguments): ValueEvaluator {
|
|
// 1. Let obj be ? ToObject(O).
|
|
const obj = Q(ToObject(O));
|
|
// 2. Let O be ? ToObject(this value).
|
|
const key = Q(yield* ToPropertyKey(P));
|
|
// 3. Return ? HasOwnProperty(obj, key).
|
|
return yield* HasOwnProperty(obj, key);
|
|
}
|
|
|
|
/** https://tc39.es/ecma262/#sec-object.is */
|
|
function Object_is([value1 = Value.undefined, value2 = Value.undefined]: Arguments) {
|
|
// 1. Return SameValue(value1, value2).
|
|
return SameValue(value1, value2);
|
|
}
|
|
|
|
/** https://tc39.es/ecma262/#sec-object.isextensible */
|
|
function* Object_isExtensible([O = Value.undefined]: Arguments): ValueEvaluator {
|
|
// 1. If Type(O) is not Object, return false.
|
|
if (!(O instanceof ObjectValue)) {
|
|
return Value.false;
|
|
}
|
|
// 2. Return ? IsExtensible(O).
|
|
return Q(yield* IsExtensible(O));
|
|
}
|
|
|
|
/** https://tc39.es/ecma262/#sec-object.isfrozen */
|
|
function* Object_isFrozen([O = Value.undefined]: Arguments): ValueEvaluator {
|
|
// 1. If Type(O) is not Object, return true.
|
|
if (!(O instanceof ObjectValue)) {
|
|
return Value.true;
|
|
}
|
|
// 2. Return ? TestIntegrityLevel(O, frozen).
|
|
return Q(yield* TestIntegrityLevel(O, 'frozen'));
|
|
}
|
|
|
|
/** https://tc39.es/ecma262/#sec-object.issealed */
|
|
function* Object_isSealed([O = Value.undefined]: Arguments): ValueEvaluator {
|
|
// 1. If Type(O) is not Object, return true.
|
|
if (!(O instanceof ObjectValue)) {
|
|
return Value.true;
|
|
}
|
|
// 2. Return ? TestIntegrityLevel(O, sealed).
|
|
return Q(yield* TestIntegrityLevel(O, 'sealed'));
|
|
}
|
|
|
|
/** https://tc39.es/ecma262/#sec-object.keys */
|
|
function* Object_keys([O = Value.undefined]: Arguments): ValueEvaluator {
|
|
// 1. Let obj be ? ToObject(O).
|
|
const obj = Q(ToObject(O));
|
|
// 2. Let nameList be ? EnumerableOwnPropertyNames(obj, key).
|
|
const nameList = Q(yield* EnumerableOwnProperties(obj, 'key'));
|
|
// 3. Return CreateArrayFromList(nameList).
|
|
return CreateArrayFromList(nameList);
|
|
}
|
|
|
|
/** https://tc39.es/ecma262/#sec-object.preventextensions */
|
|
function* Object_preventExtensions([O = Value.undefined]: Arguments) {
|
|
// 1. If Type(O) is not Object, return O.
|
|
if (!(O instanceof ObjectValue)) {
|
|
return O;
|
|
}
|
|
// 2. Let status be ? O.[[PreventExtensions]]().
|
|
const status = Q(yield* O.PreventExtensions());
|
|
// 3. If status is false, throw a TypeError exception.
|
|
if (status === Value.false) {
|
|
return surroundingAgent.Throw('TypeError', 'UnableToPreventExtensions', O);
|
|
}
|
|
// 4. Return O.
|
|
return O;
|
|
}
|
|
|
|
/** https://tc39.es/ecma262/#sec-object.seal */
|
|
function* Object_seal([O = Value.undefined]: Arguments) {
|
|
// 1. If Type(O) is not Object, return O.
|
|
if (!(O instanceof ObjectValue)) {
|
|
return O;
|
|
}
|
|
// 2. Let status be ? SetIntegrityLevel(O, sealed).
|
|
const status = Q(yield* SetIntegrityLevel(O, 'sealed'));
|
|
// 3. If status is false, throw a TypeError exception.
|
|
if (status === Value.false) {
|
|
return surroundingAgent.Throw('TypeError', 'UnableToSeal', O);
|
|
}
|
|
// 4. Return O.
|
|
return O;
|
|
}
|
|
|
|
/** https://tc39.es/ecma262/#sec-object.setprototypeof */
|
|
function* Object_setPrototypeOf([O = Value.undefined, proto = Value.undefined]: Arguments) {
|
|
// 1. Perform ? RequireObjectCoercible(O).
|
|
Q(RequireObjectCoercible(O));
|
|
// 2. If Type(proto) is neither Object nor Null, throw a TypeError exception.
|
|
if (!(proto instanceof ObjectValue) && !(proto instanceof NullValue)) {
|
|
return surroundingAgent.Throw('TypeError', 'ObjectPrototypeType');
|
|
}
|
|
// 3. If Type(O) is not Object, return O.
|
|
if (!(O instanceof ObjectValue)) {
|
|
return O;
|
|
}
|
|
// 4. Let status be ? O.[[SetPrototypeOf]](proto).
|
|
const status = Q(yield* O.SetPrototypeOf(proto));
|
|
// 5. If status is false, throw a TypeError exception.
|
|
if (status === Value.false) {
|
|
return surroundingAgent.Throw('TypeError', 'ObjectSetPrototype');
|
|
}
|
|
// 6. Return O.
|
|
return O;
|
|
}
|
|
|
|
/** https://tc39.es/ecma262/#sec-object.values */
|
|
function* Object_values([O = Value.undefined]: Arguments): ValueEvaluator {
|
|
// 1. Let obj be ? ToObject(O).
|
|
const obj = Q(ToObject(O));
|
|
// 2. Let nameList be ? EnumerableOwnPropertyNames(obj, value).
|
|
const nameList = Q(yield* EnumerableOwnProperties(obj, 'value'));
|
|
// 3. Return CreateArrayFromList(nameList).
|
|
return CreateArrayFromList(nameList);
|
|
}
|
|
|
|
export function bootstrapObject(realmRec: Realm) {
|
|
const objectConstructor = bootstrapConstructor(realmRec, ObjectConstructor, 'Object', 1, realmRec.Intrinsics['%Object.prototype%'], [
|
|
['assign', Object_assign, 2],
|
|
['create', Object_create, 2],
|
|
['defineProperties', Object_defineProperties, 2],
|
|
['defineProperty', Object_defineProperty, 3],
|
|
['entries', Object_entries, 1],
|
|
['freeze', Object_freeze, 1],
|
|
['fromEntries', Object_fromEntries, 1],
|
|
['getOwnPropertyDescriptor', Object_getOwnPropertyDescriptor, 2],
|
|
['getOwnPropertyDescriptors', Object_getOwnPropertyDescriptors, 1],
|
|
['getOwnPropertyNames', Object_getOwnPropertyNames, 1],
|
|
['getOwnPropertySymbols', Object_getOwnPropertySymbols, 1],
|
|
['getPrototypeOf', Object_getPrototypeOf, 1],
|
|
['groupBy', Object_groupBy, 2],
|
|
['hasOwn', Object_hasOwn, 2],
|
|
['is', Object_is, 2],
|
|
['isExtensible', Object_isExtensible, 1],
|
|
['isFrozen', Object_isFrozen, 1],
|
|
['isSealed', Object_isSealed, 1],
|
|
['keys', Object_keys, 1],
|
|
['preventExtensions', Object_preventExtensions, 1],
|
|
['seal', Object_seal, 1],
|
|
['setPrototypeOf', Object_setPrototypeOf, 2],
|
|
['values', Object_values, 1],
|
|
]);
|
|
|
|
realmRec.Intrinsics['%Object%'] = objectConstructor;
|
|
}
|