changed the free list implementation in hawk-inst.go
All checks were successful
continuous-integration/drone/push Build is passing

added go wrapper functions to manipulate return value and arguments
This commit is contained in:
2025-11-24 00:17:46 +09:00
parent 24c91d3376
commit a5bcb8ea6c
6 changed files with 349 additions and 112 deletions

View File

@@ -4,65 +4,75 @@ package hawk
#include <hawk.h> #include <hawk.h>
*/ */
import "C" import "C"
import "fmt"
import "sync" import "sync"
import "weak" import "weak"
type Instance struct { type CPtr interface {
c *C.hawk_t // c object //~*C.hawk_t | ~*C.hawk_rtx_t
g weak.Pointer[Hawk] // go object *C.hawk_t | *C.hawk_rtx_t
} }
type InstanceTable struct { type Instance[CT CPtr, GT interface{}] struct {
c CT // c object
g weak.Pointer[GT] // go object
next_free int
}
type InstanceTable[CT CPtr, GT interface{}] struct {
name string
mtx sync.Mutex mtx sync.Mutex
insts []Instance insts []Instance[CT, GT]
free_slots []int next_free int
next int
} }
var inst_table InstanceTable type HawkInstance = Instance[*C.hawk_t, Hawk]
type HawkInstanceTable = InstanceTable[*C.hawk_t, Hawk]
func (itab *InstanceTable) add_instance(c *C.hawk_t, g *Hawk) int { type RtxInstance = Instance[*C.hawk_rtx_t, Rtx]
var n int type RtxInstanceTable = InstanceTable[*C.hawk_rtx_t, Rtx]
var inst_table HawkInstanceTable = HawkInstanceTable{ name: "hawk", next_free: -1 }
var rtx_inst_table RtxInstanceTable = RtxInstanceTable{ name: "rtx", next_free: -1 }
func (itab *InstanceTable[CT, GT]) add_instance(c CT, g *GT) int {
itab.mtx.Lock() itab.mtx.Lock()
defer itab.mtx.Unlock() defer itab.mtx.Unlock()
n = len(itab.free_slots) if itab.next_free >= 0 {
if n <= 0 { // no free slots
itab.insts = append(itab.insts, Instance{c: c, g: weak.Make(g)})
return len(itab.insts) - 1
} else {
var slot int var slot int
n-- slot = itab.next_free
slot = itab.free_slots[n] if slot >= 0 { itab.next_free = itab.insts[slot].next_free }
itab.free_slots = itab.free_slots[:n]
itab.insts[slot].c = c itab.insts[slot].c = c
itab.insts[slot].g = weak.Make(g)
itab.insts[slot].next_free = -1
return slot return slot
} else { // no free slots
itab.insts = append(itab.insts, Instance[CT, GT]{c: c, g: weak.Make(g), next_free: -1})
return len(itab.insts) - 1
} }
} }
func (itab *InstanceTable) delete_instance(slot int) Instance { func (itab *InstanceTable[CT, GT]) delete_instance(slot int) error {
var h Instance
var n int
itab.mtx.Lock() itab.mtx.Lock()
defer itab.mtx.Unlock() defer itab.mtx.Unlock()
h = itab.insts[slot] if slot >= len(itab.insts) || slot < 0 {
itab.insts[slot].c = nil return fmt.Errorf("index %d out of range", slot)
itab.insts[slot].g = weak.Make((*Hawk)(nil)) // this may not even be necessary as it's a weak pointer }
if itab.insts[slot].next_free >= 0 {
n = len(itab.insts) return fmt.Errorf("no instance at index %d", slot)
if slot == n - 1 {
itab.insts = itab.insts[:n - 1]
} else {
itab.free_slots = append(itab.free_slots, slot)
} }
return h itab.insts[slot].c = CT(nil)
itab.insts[slot].g = weak.Make((*GT)(nil)) // this may not even be necessary as it's a weak pointer
itab.insts[slot].next_free = itab.next_free
itab.next_free = slot
return nil
} }
func (itab *InstanceTable) slot_to_instance(slot int) Instance { func (itab *InstanceTable[CT, GT]) slot_to_instance(slot int) Instance[CT, GT] {
itab.mtx.Lock() itab.mtx.Lock()
defer itab.mtx.Unlock() defer itab.mtx.Unlock()
return itab.insts[slot] return itab.insts[slot]

224
hawk.go
View File

@@ -3,6 +3,15 @@ package hawk
/* /*
#include <hawk.h> #include <hawk.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h>
struct rtx_xtn_t
{
hawk_oow_t inst_no;
hawk_oow_t rtx_inst_no;
};
typedef struct rtx_xtn_t rtx_xtn_t;
static void init_parsestd_for_text_in(hawk_parsestd_t* in, hawk_bch_t* ptr, hawk_oow_t len) static void init_parsestd_for_text_in(hawk_parsestd_t* in, hawk_bch_t* ptr, hawk_oow_t len)
{ {
@@ -36,6 +45,50 @@ static int val_to_flt(hawk_rtx_t* rtx, hawk_val_t* v, double* ret) {
*ret = (double)fv; *ret = (double)fv;
return 0; return 0;
} }
extern int hawk_go_fnc_handler(rtx_xtn_t* rtx_xtn, hawk_bch_t* name, hawk_oow_t len);
static int hawk_fnc_handler_for_go(hawk_rtx_t* rtx, const hawk_fnc_info_t* fi)
{
int n;
hawk_oow_t namelen;
hawk_bch_t* name;
rtx_xtn_t* xtn;
name = hawk_rtx_duputobchars(rtx, fi->name.ptr, fi->name.len, &namelen);
if (!name)
{
// TODO: set error information
return -1;
}
xtn = hawk_rtx_getxtn(rtx);
n = hawk_go_fnc_handler(xtn, name, namelen);
hawk_rtx_freemem(rtx, name);
return n;
}
static hawk_fnc_t* add_fnc_with_bcstr(hawk_t* hawk, const hawk_bch_t* name, hawk_oow_t min_args, hawk_oow_t max_args, const hawk_bch_t* arg_spec)
{
hawk_fnc_bspec_t spec;
memset(&spec, 0, HAWK_SIZEOF(spec));
spec.arg.min = min_args;
spec.arg.max = max_args;
spec.arg.spec = arg_spec;
spec.impl = hawk_fnc_handler_for_go;
spec.trait = 0;
return hawk_addfncwithbcstr(hawk, name, &spec);
}
static void set_errmsg(hawk_t* hawk, hawk_errnum_t errnum, const hawk_bch_t* msg)
{
hawk_seterrbfmt(hawk, HAWK_NULL, errnum, "%hs", msg);
}
static void set_rtx_errmsg(hawk_rtx_t* rtx, hawk_errnum_t errnum, const hawk_bch_t* msg)
{
hawk_rtx_seterrbfmt(rtx, HAWK_NULL, errnum, "%hs", msg);
}
*/ */
import "C" import "C"
@@ -45,19 +98,7 @@ import "runtime"
import "sync" import "sync"
import "unsafe" import "unsafe"
type Hawk struct { type Fnc func(rtx *Rtx) error
c *C.hawk_t
inst_no int
rtx_mtx sync.Mutex
rtx_count int
rtx_head *Rtx
rtx_tail *Rtx
}
type Ext struct {
inst_no int
}
type Err struct { type Err struct {
Line uint Line uint
@@ -66,8 +107,24 @@ type Err struct {
Msg string Msg string
} }
type Hawk struct {
c *C.hawk_t
inst_no int
fnctab map[string]Fnc
rtx_mtx sync.Mutex
rtx_count int
rtx_head *Rtx
rtx_tail *Rtx
}
type HawkExt struct {
inst_no int
}
type Rtx struct { type Rtx struct {
c *C.hawk_rtx_t c *C.hawk_rtx_t
inst_no int
h *Hawk h *Hawk
next *Rtx next *Rtx
@@ -137,7 +194,7 @@ func deregister_instance(h *Hawk) {
func New() (*Hawk, error) { func New() (*Hawk, error) {
var c *C.hawk_t var c *C.hawk_t
var g *Hawk var g *Hawk
var ext *Ext var ext *HawkExt
var errinf C.hawk_errinf_t var errinf C.hawk_errinf_t
c = C.hawk_openstd(C.hawk_oow_t(unsafe.Sizeof(*ext)), &errinf) c = C.hawk_openstd(C.hawk_oow_t(unsafe.Sizeof(*ext)), &errinf)
@@ -147,10 +204,11 @@ func New() (*Hawk, error) {
return nil, err return nil, err
} }
ext = (*Ext)(unsafe.Pointer(C.hawk_getxtn(c))) ext = (*HawkExt)(unsafe.Pointer(C.hawk_getxtn(c)))
g = &Hawk{c: c, inst_no: -1} g = &Hawk{c: c, inst_no: -1}
g.fnctab = make(map[string]Fnc)
g.rtx_count = 0 g.rtx_count = 0
g.rtx_head = nil g.rtx_head = nil
g.rtx_tail = nil g.rtx_tail = nil
@@ -256,6 +314,46 @@ func (hawk *Hawk) AddGlobal(name string) error {
return nil return nil
} }
//export hawk_go_fnc_handler
func hawk_go_fnc_handler(rtx_xtn *C.rtx_xtn_t, name *C.hawk_bch_t, namelen C.hawk_oow_t) C.int {
var fn Fnc
var inst HawkInstance
var rtx_inst RtxInstance
var rtx *Rtx
var fnname string
var ok bool
var err error
inst = inst_table.slot_to_instance(int(rtx_xtn.inst_no))
rtx_inst = rtx_inst_table.slot_to_instance(int(rtx_xtn.rtx_inst_no))
rtx = rtx_inst.g.Value()
fnname = C.GoStringN(name, C.int(namelen))
fn, ok = inst.g.Value().fnctab[fnname]
if !ok {
rtx.set_errmsg(C.HAWK_ENOENT, fmt.Sprintf("function '%s' not found", fnname))
return -1;
}
err = fn(rtx_inst.g.Value())
if err != nil {
rtx.set_errmsg(C.HAWK_EOTHER, fmt.Sprintf("function '%s' failure - %s", fnname, err.Error()))
return -1
}
return 0
}
func (hawk *Hawk) AddFunc(name string, min_args uint, max_args uint, spec string, fn Fnc) error {
var fnc *C.hawk_fnc_t
fnc = C.add_fnc_with_bcstr(hawk.c, C.CString(name), C.hawk_oow_t(min_args), C.hawk_oow_t(max_args), C.CString(spec));
if fnc == nil { return hawk.make_errinfo() }
hawk.fnctab[name] = fn;
return nil
}
func (hawk *Hawk) ParseFile(text string) error { func (hawk *Hawk) ParseFile(text string) error {
var x C.int var x C.int
var in [2]C.hawk_parsestd_t var in [2]C.hawk_parsestd_t
@@ -322,26 +420,7 @@ func (hawk *Hawk) unchain_rtx(rtx *Rtx) {
} }
// ----------------------------------------------------------- // -----------------------------------------------------------
func deregister_rtx_instance(rtx *Rtx) {
func (hawk *Hawk) NewRtx(id string) (*Rtx, error) {
var rtx *C.hawk_rtx_t
var g *Rtx
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}
hawk.chain_rtx(g)
// [NOTE]
// if the owning hawk is not garbaged-collected, this rtx is never
// garbaged collected as a strong pointer to a rtx object is maintained
// in the owner. i never set the runtime finalizer on this rtx object.
return g, nil
}
func (rtx* Rtx) Close() {
if rtx.h != nil { if rtx.h != nil {
//fmt.Printf("RTX CLOSING UNCHAIN %p\n", rtx) //fmt.Printf("RTX CLOSING UNCHAIN %p\n", rtx)
rtx.h.unchain_rtx(rtx) rtx.h.unchain_rtx(rtx)
@@ -354,6 +433,41 @@ func (rtx* Rtx) Close() {
C.hawk_rtx_close(rtx.c) C.hawk_rtx_close(rtx.c)
//fmt.Printf("RTX CLOSING %p\n", rtx) //fmt.Printf("RTX CLOSING %p\n", rtx)
} }
if rtx.inst_no >= 0 {
rtx_inst_table.delete_instance(rtx.inst_no)
rtx.inst_no = -1
}
}
func (hawk *Hawk) NewRtx(id string) (*Rtx, error) {
var rtx *C.hawk_rtx_t
var g *Rtx
var xtn *C.rtx_xtn_t
rtx = C.hawk_rtx_openstdwithbcstr(hawk.c, C.hawk_oow_t(unsafe.Sizeof(*xtn)), C.CString(id), nil, nil, nil)
if rtx == nil { return nil, hawk.make_errinfo() }
g = &Rtx{c: rtx}
hawk.chain_rtx(g)
// [NOTE]
// if the owning hawk is not garbaged-collected, this rtx is never
// garbaged collected as a strong pointer to a rtx object is maintained
// in the owner.
runtime.SetFinalizer(g, deregister_rtx_instance)
g.inst_no = rtx_inst_table.add_instance(rtx, g)
xtn = (*C.rtx_xtn_t)(unsafe.Pointer(C.hawk_rtx_getxtn(rtx)))
xtn.inst_no = C.hawk_oow_t(hawk.inst_no)
xtn.rtx_inst_no = C.hawk_oow_t(g.inst_no)
return g, nil
}
func (rtx* Rtx) Close() {
deregister_rtx_instance(rtx)
} }
func (rtx *Rtx) make_errinfo() *Err { func (rtx *Rtx) make_errinfo() *Err {
@@ -446,6 +560,22 @@ func (rtx *Rtx) unchain_val(val *Val) {
rtx.val_mtx.Unlock() rtx.val_mtx.Unlock()
} }
func (rtx *Rtx) GetFuncArgCount() int {
var nargs C.hawk_oow_t
nargs = C.hawk_rtx_getnargs(rtx.c)
return int(nargs)
}
func (rtx *Rtx) GetFuncArg(idx int) (*Val, error) {
return rtx.make_val(func() *C.hawk_val_t {
return C.hawk_rtx_getarg(rtx.c, C.hawk_oow_t(idx))
})
}
func (rtx *Rtx) SetFuncRet(v *Val) {
C.hawk_rtx_setretval(rtx.c, v.c)
}
// ----------------------------------------------------------- // -----------------------------------------------------------
func (hawk *Hawk) get_errmsg() string { func (hawk *Hawk) get_errmsg() string {
@@ -456,13 +586,20 @@ func (hawk *Hawk) set_errmsg(num C.hawk_errnum_t, msg string) {
var ptr *C.char var ptr *C.char
ptr = C.CString(msg) ptr = C.CString(msg)
defer C.free(unsafe.Pointer(ptr)) defer C.free(unsafe.Pointer(ptr))
C.hawk_seterrbmsg(hawk.c, nil, num, ptr) C.set_errmsg(hawk.c, num, ptr)
} }
func (rtx *Rtx) get_errmsg() string { func (rtx *Rtx) get_errmsg() string {
return C.GoString(C.hawk_rtx_geterrbmsg(rtx.c)) return C.GoString(C.hawk_rtx_geterrbmsg(rtx.c))
} }
func (rtx *Rtx) set_errmsg(num C.hawk_errnum_t, msg string) {
var ptr *C.char
ptr = C.CString(msg)
defer C.free(unsafe.Pointer(ptr))
C.set_rtx_errmsg(rtx.c, num, ptr)
}
// ----------------------------------------------------------- // -----------------------------------------------------------
func (err* Err) Error() string { func (err* Err) Error() string {
@@ -807,14 +944,23 @@ func rune_slice_to_uchars(r []rune) []C.hawk_uch_t {
} }
func c_to_go(c *C.hawk_t) *Hawk { func c_to_go(c *C.hawk_t) *Hawk {
var ext *Ext var ext *HawkExt
var inst Instance var inst HawkInstance
ext = (*Ext)(unsafe.Pointer(C.hawk_getxtn(c))) ext = (*HawkExt)(unsafe.Pointer(C.hawk_getxtn(c)))
inst = inst_table.slot_to_instance(ext.inst_no) inst = inst_table.slot_to_instance(ext.inst_no)
return inst.g.Value() return inst.g.Value()
} }
func rtx_to_go(rtx *C.hawk_rtx_t) *Rtx {
var xtn *C.rtx_xtn_t
var inst RtxInstance
xtn = (*C.rtx_xtn_t)(unsafe.Pointer(C.hawk_rtx_getxtn(rtx)))
inst = rtx_inst_table.slot_to_instance(int(xtn.rtx_inst_no))
return inst.g.Value()
}
func Must[T any](v T, err error) T { func Must[T any](v T, err error) T {
if err != nil { panic(err) } if err != nil { panic(err) }
return v return v

View File

@@ -30,6 +30,45 @@ func make_hawk(script string) (*hawk.Hawk, error) {
return h, nil return h, nil
} }
func enbase64(rtx *hawk.Rtx) error {
fmt.Printf ("*** ENABLE64 RTX %p\n", rtx) // << this is 0 from time to time.. TODO: fix it..
fmt.Printf("****ENBASE64 [%d]\n", rtx.GetFuncArgCount())
var a0 *hawk.Val = hawk.Must(rtx.GetFuncArg(0))
var a1 *hawk.Val = hawk.Must(rtx.GetFuncArg(1))
var a2 *hawk.Val = hawk.Must(rtx.GetFuncArg(2))
fmt.Printf("[%s] [%s] [%s]\n", a0.String(), a1.String(), a2.String())
rtx.SetFuncRet(hawk.Must(rtx.NewValFromStr("ENBASE64-OUTPUT")))
return nil
}
func debase64(rtx *hawk.Rtx) error {
fmt.Printf("****DEBASE64 [%d]\n", rtx.GetFuncArgCount())
rtx.SetFuncRet(hawk.Must(rtx.NewValFromFlt(-999.1111)))
return nil
//return fmt.Errorf("what the hell.....")
}
func make_hawk_extended(script string) (*hawk.Hawk, error) {
var h *hawk.Hawk
var err error
h, err = hawk.New()
if err != nil { return nil, err }
h.AddFunc("enbase64", 1, 10, "", enbase64)
h.AddFunc("debase64", 1, 1, "", debase64)
err = h.ParseText(script)
if err != nil {
h.Close()
return nil, err
}
return h, nil
}
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
@@ -109,7 +148,7 @@ return 1.9923;
h.Close() h.Close()
h = nil h = nil
fmt.Printf ("== END of run ==\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
@@ -239,6 +278,7 @@ return x;
fmt.Printf("index=[%d] value=[%v]\n", i, ff.String()) fmt.Printf("index=[%d] value=[%v]\n", i, ff.String())
i, ff = v.ArrayNextField(&itr) i, ff = v.ArrayNextField(&itr)
} }
fmt.Printf("== END OF ARRAY DUMP ==\n")
} }
} }
} }
@@ -251,3 +291,44 @@ return x;
time.Sleep(1000 * time.Millisecond) // give finalizer time to print time.Sleep(1000 * time.Millisecond) // give finalizer time to print
} }
func Test3(t *testing.T) {
var h *hawk.Hawk
var rtx *hawk.Rtx
var err error
debug.SetGCPercent(100) // enable normal GC
fmt.Printf ("BEGINNING OF TEST3\n")
h, err = make_hawk_extended(`function main(s) {
print enbase64(s, "hello", 1.289);
print debase64(s);
return x
}`)
if err != nil {
t.Errorf("Failed to make hawk - %s", err.Error())
return
}
rtx, err = h.NewRtx("test3")
if err != nil {
t.Errorf("failed to create rtx - %s", err.Error())
} else {
var v *hawk.Val
v, err = rtx.Call("main", hawk.Must(rtx.NewValFromStr("this is a test3 string")))
if err != nil {
t.Errorf("failed to call main - %s", err.Error())
} else {
fmt.Printf("V=>[%v]\n", v.String())
}
}
h.Close()
fmt.Printf ("END OF TEST3\n")
runtime.GC()
runtime.Gosched()
time.Sleep(1000 * time.Millisecond) // give finalizer time to print
}

View File

@@ -2550,7 +2550,7 @@ int Hawk::addFunction (
{ {
HAWK_ASSERT(this->hawk != HAWK_NULL); HAWK_ASSERT(this->hawk != HAWK_NULL);
hawk_fnc_mspec_t spec; hawk_fnc_bspec_t spec;
HAWK_MEMSET (&spec, 0, HAWK_SIZEOF(spec)); HAWK_MEMSET (&spec, 0, HAWK_SIZEOF(spec));
spec.arg.min = minArgs; spec.arg.min = minArgs;
@@ -2601,7 +2601,7 @@ int Hawk::addFunction (
{ {
HAWK_ASSERT(this->hawk != HAWK_NULL); HAWK_ASSERT(this->hawk != HAWK_NULL);
hawk_fnc_wspec_t spec; hawk_fnc_uspec_t spec;
HAWK_MEMSET (&spec, 0, HAWK_SIZEOF(spec)); HAWK_MEMSET (&spec, 0, HAWK_SIZEOF(spec));
spec.arg.min = minArgs; spec.arg.min = minArgs;

View File

@@ -146,66 +146,66 @@ static hawk_fnc_t* add_fnc (hawk_t* hawk, const hawk_ooch_t* name, const hawk_fn
return fnc; return fnc;
} }
hawk_fnc_t* hawk_addfncwithbcstr (hawk_t* hawk, const hawk_bch_t* name, const hawk_fnc_mspec_t* spec) hawk_fnc_t* hawk_addfncwithbcstr (hawk_t* hawk, const hawk_bch_t* name, const hawk_fnc_bspec_t* spec)
{ {
#if defined(HAWK_OOCH_IS_BCH) #if defined(HAWK_OOCH_IS_BCH)
return add_fnc(hawk, name, spec); return add_fnc(hawk, name, spec);
#else #else
hawk_ucs_t wcs; hawk_ucs_t wcs;
hawk_fnc_t* fnc; hawk_fnc_t* fnc;
hawk_fnc_spec_t wspec; hawk_fnc_spec_t uspec;
HAWK_STATIC_ASSERT (HAWK_SIZEOF(*spec) == HAWK_SIZEOF(wspec)); HAWK_STATIC_ASSERT (HAWK_SIZEOF(*spec) == HAWK_SIZEOF(uspec));
HAWK_MEMCPY (&wspec, spec, HAWK_SIZEOF(wspec)); HAWK_MEMCPY (&uspec, spec, HAWK_SIZEOF(uspec));
if (spec->arg.spec) if (spec->arg.spec)
{ {
wcs.ptr = hawk_dupbtoucstr(hawk, spec->arg.spec, &wcs.len, 0); wcs.ptr = hawk_dupbtoucstr(hawk, spec->arg.spec, &wcs.len, 0);
if (HAWK_UNLIKELY(!wcs.ptr)) return HAWK_NULL; if (HAWK_UNLIKELY(!wcs.ptr)) return HAWK_NULL;
wspec.arg.spec = wcs.ptr; uspec.arg.spec = wcs.ptr;
} }
wcs.ptr = hawk_dupbtoucstr(hawk, name, &wcs.len, 0); wcs.ptr = hawk_dupbtoucstr(hawk, name, &wcs.len, 0);
if (HAWK_UNLIKELY(!wcs.ptr)) if (HAWK_UNLIKELY(!wcs.ptr))
{ {
if (wspec.arg.spec) hawk_freemem(hawk, (hawk_uch_t*)wspec.arg.spec); if (uspec.arg.spec) hawk_freemem(hawk, (hawk_uch_t*)uspec.arg.spec);
return HAWK_NULL; return HAWK_NULL;
} }
fnc = add_fnc(hawk, wcs.ptr, &wspec); fnc = add_fnc(hawk, wcs.ptr, &uspec);
hawk_freemem(hawk, wcs.ptr); hawk_freemem(hawk, wcs.ptr);
if (wspec.arg.spec) hawk_freemem(hawk, (hawk_uch_t*)wspec.arg.spec); if (uspec.arg.spec) hawk_freemem(hawk, (hawk_uch_t*)uspec.arg.spec);
return fnc; return fnc;
#endif #endif
} }
hawk_fnc_t* hawk_addfncwithucstr (hawk_t* hawk, const hawk_uch_t* name, const hawk_fnc_wspec_t* spec) hawk_fnc_t* hawk_addfncwithucstr (hawk_t* hawk, const hawk_uch_t* name, const hawk_fnc_uspec_t* spec)
{ {
#if defined(HAWK_OOCH_IS_BCH) #if defined(HAWK_OOCH_IS_BCH)
hawk_bcs_t mbs; hawk_bcs_t mbs;
hawk_fnc_t* fnc; hawk_fnc_t* fnc;
hawk_fnc_spec_t mspec; hawk_fnc_spec_t bspec;
HAWK_STATIC_ASSERT (HAWK_SIZEOF(*spec) == HAWK_SIZEOF(mspec)); HAWK_STATIC_ASSERT (HAWK_SIZEOF(*spec) == HAWK_SIZEOF(bspec));
HAWK_MEMCPY (&mspec, spec, HAWK_SIZEOF(mspec)); HAWK_MEMCPY (&bspec, spec, HAWK_SIZEOF(bspec));
if (spec->arg.spec) if (spec->arg.spec)
{ {
mbs.ptr = hawk_duputobcstr(hawk, spec->arg.spec, &mbs.len); mbs.ptr = hawk_duputobcstr(hawk, spec->arg.spec, &mbs.len);
if (HAWK_UNLIKELY(!mbs.ptr)) return HAWK_NULL; if (HAWK_UNLIKELY(!mbs.ptr)) return HAWK_NULL;
mspec.arg.spec = mbs.ptr; bspec.arg.spec = mbs.ptr;
} }
mbs.ptr = hawk_duputobcstr(hawk, name, &mbs.len); mbs.ptr = hawk_duputobcstr(hawk, name, &mbs.len);
if (HAWK_UNLIKELY(!mbs.ptr)) if (HAWK_UNLIKELY(!mbs.ptr))
{ {
if (mspec.arg.spec) hawk_freemem(hawk, (hawk_bch_t*)mspec.arg.spec); if (bspec.arg.spec) hawk_freemem(hawk, (hawk_bch_t*)bspec.arg.spec);
return HAWK_NULL; return HAWK_NULL;
} }
fnc = add_fnc(hawk, mbs.ptr, &mspec); fnc = add_fnc(hawk, mbs.ptr, &bspec);
hawk_freemem(hawk, mbs.ptr); hawk_freemem(hawk, mbs.ptr);
if (mspec.arg.spec) hawk_freemem(hawk, (hawk_bch_t*)mspec.arg.spec); if (bspec.arg.spec) hawk_freemem(hawk, (hawk_bch_t*)bspec.arg.spec);
return fnc; return fnc;
#else #else
return add_fnc(hawk, name, spec); return add_fnc(hawk, name, spec);

View File

@@ -916,10 +916,10 @@ typedef int (*hawk_fnc_impl_t) (
); );
/** /**
* The hawk_fnc_marg_t type defines a structure to describe arguments * The hawk_fnc_barg_t type defines a structure to describe arguments
* to an implicit function. * to an implicit function.
*/ */
struct hawk_fnc_marg_t struct hawk_fnc_barg_t
{ {
/** minimum numbers of argument for a function */ /** minimum numbers of argument for a function */
hawk_oow_t min; hawk_oow_t min;
@@ -939,28 +939,28 @@ struct hawk_fnc_marg_t
*/ */
const hawk_bch_t* spec; const hawk_bch_t* spec;
}; };
typedef struct hawk_fnc_marg_t hawk_fnc_marg_t; typedef struct hawk_fnc_barg_t hawk_fnc_barg_t;
/** /**
* The hawk_fnc_warg_t type defines a structure to describe arguments * The hawk_fnc_uarg_t type defines a structure to describe arguments
* to an implicit function. * to an implicit function.
*/ */
struct hawk_fnc_warg_t struct hawk_fnc_uarg_t
{ {
hawk_oow_t min; hawk_oow_t min;
hawk_oow_t max; hawk_oow_t max;
const hawk_uch_t* spec; const hawk_uch_t* spec;
}; };
typedef struct hawk_fnc_warg_t hawk_fnc_warg_t; typedef struct hawk_fnc_uarg_t hawk_fnc_uarg_t;
/** /**
* The hawk_fnc_mspec_t type defines a structure to hold the specification * The hawk_fnc_bspec_t type defines a structure to hold the specification
* of an intrinsic function or a module function. * of an intrinsic function or a module function.
*/ */
struct hawk_fnc_mspec_t struct hawk_fnc_bspec_t
{ {
/** argument descriptor */ /** argument descriptor */
hawk_fnc_marg_t arg; hawk_fnc_barg_t arg;
/** pointer to the function implementing this function */ /** pointer to the function implementing this function */
hawk_fnc_impl_t impl; hawk_fnc_impl_t impl;
@@ -975,16 +975,16 @@ struct hawk_fnc_mspec_t
*/ */
int trait; int trait;
}; };
typedef struct hawk_fnc_mspec_t hawk_fnc_mspec_t; typedef struct hawk_fnc_bspec_t hawk_fnc_bspec_t;
/** /**
* The hawk_fnc_wspec_t type defines a structure to hold the specification * The hawk_fnc_uspec_t type defines a structure to hold the specification
* of an intrinsic function or a module function. * of an intrinsic function or a module function.
*/ */
struct hawk_fnc_wspec_t struct hawk_fnc_uspec_t
{ {
/** argument descriptor */ /** argument descriptor */
hawk_fnc_warg_t arg; hawk_fnc_uarg_t arg;
/** pointer to the function implementing this function */ /** pointer to the function implementing this function */
hawk_fnc_impl_t impl; hawk_fnc_impl_t impl;
@@ -999,14 +999,14 @@ struct hawk_fnc_wspec_t
*/ */
int trait; int trait;
}; };
typedef struct hawk_fnc_wspec_t hawk_fnc_wspec_t; typedef struct hawk_fnc_uspec_t hawk_fnc_uspec_t;
#if defined(HAWK_OOCH_IS_BCH) #if defined(HAWK_OOCH_IS_BCH)
typedef hawk_fnc_marg_t hawk_fnc_arg_t; typedef hawk_fnc_barg_t hawk_fnc_arg_t;
typedef hawk_fnc_mspec_t hawk_fnc_spec_t; typedef hawk_fnc_bspec_t hawk_fnc_spec_t;
#else #else
typedef hawk_fnc_warg_t hawk_fnc_arg_t; typedef hawk_fnc_uarg_t hawk_fnc_arg_t;
typedef hawk_fnc_wspec_t hawk_fnc_spec_t; typedef hawk_fnc_uspec_t hawk_fnc_spec_t;
#endif #endif
/* ------------------------------------------------------------------------ */ /* ------------------------------------------------------------------------ */
@@ -2002,7 +2002,7 @@ HAWK_EXPORT int hawk_findgblwithucstr (
HAWK_EXPORT hawk_fnc_t* hawk_addfncwithbcstr ( HAWK_EXPORT hawk_fnc_t* hawk_addfncwithbcstr (
hawk_t* hawk, hawk_t* hawk,
const hawk_bch_t* name, const hawk_bch_t* name,
const hawk_fnc_mspec_t* spec const hawk_fnc_bspec_t* spec
); );
/** /**
@@ -2011,7 +2011,7 @@ HAWK_EXPORT hawk_fnc_t* hawk_addfncwithbcstr (
HAWK_EXPORT hawk_fnc_t* hawk_addfncwithucstr ( HAWK_EXPORT hawk_fnc_t* hawk_addfncwithucstr (
hawk_t* hawk, hawk_t* hawk,
const hawk_uch_t* name, const hawk_uch_t* name,
const hawk_fnc_wspec_t* spec const hawk_fnc_uspec_t* spec
); );
/** /**