@@ -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