You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucy.apache.org by ma...@apache.org on 2015/09/11 23:13:57 UTC
[1/7] lucy-clownfish git commit: Don't export certain conversion
helpers.
Repository: lucy-clownfish
Updated Branches:
refs/heads/master 6f4f79e20 -> 957772687
Don't export certain conversion helpers.
Export `GoToClownfish`, but not `goToString`, `goToHash`, etc.
Project: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/commit/029d9786
Tree: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/tree/029d9786
Diff: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/diff/029d9786
Branch: refs/heads/master
Commit: 029d9786233e56d9f3c75d70b7b8bf5cb8e67096
Parents: 6f4f79e
Author: Marvin Humphrey <ma...@rectangular.com>
Authored: Wed Aug 19 18:50:41 2015 -0700
Committer: Marvin Humphrey <ma...@rectangular.com>
Committed: Fri Sep 4 14:26:57 2015 -0700
----------------------------------------------------------------------
runtime/go/clownfish/clownfish.go | 54 ++++++++++++++---------------
runtime/go/clownfish/clownfish_test.go | 14 ++++----
2 files changed, 34 insertions(+), 34 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/029d9786/runtime/go/clownfish/clownfish.go
----------------------------------------------------------------------
diff --git a/runtime/go/clownfish/clownfish.go b/runtime/go/clownfish/clownfish.go
index bae8b3d..5fd7c64 100644
--- a/runtime/go/clownfish/clownfish.go
+++ b/runtime/go/clownfish/clownfish.go
@@ -130,7 +130,7 @@ func GetClass(o Obj) Class {
}
func FetchClass(className string) Class {
- nameCF := (*C.cfish_String)(GoToString(className))
+ nameCF := (*C.cfish_String)(goToString(className))
defer C.cfish_decref(unsafe.Pointer(nameCF))
class := C.cfish_Class_fetch_class(nameCF)
return WRAPClass(unsafe.Pointer(class))
@@ -155,7 +155,7 @@ func (c *ClassIMP) MakeObj() Obj {
}
func NewMethod(name string, callbackFunc unsafe.Pointer, offset uint32) Method {
- nameCF := (*C.cfish_String)(GoToString(name))
+ nameCF := (*C.cfish_String)(goToString(name))
defer C.cfish_decref(unsafe.Pointer(nameCF))
methCF := C.cfish_Method_new(nameCF, C.cfish_method_t(callbackFunc),
C.uint32_t(offset));
@@ -268,75 +268,75 @@ func GoToClownfish(value interface{}, class unsafe.Pointer, nullable bool) unsaf
switch v := value.(type) {
case string:
if klass == C.CFISH_STRING || klass == C.CFISH_OBJ {
- converted = GoToString(value)
+ converted = goToString(value)
}
case []byte:
if klass == C.CFISH_BLOB || klass == C.CFISH_OBJ {
- converted = GoToBlob(value)
+ converted = goToBlob(value)
}
case int:
if klass == C.CFISH_INTEGER || klass == C.CFISH_OBJ {
- converted = GoToInteger(value)
+ converted = goToInteger(value)
}
case uint:
if klass == C.CFISH_INTEGER || klass == C.CFISH_OBJ {
- converted = GoToInteger(value)
+ converted = goToInteger(value)
}
case uintptr:
if klass == C.CFISH_INTEGER || klass == C.CFISH_OBJ {
- converted = GoToInteger(value)
+ converted = goToInteger(value)
}
case int64:
if klass == C.CFISH_INTEGER || klass == C.CFISH_OBJ {
- converted = GoToInteger(value)
+ converted = goToInteger(value)
}
case int32:
if klass == C.CFISH_INTEGER || klass == C.CFISH_OBJ {
- converted = GoToInteger(value)
+ converted = goToInteger(value)
}
case int16:
if klass == C.CFISH_INTEGER || klass == C.CFISH_OBJ {
- converted = GoToInteger(value)
+ converted = goToInteger(value)
}
case int8:
if klass == C.CFISH_INTEGER || klass == C.CFISH_OBJ {
- converted = GoToInteger(value)
+ converted = goToInteger(value)
}
case uint64:
if klass == C.CFISH_INTEGER || klass == C.CFISH_OBJ {
- converted = GoToInteger(value)
+ converted = goToInteger(value)
}
case uint32:
if klass == C.CFISH_INTEGER || klass == C.CFISH_OBJ {
- converted = GoToInteger(value)
+ converted = goToInteger(value)
}
case uint16:
if klass == C.CFISH_INTEGER || klass == C.CFISH_OBJ {
- converted = GoToInteger(value)
+ converted = goToInteger(value)
}
case uint8:
if klass == C.CFISH_INTEGER || klass == C.CFISH_OBJ {
- converted = GoToInteger(value)
+ converted = goToInteger(value)
}
case float32:
if klass == C.CFISH_FLOAT || klass == C.CFISH_OBJ {
- converted = GoToFloat(value)
+ converted = goToFloat(value)
}
case float64:
if klass == C.CFISH_FLOAT || klass == C.CFISH_OBJ {
- converted = GoToFloat(value)
+ converted = goToFloat(value)
}
case bool:
if klass == C.CFISH_BOOLEAN || klass == C.CFISH_OBJ {
- converted = GoToBoolean(value)
+ converted = goToBoolean(value)
}
case []interface{}:
if klass == C.CFISH_VECTOR || klass == C.CFISH_OBJ {
- converted = GoToVector(value)
+ converted = goToVector(value)
}
case map[string]interface{}:
if klass == C.CFISH_HASH || klass == C.CFISH_OBJ {
- converted = GoToHash(value)
+ converted = goToHash(value)
}
case Obj:
converted = unsafe.Pointer(C.cfish_incref(unsafe.Pointer(v.TOPTR())))
@@ -365,7 +365,7 @@ func UnwrapClownfish(value Obj, name string, nullable bool) unsafe.Pointer {
return unsafe.Pointer(value.TOPTR())
}
-func GoToString(value interface{}) unsafe.Pointer {
+func goToString(value interface{}) unsafe.Pointer {
switch v := value.(type) {
case string:
size := len(v)
@@ -380,7 +380,7 @@ func GoToString(value interface{}) unsafe.Pointer {
}
}
-func GoToBlob(value interface{}) unsafe.Pointer {
+func goToBlob(value interface{}) unsafe.Pointer {
switch v := value.(type) {
case []byte:
size := C.size_t(len(v))
@@ -398,7 +398,7 @@ func GoToBlob(value interface{}) unsafe.Pointer {
}
}
-func GoToInteger(value interface{}) unsafe.Pointer {
+func goToInteger(value interface{}) unsafe.Pointer {
switch v := value.(type) {
case int:
return unsafe.Pointer(C.cfish_Int_new(C.int64_t(v)))
@@ -443,7 +443,7 @@ func GoToInteger(value interface{}) unsafe.Pointer {
}
}
-func GoToFloat(value interface{}) unsafe.Pointer {
+func goToFloat(value interface{}) unsafe.Pointer {
switch v := value.(type) {
case float32:
return unsafe.Pointer(C.cfish_Float_new(C.double(v)))
@@ -458,7 +458,7 @@ func GoToFloat(value interface{}) unsafe.Pointer {
}
}
-func GoToBoolean(value interface{}) unsafe.Pointer {
+func goToBoolean(value interface{}) unsafe.Pointer {
switch v := value.(type) {
case bool:
if v {
@@ -475,7 +475,7 @@ func GoToBoolean(value interface{}) unsafe.Pointer {
}
}
-func GoToVector(value interface{}) unsafe.Pointer {
+func goToVector(value interface{}) unsafe.Pointer {
switch v := value.(type) {
case []interface{}:
size := len(v)
@@ -494,7 +494,7 @@ func GoToVector(value interface{}) unsafe.Pointer {
}
}
-func GoToHash(value interface{}) unsafe.Pointer {
+func goToHash(value interface{}) unsafe.Pointer {
switch v := value.(type) {
case map[string]interface{}:
size := len(v)
http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/029d9786/runtime/go/clownfish/clownfish_test.go
----------------------------------------------------------------------
diff --git a/runtime/go/clownfish/clownfish_test.go b/runtime/go/clownfish/clownfish_test.go
index 6b31527..69e9660 100644
--- a/runtime/go/clownfish/clownfish_test.go
+++ b/runtime/go/clownfish/clownfish_test.go
@@ -136,7 +136,7 @@ func TestGoToNilNotNullable(t *testing.T) {
func TestGoToString(t *testing.T) {
strings := []string{"foo", "", "z\u0000z"}
for _, val := range strings {
- got := WRAPAny(GoToString(val))
+ got := WRAPAny(goToString(val))
if _, ok := got.(String); !ok {
t.Errorf("Not a String, but a %T", got)
}
@@ -150,7 +150,7 @@ func TestGoToBlob(t *testing.T) {
strings := []string{"foo", "", "z\u0000z"}
for _, str := range strings {
val := []byte(str)
- got := WRAPAny(GoToBlob(val))
+ got := WRAPAny(goToBlob(val))
if _, ok := got.(Blob); !ok {
t.Errorf("Not a Blob, but a %T", got)
}
@@ -193,7 +193,7 @@ func TestGoToFloat(t *testing.T) {
values := []float64{math.MaxFloat64, math.SmallestNonzeroFloat64,
0.0, -0.0, 0.5, -0.5, math.Inf(1), math.Inf(-1)}
for _, val := range values {
- got := WRAPAny(GoToFloat(val))
+ got := WRAPAny(goToFloat(val))
if _, ok := got.(Float); !ok {
t.Errorf("Not a Float, but a %T", got)
}
@@ -203,7 +203,7 @@ func TestGoToFloat(t *testing.T) {
}
// NaN
- got = WRAPAny(GoToFloat(math.NaN()))
+ got = WRAPAny(goToFloat(math.NaN()))
if !math.IsNaN(ToGo(unsafe.Pointer(got.TOPTR())).(float64)) {
t.Error("Didn't convert NaN cleanly")
}
@@ -217,7 +217,7 @@ func TestGoToFloat(t *testing.T) {
func TestGoToBoolean(t *testing.T) {
values := []bool{true, false}
for _, val := range values {
- got := WRAPAny(GoToBoolean(val))
+ got := WRAPAny(goToBoolean(val))
if _, ok := got.(Boolean); !ok {
t.Errorf("Not a Boolean, but a %T", got)
}
@@ -232,7 +232,7 @@ func TestGoToHash(t *testing.T) {
"foo": int64(1),
"bar": []interface{}{},
}
- got := WRAPAny(GoToHash(expected))
+ got := WRAPAny(goToHash(expected))
if _, ok := got.(Hash); !ok {
t.Errorf("Not a Hash, but a %T", got)
}
@@ -246,7 +246,7 @@ func TestGoToVector(t *testing.T) {
[]interface{}{},
int64(-1),
}
- got := WRAPAny(GoToVector(expected))
+ got := WRAPAny(goToVector(expected))
if _, ok := got.(Vector); !ok {
t.Errorf("Not a Vector, but a %T", got)
}
[6/7] lucy-clownfish git commit: Fix refcounting error in Go arg
conversion.
Posted by ma...@apache.org.
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 <ma...@rectangular.com>
Authored: Fri Aug 28 19:25:24 2015 -0700
Committer: Marvin Humphrey <ma...@rectangular.com>
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)))
[7/7] lucy-clownfish git commit: Merge branch 'CLOWNFISH-59-nil-check'
Posted by ma...@apache.org.
Merge branch 'CLOWNFISH-59-nil-check'
Nil checking Go interface types can be subtle:
* http://play.golang.org/p/-pjThjJfxr
* http://golang.org/doc/faq#nil_error
The branch corrects nil-checking mistakes and continues tightening up
the Go/Clownfish glue code.
This fixes #37.
Project: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/commit/95777268
Tree: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/tree/95777268
Diff: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/diff/95777268
Branch: refs/heads/master
Commit: 95777268700e055caa5f1f1c9f9ca01a82b75975
Parents: 6f4f79e b0049db
Author: Marvin Humphrey <ma...@rectangular.com>
Authored: Fri Sep 11 14:09:34 2015 -0700
Committer: Marvin Humphrey <ma...@rectangular.com>
Committed: Fri Sep 11 14:11:25 2015 -0700
----------------------------------------------------------------------
compiler/src/CFCGoFunc.c | 36 +++--
runtime/go/clownfish/clownfish.go | 212 +++++++++++-----------------
runtime/go/clownfish/clownfish_test.go | 14 +-
runtime/go/clownfish/err_test.go | 6 +-
runtime/go/clownfish/hash_test.go | 14 +-
5 files changed, 121 insertions(+), 161 deletions(-)
----------------------------------------------------------------------
[2/7] lucy-clownfish git commit: Compress duplicate cases in type
switch.
Posted by ma...@apache.org.
Compress duplicate cases in type switch.
Project: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/commit/699a22b5
Tree: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/tree/699a22b5
Diff: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/diff/699a22b5
Branch: refs/heads/master
Commit: 699a22b58c26729eb8bcea2c8c2d625fc8f9ba0c
Parents: 029d978
Author: Marvin Humphrey <ma...@rectangular.com>
Authored: Wed Aug 19 19:10:00 2015 -0700
Committer: Marvin Humphrey <ma...@rectangular.com>
Committed: Fri Sep 4 14:26:58 2015 -0700
----------------------------------------------------------------------
runtime/go/clownfish/clownfish.go | 48 ++--------------------------------
1 file changed, 2 insertions(+), 46 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/699a22b5/runtime/go/clownfish/clownfish.go
----------------------------------------------------------------------
diff --git a/runtime/go/clownfish/clownfish.go b/runtime/go/clownfish/clownfish.go
index 5fd7c64..b5a9401 100644
--- a/runtime/go/clownfish/clownfish.go
+++ b/runtime/go/clownfish/clownfish.go
@@ -274,55 +274,11 @@ func GoToClownfish(value interface{}, class unsafe.Pointer, nullable bool) unsaf
if klass == C.CFISH_BLOB || klass == C.CFISH_OBJ {
converted = goToBlob(value)
}
- case int:
- if klass == C.CFISH_INTEGER || klass == C.CFISH_OBJ {
- converted = goToInteger(value)
- }
- case uint:
- if klass == C.CFISH_INTEGER || klass == C.CFISH_OBJ {
- converted = goToInteger(value)
- }
- case uintptr:
- if klass == C.CFISH_INTEGER || klass == C.CFISH_OBJ {
- converted = goToInteger(value)
- }
- case int64:
- if klass == C.CFISH_INTEGER || klass == C.CFISH_OBJ {
- converted = goToInteger(value)
- }
- case int32:
- if klass == C.CFISH_INTEGER || klass == C.CFISH_OBJ {
- converted = goToInteger(value)
- }
- case int16:
- if klass == C.CFISH_INTEGER || klass == C.CFISH_OBJ {
- converted = goToInteger(value)
- }
- case int8:
- if klass == C.CFISH_INTEGER || klass == C.CFISH_OBJ {
- converted = goToInteger(value)
- }
- case uint64:
+ case int, uint, uintptr, int64, int32, int16, int8, uint64, uint32, uint16, uint8:
if klass == C.CFISH_INTEGER || klass == C.CFISH_OBJ {
converted = goToInteger(value)
}
- case uint32:
- if klass == C.CFISH_INTEGER || klass == C.CFISH_OBJ {
- converted = goToInteger(value)
- }
- case uint16:
- if klass == C.CFISH_INTEGER || klass == C.CFISH_OBJ {
- converted = goToInteger(value)
- }
- case uint8:
- if klass == C.CFISH_INTEGER || klass == C.CFISH_OBJ {
- converted = goToInteger(value)
- }
- case float32:
- if klass == C.CFISH_FLOAT || klass == C.CFISH_OBJ {
- converted = goToFloat(value)
- }
- case float64:
+ case float32, float64:
if klass == C.CFISH_FLOAT || klass == C.CFISH_OBJ {
converted = goToFloat(value)
}
[5/7] lucy-clownfish git commit: Perform nil-checking on concrete
types.
Posted by ma...@apache.org.
Perform nil-checking on concrete types.
Nil-checking on interface types only returns true if both the type and
value slots in the interface tuple are 0. Therefore, it is necessary to
push nil-checking down into code which knows the concrete type.
Project: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/commit/bd9f043b
Tree: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/tree/bd9f043b
Diff: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/diff/bd9f043b
Branch: refs/heads/master
Commit: bd9f043b3a4ba006cc407b4a414827a2879e0b1f
Parents: 180d963
Author: Marvin Humphrey <ma...@rectangular.com>
Authored: Fri Aug 28 18:49:34 2015 -0700
Committer: Marvin Humphrey <ma...@rectangular.com>
Committed: Tue Sep 8 19:09:25 2015 -0700
----------------------------------------------------------------------
runtime/go/clownfish/clownfish.go | 120 ++++++++++++++--------------
runtime/go/clownfish/clownfish_test.go | 14 ++--
2 files changed, 65 insertions(+), 69 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/bd9f043b/runtime/go/clownfish/clownfish.go
----------------------------------------------------------------------
diff --git a/runtime/go/clownfish/clownfish.go b/runtime/go/clownfish/clownfish.go
index b31ed5f..140f1f2 100644
--- a/runtime/go/clownfish/clownfish.go
+++ b/runtime/go/clownfish/clownfish.go
@@ -131,7 +131,7 @@ func GetClass(o Obj) Class {
}
func FetchClass(className string) Class {
- nameCF := (*C.cfish_String)(goToString(className))
+ nameCF := (*C.cfish_String)(goToString(className, false))
defer C.cfish_decref(unsafe.Pointer(nameCF))
class := C.cfish_Class_fetch_class(nameCF)
return WRAPClass(unsafe.Pointer(class))
@@ -156,7 +156,7 @@ func (c *ClassIMP) MakeObj() Obj {
}
func NewMethod(name string, callbackFunc unsafe.Pointer, offset uint32) Method {
- nameCF := (*C.cfish_String)(goToString(name))
+ nameCF := (*C.cfish_String)(goToString(name, false))
defer C.cfish_decref(unsafe.Pointer(nameCF))
methCF := C.cfish_Method_new(nameCF, C.cfish_method_t(callbackFunc),
C.uint32_t(offset));
@@ -230,10 +230,17 @@ func (o *ObjIMP)Clone() Obj {
return WRAPAny(unsafe.Pointer(dupe)).(Obj)
}
-func certifyCF(value interface{}, class *C.cfish_Class) {
- cfObj, ok := value.(Obj)
- if ok {
- if C.cfish_Obj_is_a((*C.cfish_Obj)(unsafe.Pointer(cfObj.TOPTR())), class) {
+func certifyCF(value interface{}, class *C.cfish_Class, nullable bool) {
+ if nullable && value == nil {
+ return
+ }
+ if cfObj, ok := value.(Obj); ok {
+ o := (*C.cfish_Obj)(unsafe.Pointer(cfObj.TOPTR()))
+ if o == nil {
+ if nullable {
+ return
+ }
+ } else if C.cfish_Obj_is_a(o, class) {
return
}
}
@@ -247,18 +254,6 @@ func certifyCF(value interface{}, class *C.cfish_Class) {
func GoToClownfish(value interface{}, class unsafe.Pointer, nullable bool) unsafe.Pointer {
klass := (*C.cfish_Class)(class)
- // Check for nil values.
- if value == nil {
- if nullable {
- return nil
- } else if class != nil {
- className := StringToGo(unsafe.Pointer(C.CFISH_Class_Get_Name(klass)))
- panic(NewErr("Cannot be nil, must be a valid " + className))
- } else {
- panic(NewErr("Cannot be nil"))
- }
- }
-
// Default to accepting any type.
if klass == nil {
klass = C.CFISH_OBJ
@@ -269,38 +264,46 @@ func GoToClownfish(value interface{}, class unsafe.Pointer, nullable bool) unsaf
switch v := value.(type) {
case string:
if klass == C.CFISH_STRING || klass == C.CFISH_OBJ {
- converted = goToString(value)
+ converted = goToString(value, nullable)
}
case []byte:
if klass == C.CFISH_BLOB || klass == C.CFISH_OBJ {
- converted = goToBlob(value)
+ converted = 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)
+ converted = goToInteger(value, nullable)
}
case float32, float64:
if klass == C.CFISH_FLOAT || klass == C.CFISH_OBJ {
- converted = goToFloat(value)
+ converted = goToFloat(value, nullable)
}
case bool:
if klass == C.CFISH_BOOLEAN || klass == C.CFISH_OBJ {
- converted = goToBoolean(value)
+ converted = goToBoolean(value, nullable)
}
case []interface{}:
if klass == C.CFISH_VECTOR || klass == C.CFISH_OBJ {
- converted = goToVector(value)
+ converted = goToVector(value, nullable)
}
case map[string]interface{}:
if klass == C.CFISH_HASH || klass == C.CFISH_OBJ {
- converted = goToHash(value)
+ converted = goToHash(value, nullable)
}
case Obj:
+ certifyCF(value, klass, nullable)
converted = unsafe.Pointer(C.cfish_incref(unsafe.Pointer(v.TOPTR())))
+ case nil:
+ if nullable {
+ return nil
+ }
}
- // Confirm that we got what we were looking for and return.
- if converted != 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))
}
@@ -330,22 +333,21 @@ func Unwrap(value Obj, name string) unsafe.Pointer {
return ptr
}
-func goToString(value interface{}) unsafe.Pointer {
+func goToString(value interface{}, nullable bool) unsafe.Pointer {
switch v := value.(type) {
case string:
size := len(v)
str := C.CString(v)
return unsafe.Pointer(C.cfish_Str_new_steal_utf8(str, C.size_t(size)))
case Obj:
- certifyCF(v, C.CFISH_STRING)
+ certifyCF(v, C.CFISH_STRING, nullable)
return unsafe.Pointer(C.cfish_incref(unsafe.Pointer(v.TOPTR())))
- default:
- mess := fmt.Sprintf("Can't convert %T to clownfish.String", v)
- panic(NewErr(mess))
}
+ mess := fmt.Sprintf("Can't convert %T to clownfish.String", value)
+ panic(NewErr(mess))
}
-func goToBlob(value interface{}) unsafe.Pointer {
+func goToBlob(value interface{}, nullable bool) unsafe.Pointer {
switch v := value.(type) {
case []byte:
size := C.size_t(len(v))
@@ -355,15 +357,14 @@ func goToBlob(value interface{}) unsafe.Pointer {
}
return unsafe.Pointer(C.cfish_Blob_new(buf, size))
case Obj:
- certifyCF(v, C.CFISH_BLOB)
+ certifyCF(v, C.CFISH_BLOB, nullable)
return unsafe.Pointer(C.cfish_incref(unsafe.Pointer(v.TOPTR())))
- default:
- mess := fmt.Sprintf("Can't convert %T to clownfish.Blob", v)
- panic(NewErr(mess))
}
+ mess := fmt.Sprintf("Can't convert %T to clownfish.Blob", value)
+ panic(NewErr(mess))
}
-func goToInteger(value interface{}) unsafe.Pointer {
+func goToInteger(value interface{}, nullable bool) unsafe.Pointer {
switch v := value.(type) {
case int:
return unsafe.Pointer(C.cfish_Int_new(C.int64_t(v)))
@@ -400,30 +401,28 @@ func goToInteger(value interface{}) unsafe.Pointer {
case int8:
return unsafe.Pointer(C.cfish_Int_new(C.int64_t(v)))
case Obj:
- certifyCF(v, C.CFISH_INTEGER)
+ certifyCF(v, C.CFISH_INTEGER, nullable)
return unsafe.Pointer(C.cfish_incref(unsafe.Pointer(v.TOPTR())))
- default:
- mess := fmt.Sprintf("Can't convert %T to clownfish.Integer", v)
- panic(NewErr(mess))
}
+ mess := fmt.Sprintf("Can't convert %T to clownfish.Integer", value)
+ panic(NewErr(mess))
}
-func goToFloat(value interface{}) unsafe.Pointer {
+func goToFloat(value interface{}, nullable bool) unsafe.Pointer {
switch v := value.(type) {
case float32:
return unsafe.Pointer(C.cfish_Float_new(C.double(v)))
case float64:
return unsafe.Pointer(C.cfish_Float_new(C.double(v)))
case Obj:
- certifyCF(v, C.CFISH_FLOAT)
+ certifyCF(v, C.CFISH_FLOAT, nullable)
return unsafe.Pointer(C.cfish_incref(unsafe.Pointer(v.TOPTR())))
- default:
- mess := fmt.Sprintf("Can't convert %T to clownfish.Float", v)
- panic(NewErr(mess))
}
+ mess := fmt.Sprintf("Can't convert %T to clownfish.Float", value)
+ panic(NewErr(mess))
}
-func goToBoolean(value interface{}) unsafe.Pointer {
+func goToBoolean(value interface{}, nullable bool) unsafe.Pointer {
switch v := value.(type) {
case bool:
if v {
@@ -432,15 +431,14 @@ func goToBoolean(value interface{}) unsafe.Pointer {
return unsafe.Pointer(C.cfish_incref(unsafe.Pointer(C.CFISH_FALSE)))
}
case Obj:
- certifyCF(v, C.CFISH_BOOLEAN)
+ certifyCF(v, C.CFISH_BOOLEAN, nullable)
return unsafe.Pointer(C.cfish_incref(unsafe.Pointer(v.TOPTR())))
- default:
- mess := fmt.Sprintf("Can't convert %T to clownfish.Boolean", v)
- panic(NewErr(mess))
}
+ mess := fmt.Sprintf("Can't convert %T to clownfish.Boolean", value)
+ panic(NewErr(mess))
}
-func goToVector(value interface{}) unsafe.Pointer {
+func goToVector(value interface{}, nullable bool) unsafe.Pointer {
switch v := value.(type) {
case []interface{}:
size := len(v)
@@ -451,15 +449,14 @@ func goToVector(value interface{}) unsafe.Pointer {
}
return unsafe.Pointer(vec)
case Obj:
- certifyCF(v, C.CFISH_VECTOR)
+ certifyCF(v, C.CFISH_VECTOR, nullable)
return unsafe.Pointer(C.cfish_incref(unsafe.Pointer(v.TOPTR())))
- default:
- mess := fmt.Sprintf("Can't convert %T to clownfish.Vector", v)
- panic(NewErr(mess))
}
+ mess := fmt.Sprintf("Can't convert %T to clownfish.Vector", value)
+ panic(NewErr(mess))
}
-func goToHash(value interface{}) unsafe.Pointer {
+func goToHash(value interface{}, nullable bool) unsafe.Pointer {
switch v := value.(type) {
case map[string]interface{}:
size := len(v)
@@ -474,12 +471,11 @@ func goToHash(value interface{}) unsafe.Pointer {
}
return unsafe.Pointer(hash)
case Obj:
- certifyCF(v, C.CFISH_HASH)
+ certifyCF(v, C.CFISH_HASH, nullable)
return unsafe.Pointer(C.cfish_incref(unsafe.Pointer(v.TOPTR())))
- default:
- mess := fmt.Sprintf("Can't convert %T to clownfish.Hash", v)
- panic(NewErr(mess))
}
+ mess := fmt.Sprintf("Can't convert %T to clownfish.Hash", value)
+ panic(NewErr(mess))
}
func ToGo(ptr unsafe.Pointer) interface{} {
http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/bd9f043b/runtime/go/clownfish/clownfish_test.go
----------------------------------------------------------------------
diff --git a/runtime/go/clownfish/clownfish_test.go b/runtime/go/clownfish/clownfish_test.go
index 69e9660..074b58b 100644
--- a/runtime/go/clownfish/clownfish_test.go
+++ b/runtime/go/clownfish/clownfish_test.go
@@ -136,7 +136,7 @@ func TestGoToNilNotNullable(t *testing.T) {
func TestGoToString(t *testing.T) {
strings := []string{"foo", "", "z\u0000z"}
for _, val := range strings {
- got := WRAPAny(goToString(val))
+ got := WRAPAny(goToString(val, false))
if _, ok := got.(String); !ok {
t.Errorf("Not a String, but a %T", got)
}
@@ -150,7 +150,7 @@ func TestGoToBlob(t *testing.T) {
strings := []string{"foo", "", "z\u0000z"}
for _, str := range strings {
val := []byte(str)
- got := WRAPAny(goToBlob(val))
+ got := WRAPAny(goToBlob(val, false))
if _, ok := got.(Blob); !ok {
t.Errorf("Not a Blob, but a %T", got)
}
@@ -193,7 +193,7 @@ func TestGoToFloat(t *testing.T) {
values := []float64{math.MaxFloat64, math.SmallestNonzeroFloat64,
0.0, -0.0, 0.5, -0.5, math.Inf(1), math.Inf(-1)}
for _, val := range values {
- got := WRAPAny(goToFloat(val))
+ got := WRAPAny(goToFloat(val, false))
if _, ok := got.(Float); !ok {
t.Errorf("Not a Float, but a %T", got)
}
@@ -203,7 +203,7 @@ func TestGoToFloat(t *testing.T) {
}
// NaN
- got = WRAPAny(goToFloat(math.NaN()))
+ got = WRAPAny(goToFloat(math.NaN(), false))
if !math.IsNaN(ToGo(unsafe.Pointer(got.TOPTR())).(float64)) {
t.Error("Didn't convert NaN cleanly")
}
@@ -217,7 +217,7 @@ func TestGoToFloat(t *testing.T) {
func TestGoToBoolean(t *testing.T) {
values := []bool{true, false}
for _, val := range values {
- got := WRAPAny(goToBoolean(val))
+ got := WRAPAny(goToBoolean(val, false))
if _, ok := got.(Boolean); !ok {
t.Errorf("Not a Boolean, but a %T", got)
}
@@ -232,7 +232,7 @@ func TestGoToHash(t *testing.T) {
"foo": int64(1),
"bar": []interface{}{},
}
- got := WRAPAny(goToHash(expected))
+ got := WRAPAny(goToHash(expected, false))
if _, ok := got.(Hash); !ok {
t.Errorf("Not a Hash, but a %T", got)
}
@@ -246,7 +246,7 @@ func TestGoToVector(t *testing.T) {
[]interface{}{},
int64(-1),
}
- got := WRAPAny(goToVector(expected))
+ got := WRAPAny(goToVector(expected, false))
if _, ok := got.(Vector); !ok {
t.Errorf("Not a Vector, but a %T", got)
}
[3/7] lucy-clownfish git commit: Improve quoting in test messages.
Posted by ma...@apache.org.
Improve quoting in test messages.
Project: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/commit/180d963b
Tree: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/tree/180d963b
Diff: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/diff/180d963b
Branch: refs/heads/master
Commit: 180d963b64cba359cb55b44dbe49613e4dc2a76d
Parents: 7988b5f
Author: Marvin Humphrey <ma...@rectangular.com>
Authored: Fri Aug 28 18:11:13 2015 -0700
Committer: Marvin Humphrey <ma...@rectangular.com>
Committed: Tue Sep 8 19:09:24 2015 -0700
----------------------------------------------------------------------
runtime/go/clownfish/err_test.go | 6 +++---
runtime/go/clownfish/hash_test.go | 14 +++++++-------
2 files changed, 10 insertions(+), 10 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/180d963b/runtime/go/clownfish/err_test.go
----------------------------------------------------------------------
diff --git a/runtime/go/clownfish/err_test.go b/runtime/go/clownfish/err_test.go
index a7abff5..b439ab7 100644
--- a/runtime/go/clownfish/err_test.go
+++ b/runtime/go/clownfish/err_test.go
@@ -44,7 +44,7 @@ func TestErrGetMess(t *testing.T) {
err := NewErr("foo")
expected := "foo"
if got := err.GetMess(); got != expected {
- t.Errorf("Expected %v, got %v", expected, got)
+ t.Errorf("Expected '%v', got '%v'", expected, got)
}
}
@@ -53,7 +53,7 @@ func TestErrCatMess(t *testing.T) {
err.CatMess("bar")
expected := "foobar"
if got := err.GetMess(); got != expected {
- t.Errorf("Expected %v, got %v", expected, got)
+ t.Errorf("Expected '%v', got '%v'", expected, got)
}
}
@@ -61,6 +61,6 @@ func TestErrToString(t *testing.T) {
err := NewErr("foo")
expected := "foo"
if got := err.ToString(); got != expected {
- t.Errorf("Expected %v, got %v", expected, got)
+ t.Errorf("Expected '%v', got '%v'", expected, got)
}
}
http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/180d963b/runtime/go/clownfish/hash_test.go
----------------------------------------------------------------------
diff --git a/runtime/go/clownfish/hash_test.go b/runtime/go/clownfish/hash_test.go
index c2970e0..26acf49 100644
--- a/runtime/go/clownfish/hash_test.go
+++ b/runtime/go/clownfish/hash_test.go
@@ -24,11 +24,11 @@ func TestHashStoreFetch(t *testing.T) {
hash := NewHash(0)
hash.Store("foo", "bar")
if got, ok := hash.Fetch("foo").(string); !ok || got != "bar" {
- t.Errorf("Expected \"bar\", got %v", got)
+ t.Errorf("Expected 'bar', got '%v'", got)
}
hash.Store("nada", nil)
if got := hash.Fetch("nada"); got != nil {
- t.Errorf("Expected nil, got %v", got)
+ t.Errorf("Expected nil, got '%v'", got)
}
}
@@ -40,7 +40,7 @@ func TestHashDelete(t *testing.T) {
t.Errorf("Delete failed (size %d)", size)
}
if val, ok := got.(string); !ok || val != "bar" {
- t.Errorf("Delete returned unexpected value: %v")
+ t.Errorf("Delete returned unexpected value: '%v'", val)
}
}
@@ -76,7 +76,7 @@ func TestHashKeys(t *testing.T) {
sort.Strings(keys)
expected := []string{"a", "b"}
if !reflect.DeepEqual(keys, expected) {
- t.Errorf("Expected %v, got %v", expected, keys)
+ t.Errorf("Expected '%v', got '%v'", expected, keys)
}
}
@@ -92,7 +92,7 @@ func TestHashValues(t *testing.T) {
sort.Strings(vals)
expected := []string{"a", "b"}
if !reflect.DeepEqual(vals, expected) {
- t.Errorf("Expected %v, got %v", expected, vals)
+ t.Errorf("Expected '%v', got '%v'", expected, vals)
}
}
@@ -146,10 +146,10 @@ func TestHashIterator(t *testing.T) {
t.Error("Next() should proceed")
}
if key := iter.GetKey(); key != "a" {
- t.Error("Expected \"a\", got %v", key)
+ t.Error("Expected 'a', got '%v'", key)
}
if val, ok := iter.GetValue().(string); !ok || val != "foo" {
- t.Error("Expected \"a\", got %v", val)
+ t.Error("Expected 'a', got '%v'", val)
}
if iter.Next() {
t.Error("Next() should return false when iteration complete")
[4/7] lucy-clownfish git commit: Introduce `Unwrap`, `UnwrapNullable`.
Posted by ma...@apache.org.
Introduce `Unwrap`, `UnwrapNullable`.
Replace `UnwrapClownfish` with new functions that perform valid
nil-checking. For nullable parameters, perform better error checking in
Go in order to throw better errors.
Project: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/commit/7988b5ff
Tree: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/tree/7988b5ff
Diff: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/diff/7988b5ff
Branch: refs/heads/master
Commit: 7988b5ffd869afe613ab7becc3805a219b2f5c2f
Parents: 699a22b
Author: Marvin Humphrey <ma...@rectangular.com>
Authored: Thu Aug 27 19:39:19 2015 -0700
Committer: Marvin Humphrey <ma...@rectangular.com>
Committed: Tue Sep 8 19:09:24 2015 -0700
----------------------------------------------------------------------
compiler/src/CFCGoFunc.c | 34 +++++++++++++++++----------
runtime/go/clownfish/clownfish.go | 43 ++++++++++++++++++++--------------
2 files changed, 48 insertions(+), 29 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/7988b5ff/compiler/src/CFCGoFunc.c
----------------------------------------------------------------------
diff --git a/compiler/src/CFCGoFunc.c b/compiler/src/CFCGoFunc.c
index 34d3d48..0528c11 100644
--- a/compiler/src/CFCGoFunc.c
+++ b/compiler/src/CFCGoFunc.c
@@ -109,11 +109,11 @@ S_prep_start(CFCParcel *parcel, const char *name, CFCClass *invoker,
// be nullable if it has a default value of "NULL". (Since Go does
// not support default values for method parameters, this is the only
// default value we care about.)
- const char *nullable = CFCType_nullable(type) ? "true" : "false";
+ int nullable = CFCType_nullable(type);
if (default_values[i] != NULL
&& strcmp(default_values[i], "NULL") == 0
) {
- nullable = "true";
+ nullable = true;
}
const char *class_var = NULL;
@@ -136,20 +136,29 @@ S_prep_start(CFCParcel *parcel, const char *name, CFCClass *invoker,
if (class_var == NULL || (targ == IS_METHOD && i == 0)) {
// Just unwrap -- don't convert.
- char *pattern;
- if (CFCType_decremented(type)) {
- pattern =
- "\t%sCF := (*C.%s)(unsafe.Pointer(C.cfish_incref(%sUnwrapClownfish(%s, \"%s\", %s))))\n";
+ char *unwrapped;
+ if (nullable) {
+ unwrapped = CFCUtil_sprintf("%sUnwrapNullable(%s)",
+ clownfish_dot, go_name);
}
else {
- pattern =
- "\t%sCF := (*C.%s)(%sUnwrapClownfish(%s, \"%s\", %s))\n";
+ unwrapped = CFCUtil_sprintf("%sUnwrap(%s, \"%s\")",
+ clownfish_dot, go_name, go_name);
+ }
+
+ if (CFCType_decremented(type)) {
+ char *pattern = "unsafe.Pointer(C.cfish_incref(%s))";
+ char *temp = CFCUtil_sprintf(pattern, unwrapped);
+ FREEMEM(unwrapped);
+ unwrapped = temp;
}
- char *conversion = CFCUtil_sprintf(pattern, go_name, struct_name,
- clownfish_dot, go_name,
- go_name, nullable);
+
+ char *conversion
+ = CFCUtil_sprintf("\t%sCF := (*C.%s)(%s)\n", go_name,
+ struct_name, unwrapped);
converted = CFCUtil_cat(converted, conversion, NULL);
FREEMEM(conversion);
+ FREEMEM(unwrapped);
continue;
}
@@ -157,7 +166,8 @@ S_prep_start(CFCParcel *parcel, const char *name, CFCClass *invoker,
"\t%sCF := (*C.%s)(%sGoToClownfish(%s, unsafe.Pointer(C.%s), %s))\n";
char *conversion = CFCUtil_sprintf(pattern, go_name, struct_name,
clownfish_dot, go_name,
- class_var, nullable);
+ class_var,
+ nullable ? "true" : "false");
converted = CFCUtil_cat(converted, conversion, NULL);
FREEMEM(conversion);
if (CFCType_decremented(type)) {
http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/7988b5ff/runtime/go/clownfish/clownfish.go
----------------------------------------------------------------------
diff --git a/runtime/go/clownfish/clownfish.go b/runtime/go/clownfish/clownfish.go
index b5a9401..b31ed5f 100644
--- a/runtime/go/clownfish/clownfish.go
+++ b/runtime/go/clownfish/clownfish.go
@@ -66,6 +66,7 @@ GoCfish_RunRoutine(CFISH_Err_Attempt_t routine, void *context) {
import "C"
import "runtime"
import "unsafe"
+import "reflect"
import "fmt"
import "math"
import "sync"
@@ -124,7 +125,7 @@ type ObjIMP struct {
}
func GetClass(o Obj) Class {
- objCF := (*C.cfish_Obj)(unsafe.Pointer(o.TOPTR()))
+ objCF := (*C.cfish_Obj)(Unwrap(o, "o"))
classCF := C.cfish_Obj_get_class(objCF)
return WRAPClass(unsafe.Pointer(classCF))
}
@@ -137,7 +138,7 @@ func FetchClass(className string) Class {
}
func (c *ClassIMP) GetMethods() []Method {
- self := (*C.cfish_Class)(unsafe.Pointer(c.TOPTR()))
+ self := (*C.cfish_Class)(Unwrap(c, "c"))
methsVec := C.CFISH_Class_Get_Methods(self)
size := C.CFISH_Vec_Get_Size(methsVec)
meths := make([]Method, 0, int(size))
@@ -149,7 +150,7 @@ func (c *ClassIMP) GetMethods() []Method {
}
func (c *ClassIMP) MakeObj() Obj {
- self := (*C.cfish_Class)(unsafe.Pointer(c.TOPTR()))
+ self := (*C.cfish_Class)(Unwrap(c, "c"))
retvalCF := C.CFISH_Class_Make_Obj_IMP(self)
return WRAPAny(unsafe.Pointer(retvalCF))
}
@@ -170,7 +171,7 @@ func NewString(goString string) String {
}
func NewStringIterator(str String, offset uintptr) StringIterator {
- strCF := (*C.cfish_String)(unsafe.Pointer(str.TOPTR()))
+ strCF := (*C.cfish_String)(Unwrap(str, "str"))
iter := C.cfish_StrIter_new(strCF, C.size_t(offset))
return WRAPStringIterator(unsafe.Pointer(iter))
}
@@ -192,13 +193,13 @@ func NewHash(size int) Hash {
}
func NewHashIterator(hash Hash) HashIterator {
- hashCF := (*C.cfish_Hash)(unsafe.Pointer(hash.TOPTR()))
+ hashCF := (*C.cfish_Hash)(Unwrap(hash, "hash"))
cfObj := C.cfish_HashIter_new(hashCF)
return WRAPHashIterator(unsafe.Pointer(cfObj))
}
func (h *HashIMP) Keys() []string {
- self := (*C.cfish_Hash)(unsafe.Pointer(h.TOPTR()))
+ self := (*C.cfish_Hash)(Unwrap(h, "h"))
keysCF := C.CFISH_Hash_Keys(self)
numKeys := C.CFISH_Vec_Get_Size(keysCF)
keys := make([]string, 0, int(numKeys))
@@ -224,7 +225,7 @@ func (o *ObjIMP) TOPTR() uintptr {
}
func (o *ObjIMP)Clone() Obj {
- self := (*C.cfish_Obj)(unsafe.Pointer(o.TOPTR()))
+ self := (*C.cfish_Obj)(Unwrap(o, "o"))
dupe := C.CFISH_Obj_Clone(self)
return WRAPAny(unsafe.Pointer(dupe)).(Obj)
}
@@ -310,17 +311,25 @@ func GoToClownfish(value interface{}, class unsafe.Pointer, nullable bool) unsaf
panic(NewErr(fmt.Sprintf("Can't convert a %T to %s", value, className)))
}
-func UnwrapClownfish(value Obj, name string, nullable bool) unsafe.Pointer {
+func UnwrapNullable(value Obj) unsafe.Pointer {
if value == nil {
- if nullable {
- return nil
- } else {
- panic(NewErr(fmt.Sprintf("%s cannot be nil", name)))
- }
+ return nil
+ }
+ val := reflect.ValueOf(value)
+ if val.IsNil() {
+ return nil
}
return unsafe.Pointer(value.TOPTR())
}
+func Unwrap(value Obj, name string) unsafe.Pointer {
+ ptr := UnwrapNullable(value)
+ if ptr == nil {
+ panic(NewErr(fmt.Sprintf("%s cannot be nil", name)))
+ }
+ return ptr
+}
+
func goToString(value interface{}) unsafe.Pointer {
switch v := value.(type) {
case string:
@@ -628,19 +637,19 @@ func TrapErr(routine func()) (trapped error) {
}
func (s *StringIMP) CodePointAt(tick uintptr) rune {
- self := ((*C.cfish_String)(unsafe.Pointer(s.TOPTR())))
+ self := ((*C.cfish_String)(Unwrap(s, "s")))
retvalCF := C.CFISH_Str_Code_Point_At(self, C.size_t(tick))
return rune(retvalCF)
}
func (s *StringIMP) CodePointFrom(tick uintptr) rune {
- self := ((*C.cfish_String)(unsafe.Pointer(s.TOPTR())))
+ self := ((*C.cfish_String)(Unwrap(s, "s")))
retvalCF := C.CFISH_Str_Code_Point_From(self, C.size_t(tick))
return rune(retvalCF)
}
func (s *StringIMP) SwapChars(match, replacement rune) string {
- self := ((*C.cfish_String)(unsafe.Pointer(s.TOPTR())))
+ self := ((*C.cfish_String)(Unwrap(s, "s")))
retvalCF := C.CFISH_Str_Swap_Chars(self, C.int32_t(match), C.int32_t(replacement))
defer C.cfish_dec_refcount(unsafe.Pointer(retvalCF))
return CFStringToGo(unsafe.Pointer(retvalCF))
@@ -665,6 +674,6 @@ func NewBlob(content []byte) Blob {
}
func (b *BlobIMP) GetBuf() uintptr {
- self := (*C.cfish_Blob)(unsafe.Pointer(b.TOPTR()))
+ self := (*C.cfish_Blob)(Unwrap(b, "b"))
return uintptr(unsafe.Pointer(C.CFISH_Blob_Get_Buf(self)))
}