Compare commits

...
2 Commits
2 changed files with 577 additions and 174 deletions
+257 -156
View File
@@ -101,6 +101,17 @@ static void init_rtx_xtn_ecb (rtx_xtn_t* xtn)
xtn->rtx_ecb.sigset = rtx_on_sigset; xtn->rtx_ecb.sigset = rtx_on_sigset;
} }
// -----------------------------------------------
static hawk_uintptr_t val_arr_itr_elem(hawk_val_arr_itr_t* itr)
{
return (hawk_uintptr_t)itr->elem;
}
static hawk_uintptr_t val_map_itr_val(hawk_val_map_itr_t* itr)
{
return (hawk_uintptr_t)HAWK_VAL_MAP_ITR_VAL(itr);
}
// ----------------------------------------------- // -----------------------------------------------
extern int hawk_mod_go_fnc_gc(rtx_xtn_t* rtx_xtn); extern int hawk_mod_go_fnc_gc(rtx_xtn_t* rtx_xtn);
@@ -228,8 +239,14 @@ type Rtx struct {
val_tail *Val val_tail *Val
} }
type CPtrVal uintptr
type Val struct { type Val struct {
c *C.hawk_val_t // storing a raw C pointer in the go memory is usually OK.
// but the hawk encodes immediate values using tag in a pointer.
// such values are not valid C pointers and go GC triggered pointer check error.
//c *C.hawk_val_t
c CPtrVal // use a numeric type that can store the pointer
rtx *Rtx rtx *Rtx
next *Val next *Val
prev *Val prev *Val
@@ -253,7 +270,9 @@ const (
) )
type ValArrayItr struct { type ValArrayItr struct {
c C.hawk_val_arr_itr_t //c C.hawk_val_arr_itr_t
_ [0]uintptr // for alignment
c [C.sizeof_hawk_val_arr_itr_t]byte
} }
type ValMapItr struct { type ValMapItr struct {
@@ -654,7 +673,7 @@ func (rtx *Rtx) GetErrInfo() *Err {
} }
func (rtx *Rtx) SetGlobal(idx int, val *Val) error { func (rtx *Rtx) SetGlobal(idx int, val *Val) error {
if C.hawk_rtx_setgbl(rtx.c, C.int(idx), val.c) <= -1 { if C.hawk_rtx_setgbl(rtx.c, C.int(idx), (*C.hawk_val_t)(unsafe.Pointer(val.c))) <= -1 {
return rtx.make_errinfo() return rtx.make_errinfo()
} }
return nil return nil
@@ -676,7 +695,7 @@ func (rtx *Rtx) OnSigset(f RtxSigsetHandler) {
} }
func (rtx *Rtx) Exec(args []string) (*Val, error) { func (rtx *Rtx) Exec(args []string) (*Val, error) {
var val *C.hawk_val_t var val CPtrVal
var cargs []*C.hawk_bch_t var cargs []*C.hawk_bch_t
var idx int var idx int
var count int var count int
@@ -688,26 +707,26 @@ func (rtx *Rtx) Exec(args []string) (*Val, error) {
} }
if count > 0 { if count > 0 {
val = C.hawk_rtx_execwithbcstrarr(rtx.c, &cargs[0], C.hawk_oow_t(count)) val = CPtrVal(unsafe.Pointer(C.hawk_rtx_execwithbcstrarr(rtx.c, &cargs[0], C.hawk_oow_t(count))))
} else { } else {
val = C.hawk_rtx_execwithbcstrarr(rtx.c, (**C.hawk_bch_t)(nil), C.hawk_oow_t(count)) val = CPtrVal(unsafe.Pointer(C.hawk_rtx_execwithbcstrarr(rtx.c, (**C.hawk_bch_t)(nil), C.hawk_oow_t(count))))
} }
for idx = 0; idx < count; idx++ { for idx = 0; idx < count; idx++ {
C.free(unsafe.Pointer(cargs[idx])) C.free(unsafe.Pointer(cargs[idx]))
} }
if val == nil { return nil, rtx.make_errinfo() } if val == 0 { return nil, rtx.make_errinfo() }
// hawk_rtx_exec...() returns a value with the reference count incremented. // hawk_rtx_exec...() returns a value with the reference count incremented.
// create a value without going through rtx.make_val() // create a value without going through rtx.make_val()
return rtx.fix_val_with_raw(val), nil return rtx.fix_val_with_raw(val), nil
//return rtx.make_val(func() *C.hawk_val_t { return val }) //return rtx.make_val(func() CPtrVal { return val })
} }
func (rtx *Rtx) Loop() (*Val, error) { func (rtx *Rtx) Loop() (*Val, error) {
var val *C.hawk_val_t var val CPtrVal
val = C.hawk_rtx_loop(rtx.c) val = CPtrVal(unsafe.Pointer(C.hawk_rtx_loop(rtx.c)))
if val == nil { return nil, rtx.make_errinfo() } if val == 0 { return nil, rtx.make_errinfo() }
// hawk_rtx_loop() returns a value with the reference count incremented. // hawk_rtx_loop() returns a value with the reference count incremented.
// create a value without going through rtx.make_val() // create a value without going through rtx.make_val()
return rtx.fix_val_with_raw(val), nil return rtx.fix_val_with_raw(val), nil
@@ -716,7 +735,7 @@ func (rtx *Rtx) Loop() (*Val, error) {
func (rtx *Rtx) Call(name string, args ...*Val) (*Val, error) { func (rtx *Rtx) Call(name string, args ...*Val) (*Val, error) {
var fun *C.hawk_fun_t var fun *C.hawk_fun_t
var val *C.hawk_val_t var val CPtrVal
var cv *C.hawk_bch_t var cv *C.hawk_bch_t
var nargs int var nargs int
@@ -727,21 +746,21 @@ func (rtx *Rtx) Call(name string, args ...*Val) (*Val, error) {
nargs = len(args) nargs = len(args)
if nargs > 0 { if nargs > 0 {
var argv []*C.hawk_val_t var argv []CPtrVal
var v *Val var v *Val
var i int var i int
argv = make([]*C.hawk_val_t, nargs) argv = make([]CPtrVal, nargs)
for i, v = range args { argv[i] = v.c } for i, v = range args { argv[i] = v.c }
val = C.hawk_rtx_callfun(rtx.c, fun, &argv[0], C.hawk_oow_t(nargs)) val = CPtrVal(unsafe.Pointer(C.hawk_rtx_callfun(rtx.c, fun, (**C.hawk_val_t)(unsafe.Pointer(&argv[0])), C.hawk_oow_t(nargs))))
} else { } else {
val = C.hawk_rtx_callfun(rtx.c, fun, nil, 0) val = CPtrVal(unsafe.Pointer(C.hawk_rtx_callfun(rtx.c, fun, nil, 0)))
} }
if val == nil { return nil, rtx.make_errinfo() } if val == 0 { return nil, rtx.make_errinfo() }
// hawk_rtx_callfun() returns a value with the reference count incremented. // hawk_rtx_callfun() returns a value with the reference count incremented.
// i create a Val object without incrementing the reference count of val. // i create a Val object without incrementing the reference count of val.
return rtx.fix_val_with_raw(val), nil return rtx.fix_val_with_raw(val), nil
//return rtx.make_val(func() *C.hawk_val_t { return val })aAAA //return rtx.make_val(func() CPtrVal { return val })
} }
func (rtx *Rtx) ValCount() int { func (rtx *Rtx) ValCount() int {
@@ -795,63 +814,74 @@ func (rtx *Rtx) GetFuncArgCount() int {
} }
func (rtx *Rtx) GetFuncArg(idx int) (*Val, error) { func (rtx *Rtx) GetFuncArg(idx int) (*Val, error) {
return rtx.make_val(func() *C.hawk_val_t { return rtx.make_val(func() CPtrVal {
return C.hawk_rtx_getarg(rtx.c, C.hawk_oow_t(idx)) return CPtrVal(unsafe.Pointer(C.hawk_rtx_getarg(rtx.c, C.hawk_oow_t(idx))))
}) })
} }
func (rtx *Rtx) SetFuncRet(v *Val) { func (rtx *Rtx) SetFuncRet(v *Val) {
C.hawk_rtx_setretval(rtx.c, v.c) C.hawk_rtx_setretval(rtx.c, (*C.hawk_val_t)(unsafe.Pointer(v.c)))
} }
func (rtx *Rtx) SetFuncRetWithInt(v int) error { func (rtx *Rtx) SetFuncRetWithInt(v int) error {
var vv *C.hawk_val_t //var vv *C.hawk_val_t
vv = C.hawk_rtx_makeintval(rtx.c, C.hawk_int_t(v)) //vv = C.hawk_rtx_makeintval(rtx.c, C.hawk_int_t(v))
if vv == nil { return rtx.make_errinfo() } //if vv == nil { return rtx.make_errinfo() }
C.hawk_rtx_refupval(rtx.c, vv)
C.hawk_rtx_setretval(rtx.c, vv) var vv CPtrVal
C.hawk_rtx_refdownval(rtx.c, vv) vv = CPtrVal(unsafe.Pointer(C.hawk_rtx_makeintval(rtx.c, C.hawk_int_t(v))))
if vv == 0 { return rtx.make_errinfo() }
C.hawk_rtx_refupval(rtx.c, (*C.hawk_val_t)(unsafe.Pointer(vv)))
C.hawk_rtx_setretval(rtx.c, (*C.hawk_val_t)(unsafe.Pointer(vv)))
C.hawk_rtx_refdownval(rtx.c, (*C.hawk_val_t)(unsafe.Pointer(vv)))
return nil return nil
} }
func (rtx *Rtx) SetFuncRetWithFlt(v float64) error { func (rtx *Rtx) SetFuncRetWithFlt(v float64) error {
var vv *C.hawk_val_t //var vv *C.hawk_val_t
vv = C.make_flt_val(rtx.c, C.double(v)) //vv = C.make_flt_val(rtx.c, C.double(v))
if vv == nil { return rtx.make_errinfo() } //if vv == nil { return rtx.make_errinfo() }
C.hawk_rtx_refupval(rtx.c, vv)
C.hawk_rtx_setretval(rtx.c, vv) var vv CPtrVal
C.hawk_rtx_refdownval(rtx.c, vv) vv = CPtrVal(unsafe.Pointer(C.make_flt_val(rtx.c, C.double(v))))
if vv == 0 { return rtx.make_errinfo() }
C.hawk_rtx_refupval(rtx.c, (*C.hawk_val_t)(unsafe.Pointer(vv)))
C.hawk_rtx_setretval(rtx.c, (*C.hawk_val_t)(unsafe.Pointer(vv)))
C.hawk_rtx_refdownval(rtx.c, (*C.hawk_val_t)(unsafe.Pointer(vv)))
return nil return nil
} }
func (rtx *Rtx) SetFuncRetWithStr(v string) error { func (rtx *Rtx) SetFuncRetWithStr(v string) error {
var vv *C.hawk_val_t //var vv *C.hawk_val_t
var vv CPtrVal
var cv *C.hawk_bch_t var cv *C.hawk_bch_t
cv = C.CString(v) cv = C.CString(v)
vv = C.hawk_rtx_makestrvalwithbchars(rtx.c, cv, C.hawk_oow_t(len(v))) //vv = C.hawk_rtx_makestrvalwithbchars(rtx.c, cv, C.hawk_oow_t(len(v)))
vv = CPtrVal(unsafe.Pointer(C.hawk_rtx_makestrvalwithbchars(rtx.c, cv, C.hawk_oow_t(len(v)))))
C.free(unsafe.Pointer(cv)) C.free(unsafe.Pointer(cv))
if vv == nil { return rtx.make_errinfo() } //if vv == nil { return rtx.make_errinfo() }
C.hawk_rtx_refupval(rtx.c, vv) if vv == 0 { return rtx.make_errinfo() }
C.hawk_rtx_setretval(rtx.c, vv) C.hawk_rtx_refupval(rtx.c, (*C.hawk_val_t)(unsafe.Pointer(vv)))
C.hawk_rtx_refdownval(rtx.c, vv) C.hawk_rtx_setretval(rtx.c, (*C.hawk_val_t)(unsafe.Pointer(vv)))
C.hawk_rtx_refdownval(rtx.c, (*C.hawk_val_t)(unsafe.Pointer(vv)))
return nil return nil
} }
func (rtx *Rtx) GetNamedVars(vars map[string]*Val) { func (rtx *Rtx) GetNamedVars(vars map[string]*Val) {
var itr C.hawk_rtx_nv_itr_t var itr C.hawk_rtx_nv_itr_t
var val *C.hawk_val_t var val CPtrVal
var k string var k string
var err error var err error
C.hawk_init_rtx_nv_itr(&itr) C.hawk_init_rtx_nv_itr(&itr)
val = C.hawk_rtx_getfirstnv(rtx.c, &itr) val = CPtrVal(unsafe.Pointer(C.hawk_rtx_getfirstnv(rtx.c, &itr)))
for val != nil { for val != 0 {
k = string(uchars_to_rune_slice((*C.hawk_uch_t)(itr.name.ptr), uintptr(itr.name.len))) k = string(uchars_to_rune_slice((*C.hawk_uch_t)(itr.name.ptr), uintptr(itr.name.len)))
vars[k], err = rtx.make_val(func() *C.hawk_val_t { return val }) vars[k], err = rtx.make_val(func() CPtrVal { return val })
if err != nil { if err != nil { return }
return val = CPtrVal(unsafe.Pointer(C.hawk_rtx_getnextnv(rtx.c, &itr)))
}
val = C.hawk_rtx_getnextnv(rtx.c, &itr)
} }
} }
@@ -1036,97 +1066,97 @@ func (rtx *Rtx) NewVal(v interface{}) (*Val, error) {
} }
} }
func (rtx* Rtx) make_val(vmaker func() *C.hawk_val_t) (*Val, error) { func (rtx* Rtx) make_val(vmaker func() CPtrVal) (*Val, error) {
var c *C.hawk_val_t var c CPtrVal
var vv *Val var vv *Val
c = vmaker() c = vmaker()
if c == nil { return nil, rtx.make_errinfo() } if c == 0 { return nil, rtx.make_errinfo() }
C.hawk_rtx_refupval(rtx.c, c) C.hawk_rtx_refupval(rtx.c, (*C.hawk_val_t)(unsafe.Pointer(c)))
vv = &Val{rtx: rtx, c: c} vv = &Val{rtx: rtx, c: c}
rtx.chain_val(vv) rtx.chain_val(vv)
return vv, nil return vv, nil
} }
func (rtx* Rtx) fix_val_with_raw(val *C.hawk_val_t) *Val { func (rtx* Rtx) fix_val_with_raw(val CPtrVal) *Val {
// this function assumes val has the non-zero reference count // this function assumes val has the non-zero reference count
// the caller must ensure that the reference count has been incremented properly // the caller must ensure that the reference count has been incremented properly
var vv *Val var vv *Val
// immediate values or static pointer values must no check the reference count. // immediate values or static pointer values must no check the reference count.
if C.hawk_rtx_isimmorstaticval(rtx.c, val) == 0 && val.v_refs <= 0 { panic("invalid reference count") } if C.hawk_rtx_isimmorstaticval(rtx.c, (*C.hawk_val_t)(unsafe.Pointer(val))) == 0 && ((*C.hawk_val_t)(unsafe.Pointer(val))).v_refs <= 0 { panic("invalid reference count") }
vv = &Val{rtx: rtx, c: val} vv = &Val{rtx: rtx, c: val}
rtx.chain_val(vv) rtx.chain_val(vv)
return vv return vv
} }
func (rtx *Rtx) NewByteVal(v byte) (*Val, error) { func (rtx *Rtx) NewByteVal(v byte) (*Val, error) {
return rtx.make_val(func() *C.hawk_val_t { return rtx.make_val(func() CPtrVal {
return C.hawk_rtx_makebchrval(rtx.c, C.hawk_bch_t(v)) return CPtrVal(unsafe.Pointer(C.hawk_rtx_makebchrval(rtx.c, C.hawk_bch_t(v))))
}) })
} }
func (rtx *Rtx) NewCharVal(v rune) (*Val, error) { func (rtx *Rtx) NewCharVal(v rune) (*Val, error) {
return rtx.make_val(func() *C.hawk_val_t { return rtx.make_val(func() CPtrVal {
return C.hawk_rtx_makecharval(rtx.c, C.hawk_ooch_t(v)) return CPtrVal(unsafe.Pointer(C.hawk_rtx_makecharval(rtx.c, C.hawk_ooch_t(v))))
}) })
} }
func (rtx *Rtx) NewIntVal(v int) (*Val, error) { func (rtx *Rtx) NewIntVal(v int) (*Val, error) {
return rtx.make_val(func() *C.hawk_val_t { return rtx.make_val(func() CPtrVal {
return C.hawk_rtx_makeintval(rtx.c, C.hawk_int_t(v)) return CPtrVal(unsafe.Pointer(C.hawk_rtx_makeintval(rtx.c, C.hawk_int_t(v))))
}) })
} }
func (rtx *Rtx) NewFltVal(v float64) (*Val, error) { func (rtx *Rtx) NewFltVal(v float64) (*Val, error) {
return rtx.make_val(func() *C.hawk_val_t { return rtx.make_val(func() CPtrVal {
return C.make_flt_val(rtx.c, C.double(v)) return CPtrVal(unsafe.Pointer(C.make_flt_val(rtx.c, C.double(v))))
}) })
} }
func (rtx *Rtx) NewStrVal(v string) (*Val, error) { func (rtx *Rtx) NewStrVal(v string) (*Val, error) {
return rtx.make_val(func() *C.hawk_val_t { return rtx.make_val(func() CPtrVal {
var vv *C.hawk_val_t var vv CPtrVal
var cv *C.hawk_bch_t var cv *C.hawk_bch_t
cv = C.CString(v) cv = C.CString(v)
vv = C.hawk_rtx_makestrvalwithbchars(rtx.c, cv, C.hawk_oow_t(len(v))) vv = CPtrVal(unsafe.Pointer(C.hawk_rtx_makestrvalwithbchars(rtx.c, cv, C.hawk_oow_t(len(v)))))
C.free(unsafe.Pointer(cv)) C.free(unsafe.Pointer(cv))
return vv return vv
}) })
} }
func (rtx *Rtx) NewNumOrStrVal(v string, mode int) (*Val, error) { func (rtx *Rtx) NewNumOrStrVal(v string, mode int) (*Val, error) {
return rtx.make_val(func() *C.hawk_val_t { return rtx.make_val(func() CPtrVal {
var vv *C.hawk_val_t var vv CPtrVal
var cv *C.hawk_bch_t var cv *C.hawk_bch_t
cv = C.CString(v) cv = C.CString(v)
vv = C.hawk_rtx_makenumorstrvalwithbchars(rtx.c, cv, C.hawk_oow_t(len(v)), C.int(mode)) vv = CPtrVal(unsafe.Pointer(C.hawk_rtx_makenumorstrvalwithbchars(rtx.c, cv, C.hawk_oow_t(len(v)), C.int(mode))))
C.free(unsafe.Pointer(cv)) C.free(unsafe.Pointer(cv))
return vv return vv
}) })
} }
func (rtx *Rtx) NewByteArrVal(v []byte) (*Val, error) { func (rtx *Rtx) NewByteArrVal(v []byte) (*Val, error) {
return rtx.make_val(func() *C.hawk_val_t { return rtx.make_val(func() CPtrVal {
return C.hawk_rtx_makembsvalwithbchars(rtx.c, (*C.hawk_bch_t)(unsafe.Pointer(&v[0])), C.hawk_oow_t(len(v))) return CPtrVal(unsafe.Pointer(C.hawk_rtx_makembsvalwithbchars(rtx.c, (*C.hawk_bch_t)(unsafe.Pointer(&v[0])), C.hawk_oow_t(len(v)))))
}) })
} }
func (rtx *Rtx) NewBobVal(v []byte) (*Val, error) { func (rtx *Rtx) NewBobVal(v []byte) (*Val, error) {
return rtx.make_val(func() *C.hawk_val_t { return rtx.make_val(func() CPtrVal {
return C.hawk_rtx_makebobval(rtx.c, unsafe.Pointer(&v[0]), C.hawk_oow_t(len(v))) return CPtrVal(unsafe.Pointer(C.hawk_rtx_makebobval(rtx.c, unsafe.Pointer(&v[0]), C.hawk_oow_t(len(v)))))
}) })
} }
func (rtx *Rtx) NewMapVal() (*Val, error) { func (rtx *Rtx) NewMapVal() (*Val, error) {
return rtx.make_val(func() *C.hawk_val_t { return rtx.make_val(func() CPtrVal {
return C.hawk_rtx_makemapval(rtx.c) return CPtrVal(unsafe.Pointer(C.hawk_rtx_makemapval(rtx.c)))
}) })
} }
func (rtx *Rtx) NewArrVal(init_capa int) (*Val, error) { func (rtx *Rtx) NewArrVal(init_capa int) (*Val, error) {
return rtx.make_val(func() *C.hawk_val_t { return rtx.make_val(func() CPtrVal {
return C.hawk_rtx_makearrval(rtx.c, C.hawk_ooi_t(init_capa)) return CPtrVal(unsafe.Pointer(C.hawk_rtx_makearrval(rtx.c, C.hawk_ooi_t(init_capa))))
}) })
} }
@@ -1137,13 +1167,13 @@ func (val *Val) Close() {
var rtx *C.hawk_rtx_t var rtx *C.hawk_rtx_t
rtx = val.rtx.c // store this field as unchain_val() resets it to nil rtx = val.rtx.c // store this field as unchain_val() resets it to nil
val.rtx.unchain_val(val) val.rtx.unchain_val(val)
C.hawk_rtx_refdownval(rtx, val.c) C.hawk_rtx_refdownval(rtx, (*C.hawk_val_t)(unsafe.Pointer(val.c)))
} }
} }
func (val *Val) Type() ValType { func (val *Val) Type() ValType {
var x C.int var x C.int
x = C.hawk_rtx_getvaltype(val.rtx.c, val.c) x = C.hawk_rtx_getvaltype(val.rtx.c, (*C.hawk_val_t)(unsafe.Pointer(val.c)))
return ValType(x) return ValType(x)
} }
@@ -1157,7 +1187,7 @@ func (val *Val) ToInt() (int, error) {
var v C.hawk_int_t var v C.hawk_int_t
var x C.int var x C.int
x = C.hawk_rtx_valtoint(val.rtx.c, val.c, &v) x = C.hawk_rtx_valtoint(val.rtx.c, (*C.hawk_val_t)(unsafe.Pointer(val.c)), &v)
if x <= -1 { return 0, val.rtx.make_errinfo() } if x <= -1 { return 0, val.rtx.make_errinfo() }
return int(v), nil return int(v), nil
@@ -1168,7 +1198,7 @@ func (val *Val) ToFlt() (float64, error) {
var x C.int var x C.int
//x = C.hawk_rtx_valtoflt(val.rtx.c, val.c, &v) //x = C.hawk_rtx_valtoflt(val.rtx.c, val.c, &v)
x = C.val_to_flt(val.rtx.c, val.c, (*C.double)(&v)) x = C.val_to_flt(val.rtx.c, (*C.hawk_val_t)(unsafe.Pointer(val.c)), (*C.double)(&v))
if x <= -1 { return 0, val.rtx.make_errinfo() } if x <= -1 { return 0, val.rtx.make_errinfo() }
return v, nil return v, nil
@@ -1182,7 +1212,7 @@ func (val *Val) ToStr() (string, error) {
var x C.int var x C.int
out._type = C.HAWK_RTX_VALTOSTR_CPLDUP out._type = C.HAWK_RTX_VALTOSTR_CPLDUP
x = C.hawk_rtx_valtostr(val.rtx.c, val.c, &out) x = C.hawk_rtx_valtostr(val.rtx.c, (*C.hawk_val_t)(unsafe.Pointer(val.c)), &out)
if x <= -1 { return "", val.rtx.make_errinfo() } if x <= -1 { return "", val.rtx.make_errinfo() }
ptr = C.valtostr_out_cpldup(&out, &len) ptr = C.valtostr_out_cpldup(&out, &len)
@@ -1197,7 +1227,7 @@ func (val *Val) ToByteArr() ([]byte, error) {
var len C.hawk_oow_t var len C.hawk_oow_t
var v []byte var v []byte
ptr = C.hawk_rtx_valtobcstrdupwithcmgr(val.rtx.c, val.c, &len, C.hawk_rtx_getcmgr(val.rtx.c)) ptr = C.hawk_rtx_valtobcstrdupwithcmgr(val.rtx.c, (*C.hawk_val_t)(unsafe.Pointer(val.c)), &len, C.hawk_rtx_getcmgr(val.rtx.c))
if ptr == nil { return nil, val.rtx.make_errinfo() } if ptr == nil { return nil, val.rtx.make_errinfo() }
v = C.GoBytes(unsafe.Pointer(ptr), C.int(len)) v = C.GoBytes(unsafe.Pointer(ptr), C.int(len))
@@ -1209,149 +1239,212 @@ func (val *Val) ToByteArr() ([]byte, error) {
func (val *Val) ArrayTally() int { func (val *Val) ArrayTally() int {
var v C.hawk_ooi_t var v C.hawk_ooi_t
// TODO: if not array .. panic or return -1 or 0? // TODO: if not array .. panic or return -1 or 0?
v = C.hawk_rtx_getarrvaltally(val.rtx.c, val.c) v = C.hawk_rtx_getarrvaltally(val.rtx.c, (*C.hawk_val_t)(unsafe.Pointer(val.c)))
return int(v) return int(v)
} }
// TODO: function to get the first index and last index or the capacity // TODO: function to get the first index and last index or the capacity
// function to traverse? // function to traverse?
func (val *Val) GetArrayField(index int) (*Val, error) { func (val *Val) GetArrayField(index int) (*Val, error) {
var v *C.hawk_val_t var v CPtrVal
v = C.hawk_rtx_getarrvalfld(val.rtx.c, val.c, C.hawk_ooi_t(index)) v = CPtrVal(unsafe.Pointer(C.hawk_rtx_getarrvalfld(val.rtx.c, (*C.hawk_val_t)(unsafe.Pointer(val.c)), C.hawk_ooi_t(index))))
if v == nil { return nil, val.rtx.make_errinfo() } if v == 0 { return nil, val.rtx.make_errinfo() }
return val.rtx.make_val(func() *C.hawk_val_t { return v }) return val.rtx.make_val(func() CPtrVal { return v })
} }
func (val *Val) SetArrayField(index int, v *Val) error { func (val *Val) SetArrayField(index int, v *Val) error {
var vv *C.hawk_val_t var vv CPtrVal
vv = C.hawk_rtx_setarrvalfld(val.rtx.c, val.c, C.hawk_ooi_t(index), v.c) vv = CPtrVal(unsafe.Pointer(C.hawk_rtx_setarrvalfld(
if vv == nil { return val.rtx.make_errinfo() } val.rtx.c,
(*C.hawk_val_t)(unsafe.Pointer(val.c)),
C.hawk_ooi_t(index),
(*C.hawk_val_t)(unsafe.Pointer(v.c)))))
if vv == 0 { return val.rtx.make_errinfo() }
return nil return nil
} }
func (val *Val) SetArrayFieldWithInt(index int, v int) error { func (val *Val) SetArrayFieldWithInt(index int, v int) error {
var vv *C.hawk_val_t var vv CPtrVal
var ww *C.hawk_val_t var ww CPtrVal
vv = C.hawk_rtx_makeintval(val.rtx.c, C.hawk_int_t(v)) vv = CPtrVal(unsafe.Pointer(C.hawk_rtx_makeintval(val.rtx.c, C.hawk_int_t(v))))
if vv == nil { return val.rtx.make_errinfo() } if vv == 0 { return val.rtx.make_errinfo() }
C.hawk_rtx_refupval(val.rtx.c, vv) C.hawk_rtx_refupval(val.rtx.c, (*C.hawk_val_t)(unsafe.Pointer(vv)))
ww = C.hawk_rtx_setarrvalfld(val.rtx.c, val.c, C.hawk_ooi_t(index), vv) ww = CPtrVal(unsafe.Pointer(C.hawk_rtx_setarrvalfld(
C.hawk_rtx_refdownval(val.rtx.c, vv) val.rtx.c,
if ww == nil { return val.rtx.make_errinfo() } (*C.hawk_val_t)(unsafe.Pointer(val.c)),
C.hawk_ooi_t(index),
(*C.hawk_val_t)(unsafe.Pointer(vv)))))
C.hawk_rtx_refdownval(val.rtx.c, (*C.hawk_val_t)(unsafe.Pointer(vv)))
if ww == 0 { return val.rtx.make_errinfo() }
return nil return nil
} }
func (val *Val) SetArrayFieldWithFlt(index int, v float64) error { func (val *Val) SetArrayFieldWithFlt(index int, v float64) error {
var vv *C.hawk_val_t var vv CPtrVal
vv = C.make_flt_val(val.rtx.c, C.double(v)) var ww CPtrVal
if vv == nil { return val.rtx.make_errinfo() } vv = CPtrVal(unsafe.Pointer(C.make_flt_val(val.rtx.c, C.double(v))))
C.hawk_rtx_refupval(val.rtx.c, vv) if vv == 0 { return val.rtx.make_errinfo() }
vv = C.hawk_rtx_setarrvalfld(val.rtx.c, val.c, C.hawk_ooi_t(index), vv) C.hawk_rtx_refupval(val.rtx.c, (*C.hawk_val_t)(unsafe.Pointer(vv)))
C.hawk_rtx_refdownval(val.rtx.c, vv) ww = CPtrVal(unsafe.Pointer(C.hawk_rtx_setarrvalfld(
if vv == nil { return val.rtx.make_errinfo() } val.rtx.c,
(*C.hawk_val_t)(unsafe.Pointer(val.c)),
C.hawk_ooi_t(index),
(*C.hawk_val_t)(unsafe.Pointer(vv)))))
C.hawk_rtx_refdownval(val.rtx.c, (*C.hawk_val_t)(unsafe.Pointer(vv)))
if ww == 0 { return val.rtx.make_errinfo() }
return nil return nil
} }
func (val *Val) SetArrayFieldWithStr(index int, v string) error { func (val *Val) SetArrayFieldWithStr(index int, v string) error {
var vv *C.hawk_val_t var vv CPtrVal
var ww CPtrVal
var cv *C.hawk_bch_t var cv *C.hawk_bch_t
cv = C.CString(v) cv = C.CString(v)
vv = C.hawk_rtx_makestrvalwithbchars(val.rtx.c, cv, C.hawk_oow_t(len(v))) vv = CPtrVal(unsafe.Pointer(C.hawk_rtx_makestrvalwithbchars(val.rtx.c, cv, C.hawk_oow_t(len(v)))))
C.free(unsafe.Pointer(cv)) C.free(unsafe.Pointer(cv))
if vv == nil { return val.rtx.make_errinfo() } if vv == 0 { return val.rtx.make_errinfo() }
C.hawk_rtx_refupval(val.rtx.c, vv) C.hawk_rtx_refupval(val.rtx.c, (*C.hawk_val_t)(unsafe.Pointer(vv)))
vv = C.hawk_rtx_setarrvalfld(val.rtx.c, val.c, C.hawk_ooi_t(index), vv) ww = CPtrVal(unsafe.Pointer(C.hawk_rtx_setarrvalfld(
C.hawk_rtx_refdownval(val.rtx.c, vv) val.rtx.c,
if vv == nil { return val.rtx.make_errinfo() } (*C.hawk_val_t)(unsafe.Pointer(val.c)),
C.hawk_ooi_t(index),
(*C.hawk_val_t)(unsafe.Pointer(vv)))))
C.hawk_rtx_refdownval(val.rtx.c, (*C.hawk_val_t)(unsafe.Pointer(vv)))
if ww == 0 { return val.rtx.make_errinfo() }
return nil return nil
} }
func (itr *ValArrayItr) cptr() *C.hawk_val_arr_itr_t {
return (*C.hawk_val_arr_itr_t)(unsafe.Pointer(&itr.c[0]))
}
func (val *Val) GetFirstArrayField(itr *ValArrayItr) (int, *Val) { func (val *Val) GetFirstArrayField(itr *ValArrayItr) (int, *Val) {
var i *C.hawk_val_arr_itr_t //var i *C.hawk_val_arr_itr_t
var i uintptr
var v *Val var v *Val
var err error var err error
i = C.hawk_rtx_getfirstarrvalitr(val.rtx.c, val.c, &itr.c)
if i == nil { return -1, nil } i = uintptr(unsafe.Pointer(C.hawk_rtx_getfirstarrvalitr(
v, err = val.rtx.make_val(func() *C.hawk_val_t { return itr.c.elem }) val.rtx.c,
(*C.hawk_val_t)(unsafe.Pointer(val.c)),
itr.cptr())))
if i == 0 { return -1, nil }
v, err = val.rtx.make_val(func() CPtrVal {
return CPtrVal(C.val_arr_itr_elem(itr.cptr()))
})
if err != nil { return -1, nil } if err != nil { return -1, nil }
return int(itr.c.itr.idx), v; return int(itr.cptr().itr.idx), v;
} }
func (val *Val) GetNextArrayField(itr *ValArrayItr) (int, *Val) { func (val *Val) GetNextArrayField(itr *ValArrayItr) (int, *Val) {
var i *C.hawk_val_arr_itr_t //var i *C.hawk_val_arr_itr_t
var i uintptr
var v *Val var v *Val
var err error var err error
i = C.hawk_rtx_getnextarrvalitr(val.rtx.c, val.c, &itr.c)
if i == nil { return -1, nil } i = uintptr(unsafe.Pointer(C.hawk_rtx_getnextarrvalitr(
v, err = val.rtx.make_val(func() *C.hawk_val_t { return itr.c.elem }) val.rtx.c,
(*C.hawk_val_t)(unsafe.Pointer(val.c)),
itr.cptr())))
if i == 0 { return -1, nil }
v, err = val.rtx.make_val(func() CPtrVal {
return CPtrVal(C.val_arr_itr_elem(itr.cptr()))
})
if err != nil { return -1, nil } if err != nil { return -1, nil }
return int(itr.c.itr.idx), v; return int(itr.cptr().itr.idx), v;
} }
func (val *Val) GetMapField(key string) (*Val, error) { func (val *Val) GetMapField(key string) (*Val, error) {
var v *C.hawk_val_t var v CPtrVal
var uc []C.hawk_uch_t var uc []C.hawk_uch_t
uc = string_to_uchars(key) uc = string_to_uchars(key)
v = C.hawk_rtx_getmapvalfld(val.rtx.c, val.c, &uc[0], C.hawk_oow_t(len(uc))) v = (CPtrVal)(unsafe.Pointer(C.hawk_rtx_getmapvalfld(
if v == nil { return nil, val.rtx.make_errinfo() } val.rtx.c,
return val.rtx.make_val(func() *C.hawk_val_t { return v }) (*C.hawk_val_t)(unsafe.Pointer(val.c)),
&uc[0],
C.hawk_oow_t(len(uc)))))
if v == 0 { return nil, val.rtx.make_errinfo() }
return val.rtx.make_val(func() CPtrVal { return v })
} }
func (val *Val) SetMapField(key string, v *Val) error { func (val *Val) SetMapField(key string, v *Val) error {
var vv *C.hawk_val_t var vv CPtrVal
var kk []C.hawk_uch_t var kk []C.hawk_uch_t
kk = string_to_uchars(key) kk = string_to_uchars(key)
vv = C.hawk_rtx_setmapvalfld(val.rtx.c, val.c, &kk[0], C.hawk_oow_t(len(kk)), v.c) vv = (CPtrVal)(unsafe.Pointer(C.hawk_rtx_setmapvalfld(
if vv == nil { return val.rtx.make_errinfo() } val.rtx.c,
(*C.hawk_val_t)(unsafe.Pointer(val.c)),
&kk[0],
C.hawk_oow_t(len(kk)),
(*C.hawk_val_t)(unsafe.Pointer(v.c)))))
if vv == 0 { return val.rtx.make_errinfo() }
return nil return nil
} }
func (val *Val) SetMapFieldWithInt(key string, v int) error { func (val *Val) SetMapFieldWithInt(key string, v int) error {
var kk []C.hawk_uch_t var kk []C.hawk_uch_t
var vv *C.hawk_val_t var vv CPtrVal
var ww *C.hawk_val_t var ww CPtrVal
kk = string_to_uchars(key) kk = string_to_uchars(key)
vv = C.hawk_rtx_makeintval(val.rtx.c, C.hawk_int_t(v)) vv = CPtrVal(unsafe.Pointer(C.hawk_rtx_makeintval(val.rtx.c, C.hawk_int_t(v))))
if vv == nil { return val.rtx.make_errinfo() } if vv == 0 { return val.rtx.make_errinfo() }
C.hawk_rtx_refupval(val.rtx.c, vv) C.hawk_rtx_refupval(val.rtx.c, (*C.hawk_val_t)(unsafe.Pointer(vv)))
ww = C.hawk_rtx_setmapvalfld(val.rtx.c, val.c, &kk[0], C.hawk_oow_t(len(kk)), vv) ww = CPtrVal(unsafe.Pointer(C.hawk_rtx_setmapvalfld(
C.hawk_rtx_refdownval(val.rtx.c, vv) val.rtx.c,
if ww == nil { return val.rtx.make_errinfo() } (*C.hawk_val_t)(unsafe.Pointer(val.c)),
&kk[0],
C.hawk_oow_t(len(kk)),
(*C.hawk_val_t)(unsafe.Pointer(vv)))))
C.hawk_rtx_refdownval(val.rtx.c, (*C.hawk_val_t)(unsafe.Pointer(vv)))
if ww == 0 { return val.rtx.make_errinfo() }
return nil return nil
} }
func (val *Val) SetMapFieldWithFlt(key string, v float64) error { func (val *Val) SetMapFieldWithFlt(key string, v float64) error {
var kk []C.hawk_uch_t var kk []C.hawk_uch_t
var vv *C.hawk_val_t var vv CPtrVal
var ww *C.hawk_val_t var ww CPtrVal
kk = string_to_uchars(key) kk = string_to_uchars(key)
vv = C.make_flt_val(val.rtx.c, C.double(v)) vv = CPtrVal(unsafe.Pointer(C.make_flt_val(val.rtx.c, C.double(v))))
if vv == nil { return val.rtx.make_errinfo() } if vv == 0 { return val.rtx.make_errinfo() }
C.hawk_rtx_refupval(val.rtx.c, vv) C.hawk_rtx_refupval(val.rtx.c, (*C.hawk_val_t)(unsafe.Pointer(vv)))
ww = C.hawk_rtx_setmapvalfld(val.rtx.c, val.c, &kk[0], C.hawk_oow_t(len(kk)), vv) ww = CPtrVal(unsafe.Pointer(C.hawk_rtx_setmapvalfld(
C.hawk_rtx_refdownval(val.rtx.c, vv) val.rtx.c,
if ww == nil { return val.rtx.make_errinfo() } (*C.hawk_val_t)(unsafe.Pointer(val.c)),
&kk[0],
C.hawk_oow_t(len(kk)),
(*C.hawk_val_t)(unsafe.Pointer(vv)))))
C.hawk_rtx_refdownval(val.rtx.c, (*C.hawk_val_t)(unsafe.Pointer(vv)))
if ww == 0 { return val.rtx.make_errinfo() }
return nil return nil
} }
func (val *Val) SetMapFieldWithStr(key string, v string) error { func (val *Val) SetMapFieldWithStr(key string, v string) error {
var kk []C.hawk_uch_t var kk []C.hawk_uch_t
var vv *C.hawk_val_t var vv CPtrVal
var ww *C.hawk_val_t var ww CPtrVal
var cv *C.hawk_bch_t var cv *C.hawk_bch_t
kk = string_to_uchars(key) kk = string_to_uchars(key)
cv = C.CString(v) cv = C.CString(v)
vv = C.hawk_rtx_makestrvalwithbchars(val.rtx.c, cv, C.hawk_oow_t(len(v))) vv = CPtrVal(unsafe.Pointer(C.hawk_rtx_makestrvalwithbchars(val.rtx.c, cv, C.hawk_oow_t(len(v)))))
C.free(unsafe.Pointer(cv)) C.free(unsafe.Pointer(cv))
if vv == nil { return val.rtx.make_errinfo() } if vv == 0 { return val.rtx.make_errinfo() }
C.hawk_rtx_refupval(val.rtx.c, vv) C.hawk_rtx_refupval(val.rtx.c, (*C.hawk_val_t)(unsafe.Pointer(vv)))
ww = C.hawk_rtx_setmapvalfld(val.rtx.c, val.c, &kk[0], C.hawk_oow_t(len(kk)), vv) ww = CPtrVal(unsafe.Pointer(C.hawk_rtx_setmapvalfld(
C.hawk_rtx_refdownval(val.rtx.c, vv) val.rtx.c,
if ww == nil { return val.rtx.make_errinfo() } (*C.hawk_val_t)(unsafe.Pointer(val.c)),
&kk[0],
C.hawk_oow_t(len(kk)),
(*C.hawk_val_t)(unsafe.Pointer(vv)))))
C.hawk_rtx_refdownval(val.rtx.c, (*C.hawk_val_t)(unsafe.Pointer(vv)))
if ww == 0 { return val.rtx.make_errinfo() }
return nil return nil
} }
@@ -1360,10 +1453,14 @@ func (val *Val) GetFirstMapField(itr *ValMapItr) (string, *Val) {
var k string var k string
var v *Val var v *Val
var err error var err error
i = C.hawk_rtx_getfirstmapvalitr(val.rtx.c, val.c, &itr.c)
i = C.hawk_rtx_getfirstmapvalitr(val.rtx.c, (*C.hawk_val_t)(unsafe.Pointer(val.c)), &itr.c)
if i == nil { return "", nil } if i == nil { return "", nil }
k = string(uchars_to_rune_slice((*C.hawk_uch_t)(itr.c.pair.key.ptr), uintptr(itr.c.pair.key.len))) k = string(uchars_to_rune_slice((*C.hawk_uch_t)(itr.c.pair.key.ptr), uintptr(itr.c.pair.key.len)))
v, err = val.rtx.make_val(func() *C.hawk_val_t { return (*C.hawk_val_t)(itr.c.pair.val.ptr) }) v, err = val.rtx.make_val(func() CPtrVal {
return CPtrVal(C.val_map_itr_val(&itr.c))
})
if err != nil { return "", nil } if err != nil { return "", nil }
return k, v; return k, v;
} }
@@ -1373,10 +1470,14 @@ func (val *Val) GetNextMapField(itr *ValMapItr) (string, *Val) {
var k string var k string
var v *Val var v *Val
var err error var err error
i = C.hawk_rtx_getnextmapvalitr(val.rtx.c, val.c, &itr.c)
i = C.hawk_rtx_getnextmapvalitr(val.rtx.c, (*C.hawk_val_t)(unsafe.Pointer(val.c)), &itr.c)
if i == nil { return "", nil } if i == nil { return "", nil }
k = string(uchars_to_rune_slice((*C.hawk_uch_t)(itr.c.pair.key.ptr), uintptr(itr.c.pair.key.len))) k = string(uchars_to_rune_slice((*C.hawk_uch_t)(itr.c.pair.key.ptr), uintptr(itr.c.pair.key.len)))
v, err = val.rtx.make_val(func() *C.hawk_val_t { return (*C.hawk_val_t)(itr.c.pair.val.ptr) }) v, err = val.rtx.make_val(func() CPtrVal {
return CPtrVal(C.val_map_itr_val(&itr.c))
})
if err != nil { return "", nil } if err != nil { return "", nil }
return k, v; return k, v;
} }
+320 -18
View File
@@ -19,7 +19,9 @@ func make_hawk(script string) (*hawk.Hawk, error) {
var err error var err error
h, err = hawk.New() h, err = hawk.New()
if err != nil { return nil, err } if err != nil {
return nil, err
}
err = h.ParseText(script) err = h.ParseText(script)
if err != nil { if err != nil {
@@ -31,7 +33,7 @@ func make_hawk(script string) (*hawk.Hawk, error) {
} }
func enbase64(rtx *hawk.Rtx) error { func enbase64(rtx *hawk.Rtx) error {
fmt.Printf ("*** ENBASE64 RTX %p\n", rtx) // << this is 0 from time to time.. TODO: fix it.. fmt.Printf("*** ENBASE64 RTX %p\n", rtx) // << this is 0 from time to time.. TODO: fix it..
fmt.Printf("****ENBASE64 [%d]\n", rtx.GetFuncArgCount()) fmt.Printf("****ENBASE64 [%d]\n", rtx.GetFuncArgCount())
var a0 *hawk.Val = hawk.Must(rtx.GetFuncArg(0)) var a0 *hawk.Val = hawk.Must(rtx.GetFuncArg(0))
@@ -47,7 +49,7 @@ func debase64(rtx *hawk.Rtx) error {
fmt.Printf("****DEBASE64 [%d]\n", rtx.GetFuncArgCount()) fmt.Printf("****DEBASE64 [%d]\n", rtx.GetFuncArgCount())
rtx.SetFuncRet(hawk.Must(rtx.NewFltVal(-999.1111))) rtx.SetFuncRet(hawk.Must(rtx.NewFltVal(-999.1111)))
return nil return nil
//return fmt.Errorf("what the hell.....") // return fmt.Errorf("what the hell.....")
} }
func make_hawk_extended(script string) (*hawk.Hawk, error) { func make_hawk_extended(script string) (*hawk.Hawk, error) {
@@ -55,7 +57,9 @@ func make_hawk_extended(script string) (*hawk.Hawk, error) {
var err error var err error
h, err = hawk.New() h, err = hawk.New()
if err != nil { return nil, err } if err != nil {
return nil, err
}
h.AddFunc("enbase64", 1, 10, "", enbase64) h.AddFunc("enbase64", 1, 10, "", enbase64)
h.AddFunc("debase64", 1, 1, "", debase64) h.AddFunc("debase64", 1, 1, "", debase64)
@@ -69,6 +73,155 @@ func make_hawk_extended(script string) (*hawk.Hawk, error) {
return h, nil return h, nil
} }
func echoint(rtx *hawk.Rtx) error {
var v *hawk.Val
var i int
var err error
v, err = rtx.GetFuncArg(0)
if err != nil {
return err
}
i, err = v.ToInt()
if err != nil {
return err
}
return rtx.SetFuncRetWithInt(i)
}
func force_gc() {
runtime.GC()
runtime.Gosched()
}
func expect_int_val(t *testing.T, v *hawk.Val, want int, msg string) {
var got int
var s string
var err error
t.Helper()
got, err = v.ToInt()
if err != nil {
t.Fatalf("%s: failed to convert to int - %s", msg, err.Error())
}
if got != want {
t.Fatalf("%s: expected %d but got %d", msg, want, got)
}
s, err = v.ToStr()
if err != nil {
t.Fatalf("%s: failed to convert to string - %s", msg, err.Error())
}
if s != fmt.Sprintf("%d", want) {
t.Fatalf("%s: expected string %q but got %q", msg, fmt.Sprintf("%d", want), s)
}
}
func expect_map_ints(t *testing.T, v *hawk.Val, want map[string]int) {
var key string
var f *hawk.Val
var got map[string]int
var itr hawk.ValMapItr
var err error
t.Helper()
if v.Type() != hawk.VAL_MAP {
t.Fatalf("expected a map but got %s", v.Type().String())
}
for key = range want {
force_gc()
f, err = v.GetMapField(key)
if err != nil {
t.Fatalf("failed to get map field %q - %s", key, err.Error())
}
expect_int_val(t, f, want[key], fmt.Sprintf("map field %q", key))
}
got = make(map[string]int)
key, f = v.GetFirstMapField(&itr)
for f != nil {
var iv int
force_gc()
iv, err = f.ToInt()
if err != nil {
t.Fatalf("failed to convert iterated map value for key %q - %s", key, err.Error())
}
got[key] = iv
force_gc()
key, f = v.GetNextMapField(&itr)
}
if len(got) != len(want) {
t.Fatalf("expected %d iterated map entries but got %d", len(want), len(got))
}
for key = range want {
if got[key] != want[key] {
t.Fatalf("iterated map field %q: expected %d but got %d", key, want[key], got[key])
}
}
}
func expect_array_ints(t *testing.T, v *hawk.Val, want map[int]int) {
var idx int
var f *hawk.Val
var got map[int]int
var itr hawk.ValArrayItr
var err error
t.Helper()
if v.Type() != hawk.VAL_ARR {
t.Fatalf("expected an array but got %s", v.Type().String())
}
if v.ArrayTally() != len(want) {
t.Fatalf("expected %d array elements but got %d", len(want), v.ArrayTally())
}
for idx = range want {
force_gc()
f, err = v.GetArrayField(idx)
if err != nil {
t.Fatalf("failed to get array field %d - %s", idx, err.Error())
}
expect_int_val(t, f, want[idx], fmt.Sprintf("array field %d", idx))
}
got = make(map[int]int)
idx, f = v.GetFirstArrayField(&itr)
for f != nil {
var iv int
force_gc()
iv, err = f.ToInt()
if err != nil {
t.Fatalf("failed to convert iterated array value at %d - %s", idx, err.Error())
}
got[idx] = iv
force_gc()
idx, f = v.GetNextArrayField(&itr)
}
if len(got) != len(want) {
t.Fatalf("expected %d iterated array entries but got %d", len(want), len(got))
}
for idx = range want {
if got[idx] != want[idx] {
t.Fatalf("iterated array field %d: expected %d but got %d", idx, want[idx], got[idx])
}
}
}
func run_hawk(h *hawk.Hawk, id int, t *testing.T, wg *sync.WaitGroup) { func run_hawk(h *hawk.Hawk, id int, t *testing.T, wg *sync.WaitGroup) {
var rtx *hawk.Rtx var rtx *hawk.Rtx
var v *hawk.Val var v *hawk.Val
@@ -86,9 +239,9 @@ func run_hawk(h *hawk.Hawk, id int, t *testing.T, wg *sync.WaitGroup) {
} }
v, err = rtx.Call("x", v, err = rtx.Call("x",
hawk.Must(rtx.NewVal/*FromInt*/(id + 10)), hawk.Must(rtx.NewVal /*FromInt*/ (id+10)),
hawk.Must(rtx.NewVal([]byte{'A',66,67,68,69})), hawk.Must(rtx.NewVal([]byte{'A', 66, 67, 68, 69})),
hawk.Must(rtx.NewVal/*FromStr*/("this is cool"))) hawk.Must(rtx.NewVal /*FromStr*/ ("this is cool")))
if err != nil { if err != nil {
t.Errorf("failed to invoke function 'x' for rtx id[%d] - %s", id, err.Error()) t.Errorf("failed to invoke function 'x' for rtx id[%d] - %s", id, err.Error())
rtx.Close() rtx.Close()
@@ -105,13 +258,17 @@ func run_hawk(h *hawk.Hawk, id int, t *testing.T, wg *sync.WaitGroup) {
// check if ValCount() returns the right number of values created. 3 explicitly and 1 return value // check if ValCount() returns the right number of values created. 3 explicitly and 1 return value
i = rtx.ValCount() i = rtx.ValCount()
if i != 4 { t.Errorf("the number of val objects for rtx id[%d] must be 4. but %d was returned", id, i) } if i != 4 {
t.Errorf("the number of val objects for rtx id[%d] must be 4. but %d was returned", id, i)
}
rtx.Close() rtx.Close()
// it's safe to all ValCount() after Close() has been called. // it's safe to all ValCount() after Close() has been called.
i = rtx.ValCount() i = rtx.ValCount()
if i != 0 { t.Errorf("the number of val objects for rtx id[%d] must be 0. but %d was returned", id, i) } if i != 0 {
t.Errorf("the number of val objects for rtx id[%d] must be 0. but %d was returned", id, i)
}
} }
func Test1(t *testing.T) { func Test1(t *testing.T) {
@@ -143,12 +300,14 @@ return 1.9923;
// when rtx objects are all closed, the counter must drop to 0 // when rtx objects are all closed, the counter must drop to 0
i = h.RtxCount() i = h.RtxCount()
if i != 0 { t.Errorf("the number of rtx objects must be 0. but %d was returned", i) } if i != 0 {
t.Errorf("the number of rtx objects must be 0. but %d was returned", i)
}
h.Close() h.Close()
h = nil h = nil
fmt.Printf ("== END of Test1 ==\n") fmt.Printf("== END of Test1 ==\n")
runtime.GC() runtime.GC()
runtime.Gosched() runtime.Gosched()
time.Sleep(1000 * time.Millisecond) // give finalizer time to print time.Sleep(1000 * time.Millisecond) // give finalizer time to print
@@ -184,7 +343,7 @@ return x;
rtx, err = h.NewRtx("test2", nil, nil) rtx, err = h.NewRtx("test2", nil, nil)
if err != nil { if err != nil {
t.Errorf("failed to create rtx - %s", err.Error()) t.Errorf("failed to create rtx - %s", err.Error())
} else { } else {
var v *hawk.Val var v *hawk.Val
v, err = rtx.Call("get_map", hawk.Must(rtx.NewStrVal("hawk flies"))) v, err = rtx.Call("get_map", hawk.Must(rtx.NewStrVal("hawk flies")))
@@ -265,9 +424,9 @@ return x;
} }
/* /*
for i = 1; i <= sz; i++ { for i = 1; i <= sz; i++ {
fmt.Printf("%d %v\n", i, hawk.Must(v.GetArrayField(i))) fmt.Printf("%d %v\n", i, hawk.Must(v.GetArrayField(i)))
} }
*/ */
fmt.Printf("== CHANGING ARRAY ==\n") fmt.Printf("== CHANGING ARRAY ==\n")
v.SetArrayField(88, hawk.Must(rtx.NewStrVal("eighty eight"))) v.SetArrayField(88, hawk.Must(rtx.NewStrVal("eighty eight")))
@@ -298,7 +457,7 @@ func Test3(t *testing.T) {
debug.SetGCPercent(100) // enable normal GC debug.SetGCPercent(100) // enable normal GC
fmt.Printf ("BEGINNING OF TEST3\n") fmt.Printf("BEGINNING OF TEST3\n")
h, err = make_hawk_extended(`function main(s) { h, err = make_hawk_extended(`function main(s) {
print enbase64(s, "hello", 1.289); print enbase64(s, "hello", 1.289);
@@ -313,7 +472,7 @@ return x
rtx, err = h.NewRtx("test3", nil, nil) rtx, err = h.NewRtx("test3", nil, nil)
if err != nil { if err != nil {
t.Errorf("failed to create rtx - %s", err.Error()) t.Errorf("failed to create rtx - %s", err.Error())
} else { } else {
var v *hawk.Val var v *hawk.Val
v, err = rtx.Call("main", hawk.Must(rtx.NewStrVal("this is a test3 string"))) v, err = rtx.Call("main", hawk.Must(rtx.NewStrVal("this is a test3 string")))
@@ -325,10 +484,153 @@ return x
} }
h.Close() h.Close()
fmt.Printf ("END OF TEST3\n") fmt.Printf("END OF TEST3\n")
runtime.GC() runtime.GC()
runtime.Gosched() runtime.Gosched()
time.Sleep(1000 * time.Millisecond) // give finalizer time to print time.Sleep(1000 * time.Millisecond) // give finalizer time to print
} }
func Test4(t *testing.T) {
var h *hawk.Hawk
var rtx *hawk.Rtx
var v *hawk.Val
var gm *hawk.Val
var ga *hawk.Val
var err error
var round int
debug.SetGCPercent(100)
h, err = hawk.New()
if err != nil {
t.Fatalf("Failed to make hawk - %s", err.Error())
}
h.AddFunc("echoint", 1, 1, "", echoint)
err = h.ParseText(`function ret_zero() { return 0; }
function ret_one() { return 1; }
function ret_neg() { return -1; }
function call_echo_zero() { return echoint(0); }
function call_echo_neg() { return echoint(-1); }
function make_int_map() {
@local x;
x["zero"] = 0;
x["one"] = 1;
x["neg"] = -1;
return x;
}
function make_int_arr() {
@local x;
x = hawk::array(0, 1, -1);
return x;
}`)
if err != nil {
h.Close()
t.Fatalf("Failed to parse hawk script - %s", err.Error())
}
rtx, err = h.NewRtx("test4", nil, nil)
if err != nil {
h.Close()
t.Fatalf("failed to create rtx - %s", err.Error())
}
for round = 0; round < 32; round++ {
for _, tc := range []struct {
name string
want int
}{
{"ret_zero", 0},
{"ret_one", 1},
{"ret_neg", -1},
{"call_echo_zero", 0},
{"call_echo_neg", -1},
} {
force_gc()
v, err = rtx.Call(tc.name)
if err != nil {
rtx.Close()
h.Close()
t.Fatalf("failed to call %s - %s", tc.name, err.Error())
}
force_gc()
expect_int_val(t, v, tc.want, tc.name)
}
}
v, err = rtx.Call("make_int_map")
if err != nil {
rtx.Close()
h.Close()
t.Fatalf("failed to call make_int_map - %s", err.Error())
}
expect_map_ints(t, v, map[string]int{
"zero": 0,
"one": 1,
"neg": -1,
})
v, err = rtx.Call("make_int_arr")
if err != nil {
rtx.Close()
h.Close()
t.Fatalf("failed to call make_int_arr - %s", err.Error())
}
expect_array_ints(t, v, map[int]int{
1: 0,
2: 1,
3: -1,
})
gm = hawk.Must(rtx.NewMapVal())
if err = gm.SetMapFieldWithInt("zero", 0); err != nil {
rtx.Close()
h.Close()
t.Fatalf("failed to set zero map field - %s", err.Error())
}
if err = gm.SetMapFieldWithInt("one", 1); err != nil {
rtx.Close()
h.Close()
t.Fatalf("failed to set one map field - %s", err.Error())
}
if err = gm.SetMapFieldWithInt("neg", -1); err != nil {
rtx.Close()
h.Close()
t.Fatalf("failed to set neg map field - %s", err.Error())
}
expect_map_ints(t, gm, map[string]int{
"zero": 0,
"one": 1,
"neg": -1,
})
ga = hawk.Must(rtx.NewArrVal(0))
if err = ga.SetArrayFieldWithInt(1, 0); err != nil {
rtx.Close()
h.Close()
t.Fatalf("failed to set array field 1 - %s", err.Error())
}
if err = ga.SetArrayFieldWithInt(2, 1); err != nil {
rtx.Close()
h.Close()
t.Fatalf("failed to set array field 2 - %s", err.Error())
}
if err = ga.SetArrayFieldWithInt(3, -1); err != nil {
rtx.Close()
h.Close()
t.Fatalf("failed to set array field 3 - %s", err.Error())
}
expect_array_ints(t, ga, map[int]int{
1: 0,
2: 1,
3: -1,
})
rtx.Close()
h.Close()
force_gc()
time.Sleep(100 * time.Millisecond)
}