Skip to content

Commit e025c84

Browse files
ExE-Bossdomenic
authored andcommitted
Add and use utils.define(…) helper
1 parent 66c9357 commit e025c84

File tree

3 files changed

+384
-434
lines changed

3 files changed

+384
-434
lines changed

Diff for: lib/constructs/interface.js

+6-14
Original file line numberDiff line numberDiff line change
@@ -1277,11 +1277,7 @@ class Interface {
12771277

12781278
if (_needsUnforgeablesObject) {
12791279
this.str += `
1280-
const unforgeables = getUnforgeables(globalObject);
1281-
for (const key of Reflect.ownKeys(unforgeables)) {
1282-
const descriptor = Reflect.getOwnPropertyDescriptor(unforgeables, key);
1283-
Object.defineProperty(wrapper, key, descriptor);
1284-
}
1280+
utils.define(wrapper, getUnforgeables(globalObject));
12851281
`;
12861282
}
12871283

@@ -1572,10 +1568,9 @@ class Interface {
15721568
const propStrs = [...props].map(([name, body]) => `${name}: ${body}`);
15731569
if (methods.length > 0) {
15741570
this.str += `
1575-
Object.defineProperties(
1576-
wrapper,
1577-
Object.getOwnPropertyDescriptors({ ${methods.join(", ")} })
1578-
);
1571+
utils.define(wrapper, {
1572+
${methods.join(", ")}
1573+
});
15791574
`;
15801575
}
15811576
if (propStrs.length > 0) {
@@ -1626,16 +1621,13 @@ class Interface {
16261621
function getUnforgeables(globalObject) {
16271622
let unforgeables = unforgeablesMap.get(globalObject);
16281623
if (unforgeables === undefined) {
1629-
unforgeables = Object.create(
1630-
null,
1624+
unforgeables = Object.create(null);
16311625
`;
16321626

16331627
if (methods.length > 0) {
1634-
this.str += `Object.getOwnPropertyDescriptors({ ${methods.join(", ")} }),`;
1628+
this.str += `utils.define(unforgeables, { ${methods.join(", ")} });`;
16351629
}
16361630

1637-
this.str += ");";
1638-
16391631
if (props.size > 0) {
16401632
const propStrs = [...props].map(([name, body]) => `${name}: ${body}`);
16411633
this.str += `

Diff for: lib/output/utils.js

+12
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,17 @@ function isObject(value) {
77

88
const hasOwn = Function.prototype.call.bind(Object.prototype.hasOwnProperty);
99

10+
// Like `Object.assign`, but using `[[GetOwnProperty]]` and `[[DefineOwnProperty]]`
11+
// instead of `[[Get]]` and `[[Set]]` and only allowing objects
12+
function define(target, source) {
13+
for (const key of Reflect.ownKeys(source)) {
14+
const descriptor = Reflect.getOwnPropertyDescriptor(source, key);
15+
if (descriptor && !Reflect.defineProperty(target, key, descriptor)) {
16+
throw new TypeError(`Cannot redefine property: ${String(key)}`);
17+
}
18+
}
19+
}
20+
1021
const wrapperSymbol = Symbol("wrapper");
1122
const implSymbol = Symbol("impl");
1223
const sameObjectCaches = Symbol("SameObject caches");
@@ -131,6 +142,7 @@ const asyncIteratorEOI = Symbol("async iterator end of iteration");
131142
module.exports = exports = {
132143
isObject,
133144
hasOwn,
145+
define,
134146
wrapperSymbol,
135147
implSymbol,
136148
getSameObject,

0 commit comments

Comments
 (0)