fixing the gc issues in go wrapper code
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
155
hawk.go
155
hawk.go
@@ -19,6 +19,12 @@ static void init_parsestd_for_file_in(hawk_parsestd_t* in, hawk_bch_t* path)
|
||||
in[0].u.fileb.cmgr = HAWK_NULL;
|
||||
in[1].type = HAWK_PARSESTD_NULL;
|
||||
}
|
||||
|
||||
static hawk_ooch_t* valtostr_out_cpldup(hawk_rtx_valtostr_out_t* out, hawk_oow_t* len)
|
||||
{
|
||||
*len = out->u.cpldup.len;
|
||||
return out->u.cpldup.ptr;
|
||||
}
|
||||
*/
|
||||
import "C"
|
||||
|
||||
@@ -27,8 +33,11 @@ import "runtime"
|
||||
import "unsafe"
|
||||
|
||||
type Hawk struct {
|
||||
c *C.hawk_t
|
||||
c *C.hawk_t
|
||||
inst_no int
|
||||
|
||||
rtx_head *Rtx
|
||||
rtx_tail *Rtx
|
||||
}
|
||||
|
||||
type Ext struct {
|
||||
@@ -44,14 +53,31 @@ type Err struct {
|
||||
|
||||
type Rtx struct {
|
||||
c *C.hawk_rtx_t
|
||||
h *Hawk
|
||||
|
||||
next *Rtx
|
||||
prev *Rtx
|
||||
}
|
||||
|
||||
type Val struct {
|
||||
c *C.hawk_val_t
|
||||
rtx *Rtx
|
||||
}
|
||||
|
||||
type BitMask C.hawk_bitmask_t
|
||||
|
||||
var inst_table InstanceTable
|
||||
|
||||
func deregister_instance(g *Hawk) {
|
||||
for g.rtx_head != nil {
|
||||
g.rtx_head.Close()
|
||||
}
|
||||
|
||||
if g.c != nil {
|
||||
fmt.Printf ("CLOSING g.c\n")
|
||||
C.hawk_close(g.c)
|
||||
g.c = nil
|
||||
}
|
||||
if g.inst_no >= 0 {
|
||||
fmt.Printf ("DELETING instance g\n")
|
||||
inst_table.delete_instance(g.inst_no)
|
||||
g.inst_no = -1
|
||||
}
|
||||
@@ -73,7 +99,7 @@ func New() (*Hawk, error) {
|
||||
ext = (*Ext)(unsafe.Pointer(C.hawk_getxtn(c)))
|
||||
|
||||
g = &Hawk{c: c, inst_no: -1}
|
||||
|
||||
|
||||
runtime.SetFinalizer(g, deregister_instance)
|
||||
g.inst_no = inst_table.add_instance(c, g)
|
||||
ext.inst_no = g.inst_no
|
||||
@@ -83,13 +109,16 @@ func New() (*Hawk, error) {
|
||||
|
||||
func (hawk *Hawk) Close() {
|
||||
// TODO: close all rtx?
|
||||
C.hawk_close(hawk.c)
|
||||
//if hawk.c != nil {
|
||||
// C.hawk_close(hawk.c)
|
||||
// hawk.c = nil
|
||||
//}
|
||||
deregister_instance(hawk)
|
||||
}
|
||||
|
||||
func (hawk *Hawk) make_errinfo() *Err {
|
||||
/*
|
||||
var errinf C.hawk_erruinf_t
|
||||
var errinf C.hawk_erruinf_t
|
||||
var err Err
|
||||
|
||||
C.hawk_geterruinf(hawk.c, &errinf)
|
||||
@@ -174,12 +203,12 @@ func (hawk *Hawk) AddGlobal(name string) error {
|
||||
var x C.int
|
||||
x = C.hawk_addgblwithbcstr(hawk.c, C.CString(name))
|
||||
if x <= -1 { return hawk.make_errinfo() }
|
||||
return nil
|
||||
return nil
|
||||
}
|
||||
|
||||
func (hawk *Hawk) ParseFile(text string) error {
|
||||
var x C.int
|
||||
var in [2]C.hawk_parsestd_t
|
||||
var in [2]C.hawk_parsestd_t
|
||||
C.init_parsestd_for_file_in(&in[0], C.CString(text))
|
||||
x = C.hawk_parsestd(hawk.c, &in[0], nil)
|
||||
if x <= -1 { return hawk.make_errinfo() }
|
||||
@@ -188,7 +217,7 @@ func (hawk *Hawk) ParseFile(text string) error {
|
||||
|
||||
func (hawk *Hawk) ParseText(text string) error {
|
||||
var x C.int
|
||||
var in [2]C.hawk_parsestd_t
|
||||
var in [2]C.hawk_parsestd_t
|
||||
|
||||
C.init_parsestd_for_text_in(&in[0], C.CString(text), C.hawk_oow_t(len(text)))
|
||||
x = C.hawk_parsestd(hawk.c, &in[0], nil)
|
||||
@@ -196,6 +225,35 @@ func (hawk *Hawk) ParseText(text string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (hawk *Hawk) chain_rtx(rtx *Rtx) {
|
||||
if hawk.rtx_head == nil {
|
||||
rtx.prev = nil
|
||||
hawk.rtx_head = rtx
|
||||
} else {
|
||||
rtx.prev = hawk.rtx_tail
|
||||
hawk.rtx_tail.next = rtx
|
||||
}
|
||||
rtx.next = nil
|
||||
hawk.rtx_tail = rtx
|
||||
}
|
||||
|
||||
func (hawk *Hawk) unchain_rtx(rtx *Rtx) {
|
||||
if rtx.prev == nil {
|
||||
hawk.rtx_head = rtx.next
|
||||
} else {
|
||||
rtx.prev.next = rtx.next
|
||||
}
|
||||
|
||||
if rtx.next == nil {
|
||||
hawk.rtx_tail = rtx.prev
|
||||
} else {
|
||||
rtx.next.prev = rtx.prev
|
||||
}
|
||||
|
||||
rtx.next = nil
|
||||
rtx.prev = nil
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------
|
||||
|
||||
func (hawk *Hawk) NewRtx(id string) (*Rtx, error) {
|
||||
@@ -205,13 +263,15 @@ func (hawk *Hawk) NewRtx(id string) (*Rtx, error) {
|
||||
rtx = C.hawk_rtx_openstdwithbcstr(hawk.c, 0, C.CString(id), nil, nil, nil)
|
||||
if rtx == nil { return nil, hawk.make_errinfo() }
|
||||
|
||||
g = &Rtx{c: rtx}
|
||||
g = &Rtx{c: rtx, h: hawk}
|
||||
hawk.chain_rtx(g)
|
||||
return g, nil
|
||||
}
|
||||
|
||||
func (rtx* Rtx) Close() {
|
||||
rtx.h.unchain_rtx(rtx)
|
||||
C.hawk_rtx_close(rtx.c)
|
||||
// TODO: may need deregister??
|
||||
fmt.Printf("RTX CLOSING %p\n", rtx)
|
||||
}
|
||||
|
||||
func (rtx *Rtx) make_errinfo() *Err {
|
||||
@@ -234,16 +294,18 @@ func (rtx *Rtx) make_errinfo() *Err {
|
||||
return &err
|
||||
}
|
||||
|
||||
func (rtx *Rtx) Call(name string) error {
|
||||
func (rtx *Rtx) Call(name string) (*Val, error) {
|
||||
var fun *C.hawk_fun_t
|
||||
var val *C.hawk_val_t
|
||||
|
||||
fun = C.hawk_rtx_findfunwithbcstr(rtx.c, C.CString(name))
|
||||
if fun == nil { return rtx.make_errinfo() }
|
||||
if fun == nil { return nil, rtx.make_errinfo() }
|
||||
val = C.hawk_rtx_callfun(rtx.c, fun, nil, 0)
|
||||
if val == nil { return rtx.make_errinfo() }
|
||||
// TODO: convert val to Val object
|
||||
return nil
|
||||
if val == nil { return nil, rtx.make_errinfo() }
|
||||
|
||||
// hawk_rtx_callfun() returns a value with the reference count incremented.
|
||||
// i create a Val object without incrementing the reference count of val.
|
||||
return &Val{rtx: rtx, c: val}, nil
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------
|
||||
@@ -317,7 +379,7 @@ func c_to_go(c *C.hawk_t) *Hawk {
|
||||
|
||||
ext = (*Ext)(unsafe.Pointer(C.hawk_getxtn(c)))
|
||||
inst = inst_table.slot_to_instance(ext.inst_no)
|
||||
return inst.g
|
||||
return inst.g.Value()
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------
|
||||
@@ -325,3 +387,62 @@ func c_to_go(c *C.hawk_t) *Hawk {
|
||||
func (err* Err) Error() string {
|
||||
return fmt.Sprintf("%s[%d,%d] %s", err.File, err.Line, err.Colm, err.Msg)
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------
|
||||
|
||||
func deref_val(v *Val) {
|
||||
C.hawk_rtx_refdownval(v.rtx.c, v.c)
|
||||
}
|
||||
|
||||
func (rtx *Rtx) NewValFromInt(v int) (*Val, error) {
|
||||
var c *C.hawk_val_t
|
||||
var vv *Val
|
||||
|
||||
c = C.hawk_rtx_makeintval(rtx.c, C.hawk_int_t(v))
|
||||
if c == nil { return nil, rtx.make_errinfo() }
|
||||
|
||||
C.hawk_rtx_refupval(rtx.c, c)
|
||||
vv = &Val{rtx: rtx, c: c}
|
||||
runtime.SetFinalizer(vv, deref_val)
|
||||
|
||||
return vv, nil
|
||||
}
|
||||
|
||||
func (val* Val) ToInt() (int, error) {
|
||||
var v C.hawk_int_t
|
||||
var x C.int
|
||||
|
||||
x = C.hawk_rtx_valtoint(val.rtx.c, val.c, &v)
|
||||
if x <= -1 { return 0, val.rtx.make_errinfo() }
|
||||
|
||||
return int(v), nil
|
||||
}
|
||||
|
||||
/*
|
||||
func (val* Val) ToFlt() (double, error) {
|
||||
var v C.hawk_flt_t
|
||||
var x C.int
|
||||
|
||||
x = C.hawk_rtx_valtoflt(val.rtx.c, val.c, &v)
|
||||
if x <= -1 { return 0, val.rtx.make_errinfo() }
|
||||
|
||||
return double(v), nil
|
||||
}*/
|
||||
|
||||
func (val* Val) ToStr() (string, error) {
|
||||
var out C.hawk_rtx_valtostr_out_t
|
||||
var ptr *C.hawk_ooch_t
|
||||
var len C.hawk_oow_t
|
||||
var v string
|
||||
var x C.int
|
||||
|
||||
out._type = C.HAWK_RTX_VALTOSTR_CPLDUP
|
||||
x = C.hawk_rtx_valtostr(val.rtx.c, val.c, &out)
|
||||
if x <= -1 { return "", val.rtx.make_errinfo() }
|
||||
|
||||
ptr = C.valtostr_out_cpldup(&out, &len)
|
||||
v = string(uchars_to_rune_slice(ptr, uintptr(len)))
|
||||
C.hawk_rtx_freemem(val.rtx.c, unsafe.Pointer(ptr))
|
||||
|
||||
return v, nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user