From 0bb30e716c971d4bebf5670e98e1fb366a86d020 Mon Sep 17 00:00:00 2001 From: hyung-hwan Date: Wed, 10 Dec 2025 20:50:20 +0900 Subject: [PATCH] enhanced hawkgo to print named variables if -D is given --- bin/hawk.c | 12 ++++++------ bin/hawkgo.go | 22 ++++++++++++++++++++-- hawk.go | 39 ++++++++++++++++++++++++++++++++++++--- 3 files changed, 62 insertions(+), 11 deletions(-) diff --git a/bin/hawk.c b/bin/hawk.c index 9eaa9816..5ff3ac31 100644 --- a/bin/hawk.c +++ b/bin/hawk.c @@ -298,25 +298,25 @@ static void dprint_return (hawk_rtx_t* rtx, hawk_val_t* ret) if (hawk_rtx_isnilval(rtx, ret)) { - hawk_logfmt (hawk, HAWK_LOG_STDERR,HAWK_T("[RETURN] - ***nil***\n")); + hawk_logfmt(hawk, HAWK_LOG_STDERR,HAWK_T("[RETURN] - ***nil***\n")); } else { str = hawk_rtx_valtooocstrdup(rtx, ret, &len); if (str == HAWK_NULL) { - hawk_logfmt (hawk, HAWK_LOG_STDERR,HAWK_T("[RETURN] - ***OUT OF MEMORY***\n")); + hawk_logfmt(hawk, HAWK_LOG_STDERR,HAWK_T("[RETURN] - ***OUT OF MEMORY***\n")); } else { - hawk_logfmt (hawk, HAWK_LOG_STDERR, HAWK_T("[RETURN] - [%.*js]\n"), len, str); + hawk_logfmt(hawk, HAWK_LOG_STDERR, HAWK_T("[RETURN] - [%.*js]\n"), len, str); hawk_freemem(hawk_rtx_gethawk(rtx), str); } } - hawk_logfmt (hawk, HAWK_LOG_STDERR, HAWK_T("[NAMED VARIABLES]\n")); - hawk_htb_walk (hawk_rtx_getnvmap(rtx), print_awk_value, rtx); - hawk_logfmt (hawk, HAWK_LOG_STDERR, HAWK_T("[END NAMED VARIABLES]\n")); + hawk_logfmt(hawk, HAWK_LOG_STDERR, HAWK_T("[NAMED VARIABLES]\n")); + hawk_htb_walk(hawk_rtx_getnvmap(rtx), print_awk_value, rtx); + hawk_logfmt(hawk, HAWK_LOG_STDERR, HAWK_T("[END OF NAMED VARIABLES]\n")); } #if defined(ENABLE_CALLBACK) diff --git a/bin/hawkgo.go b/bin/hawkgo.go index 0e96d956..ab1d5bbf 100644 --- a/bin/hawkgo.go +++ b/bin/hawkgo.go @@ -4,6 +4,8 @@ import "hawk" import "flag" import "fmt" import "io" +//import "net/http" +//import _ "net/http/pprof" import "os" import "path/filepath" import "runtime" @@ -99,6 +101,9 @@ func main() { var fs_idx int = -1 var err error + // for profiling + //go http.ListenAndServe("0.0.0.0:6060", nil) + debug.SetGCPercent(100) // enable normal GC if parse_args_to_config(&cfg) == false { os.Exit(99) } @@ -221,8 +226,20 @@ func main() { } if cfg.show_extra_info { + var named_vars map[string]*hawk.Val + var vn string + var vv *hawk.Val + fmt.Printf("[RETURN] - [%v]\n", retv.String()) - // TODO: print global variables and values + + + fmt.Printf("NAMED VARIABLES]\n") + named_vars = make(map[string]*hawk.Val) + rtx.GetNamedVars(named_vars) + for vn, vv = range named_vars { + fmt.Printf("%s = %s\n", vn, vv.String()) + } + fmt.Printf("END OF NAMED VARIABLES]\n") } } @@ -233,7 +250,8 @@ func main() { runtime.GC() runtime.Gosched() -// time.Sleep(1000 * time.Millisecond) // give finalizer time to print + + //time.Sleep(100000 * time.Millisecond) return oops: diff --git a/hawk.go b/hawk.go index 943d7edc..04779b46 100644 --- a/hawk.go +++ b/hawk.go @@ -590,14 +590,21 @@ func (rtx *Rtx) Exec(args []string) (*Val, error) { C.free(unsafe.Pointer(cargs[idx])) } if val == nil { return nil, rtx.make_errinfo() } - return &Val{rtx: rtx, c: val}, nil + + // hawk_rtx_exec...() returns a value with the reference count incremented. + // create a value without going through rtx.make_val() + return rtx.fix_val_with_raw(val), nil + //return rtx.make_val(func() *C.hawk_val_t { return val })aAAA } func (rtx *Rtx) Loop() (*Val, error) { var val *C.hawk_val_t val = C.hawk_rtx_loop(rtx.c) if val == nil { return nil, rtx.make_errinfo() } - return &Val{rtx: rtx, c: val}, nil + // hawk_rtx_loop() returns a value with the reference count incremented. + // create a value without going through rtx.make_val() + return rtx.fix_val_with_raw(val), nil + //return rtx.make_val(func() *C.hawk_val_t { return val })aAAA } func (rtx *Rtx) Call(name string, args ...*Val) (*Val, error) { @@ -623,7 +630,8 @@ func (rtx *Rtx) Call(name string, args ...*Val) (*Val, error) { // 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 + return rtx.fix_val_with_raw(val), nil + //return rtx.make_val(func() *C.hawk_val_t { return val })aAAA } func (rtx *Rtx) ValCount() int { @@ -686,6 +694,21 @@ func (rtx *Rtx) SetFuncRet(v *Val) { C.hawk_rtx_setretval(rtx.c, v.c) } +func (rtx *Rtx) GetNamedVars(vars map[string]*Val) { + var tab *C.hawk_htb_t + var itr C.hawk_htb_itr_t + var pair *C.hawk_htb_pair_t + var k string + + tab = C.hawk_rtx_getnvmap(rtx.c) + pair = C.hawk_htb_getfirstpair(tab, &itr) + for pair != nil { + k = string(uchars_to_rune_slice((*C.hawk_uch_t)(pair.key.ptr), uintptr(pair.key.len))) + vars[k], _ = rtx.make_val(func() *C.hawk_val_t { return (*C.hawk_val_t)(pair.val.ptr) }) + pair = C.hawk_htb_getnextpair(tab, &itr) + } +} + // ----------------------------------------------------------- func (hawk *Hawk) get_errmsg() string { @@ -759,6 +782,16 @@ func (rtx* Rtx) make_val(vmaker func() *C.hawk_val_t) (*Val, error) { return vv, nil } +func (rtx* Rtx) fix_val_with_raw(val *C.hawk_val_t) *Val { + // this function assumes val has the non-zero reference count + // the caller must ensure that the reference count has been incremented properly + var vv *Val + if val.v_refs <= 0 && C.hawk_rtx_isstaticval(rtx.c, val) == 0 { panic("invalid reference count") } + vv = &Val{rtx: rtx, c: val} + rtx.chain_val(vv) + return vv +} + func (rtx *Rtx) NewByteVal(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))