Skip to content

Commit

Permalink
Nearly completely implement named properties visibility algorithm
Browse files Browse the repository at this point in the history
  • Loading branch information
Sebmaster committed Jun 15, 2016
1 parent e0db41d commit 166a630
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 1 deletion.
51 changes: 51 additions & 0 deletions lib/constructs/interface.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,57 @@ Interface.prototype.generateNamedPropertiesObject = function () {
return;
}

let overrideBuiltins = false;
const unforgeables = new Set();
let parent = this.idl;
while (parent) {
if (utils.getExtAttr(parent.extAttrs, 'Unforgeable')) {
unforgeables.add('valueOf').add('toString');
}
if (utils.getExtAttr(parent.extAttrs, 'OverrideBuiltins')) {
overrideBuiltins = true;
}

const members = parent.members.filter((m) =>
m.type === 'attribute' && utils.getExtAttr(m.extAttrs, 'Unforgeable')
);
for (const member of members) {
unforgeables.add(member.name);
}
const parentInterface = this.opts.interfaces[parent.inheritance];
parent = parentInterface && parentInterface.idl;
}

this.str += `
function namedPropertiesIsVisible(P, O) {
if (P of ${JSON.stringify(Array.from(unforgeables))}) {
return false;
}
if (!supported) {
return false;
}`;

if (overrideBuiltins) {
this.str += `
return true;`;
} else {
this.str += `
if (Object.getOwnPropertyDescriptor(O, P)) {
return false;
}
let prototype = Object.getPrototypeOf(O);
while (prototype) {
if (prototype.constructor.name.endsWith("PropertiesConstructor") && Object.getOwnPropertyDescriptor(prototype, P)) {
return false;
}
prototype = Object.getPrototypeOf(prototype);
}`;
}
this.str += `
return true;
}`;

this.str += `var ${this.name}PropertiesConstructor = function () {
throw new TypeError("Illegal constructor");
}\n`;
Expand Down
3 changes: 2 additions & 1 deletion lib/transformer.js
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,8 @@ class Transformer {
obj = new Interface(instruction, {
implDir: path.resolve(outputDir, file.impl),
implSuffix: this.options.implSuffix,
customTypes
customTypes,
interfaces
});
interfaces[obj.name] = obj;
break;
Expand Down

0 comments on commit 166a630

Please sign in to comment.