Skip to content
Browse files

Fix weird bug due to getter / setter object descriptors.

  • Loading branch information...
1 parent 76e18d7 commit 204011d13039ece6704362f018e3e1ee8e5a0211 @mbebenita mbebenita committed Apr 9, 2013
Showing with 57 additions and 4 deletions.
  1. +4 −2 src/avm2/runtime.js
  2. +31 −0 src/avm2/tests/regress/correctness/pass/callsuper8.as
  3. +22 −2 src/avm2/util.js
View
6 src/avm2/runtime.js
@@ -1627,7 +1627,7 @@ var Runtime = (function () {
};
function makeQualifiedNameTraitMap(traits) {
- var map = {};
+ var map = Object.create(null);
for (var i = 0; i < traits.length; i++) {
map[Multiname.getQualifiedName(traits[i].name)] = traits[i];
}
@@ -1650,7 +1650,9 @@ var Runtime = (function () {
var baseOpenMethods = base[VM_OPEN_METHODS];
for (var i = 0; i < baseBindings.length; 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);
Object.defineProperty(obj, qn, baseBindingDescriptor);
if (baseOpenMethods.hasOwnProperty(qn)) {
View
31 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("--");
+}
View
24 src/avm2/util.js
@@ -85,12 +85,32 @@ function defineReadOnlyProperty(obj, name, value) {
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) {
+ var descriptor = getLatestGetterOrSetterPropertyDescriptor(obj, name);
+ descriptor.configurable = true;
+ descriptor.enumerable = false;
if (isGetter) {
- defineNonEnumerableGetter(obj, name, value);
+ descriptor.get = value;
} else {
- defineNonEnumerableSetter(obj, name, value);
+ descriptor.set = value;
}
+ Object.defineProperty(obj, name, descriptor);
}
function defineNonEnumerableGetter(obj, name, getter) {

0 comments on commit 204011d

Please sign in to comment.
Something went wrong with that request. Please try again.