Skip to content
This repository has been archived by the owner on Jul 3, 2019. It is now read-only.

Commit

Permalink
Fix weird bug due to getter / setter object descriptors.
Browse files Browse the repository at this point in the history
  • Loading branch information
mbebenita committed Apr 9, 2013
1 parent 76e18d7 commit 204011d
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 4 deletions.
6 changes: 4 additions & 2 deletions src/avm2/runtime.js
Expand Up @@ -1627,7 +1627,7 @@ var Runtime = (function () {
}; };


function makeQualifiedNameTraitMap(traits) { function makeQualifiedNameTraitMap(traits) {
var map = {}; var map = Object.create(null);
for (var i = 0; i < traits.length; i++) { for (var i = 0; i < traits.length; i++) {
map[Multiname.getQualifiedName(traits[i].name)] = traits[i]; map[Multiname.getQualifiedName(traits[i].name)] = traits[i];
} }
Expand All @@ -1650,7 +1650,9 @@ var Runtime = (function () {
var baseOpenMethods = base[VM_OPEN_METHODS]; var baseOpenMethods = base[VM_OPEN_METHODS];
for (var i = 0; i < baseBindings.length; i++) { for (var i = 0; i < baseBindings.length; i++) {
var qn = baseBindings[i]; var qn = baseBindings[i];
if (!traitMap[qn]) { // TODO: Make sure we don't add overriden methods as patch targets. This may be
// broken for getters / setters.
if (!traitMap[qn] || traitMap[qn].isGetter() || traitMap[qn].isSetter()) {
var baseBindingDescriptor = Object.getOwnPropertyDescriptor(base, qn); var baseBindingDescriptor = Object.getOwnPropertyDescriptor(base, qn);
Object.defineProperty(obj, qn, baseBindingDescriptor); Object.defineProperty(obj, qn, baseBindingDescriptor);
if (baseOpenMethods.hasOwnProperty(qn)) { if (baseOpenMethods.hasOwnProperty(qn)) {
Expand Down
31 changes: 31 additions & 0 deletions src/avm2/tests/regress/correctness/pass/callsuper8.as
@@ -0,0 +1,31 @@
package {

interface I {
function get x ();
}

class A implements I {
public function get x () {
return 1;
}
}

class B extends A implements I {
public function set x (v) {
trace("set");
}
}

class C extends B implements I {
public override function get x () {
return 1 + super.x;
}
}

// Overriding a getter that is defined two levels up and which has a
// setter in between.

trace(new C().x);

trace("--");
}
24 changes: 22 additions & 2 deletions src/avm2/util.js
Expand Up @@ -85,12 +85,32 @@ function defineReadOnlyProperty(obj, name, value) {
enumerable: false }); enumerable: false });
} }


function getLatestGetterOrSetterPropertyDescriptor(obj, name) {
var descriptor = {};
while (obj) {
var tmp = Object.getOwnPropertyDescriptor(obj, name);
if (tmp) {
descriptor.get = descriptor.get || tmp.get;
descriptor.set = descriptor.set || tmp.set;
}
if (descriptor.get && descriptor.set) {
break;
}
obj = Object.getPrototypeOf(obj);
}
return descriptor;
}

function defineNonEnumerableGetterOrSetter(obj, name, value, isGetter) { function defineNonEnumerableGetterOrSetter(obj, name, value, isGetter) {
var descriptor = getLatestGetterOrSetterPropertyDescriptor(obj, name);
descriptor.configurable = true;
descriptor.enumerable = false;
if (isGetter) { if (isGetter) {
defineNonEnumerableGetter(obj, name, value); descriptor.get = value;
} else { } else {
defineNonEnumerableSetter(obj, name, value); descriptor.set = value;
} }
Object.defineProperty(obj, name, descriptor);
} }


function defineNonEnumerableGetter(obj, name, getter) { function defineNonEnumerableGetter(obj, name, getter) {
Expand Down

0 comments on commit 204011d

Please sign in to comment.