Skip to content
This repository
Browse code

Fix weird bug due to getter / setter object descriptors.

  • Loading branch information...
commit 204011d13039ece6704362f018e3e1ee8e5a0211 1 parent 76e18d7
Michael Bebenita mbebenita authored
6 src/avm2/runtime.js
@@ -1627,7 +1627,7 @@ var Runtime = (function () {
1627 1627 };
1628 1628
1629 1629 function makeQualifiedNameTraitMap(traits) {
1630   - var map = {};
  1630 + var map = Object.create(null);
1631 1631 for (var i = 0; i < traits.length; i++) {
1632 1632 map[Multiname.getQualifiedName(traits[i].name)] = traits[i];
1633 1633 }
@@ -1650,7 +1650,9 @@ var Runtime = (function () {
1650 1650 var baseOpenMethods = base[VM_OPEN_METHODS];
1651 1651 for (var i = 0; i < baseBindings.length; i++) {
1652 1652 var qn = baseBindings[i];
1653   - if (!traitMap[qn]) {
  1653 + // TODO: Make sure we don't add overriden methods as patch targets. This may be
  1654 + // broken for getters / setters.
  1655 + if (!traitMap[qn] || traitMap[qn].isGetter() || traitMap[qn].isSetter()) {
1654 1656 var baseBindingDescriptor = Object.getOwnPropertyDescriptor(base, qn);
1655 1657 Object.defineProperty(obj, qn, baseBindingDescriptor);
1656 1658 if (baseOpenMethods.hasOwnProperty(qn)) {
31 src/avm2/tests/regress/correctness/pass/callsuper8.as
... ... @@ -0,0 +1,31 @@
  1 +package {
  2 +
  3 + interface I {
  4 + function get x ();
  5 + }
  6 +
  7 + class A implements I {
  8 + public function get x () {
  9 + return 1;
  10 + }
  11 + }
  12 +
  13 + class B extends A implements I {
  14 + public function set x (v) {
  15 + trace("set");
  16 + }
  17 + }
  18 +
  19 + class C extends B implements I {
  20 + public override function get x () {
  21 + return 1 + super.x;
  22 + }
  23 + }
  24 +
  25 + // Overriding a getter that is defined two levels up and which has a
  26 + // setter in between.
  27 +
  28 + trace(new C().x);
  29 +
  30 + trace("--");
  31 +}
24 src/avm2/util.js
@@ -85,12 +85,32 @@ function defineReadOnlyProperty(obj, name, value) {
85 85 enumerable: false });
86 86 }
87 87
  88 +function getLatestGetterOrSetterPropertyDescriptor(obj, name) {
  89 + var descriptor = {};
  90 + while (obj) {
  91 + var tmp = Object.getOwnPropertyDescriptor(obj, name);
  92 + if (tmp) {
  93 + descriptor.get = descriptor.get || tmp.get;
  94 + descriptor.set = descriptor.set || tmp.set;
  95 + }
  96 + if (descriptor.get && descriptor.set) {
  97 + break;
  98 + }
  99 + obj = Object.getPrototypeOf(obj);
  100 + }
  101 + return descriptor;
  102 +}
  103 +
88 104 function defineNonEnumerableGetterOrSetter(obj, name, value, isGetter) {
  105 + var descriptor = getLatestGetterOrSetterPropertyDescriptor(obj, name);
  106 + descriptor.configurable = true;
  107 + descriptor.enumerable = false;
89 108 if (isGetter) {
90   - defineNonEnumerableGetter(obj, name, value);
  109 + descriptor.get = value;
91 110 } else {
92   - defineNonEnumerableSetter(obj, name, value);
  111 + descriptor.set = value;
93 112 }
  113 + Object.defineProperty(obj, name, descriptor);
94 114 }
95 115
96 116 function defineNonEnumerableGetter(obj, name, getter) {

0 comments on commit 204011d

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