Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

lib: add TypedArray to the primordials #32127

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 5 additions & 13 deletions lib/buffer.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,11 @@ const {
ObjectCreate,
ObjectDefineProperties,
ObjectDefineProperty,
ObjectGetOwnPropertyDescriptor,
ObjectGetPrototypeOf,
ObjectSetPrototypeOf,
SymbolSpecies,
SymbolToPrimitive,
Uint8ArrayPrototype,
TypedArrayPrototypeByteLength,
TypedArrayPrototypeFill,
} = primordials;

const {
Expand Down Expand Up @@ -107,13 +106,6 @@ const {
addBufferPrototypeMethods
} = require('internal/buffer');

const TypedArrayPrototype = ObjectGetPrototypeOf(Uint8ArrayPrototype);

const TypedArrayProto_byteLength =
ObjectGetOwnPropertyDescriptor(TypedArrayPrototype,
'byteLength').get;
const TypedArrayFill = TypedArrayPrototype.fill;

FastBuffer.prototype.constructor = Buffer;
Buffer.prototype = FastBuffer.prototype;
addBufferPrototypeMethods(Buffer.prototype);
Expand Down Expand Up @@ -581,7 +573,7 @@ Buffer.concat = function concat(list, length) {
// Zero-fill the remaining bytes if the specified `length` was more than
// the actual total length, i.e. if we have some remaining allocated bytes
// there were not initialized.
TypedArrayFill.call(buffer, 0, pos, length);
TypedArrayPrototypeFill(buffer, 0, pos, length);
}

return buffer;
Expand Down Expand Up @@ -1020,12 +1012,12 @@ function _fill(buf, value, offset, end, encoding) {

if (typeof value === 'number') {
// OOB check
const byteLen = TypedArrayProto_byteLength.call(buf);
const byteLen = TypedArrayPrototypeByteLength(buf);
const fillLength = end - offset;
if (offset > end || fillLength + offset > byteLen)
throw new ERR_BUFFER_OUT_OF_BOUNDS();

TypedArrayFill.call(buf, value, offset, end);
TypedArrayPrototypeFill(buf, value, offset, end);
} else {
const res = bindingFill(buf, value, offset, end, encoding);
if (res < 0) {
Expand Down
33 changes: 24 additions & 9 deletions lib/internal/per_context/primordials.js
Original file line number Diff line number Diff line change
Expand Up @@ -65,16 +65,22 @@ function copyPropsRenamedBound(src, dest, prefix) {

function copyPrototype(src, dest, prefix) {
for (const key of Reflect.ownKeys(src)) {
if (typeof key === 'string') {
const desc = Reflect.getOwnPropertyDescriptor(src, key);
if (typeof desc.value === 'function') {
desc.value = uncurryThis(desc.value);
}
Reflect.defineProperty(
dest,
`${prefix}${key[0].toUpperCase()}${key.slice(1)}`,
desc);
let newKey;
if (typeof key === 'symbol') {
const name = key.description.slice(7);
newKey = `${prefix}Symbol${name[0].toUpperCase()}${name.slice(1)}`;
} else {
newKey = `${prefix}${key[0].toUpperCase()}${key.slice(1)}`;
}
const desc = Reflect.getOwnPropertyDescriptor(src, key);
if (typeof desc.value === 'function') {
desc.value = uncurryThis(desc.value);
} else if (typeof desc.get === 'function') {
desc.value = uncurryThis(desc.get);
delete desc.get;
delete desc.set;
}
Reflect.defineProperty(dest, newKey, desc);
Comment on lines +75 to +83
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should probably also save the setter if it exists.

Suggested change
const desc = Reflect.getOwnPropertyDescriptor(src, key);
if (typeof desc.value === 'function') {
desc.value = uncurryThis(desc.value);
} else if (typeof desc.get === 'function') {
desc.value = uncurryThis(desc.get);
delete desc.get;
delete desc.set;
}
Reflect.defineProperty(dest, newKey, desc);
const desc = Reflect.getOwnPropertyDescriptor(src, key);
let setterDesc;
if (typeof desc.value === 'function') {
desc.value = uncurryThis(desc.value);
} else if (typeof desc.get === 'function') {
desc.value = uncurryThis(desc.get);
if (typeof desc.set === 'function') {
setterDesc = { value: uncurryThis(desc.set), enumerable: desc.enumerable };
}
delete desc.get;
delete desc.set;
}
Reflect.defineProperty(dest, newKey, desc);
if (setterDesc) {
Reflect.defineProperty(dest, `${newKey}Setter`, desc);
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I’ve extracted this change into #36329.

}
}

Expand Down Expand Up @@ -163,5 +169,14 @@ primordials.SafePromise = makeSafe(
copyPrototype(original.prototype, primordials, `${name}Prototype`);
});

// Create copies of objects that are not immediately available on `globalThis`.
[
['TypedArray', Object.getPrototypeOf(Uint8Array)]
].forEach(([name, original]) => {
primordials[name] = original;
copyPropsRenamed(original, primordials, name);
copyPrototype(original.prototype, primordials, `${name}Prototype`);
});

Object.setPrototypeOf(primordials, null);
Object.freeze(primordials);
19 changes: 6 additions & 13 deletions lib/internal/util/inspect.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ const {
Float32Array,
JSONStringify,
Map,
MapPrototype,
MapPrototypeEntries,
MapPrototypeSize,
MathFloor,
MathMax,
MathMin,
Expand All @@ -39,13 +39,14 @@ const {
RegExp,
RegExpPrototypeToString,
Set,
SetPrototype,
SetPrototypeSize,
SetPrototypeValues,
StringPrototypeValueOf,
SymbolPrototypeToString,
SymbolPrototypeValueOf,
SymbolIterator,
SymbolToStringTag,
TypedArrayPrototypeLength,
Uint16Array,
uncurryThis,
} = primordials;
Expand Down Expand Up @@ -120,14 +121,6 @@ const assert = require('internal/assert');

const { NativeModule } = require('internal/bootstrap/loaders');

const setSizeGetter = uncurryThis(
ObjectGetOwnPropertyDescriptor(SetPrototype, 'size').get);
const mapSizeGetter = uncurryThis(
ObjectGetOwnPropertyDescriptor(MapPrototype, 'size').get);
const typedArraySizeGetter = uncurryThis(
ObjectGetOwnPropertyDescriptor(
ObjectGetPrototypeOf(Uint8Array.prototype), 'length').get);

let hexSlice;

const builtInObjects = new Set(
Expand Down Expand Up @@ -802,7 +795,7 @@ function formatRaw(ctx, value, recurseTimes, typedArray) {
extrasType = kArrayExtrasType;
formatter = formatArray;
} else if (isSet(value)) {
const size = setSizeGetter(value);
const size = SetPrototypeSize(value);
const prefix = getPrefix(constructor, tag, 'Set', `(${size})`);
keys = getKeys(value, ctx.showHidden);
formatter = constructor !== null ?
Expand All @@ -812,7 +805,7 @@ function formatRaw(ctx, value, recurseTimes, typedArray) {
return `${prefix}{}`;
braces = [`${prefix}{`, '}'];
} else if (isMap(value)) {
const size = mapSizeGetter(value);
const size = MapPrototypeSize(value);
const prefix = getPrefix(constructor, tag, 'Map', `(${size})`);
keys = getKeys(value, ctx.showHidden);
formatter = constructor !== null ?
Expand All @@ -831,7 +824,7 @@ function formatRaw(ctx, value, recurseTimes, typedArray) {
// Reconstruct the array information.
bound = new constr(value);
}
const size = typedArraySizeGetter(value);
const size = TypedArrayPrototypeLength(value);
const prefix = getPrefix(constructor, tag, fallback, `(${size})`);
braces = [`${prefix}[`, ']'];
if (value.length === 0 && keys.length === 0 && !ctx.showHidden)
Expand Down
36 changes: 13 additions & 23 deletions lib/internal/util/types.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,65 +2,55 @@

const {
ArrayBufferIsView,
ObjectGetOwnPropertyDescriptor,
ObjectGetPrototypeOf,
SymbolToStringTag,
uncurryThis,
TypedArrayPrototypeSymbolToStringTag,
} = primordials;

const TypedArrayPrototype = ObjectGetPrototypeOf(Uint8Array.prototype);

const TypedArrayProto_toStringTag =
uncurryThis(
ObjectGetOwnPropertyDescriptor(TypedArrayPrototype,
SymbolToStringTag).get);

function isTypedArray(value) {
return TypedArrayProto_toStringTag(value) !== undefined;
return TypedArrayPrototypeSymbolToStringTag(value) !== undefined;
}

function isUint8Array(value) {
return TypedArrayProto_toStringTag(value) === 'Uint8Array';
return TypedArrayPrototypeSymbolToStringTag(value) === 'Uint8Array';
}

function isUint8ClampedArray(value) {
return TypedArrayProto_toStringTag(value) === 'Uint8ClampedArray';
return TypedArrayPrototypeSymbolToStringTag(value) === 'Uint8ClampedArray';
}

function isUint16Array(value) {
return TypedArrayProto_toStringTag(value) === 'Uint16Array';
return TypedArrayPrototypeSymbolToStringTag(value) === 'Uint16Array';
}

function isUint32Array(value) {
return TypedArrayProto_toStringTag(value) === 'Uint32Array';
return TypedArrayPrototypeSymbolToStringTag(value) === 'Uint32Array';
}

function isInt8Array(value) {
return TypedArrayProto_toStringTag(value) === 'Int8Array';
return TypedArrayPrototypeSymbolToStringTag(value) === 'Int8Array';
}

function isInt16Array(value) {
return TypedArrayProto_toStringTag(value) === 'Int16Array';
return TypedArrayPrototypeSymbolToStringTag(value) === 'Int16Array';
}

function isInt32Array(value) {
return TypedArrayProto_toStringTag(value) === 'Int32Array';
return TypedArrayPrototypeSymbolToStringTag(value) === 'Int32Array';
}

function isFloat32Array(value) {
return TypedArrayProto_toStringTag(value) === 'Float32Array';
return TypedArrayPrototypeSymbolToStringTag(value) === 'Float32Array';
}

function isFloat64Array(value) {
return TypedArrayProto_toStringTag(value) === 'Float64Array';
return TypedArrayPrototypeSymbolToStringTag(value) === 'Float64Array';
}

function isBigInt64Array(value) {
return TypedArrayProto_toStringTag(value) === 'BigInt64Array';
return TypedArrayPrototypeSymbolToStringTag(value) === 'BigInt64Array';
}

function isBigUint64Array(value) {
return TypedArrayProto_toStringTag(value) === 'BigUint64Array';
return TypedArrayPrototypeSymbolToStringTag(value) === 'BigUint64Array';
}

module.exports = {
Expand Down