Skip to content

Commit bfcd994

Browse files
authored
Put globalObject and interfaceNmae into scope for replacement code
Now the replacement code returned by the processCEReactions and processHTMLConstructor handlers can reference the globalObject and interfaceName variables, as is documented in the README. This was meant to be introduced in fda810e, but the previous merging of 7c8037f prevented that from working properly.
1 parent 3e5f7f6 commit bfcd994

File tree

2 files changed

+250
-98
lines changed

2 files changed

+250
-98
lines changed

lib/constructs/interface.js

Lines changed: 70 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ class Interface {
9090
this.namedSetter = null;
9191
this.namedDeleter = null;
9292
this.stringifier = null;
93+
this.needsPerGlobalProxyHandler = false;
9394

9495
this.iterable = null;
9596
this._analyzed = false;
@@ -229,11 +230,17 @@ class Interface {
229230
throw new Error(msg + "duplicated indexed setter");
230231
}
231232
this.indexedSetter = member;
233+
if (utils.hasCEReactions(member)) {
234+
this.needsPerGlobalProxyHandler = true;
235+
}
232236
} else if (isNamed(member)) {
233237
if (this.namedSetter) {
234238
throw new Error(msg + "duplicated named setter");
235239
}
236240
this.namedSetter = member;
241+
if (utils.hasCEReactions(member)) {
242+
this.needsPerGlobalProxyHandler = true;
243+
}
237244
} else {
238245
throw new Error(msg + "setter is neither indexed nor named");
239246
}
@@ -253,6 +260,9 @@ class Interface {
253260
throw new Error(msg + "duplicated named deleter");
254261
}
255262
this.namedDeleter = member;
263+
if (utils.hasCEReactions(member)) {
264+
this.needsPerGlobalProxyHandler = true;
265+
}
256266
} else {
257267
throw new Error(msg + "deleter is not named");
258268
}
@@ -683,7 +693,6 @@ class Interface {
683693
${conv.body}
684694
`;
685695

686-
687696
let invocation;
688697
if (!this.namedSetter.name) {
689698
invocation = `
@@ -709,9 +718,21 @@ class Interface {
709718
return prolog + invocation;
710719
};
711720

712-
this.str += `
713-
const proxyHandler = {
714-
`;
721+
let sep = "";
722+
if (this.needsPerGlobalProxyHandler) {
723+
this.str += `
724+
const proxyHandlerCache = new WeakMap();
725+
class ProxyHandler {
726+
constructor(globalObject) {
727+
this._globalObject = globalObject;
728+
}
729+
`;
730+
} else {
731+
this.str += `
732+
const proxyHandler = {
733+
`;
734+
sep = ",";
735+
}
715736

716737
// [[Get]] (necessary because of proxy semantics)
717738
this.str += `
@@ -735,7 +756,7 @@ class Interface {
735756
return undefined;
736757
}
737758
return Reflect.apply(getter, receiver, []);
738-
},
759+
}${sep}
739760
`;
740761

741762
// [[HasProperty]] (necessary because of proxy semantics)
@@ -753,7 +774,7 @@ class Interface {
753774
return Reflect.has(parent, P);
754775
}
755776
return false;
756-
},
777+
}${sep}
757778
`;
758779

759780
// [[OwnPropertyKeys]]
@@ -784,7 +805,7 @@ class Interface {
784805
keys.add(key);
785806
}
786807
return [...keys];
787-
},
808+
}${sep}
788809
`;
789810

790811
// [[GetOwnProperty]]
@@ -858,7 +879,7 @@ class Interface {
858879
}
859880
this.str += `
860881
return Reflect.getOwnPropertyDescriptor(target, P);
861-
},
882+
}${sep}
862883
`;
863884

864885
// [[Set]]
@@ -870,6 +891,12 @@ class Interface {
870891
if (target === receiver) {
871892
`;
872893

894+
if (this.needsPerGlobalProxyHandler) {
895+
this.str += `
896+
const globalObject = this._globalObject;
897+
`;
898+
}
899+
873900
if (this.supportsIndexedProperties) {
874901
if (hasIndexedSetter) {
875902
this.str += `
@@ -966,7 +993,7 @@ class Interface {
966993
valueDesc = { writable: true, enumerable: true, configurable: true, value: V };
967994
}
968995
return Reflect.defineProperty(receiver, P, valueDesc);
969-
},
996+
}${sep}
970997
`;
971998

972999
// [[DefineOwnProperty]]
@@ -976,6 +1003,13 @@ class Interface {
9761003
return Reflect.defineProperty(target, P, desc);
9771004
}
9781005
`;
1006+
1007+
if (this.needsPerGlobalProxyHandler) {
1008+
this.str += `
1009+
const globalObject = this._globalObject;
1010+
`;
1011+
}
1012+
9791013
if (this.supportsIndexedProperties) {
9801014
this.str += `
9811015
if (utils.isArrayIndexPropName(P)) {
@@ -1054,7 +1088,7 @@ class Interface {
10541088
`;
10551089
}
10561090
this.str += `
1057-
},
1091+
}${sep}
10581092
`;
10591093

10601094
// [[Delete]]
@@ -1064,6 +1098,13 @@ class Interface {
10641098
return Reflect.deleteProperty(target, P);
10651099
}
10661100
`;
1101+
1102+
if (this.needsPerGlobalProxyHandler) {
1103+
this.str += `
1104+
const globalObject = this._globalObject;
1105+
`;
1106+
}
1107+
10671108
if (this.supportsIndexedProperties) {
10681109
this.str += `
10691110
if (utils.isArrayIndexPropName(P)) {
@@ -1109,7 +1150,7 @@ class Interface {
11091150
}
11101151
this.str += `
11111152
return Reflect.deleteProperty(target, P);
1112-
},
1153+
}${sep}
11131154
`;
11141155

11151156
// [[PreventExtensions]]
@@ -1168,9 +1209,22 @@ class Interface {
11681209
`;
11691210

11701211
if (this.isLegacyPlatformObj) {
1171-
this.str += `
1212+
if (this.needsPerGlobalProxyHandler) {
1213+
this.str += `
1214+
{
1215+
let proxyHandler = proxyHandlerCache.get(globalObject);
1216+
if (proxyHandler === undefined) {
1217+
proxyHandler = new ProxyHandler(globalObject);
1218+
proxyHandlerCache.set(globalObject, proxyHandler);
1219+
}
1220+
obj = new Proxy(obj, proxyHandler);
1221+
}
1222+
`;
1223+
} else {
1224+
this.str += `
11721225
obj = new Proxy(obj, proxyHandler);
1173-
`;
1226+
`;
1227+
}
11741228
}
11751229

11761230
this.str += `
@@ -1451,7 +1505,6 @@ class Interface {
14511505

14521506
this.str += `
14531507
exports.install = function install(globalObject) {
1454-
const interfaceName = "${name}";
14551508
`;
14561509

14571510
if (idl.inheritance) {
@@ -1486,6 +1539,9 @@ class Interface {
14861539
}
14871540

14881541
generate() {
1542+
this.str += `
1543+
const interfaceName = "${this.name}";
1544+
`;
14891545
this.generateIterator();
14901546

14911547
this.generateExport();

0 commit comments

Comments
 (0)