[gjs] Class: fix for reentrant calls



commit 378e7b949c88f75701abb1d766dce9c922a17b97
Author: Giovanni Campagna <gcampagna src gnome org>
Date:   Sun Nov 20 17:50:12 2011 +0100

    Class: fix for reentrant calls
    
    Uponing entering a method from another on the same object, the
    function wrapper must save the previous value of __caller__, or
    susbsequents calls to parent() would fail.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=664437

 modules/lang.js      |    7 ++++---
 test/js/testClass.js |   20 ++++++++++++++++++++
 2 files changed, 24 insertions(+), 3 deletions(-)
---
diff --git a/modules/lang.js b/modules/lang.js
index 344720e..413b72c 100644
--- a/modules/lang.js
+++ b/modules/lang.js
@@ -136,6 +136,7 @@ function defineAccessorProperty(object, name, getter, setter) {
 function _Base() {
 }
 
+_Base.prototype._init = function() { };
 _Base.prototype.__name__ = '_Base';
 _Base.prototype.toString = function() {
     return '[object ' + this.__name__ + ']';
@@ -161,9 +162,10 @@ function wrapFunction(obj, name, meth) {
     if (meth._origin) meth = meth._origin;
 
     function wrapper() {
+        let prevCaller = this.__caller__;
         this.__caller__ = wrapper;
         let result = meth.apply(this, arguments);
-        this.__caller__ = null;
+        this.__caller__ = prevCaller;
         return result;
     }
 
@@ -187,8 +189,7 @@ function Class(params) {
         };
     } else {
         newClass = function() {
-            if (!this._init)
-                return this;
+            this.__caller__ = null;
 
             return this._init.apply(this, arguments);
         };
diff --git a/test/js/testClass.js b/test/js/testClass.js
index 06c37d3..f61de3f 100644
--- a/test/js/testClass.js
+++ b/test/js/testClass.js
@@ -20,6 +20,10 @@ const MagicBase = new Lang.Class({
     foo: function(a, buffer) {
         buffer.push(a);
         return a * 3;
+    },
+
+    bar: function(a) {
+        return a * 5;
     }
 });
 
@@ -38,6 +42,11 @@ const Magic = new Lang.Class({
         let val = this.parent(a, buffer);
         buffer.push(b);
         return val * 2;
+    },
+
+    bar: function(a, buffer) {
+        this.foo(a, 2*a, buffer);
+        return this.parent(a);
     }
 });
 
@@ -165,4 +174,15 @@ function testAbstract() {
     assertEquals(42, newAbstract.foo);
 }
 
+function testCrossCall() {
+    // test that a method can call another without clobbering
+    // __caller__
+    let newMagic = new Magic();
+    let buffer = [];
+
+    let res = newMagic.bar(10, buffer);
+    assertArrayEquals([10, 20], buffer);
+    assertEquals(50, res);
+}
+
 gjstestRun();



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]