Skip to content

Commit b8f389f

Browse files
authored
Fix realm for async iterators and iterator result objects
1 parent f60e95a commit b8f389f

File tree

4 files changed

+117
-67
lines changed

4 files changed

+117
-67
lines changed

lib/constructs/interface.js

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -424,13 +424,15 @@ class Interface {
424424
}
425425

426426
if (iterable.isAsync) {
427+
this.requires.addRaw("newObjectInRealm", "utils.newObjectInRealm");
427428
this.str += `
428-
ctorRegistry["${this.name} AsyncIterator"] = Object.create(utils.AsyncIteratorPrototype, {
429-
[Symbol.toStringTag]: {
430-
value: "${this.name} AsyncIterator",
431-
configurable: true
432-
}
433-
});
429+
ctorRegistry["${this.name} AsyncIterator"] =
430+
Object.create(ctorRegistry["%AsyncIteratorPrototype%"], {
431+
[Symbol.toStringTag]: {
432+
value: "${this.name} AsyncIterator",
433+
configurable: true
434+
}
435+
});
434436
utils.define(ctorRegistry["${this.name} AsyncIterator"], {
435437
next() {
436438
const internal = this && this[utils.iterInternalSymbol];
@@ -440,7 +442,7 @@ class Interface {
440442
441443
const nextSteps = () => {
442444
if (internal.isFinished) {
443-
return Promise.resolve({ value: undefined, done: true });
445+
return Promise.resolve(newObjectInRealm(globalObject, { value: undefined, done: true }));
444446
}
445447
446448
const nextPromise = internal.target[implSymbol][utils.asyncIteratorNext](this);
@@ -449,15 +451,15 @@ class Interface {
449451
internal.ongoingPromise = null;
450452
if (next === utils.asyncIteratorEOI) {
451453
internal.isFinished = true;
452-
return { value: undefined, done: true };
454+
return newObjectInRealm(globalObject, { value: undefined, done: true });
453455
}`;
454456
if (iterable.isPair) {
455457
this.str += `
456-
return utils.iteratorResult(next.map(utils.tryWrapperForImpl), kind);
458+
return newObjectInRealm(globalObject, utils.iteratorResult(next.map(utils.tryWrapperForImpl), kind));
457459
`;
458460
} else {
459461
this.str += `
460-
return { value: utils.tryWrapperForImpl(next), done: false };
462+
return newObjectInRealm(globalObject, { value: utils.tryWrapperForImpl(next), done: false });
461463
`;
462464
}
463465
this.str += `
@@ -487,7 +489,7 @@ class Interface {
487489
488490
const returnSteps = () => {
489491
if (internal.isFinished) {
490-
return Promise.resolve({ value, done: true });
492+
return Promise.resolve(newObjectInRealm(globalObject, { value, done: true }));
491493
}
492494
internal.isFinished = true;
493495
@@ -497,14 +499,15 @@ class Interface {
497499
const returnPromise = internal.ongoingPromise ?
498500
internal.ongoingPromise.then(returnSteps, returnSteps) :
499501
returnSteps();
500-
return returnPromise.then(() => ({ value, done: true }));
502+
return returnPromise.then(() => newObjectInRealm(globalObject, { value, done: true }));
501503
}
502504
`;
503505
}
504506
this.str += `
505507
});
506508
`;
507509
} else if (iterable.isPair) {
510+
this.requires.addRaw("newObjectInRealm", "utils.newObjectInRealm");
508511
this.str += `
509512
ctorRegistry["${this.name} Iterator"] =
510513
Object.create(ctorRegistry["%IteratorPrototype%"], {
@@ -526,12 +529,12 @@ class Interface {
526529
const values = Array.from(target[implSymbol]);
527530
const len = values.length;
528531
if (index >= len) {
529-
return { value: undefined, done: true };
532+
return newObjectInRealm(globalObject, { value: undefined, done: true });
530533
}
531534
532535
const pair = values[index];
533536
internal.index = index + 1;
534-
return utils.iteratorResult(pair.map(utils.tryWrapperForImpl), kind);
537+
return newObjectInRealm(globalObject, utils.iteratorResult(pair.map(utils.tryWrapperForImpl), kind));
535538
}
536539
}
537540
);

lib/output/utils.js

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,14 @@ function define(target, source) {
1818
}
1919
}
2020

21+
function newObjectInRealm(globalObject, object) {
22+
const ctorRegistry = initCtorRegistry(globalObject);
23+
return Object.defineProperties(
24+
Object.create(ctorRegistry["%Object.prototype%"]),
25+
Object.getOwnPropertyDescriptors(object)
26+
);
27+
}
28+
2129
const wrapperSymbol = Symbol("wrapper");
2230
const implSymbol = Symbol("impl");
2331
const sameObjectCaches = Symbol("SameObject caches");
@@ -26,6 +34,8 @@ const ctorRegistrySymbol = Symbol.for("[webidl2js] constructor registry");
2634
// This only contains the intrinsic names that are referenced from the `ctorRegistry`:
2735
const intrinsicConstructors = ["Array"];
2836

37+
const AsyncIteratorPrototype = Object.getPrototypeOf(Object.getPrototypeOf(async function* () {}).prototype);
38+
2939
function initCtorRegistry(globalObject) {
3040
if (hasOwn(globalObject, ctorRegistrySymbol)) {
3141
return globalObject[ctorRegistrySymbol];
@@ -36,11 +46,21 @@ function initCtorRegistry(globalObject) {
3646
ctorRegistry[`%${intrinsic}%`] = globalObject[intrinsic];
3747
}
3848

39-
// TODO: Also capture `%AsyncIteratorPrototype%`
49+
ctorRegistry["%Object.prototype%"] = globalObject.Object.prototype;
4050
ctorRegistry["%IteratorPrototype%"] = Object.getPrototypeOf(
4151
Object.getPrototypeOf(new ctorRegistry["%Array%"]()[Symbol.iterator]())
4252
);
4353

54+
try {
55+
ctorRegistry["%AsyncIteratorPrototype%"] = Object.getPrototypeOf(
56+
Object.getPrototypeOf(
57+
globalObject.eval("(async function* () {})").prototype
58+
)
59+
);
60+
} catch {
61+
ctorRegistry["%AsyncIteratorPrototype%"] = AsyncIteratorPrototype;
62+
}
63+
4464
globalObject[ctorRegistrySymbol] = ctorRegistry;
4565
return ctorRegistry;
4666
}
@@ -77,8 +97,6 @@ function tryImplForWrapper(wrapper) {
7797
}
7898

7999
const iterInternalSymbol = Symbol("internal");
80-
const IteratorPrototype = Object.getPrototypeOf(Object.getPrototypeOf([][Symbol.iterator]()));
81-
const AsyncIteratorPrototype = Object.getPrototypeOf(Object.getPrototypeOf(async function* () {}).prototype);
82100

83101
function isArrayIndexPropName(P) {
84102
if (typeof P !== "string") {
@@ -143,6 +161,7 @@ module.exports = exports = {
143161
isObject,
144162
hasOwn,
145163
define,
164+
newObjectInRealm,
146165
wrapperSymbol,
147166
implSymbol,
148167
getSameObject,
@@ -153,8 +172,6 @@ module.exports = exports = {
153172
tryWrapperForImpl,
154173
tryImplForWrapper,
155174
iterInternalSymbol,
156-
IteratorPrototype,
157-
AsyncIteratorPrototype,
158175
isArrayBuffer,
159176
isArrayIndexPropName,
160177
supportsPropertyIndex,

0 commit comments

Comments
 (0)