Skip to content

Commit 2cbc9d9

Browse files
committed
Nearly completely implement named properties visibility algorithm
1 parent de16fdd commit 2cbc9d9

File tree

2 files changed

+53
-1
lines changed

2 files changed

+53
-1
lines changed

lib/constructs/interface.js

+51
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,57 @@ Interface.prototype.generateNamedPropertiesObject = function () {
3131
return;
3232
}
3333

34+
let overrideBuiltins = false;
35+
const unforgeables = new Set();
36+
let parent = this.idl;
37+
while (parent) {
38+
if (utils.getExtAttr(parent.extAttrs, 'Unforgeable')) {
39+
unforgeables.add('valueOf').add('toString');
40+
}
41+
if (utils.getExtAttr(parent.extAttrs, 'OverrideBuiltins')) {
42+
overrideBuiltins = true;
43+
}
44+
45+
const members = parent.members.filter((m) =>
46+
m.type === 'attribute' && utils.getExtAttr(m.extAttrs, 'Unforgeable')
47+
);
48+
for (const member of members) {
49+
unforgeables.add(member.name);
50+
}
51+
const parentInterface = this.opts.interfaces[parent.inheritance];
52+
parent = parentInterface && parentInterface.idl;
53+
}
54+
55+
this.str += `
56+
function namedPropertiesIsVisible(P, O) {
57+
if (P of ${JSON.stringify(Array.from(unforgeables))}) {
58+
return false;
59+
}
60+
if (!supported) {
61+
return false;
62+
}`;
63+
64+
if (overrideBuiltins) {
65+
this.str += `
66+
return true;`;
67+
} else {
68+
this.str += `
69+
if (Object.getOwnPropertyDescriptor(O, P)) {
70+
return false;
71+
}
72+
73+
let prototype = Object.getPrototypeOf(O);
74+
while (prototype) {
75+
if (prototype.constructor.name.endsWith("PropertiesConstructor") && Object.getOwnPropertyDescriptor(prototype, P)) {
76+
return false;
77+
}
78+
prototype = Object.getPrototypeOf(prototype);
79+
}`;
80+
}
81+
this.str += `
82+
return true;
83+
}`;
84+
3485
this.str += `var ${this.name}PropertiesConstructor = function () {
3586
throw new TypeError("Illegal constructor");
3687
}\n`;

lib/transformer.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,8 @@ class Transformer {
9292
obj = new Interface(instruction, {
9393
implDir: path.resolve(outputDir, file.impl),
9494
implSuffix: this.options.implSuffix,
95-
customTypes
95+
customTypes,
96+
interfaces
9697
});
9798
interfaces[obj.name] = obj;
9899
break;

0 commit comments

Comments
 (0)