From 2fb423df1a254dd54d9ecc133766b47ee97834e5 Mon Sep 17 00:00:00 2001 From: hyung-hwan Date: Sat, 1 Nov 2025 13:29:49 +0900 Subject: [PATCH] updating more value manipulation code for the go wrapper --- Makefile.am | 8 +++++ Makefile.in | 8 +++++ hawk.go | 95 +++++++++++++++++++++++++++++++++++----------------- hawk_test.go | 92 ++++++++++++++++++++++++++++++++++++++++++++++++++ lib/hawk.h | 8 ++--- lib/run.c | 1 - 6 files changed, 176 insertions(+), 36 deletions(-) create mode 100644 hawk_test.go diff --git a/Makefile.am b/Makefile.am index 86400341..bb739908 100644 --- a/Makefile.am +++ b/Makefile.am @@ -51,6 +51,14 @@ hawkgo.bin: lib/libhawk.la $(hawkgo_OBJECTS) go build -C $(srcdir) -ldflags "-X 'main.BINDIR=$(bindir)' -X 'main.SBINDIR=$(sbindir)' -X 'main.LIBDIR=$(libdir)' -X 'main.SYSCONFDIR=$(sysconfdir)'" -x -o $(abs_builddir)/hawkgo.bin -modfile $(abs_builddir)/go.mod ## --------------------------------------------------------------- go clean -C $(srcdir) -x -modfile $(abs_builddir)/go.mod + +hawkgo.check: + CC=$(CC) \ + CGO_CFLAGS="-I$(abs_srcdir)/lib -I$(abs_builddir)/lib $(CFLAGS) $(CGO_CFLAGS_EXTRA)" \ + CGO_LDFLAGS="-L$(abs_builddir)/lib -L$(abs_builddir)/lib/.libs -lhawk -ldl $(LIBM) $(CGO_LDFLAGS_EXTRA)" \ + go test -C $(srcdir) -ldflags "-X 'main.BINDIR=$(bindir)' -X 'main.SBINDIR=$(sbindir)' -X 'main.LIBDIR=$(libdir)' -X 'main.SYSCONFDIR=$(sysconfdir)'" -x -o $(abs_builddir)/hawkgo.bin -modfile $(abs_builddir)/go.mod + go clean -C $(srcdir) -x -modfile $(abs_builddir)/go.mod + # fake recipes to deceive make .go.o: echo $< > $@ diff --git a/Makefile.in b/Makefile.in index 5a0f69c5..d0d256d2 100644 --- a/Makefile.in +++ b/Makefile.in @@ -965,6 +965,14 @@ clean-local: @ENABLE_HAWKGO_TRUE@ CGO_LDFLAGS="-L$(abs_builddir)/lib -L$(abs_builddir)/lib/.libs -lhawk -ldl $(LIBM) $(CGO_LDFLAGS_EXTRA)" \ @ENABLE_HAWKGO_TRUE@ go build -C $(srcdir) -ldflags "-X 'main.BINDIR=$(bindir)' -X 'main.SBINDIR=$(sbindir)' -X 'main.LIBDIR=$(libdir)' -X 'main.SYSCONFDIR=$(sysconfdir)'" -x -o $(abs_builddir)/hawkgo.bin -modfile $(abs_builddir)/go.mod @ENABLE_HAWKGO_TRUE@ go clean -C $(srcdir) -x -modfile $(abs_builddir)/go.mod + +@ENABLE_HAWKGO_TRUE@hawkgo.check: +@ENABLE_HAWKGO_TRUE@ CC=$(CC) \ +@ENABLE_HAWKGO_TRUE@ CGO_CFLAGS="-I$(abs_srcdir)/lib -I$(abs_builddir)/lib $(CFLAGS) $(CGO_CFLAGS_EXTRA)" \ +@ENABLE_HAWKGO_TRUE@ CGO_LDFLAGS="-L$(abs_builddir)/lib -L$(abs_builddir)/lib/.libs -lhawk -ldl $(LIBM) $(CGO_LDFLAGS_EXTRA)" \ +@ENABLE_HAWKGO_TRUE@ go test -C $(srcdir) -ldflags "-X 'main.BINDIR=$(bindir)' -X 'main.SBINDIR=$(sbindir)' -X 'main.LIBDIR=$(libdir)' -X 'main.SYSCONFDIR=$(sysconfdir)'" -x -o $(abs_builddir)/hawkgo.bin -modfile $(abs_builddir)/go.mod +@ENABLE_HAWKGO_TRUE@ go clean -C $(srcdir) -x -modfile $(abs_builddir)/go.mod + # fake recipes to deceive make @ENABLE_HAWKGO_TRUE@.go.o: @ENABLE_HAWKGO_TRUE@ echo $< > $@ diff --git a/hawk.go b/hawk.go index fad00360..4292500f 100644 --- a/hawk.go +++ b/hawk.go @@ -450,6 +450,8 @@ func (rtx *Rtx) NewVal(v interface{}) (*Val, error) { switch _type.Kind() { case reflect.Int: return rtx.NewValFromInt(v.(int)) + case reflect.Float32: + return rtx.NewValFromFlt(float64(v.(float32))) case reflect.Float64: return rtx.NewValFromFlt(v.(float64)) case reflect.String: @@ -470,12 +472,11 @@ func (rtx *Rtx) NewVal(v interface{}) (*Val, error) { } } - -func (rtx *Rtx) NewValFromInt(v int) (*Val, error) { +func (rtx* Rtx) make_val(vmaker func() *C.hawk_val_t) (*Val, error) { var c *C.hawk_val_t var vv *Val - c = C.hawk_rtx_makeintval(rtx.c, C.hawk_int_t(v)) + c = vmaker() if c == nil { return nil, rtx.make_errinfo() } C.hawk_rtx_refupval(rtx.c, c) @@ -484,43 +485,58 @@ func (rtx *Rtx) NewValFromInt(v int) (*Val, error) { return vv, nil } +func (rtx *Rtx) NewValFromByte(v byte) (*Val, error) { + return rtx.make_val(func() *C.hawk_val_t { + return C.hawk_rtx_makebchrval(rtx.c, C.hawk_bch_t(v)) + }) +} + +func (rtx *Rtx) NewValFromRune(v rune) (*Val, error) { + return rtx.make_val(func() *C.hawk_val_t { + return C.hawk_rtx_makecharval(rtx.c, C.hawk_ooch_t(v)) + }) +} + +func (rtx *Rtx) NewValFromInt(v int) (*Val, error) { + return rtx.make_val(func() *C.hawk_val_t { + return C.hawk_rtx_makeintval(rtx.c, C.hawk_int_t(v)) + }) +} + func (rtx *Rtx) NewValFromFlt(v float64) (*Val, error) { - var c *C.hawk_val_t - var vv *Val - - c = C.make_flt_val(rtx.c, C.double(v)) - if c == nil { return nil, rtx.make_errinfo() } - - C.hawk_rtx_refupval(rtx.c, c) - vv = &Val{rtx: rtx, c: c} - rtx.chain_val(vv) - return vv, nil + return rtx.make_val(func() *C.hawk_val_t { + return C.make_flt_val(rtx.c, C.double(v)) + }) } func (rtx *Rtx) NewValFromStr(v string) (*Val, error) { - var c *C.hawk_val_t - var vv *Val - - c = C.hawk_rtx_makestrvalwithbchars(rtx.c, C.CString(v), C.hawk_oow_t(len(v))) - if c == nil { return nil, rtx.make_errinfo() } - - C.hawk_rtx_refupval(rtx.c, c) - vv = &Val{rtx: rtx, c: c} - rtx.chain_val(vv) - return vv, nil + return rtx.make_val(func() *C.hawk_val_t { + return C.hawk_rtx_makestrvalwithbchars(rtx.c, C.CString(v), C.hawk_oow_t(len(v))) + }) } func (rtx *Rtx) NewValFromByteArr(v []byte) (*Val, error) { - var c *C.hawk_val_t - var vv *Val + return rtx.make_val(func() *C.hawk_val_t { + return C.hawk_rtx_makembsvalwithbchars(rtx.c, (*C.hawk_bch_t)(unsafe.Pointer(&v[0])), C.hawk_oow_t(len(v))) + }) +} - c = C.hawk_rtx_makembsvalwithbchars(rtx.c, (*C.hawk_bch_t)(unsafe.Pointer(&v[0])), C.hawk_oow_t(len(v))) - if c == nil { return nil, rtx.make_errinfo() } +func (rtx *Rtx) NewBobVal(v []byte) (*Val, error) { + return rtx.make_val(func() *C.hawk_val_t { + return C.hawk_rtx_makebobval(rtx.c, unsafe.Pointer(&v[0]), C.hawk_oow_t(len(v))) + }) +} - C.hawk_rtx_refupval(rtx.c, c) - vv = &Val{rtx: rtx, c: c} - rtx.chain_val(vv) - return vv, nil +func (rtx *Rtx) NewMapVal() (*Val, error) { + return rtx.make_val(func() *C.hawk_val_t { + return C.hawk_rtx_makemapval(rtx.c) + }) +} + +func (rtx *Rtx) NewArrVal(init_capa int) (*Val, error) { + return rtx.make_val(func() *C.hawk_val_t { + return C.hawk_rtx_makearrval(rtx.c, C.hawk_ooi_t(init_capa)) + }) } func (val *Val) Close() { @@ -530,6 +546,12 @@ func (val *Val) Close() { } } +/*func (val* Val) ToByte() (byte, error) { +} + +func (val* Val) ToRune() (rune, error) { +}*/ + func (val* Val) ToInt() (int, error) { var v C.hawk_int_t var x C.int @@ -570,6 +592,17 @@ func (val* Val) ToStr() (string, error) { } func (val* Val) ToByteArr() ([]byte, error) { + var ptr *C.hawk_bch_t + var len C.hawk_oow_t + var v []byte + + ptr = C.hawk_rtx_valtobcstrdupwithcmgr(val.rtx.c, val.c, &len, C.hawk_rtx_getcmgr(val.rtx.c)) + if ptr == nil { return nil, val.rtx.make_errinfo() } + + v = C.GoBytes(unsafe.Pointer(ptr), C.int(len)) + C.hawk_rtx_freemem(val.rtx.c, unsafe.Pointer(ptr)) + + return v, nil } // ----------------------------------------------------------- diff --git a/hawk_test.go b/hawk_test.go new file mode 100644 index 00000000..398f4252 --- /dev/null +++ b/hawk_test.go @@ -0,0 +1,92 @@ +package hawk_test + +import "hawk" +import "fmt" +import "os" +import "runtime" +import "runtime/debug" +import "sync" +import "testing" +import "time" + +func exit_with_error(msg string, err error) { + fmt.Printf("ERROR: %s - %s\n", msg, err.Error()) + os.Exit(1) +} + +func make_hawk() (*hawk.Hawk, error) { + var h *hawk.Hawk + var err error + + h, err = hawk.New() + if err != nil { return nil, err } + + err = h.ParseText(`function x(a1, a2, a3) { +for (i = 0; i < 10; i++) { + printf("hello, world [%d] [%s] [%s]\n", a1, a2, a3); + ##if (i == 3) sys::sleep(1); +} +##return "welcome to the jungle 999"; +return 1.9923; +}`) + if err != nil { return nil, err } + + return h, nil +} + +func run_hawk(h *hawk.Hawk, id int, wg *sync.WaitGroup) { + var r *hawk.Rtx + var v *hawk.Val + //var ret string + var ret []byte //float64 + var err error + + defer wg.Done() + + r, err = h.NewRtx(fmt.Sprintf("%d", id)) + if err != nil { + } + + v, err = r.Call("x", + hawk.Must(r.NewVal/*FromInt*/(id + 10)), + hawk.Must(r.NewVal([]byte{'A',66,67,68,69})), + hawk.Must(r.NewVal/*FromStr*/("this is cool"))) + if err != nil { exit_with_error("rtx call", err) } + + ret, err = v.ToByteArr() + if err != nil { + fmt.Printf("failed to get return value - %s\n", err.Error()) + } else { + fmt.Printf("RET[%d] => [%v]\n", id, ret) + } + + r.Close() +} + +func Test1(t *testing.T) { + var h *hawk.Hawk + var wg sync.WaitGroup + var i int + var err error + + debug.SetGCPercent(100) // enable normal GC + + h, err = make_hawk() + if err != nil { exit_with_error("Failed to make hawk", err) } + + for i = 0; i < 10; i++ { + wg.Add(1) + go run_hawk(h, i, &wg) + } + wg.Wait() + + fmt.Printf ("%d RTX objects\n", h.RtxCount()) + h.Close() + h = nil + +fmt.Printf ("== END of run ==\n") + runtime.GC() + runtime.Gosched() + time.Sleep(1000 * time.Millisecond) // give finalizer time to print +} + diff --git a/lib/hawk.h b/lib/hawk.h index 3b02d1fe..22047054 100644 --- a/lib/hawk.h +++ b/lib/hawk.h @@ -3661,10 +3661,10 @@ HAWK_EXPORT void hawk_rtx_freevalbcstr ( * hawk_int_t l; * hawk_flt_t r; * int n; - * n = hawk_rtx_valtonum (v, &l, &r); - * if (n <= -1) error (); - * else if (n == 0) print_int (l); - * else if (n >= 1) print_flt (r); + * n = hawk_rtx_valtonum(v, &l, &r); + * if (n <= -1) error(); + * else if (n == 0) print_int(l); + * else if (n >= 1) print_flt(r); * \endcode * * \return -1 on failure, 0 if converted to an integer, 1 if converted to diff --git a/lib/run.c b/lib/run.c index 60226590..ccf82137 100644 --- a/lib/run.c +++ b/lib/run.c @@ -9845,7 +9845,6 @@ wp_mod_main: else ch = 0; break; - default: hawk_rtx_refdownval(rtx, v); hawk_rtx_seterrnum(rtx, HAWK_NULL, HAWK_EVALTOCHR);