Skip to content

Commit 5506762

Browse files
committed
Make wrapper instanciation lazy
1 parent fda810e commit 5506762

File tree

3 files changed

+1060
-664
lines changed

3 files changed

+1060
-664
lines changed

lib/constructs/interface.js

+39-28
Original file line numberDiff line numberDiff line change
@@ -501,6 +501,9 @@ class Interface {
501501
generateRequires() {
502502
this.requires.addRaw("impl", "utils.implSymbol");
503503
this.requires.addRaw("ctorRegistry", "utils.ctorRegistrySymbol");
504+
this.requires.addRaw("wrapperSymbol", "utils.wrapperSymbol");
505+
this.requires.addRaw("globalObjectSymbol", "utils.globalObjectSymbol");
506+
this.requires.addRaw("createWrapperSymbol", "utils.createWrapperSymbol");
504507

505508
if (this.idl.inheritance !== null) {
506509
this.requires.add(this.idl.inheritance);
@@ -1126,7 +1129,9 @@ class Interface {
11261129

11271130
generateIface() {
11281131
this.str += `
1129-
exports.create = function create(globalObject, constructorArgs, privateData) {
1132+
function createWrapper(implObject) {
1133+
const globalObject = implObject[globalObjectSymbol];
1134+
11301135
if (globalObject[ctorRegistry] === undefined) {
11311136
throw new Error('Internal error: invalid global object');
11321137
}
@@ -1136,49 +1141,55 @@ class Interface {
11361141
throw new Error('Internal error: constructor ${this.name} is not installed on the passed global object');
11371142
}
11381143
1139-
let obj = Object.create(ctor.prototype);
1140-
obj = exports.setup(obj, globalObject, constructorArgs, privateData);
1141-
return obj;
1142-
};
1143-
exports.createImpl = function createImpl(globalObject, constructorArgs, privateData) {
1144-
const obj = exports.create(globalObject, constructorArgs, privateData);
1145-
return utils.implForWrapper(obj);
1146-
};
1147-
exports._internalSetup = function _internalSetup(obj) {
1144+
let wrapperObject = Object.create(ctor.prototype);
1145+
exports._internalSetup(wrapperObject);
11481146
`;
11491147

1150-
if (this.idl.inheritance) {
1148+
if (this.isLegacyPlatformObj) {
11511149
this.str += `
1152-
${this.idl.inheritance}._internalSetup(obj);
1150+
wrapperObject = new Proxy(wrapperObject, proxyHandler);
11531151
`;
11541152
}
11551153

1156-
this.generateOnInstance();
1157-
11581154
this.str += `
1155+
implObject[wrapperSymbol] = wrapperObject;
1156+
wrapperObject[impl] = implObject;
1157+
return wrapperObject;
11591158
};
1160-
exports.setup = function setup(obj, globalObject, constructorArgs = [], privateData = {}) {
1161-
privateData.wrapper = obj;
1159+
exports.create = function create(globalObject, constructorArgs, privateData) {
1160+
const implObject = exports.createImpl(globalObject, constructorArgs, privateData);
1161+
return utils.wrapperForImpl(implObject);
1162+
};
1163+
exports.createImpl = function createImpl(globalObject, constructorArgs = [], privateData = {}) {
1164+
const implObject = new Impl.implementation(globalObject, constructorArgs, privateData);
11621165
1163-
exports._internalSetup(obj);
1164-
Object.defineProperty(obj, impl, {
1165-
value: new Impl.implementation(globalObject, constructorArgs, privateData),
1166-
configurable: true
1167-
});
1166+
implObject[wrapperSymbol] = null;
1167+
implObject[globalObjectSymbol] = globalObject;
1168+
implObject[createWrapperSymbol] = createWrapper;
1169+
1170+
return implObject;
1171+
};
1172+
exports.setup = function setup(wrapperObject, globalObject, constructorArgs = [], privateData = {}) {
1173+
const implObject = exports.createImpl(globalObject, constructorArgs, privateData);
1174+
1175+
implObject[wrapperSymbol] = wrapperObject;
1176+
wrapperObject[impl] = implObject;
1177+
1178+
exports._internalSetup(wrapperObject);
1179+
1180+
return wrapperObject;
1181+
};
1182+
exports._internalSetup = function _internalSetup(obj) {
11681183
`;
11691184

1170-
if (this.isLegacyPlatformObj) {
1185+
if (this.idl.inheritance) {
11711186
this.str += `
1172-
obj = new Proxy(obj, proxyHandler);
1187+
${this.idl.inheritance}._internalSetup(obj);
11731188
`;
11741189
}
1190+
this.generateOnInstance();
11751191

11761192
this.str += `
1177-
obj[impl][utils.wrapperSymbol] = obj;
1178-
if (Impl.init) {
1179-
Impl.init(obj[impl], privateData);
1180-
}
1181-
return obj;
11821193
};
11831194
`;
11841195
}

lib/output/utils.js

+14-1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ function hasOwn(obj, prop) {
1111

1212
const wrapperSymbol = Symbol("wrapper");
1313
const implSymbol = Symbol("impl");
14+
const globalObjectSymbol = Symbol("global object");
15+
const createWrapperSymbol = Symbol("create wrapper");
1416
const sameObjectCaches = Symbol("SameObject caches");
1517
const ctorRegistrySymbol = Symbol.for("[webidl2js] constructor registry");
1618

@@ -28,7 +30,16 @@ function getSameObject(wrapper, prop, creator) {
2830
}
2931

3032
function wrapperForImpl(impl) {
31-
return impl ? impl[wrapperSymbol] : null;
33+
if (!impl) {
34+
return null;
35+
}
36+
37+
const wrapper = impl[wrapperSymbol];
38+
if (wrapper === undefined || wrapper !== null) {
39+
return wrapper;
40+
}
41+
42+
return impl[createWrapperSymbol](impl);
3243
}
3344

3445
function implForWrapper(wrapper) {
@@ -91,6 +102,8 @@ module.exports = exports = {
91102
hasOwn,
92103
wrapperSymbol,
93104
implSymbol,
105+
globalObjectSymbol,
106+
createWrapperSymbol,
94107
getSameObject,
95108
ctorRegistrySymbol,
96109
wrapperForImpl,

0 commit comments

Comments
 (0)