Fix refcounting error in Go arg conversion.

Fix reversed logic for applying decrefs.

*   If the arg is decremented but only unwrapped, add a decref.
*   If the arg is not decremented but is converted using GoToClownfish
    (which returns an incremented value), add a decref.

Then, remove the spurious extra incref in GoToClownfish (a memory leak
in many cases) which had balanced out the extra decref.


Project: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/commit/b0049db2
Tree: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/tree/b0049db2
Diff: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/diff/b0049db2

Branch: refs/heads/master
Commit: b0049db2a1c0c4c8046855bd18075961f33b0f13
Parents: bd9f043
Author: Marvin Humphrey <[email protected]>
Authored: Fri Aug 28 19:25:24 2015 -0700
Committer: Marvin Humphrey <[email protected]>
Committed: Tue Sep 8 19:09:25 2015 -0700

----------------------------------------------------------------------
 compiler/src/CFCGoFunc.c          |  2 +-
 runtime/go/clownfish/clownfish.go | 27 ++++++++-------------------
 2 files changed, 9 insertions(+), 20 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/b0049db2/compiler/src/CFCGoFunc.c
----------------------------------------------------------------------
diff --git a/compiler/src/CFCGoFunc.c b/compiler/src/CFCGoFunc.c
index 0528c11..1d94f04 100644
--- a/compiler/src/CFCGoFunc.c
+++ b/compiler/src/CFCGoFunc.c
@@ -170,7 +170,7 @@ S_prep_start(CFCParcel *parcel, const char *name, CFCClass 
*invoker,
                                            nullable ? "true" : "false");
         converted = CFCUtil_cat(converted, conversion, NULL);
         FREEMEM(conversion);
-        if (CFCType_decremented(type)) {
+        if (!CFCType_decremented(type)) {
             converted = CFCUtil_cat(converted,
                                     "\tdefer C.cfish_decref(unsafe.Pointer(",
                                     go_name, "CF))\n", NULL);

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/b0049db2/runtime/go/clownfish/clownfish.go
----------------------------------------------------------------------
diff --git a/runtime/go/clownfish/clownfish.go 
b/runtime/go/clownfish/clownfish.go
index 140f1f2..2cb012f 100644
--- a/runtime/go/clownfish/clownfish.go
+++ b/runtime/go/clownfish/clownfish.go
@@ -260,55 +260,44 @@ func GoToClownfish(value interface{}, class 
unsafe.Pointer, nullable bool) unsaf
        }
 
        // Convert the value according to its type if possible.
-       var converted unsafe.Pointer
        switch v := value.(type) {
        case string:
                if klass == C.CFISH_STRING || klass == C.CFISH_OBJ {
-                       converted = goToString(value, nullable)
+                       return goToString(value, nullable)
                }
        case []byte:
                if klass == C.CFISH_BLOB || klass == C.CFISH_OBJ {
-                       converted = goToBlob(value, nullable)
+                       return goToBlob(value, nullable)
                }
        case int, uint, uintptr, int64, int32, int16, int8, uint64, uint32, 
uint16, uint8:
                if klass == C.CFISH_INTEGER || klass == C.CFISH_OBJ {
-                       converted = goToInteger(value, nullable)
+                       return goToInteger(value, nullable)
                }
        case float32, float64:
                if klass == C.CFISH_FLOAT || klass == C.CFISH_OBJ {
-                       converted = goToFloat(value, nullable)
+                       return goToFloat(value, nullable)
                }
        case bool:
                if klass == C.CFISH_BOOLEAN || klass == C.CFISH_OBJ {
-                       converted = goToBoolean(value, nullable)
+                       return goToBoolean(value, nullable)
                }
        case []interface{}:
                if klass == C.CFISH_VECTOR || klass == C.CFISH_OBJ {
-                       converted = goToVector(value, nullable)
+                       return goToVector(value, nullable)
                }
        case map[string]interface{}:
                if klass == C.CFISH_HASH || klass == C.CFISH_OBJ {
-                       converted = goToHash(value, nullable)
+                       return goToHash(value, nullable)
                }
        case Obj:
                certifyCF(value, klass, nullable)
-               converted = 
unsafe.Pointer(C.cfish_incref(unsafe.Pointer(v.TOPTR())))
+               return unsafe.Pointer(C.cfish_incref(unsafe.Pointer(v.TOPTR())))
        case nil:
                if nullable {
                        return nil
                }
        }
 
-       if converted == nil {
-               if nullable {
-                       return nil
-               }
-       } else {
-               if C.cfish_Obj_is_a((*C.cfish_Obj)(converted), klass) {
-                       return unsafe.Pointer(C.cfish_incref(converted))
-               }
-       }
-
        // Report a conversion error.
        className := StringToGo(unsafe.Pointer(C.CFISH_Class_Get_Name(klass)))
        panic(NewErr(fmt.Sprintf("Can't convert a %T to %s", value, className)))

Reply via email to