Compare commits
8 Commits
d2eff711ac
...
b0a0746f02
| Author | SHA1 | Date | |
|---|---|---|---|
| b0a0746f02 | |||
| eab345b1e2 | |||
| b79c24dd17 | |||
| 0d312f57bf | |||
| 36bf278632 | |||
| 06655bccde | |||
| 830945ab51 | |||
| 407713e7a3 |
@@ -372,7 +372,9 @@ struct opttab_t
|
|||||||
const hawk_bch_t* desc;
|
const hawk_bch_t* desc;
|
||||||
} opttab[] =
|
} opttab[] =
|
||||||
{
|
{
|
||||||
|
/* the values must be present in the "lng" table in process_argv[] */
|
||||||
{ "blankconcat", HAWK_BLANKCONCAT, "enable concatenation by blanks" },
|
{ "blankconcat", HAWK_BLANKCONCAT, "enable concatenation by blanks" },
|
||||||
|
{ "buildbc", HAWK_BUILDBC, "enable byte-code building" },
|
||||||
{ "crlf", HAWK_CRLF, "use CRLF for a newline" },
|
{ "crlf", HAWK_CRLF, "use CRLF for a newline" },
|
||||||
{ "flexmap", HAWK_FLEXMAP, "allow a map to be assigned or returned" },
|
{ "flexmap", HAWK_FLEXMAP, "allow a map to be assigned or returned" },
|
||||||
{ "implicit", HAWK_IMPLICIT, "allow undeclared variables" },
|
{ "implicit", HAWK_IMPLICIT, "allow undeclared variables" },
|
||||||
@@ -391,6 +393,7 @@ struct opttab_t
|
|||||||
{ "striprecspc", HAWK_STRIPRECSPC, "strip spaces in splitting a record" },
|
{ "striprecspc", HAWK_STRIPRECSPC, "strip spaces in splitting a record" },
|
||||||
{ "stripstrspc", HAWK_STRIPSTRSPC, "strip spaces in string-to-number conversion" },
|
{ "stripstrspc", HAWK_STRIPSTRSPC, "strip spaces in string-to-number conversion" },
|
||||||
{ "tolerant", HAWK_TOLERANT, "make more fault-tolerant" },
|
{ "tolerant", HAWK_TOLERANT, "make more fault-tolerant" },
|
||||||
|
{ "xcall", HAWK_XCALL, "enable the extended call syntax" },
|
||||||
{ HAWK_NULL, 0, HAWK_NULL }
|
{ HAWK_NULL, 0, HAWK_NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -450,6 +453,7 @@ static int process_argv (int argc, hawk_bch_t* argv[], const hawk_bch_t* real_ar
|
|||||||
static hawk_bcli_lng_t lng[] =
|
static hawk_bcli_lng_t lng[] =
|
||||||
{
|
{
|
||||||
{ ":blankconcat", '\0' },
|
{ ":blankconcat", '\0' },
|
||||||
|
{ ":buildbc", '\0' },
|
||||||
{ ":crlf", '\0' },
|
{ ":crlf", '\0' },
|
||||||
{ ":flexmap", '\0' },
|
{ ":flexmap", '\0' },
|
||||||
{ ":implicit", '\0' },
|
{ ":implicit", '\0' },
|
||||||
@@ -468,6 +472,7 @@ static int process_argv (int argc, hawk_bch_t* argv[], const hawk_bch_t* real_ar
|
|||||||
{ ":striprecspc", '\0' },
|
{ ":striprecspc", '\0' },
|
||||||
{ ":stripstrspc", '\0' },
|
{ ":stripstrspc", '\0' },
|
||||||
{ ":tolerant", '\0' },
|
{ ":tolerant", '\0' },
|
||||||
|
{ ":xcall", '\0' },
|
||||||
|
|
||||||
{ ":call", 'c' },
|
{ ":call", 'c' },
|
||||||
{ ":file", 'f' },
|
{ ":file", 'f' },
|
||||||
|
|||||||
+29
-13
@@ -36,6 +36,11 @@ type Config struct {
|
|||||||
data_out_files []string
|
data_out_files []string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type RtxEvent struct {
|
||||||
|
rtx *hawk.Rtx
|
||||||
|
added bool
|
||||||
|
}
|
||||||
|
|
||||||
func exit_with_error(msg string, err error) {
|
func exit_with_error(msg string, err error) {
|
||||||
fmt.Fprintf(os.Stderr, "ERROR: %s - %s\n", msg, err.Error())
|
fmt.Fprintf(os.Stderr, "ERROR: %s - %s\n", msg, err.Error())
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
@@ -144,7 +149,7 @@ wrong_usage:
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func run_script(h *hawk.Hawk, fs_idx int, data_idx int, cfg* Config, rtx_chan chan *hawk.Rtx, sig_chan chan os.Signal) error {
|
func run_script(h *hawk.Hawk, fs_idx int, data_idx int, cfg* Config, rtx_chan chan RtxEvent, sig_chan chan os.Signal) error {
|
||||||
var rtx *hawk.Rtx
|
var rtx *hawk.Rtx
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
@@ -226,7 +231,7 @@ func run_script(h *hawk.Hawk, fs_idx int, data_idx int, cfg* Config, rtx_chan ch
|
|||||||
signal.Notify(sig_chan, s)
|
signal.Notify(sig_chan, s)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
rtx_chan <- rtx
|
rtx_chan <- RtxEvent{rtx: rtx, added: true}
|
||||||
retv, err = rtx.Call(cfg.call, args...)
|
retv, err = rtx.Call(cfg.call, args...)
|
||||||
for idx = 0; idx < count; idx++ {
|
for idx = 0; idx < count; idx++ {
|
||||||
// it's ok not to call Close() on args as rtx.Close() closes them automatically.
|
// it's ok not to call Close() on args as rtx.Close() closes them automatically.
|
||||||
@@ -244,7 +249,7 @@ func run_script(h *hawk.Hawk, fs_idx int, data_idx int, cfg* Config, rtx_chan ch
|
|||||||
signal.Notify(sig_chan, s)
|
signal.Notify(sig_chan, s)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
rtx_chan <- rtx
|
rtx_chan <- RtxEvent{rtx: rtx, added: true}
|
||||||
//v, err = rtx.Loop()
|
//v, err = rtx.Loop()
|
||||||
retv, err = rtx.Exec(cfg.data_in_files)
|
retv, err = rtx.Exec(cfg.data_in_files)
|
||||||
}
|
}
|
||||||
@@ -272,17 +277,24 @@ func run_script(h *hawk.Hawk, fs_idx int, data_idx int, cfg* Config, rtx_chan ch
|
|||||||
|
|
||||||
// let's not care about closing args or return values
|
// let's not care about closing args or return values
|
||||||
// because rtx.Close() will close them automatically
|
// because rtx.Close() will close them automatically
|
||||||
if rtx != nil { rtx.Close() }
|
if rtx != nil {
|
||||||
|
rtx_chan <- RtxEvent{rtx: rtx, added: false}
|
||||||
|
rtx.Close()
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
|
|
||||||
oops:
|
oops:
|
||||||
if rtx != nil { rtx.Close() }
|
if rtx != nil {
|
||||||
|
rtx_chan <- RtxEvent{rtx: rtx, added: false}
|
||||||
|
rtx.Close()
|
||||||
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func run_signal_handler(rtx_chan chan *hawk.Rtx, sig_chan chan os.Signal, wg *sync.WaitGroup) {
|
func run_signal_handler(rtx_chan chan RtxEvent, sig_chan chan os.Signal, wg *sync.WaitGroup) {
|
||||||
var sig os.Signal
|
var sig os.Signal
|
||||||
var rtx *hawk.Rtx
|
var rtx *hawk.Rtx
|
||||||
|
var ev RtxEvent
|
||||||
var rtx_bag map[*hawk.Rtx]struct{}
|
var rtx_bag map[*hawk.Rtx]struct{}
|
||||||
|
|
||||||
defer wg.Done()
|
defer wg.Done()
|
||||||
@@ -293,14 +305,18 @@ func run_signal_handler(rtx_chan chan *hawk.Rtx, sig_chan chan os.Signal, wg *sy
|
|||||||
chan_loop:
|
chan_loop:
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case rtx = <-rtx_chan:
|
case ev = <-rtx_chan:
|
||||||
if rtx == nil {
|
if ev.rtx == nil {
|
||||||
// terminate the loop for the value of nil
|
// terminate the loop for the value of nil
|
||||||
break chan_loop
|
break chan_loop
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ev.added {
|
||||||
// remember all the rtx object created for signal broadcasting
|
// remember all the rtx object created for signal broadcasting
|
||||||
rtx_bag[rtx] = struct{}{}
|
rtx_bag[ev.rtx] = struct{}{}
|
||||||
|
} else {
|
||||||
|
delete(rtx_bag, ev.rtx)
|
||||||
|
}
|
||||||
|
|
||||||
case sig = <- sig_chan:
|
case sig = <- sig_chan:
|
||||||
var signo syscall.Signal
|
var signo syscall.Signal
|
||||||
@@ -320,7 +336,7 @@ func main() {
|
|||||||
var h *hawk.Hawk
|
var h *hawk.Hawk
|
||||||
var cfg Config
|
var cfg Config
|
||||||
var fs_idx int = -1
|
var fs_idx int = -1
|
||||||
var rtx_chan chan *hawk.Rtx
|
var rtx_chan chan RtxEvent
|
||||||
var sig_chan chan os.Signal
|
var sig_chan chan os.Signal
|
||||||
var sig_wg sync.WaitGroup
|
var sig_wg sync.WaitGroup
|
||||||
var err error
|
var err error
|
||||||
@@ -390,7 +406,7 @@ func main() {
|
|||||||
goto oops
|
goto oops
|
||||||
}
|
}
|
||||||
|
|
||||||
rtx_chan = make(chan *hawk.Rtx, 10)
|
rtx_chan = make(chan RtxEvent, 10)
|
||||||
sig_chan = make(chan os.Signal, 5)
|
sig_chan = make(chan os.Signal, 5)
|
||||||
sig_wg.Add(1)
|
sig_wg.Add(1)
|
||||||
go run_signal_handler(rtx_chan, sig_chan, &sig_wg)
|
go run_signal_handler(rtx_chan, sig_chan, &sig_wg)
|
||||||
@@ -421,7 +437,7 @@ func main() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
rtx_chan <- nil // to terminate the signal handler
|
rtx_chan <- RtxEvent{ rtx: nil, added: false } // to terminate the signal handler
|
||||||
sig_wg.Wait()
|
sig_wg.Wait()
|
||||||
h.Close()
|
h.Close()
|
||||||
|
|
||||||
@@ -434,7 +450,7 @@ func main() {
|
|||||||
oops:
|
oops:
|
||||||
// if rtx != nil { rtx.Close() }
|
// if rtx != nil { rtx.Close() }
|
||||||
if rtx_chan != nil {
|
if rtx_chan != nil {
|
||||||
rtx_chan <- nil
|
rtx_chan <- RtxEvent{rtx: nil, added: false}
|
||||||
sig_wg.Wait()
|
sig_wg.Wait()
|
||||||
}
|
}
|
||||||
if h != nil { h.Close() }
|
if h != nil { h.Close() }
|
||||||
|
|||||||
@@ -706,9 +706,12 @@ 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 *C.hawk_val_t
|
||||||
|
var cv *C.hawk_bch_t
|
||||||
var nargs int
|
var nargs int
|
||||||
|
|
||||||
fun = C.hawk_rtx_findfunwithbcstr(rtx.c, C.CString(name))
|
cv = C.CString(name)
|
||||||
|
fun = C.hawk_rtx_findfunwithbcstr(rtx.c, cv)
|
||||||
|
C.free(unsafe.Pointer(cv))
|
||||||
if fun == nil { return nil, rtx.make_errinfo() }
|
if fun == nil { return nil, rtx.make_errinfo() }
|
||||||
|
|
||||||
nargs = len(args)
|
nargs = len(args)
|
||||||
@@ -968,8 +971,8 @@ func (hawk *Hawk) get_errmsg() string {
|
|||||||
func (hawk *Hawk) set_errmsg(num C.hawk_errnum_t, msg string) {
|
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))
|
|
||||||
C.set_errmsg(hawk.c, num, ptr)
|
C.set_errmsg(hawk.c, num, ptr)
|
||||||
|
C.free(unsafe.Pointer(ptr))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (rtx *Rtx) get_errmsg() string {
|
func (rtx *Rtx) get_errmsg() string {
|
||||||
@@ -979,8 +982,8 @@ func (rtx *Rtx) get_errmsg() string {
|
|||||||
func (rtx *Rtx) set_errmsg(num C.hawk_errnum_t, msg string) {
|
func (rtx *Rtx) 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))
|
|
||||||
C.set_rtx_errmsg(rtx.c, num, ptr)
|
C.set_rtx_errmsg(rtx.c, num, ptr)
|
||||||
|
C.free(unsafe.Pointer(ptr))
|
||||||
}
|
}
|
||||||
|
|
||||||
// -----------------------------------------------------------
|
// -----------------------------------------------------------
|
||||||
@@ -1213,12 +1216,13 @@ func (val *Val) SetArrayField(index int, v *Val) error {
|
|||||||
|
|
||||||
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 *C.hawk_val_t
|
||||||
|
var ww *C.hawk_val_t
|
||||||
vv = C.hawk_rtx_makeintval(val.rtx.c, C.hawk_int_t(v))
|
vv = C.hawk_rtx_makeintval(val.rtx.c, C.hawk_int_t(v))
|
||||||
if vv == nil { return val.rtx.make_errinfo() }
|
if vv == nil { return val.rtx.make_errinfo() }
|
||||||
C.hawk_rtx_refupval(val.rtx.c, vv)
|
C.hawk_rtx_refupval(val.rtx.c, vv)
|
||||||
vv = C.hawk_rtx_setarrvalfld(val.rtx.c, val.c, C.hawk_ooi_t(index), vv)
|
ww = C.hawk_rtx_setarrvalfld(val.rtx.c, val.c, C.hawk_ooi_t(index), vv)
|
||||||
C.hawk_rtx_refdownval(val.rtx.c, vv)
|
C.hawk_rtx_refdownval(val.rtx.c, vv)
|
||||||
if vv == nil { return val.rtx.make_errinfo() }
|
if ww == nil { return val.rtx.make_errinfo() }
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1291,34 +1295,37 @@ func (val *Val) SetMapField(key string, v *Val) error {
|
|||||||
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 *C.hawk_val_t
|
||||||
|
var ww *C.hawk_val_t
|
||||||
|
|
||||||
kk = string_to_uchars(key)
|
kk = string_to_uchars(key)
|
||||||
vv = C.hawk_rtx_makeintval(val.rtx.c, C.hawk_int_t(v))
|
vv = C.hawk_rtx_makeintval(val.rtx.c, C.hawk_int_t(v))
|
||||||
if vv == nil { return val.rtx.make_errinfo() }
|
if vv == nil { return val.rtx.make_errinfo() }
|
||||||
C.hawk_rtx_refupval(val.rtx.c, vv)
|
C.hawk_rtx_refupval(val.rtx.c, vv)
|
||||||
vv = C.hawk_rtx_setmapvalfld(val.rtx.c, val.c, &kk[0], C.hawk_oow_t(len(kk)), vv)
|
ww = C.hawk_rtx_setmapvalfld(val.rtx.c, val.c, &kk[0], C.hawk_oow_t(len(kk)), vv)
|
||||||
C.hawk_rtx_refdownval(val.rtx.c, vv)
|
C.hawk_rtx_refdownval(val.rtx.c, vv)
|
||||||
if vv == nil { return val.rtx.make_errinfo() }
|
if ww == nil { 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 *C.hawk_val_t
|
||||||
|
var ww *C.hawk_val_t
|
||||||
|
|
||||||
kk = string_to_uchars(key)
|
kk = string_to_uchars(key)
|
||||||
vv = C.make_flt_val(val.rtx.c, C.double(v))
|
vv = C.make_flt_val(val.rtx.c, C.double(v))
|
||||||
if vv == nil { return val.rtx.make_errinfo() }
|
if vv == nil { return val.rtx.make_errinfo() }
|
||||||
C.hawk_rtx_refupval(val.rtx.c, vv)
|
C.hawk_rtx_refupval(val.rtx.c, vv)
|
||||||
vv = C.hawk_rtx_setmapvalfld(val.rtx.c, val.c, &kk[0], C.hawk_oow_t(len(kk)), vv)
|
ww = C.hawk_rtx_setmapvalfld(val.rtx.c, val.c, &kk[0], C.hawk_oow_t(len(kk)), vv)
|
||||||
C.hawk_rtx_refdownval(val.rtx.c, vv)
|
C.hawk_rtx_refdownval(val.rtx.c, vv)
|
||||||
if vv == nil { return val.rtx.make_errinfo() }
|
if ww == nil { 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 *C.hawk_val_t
|
||||||
|
var ww *C.hawk_val_t
|
||||||
var cv *C.hawk_bch_t
|
var cv *C.hawk_bch_t
|
||||||
|
|
||||||
kk = string_to_uchars(key)
|
kk = string_to_uchars(key)
|
||||||
@@ -1327,9 +1334,9 @@ func (val *Val) SetMapFieldWithStr(key string, v string) error {
|
|||||||
C.free(unsafe.Pointer(cv))
|
C.free(unsafe.Pointer(cv))
|
||||||
if vv == nil { return val.rtx.make_errinfo() }
|
if vv == nil { return val.rtx.make_errinfo() }
|
||||||
C.hawk_rtx_refupval(val.rtx.c, vv)
|
C.hawk_rtx_refupval(val.rtx.c, vv)
|
||||||
vv = C.hawk_rtx_setmapvalfld(val.rtx.c, val.c, &kk[0], C.hawk_oow_t(len(kk)), vv)
|
ww = C.hawk_rtx_setmapvalfld(val.rtx.c, val.c, &kk[0], C.hawk_oow_t(len(kk)), vv)
|
||||||
C.hawk_rtx_refdownval(val.rtx.c, vv)
|
C.hawk_rtx_refdownval(val.rtx.c, vv)
|
||||||
if vv == nil { return val.rtx.make_errinfo() }
|
if ww == nil { return val.rtx.make_errinfo() }
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+34
-2
@@ -1314,9 +1314,21 @@ typedef enum hawk_log_mask_t hawk_log_mask_t;
|
|||||||
#if __has_builtin(__atomic_exchange_n)
|
#if __has_builtin(__atomic_exchange_n)
|
||||||
#define HAWK_HAVE_ATOMIC_EXCHANGE_N
|
#define HAWK_HAVE_ATOMIC_EXCHANGE_N
|
||||||
#endif
|
#endif
|
||||||
|
#if __has_builtin(__atomic_fetch_add)
|
||||||
|
#define HAWK_HAVE_ATOMIC_FETCH_ADD
|
||||||
|
#endif
|
||||||
|
#if __has_builtin(__atomic_fetch_and)
|
||||||
|
#define HAWK_HAVE_ATOMIC_FETCH_AND
|
||||||
|
#endif
|
||||||
#if __has_builtin(__atomic_fetch_or)
|
#if __has_builtin(__atomic_fetch_or)
|
||||||
#define HAWK_HAVE_ATOMIC_FETCH_OR
|
#define HAWK_HAVE_ATOMIC_FETCH_OR
|
||||||
#endif
|
#endif
|
||||||
|
#if __has_builtin(__atomic_fetch_sub)
|
||||||
|
#define HAWK_HAVE_ATOMIC_FETCH_SUB
|
||||||
|
#endif
|
||||||
|
#if __has_builtin(__atomic_fetch_xor)
|
||||||
|
#define HAWK_HAVE_ATOMIC_FETCH_XOR
|
||||||
|
#endif
|
||||||
#if __has_builtin(__atomic_load_n)
|
#if __has_builtin(__atomic_load_n)
|
||||||
#define HAWK_HAVE_ATOMIC_LOAD_N
|
#define HAWK_HAVE_ATOMIC_LOAD_N
|
||||||
#endif
|
#endif
|
||||||
@@ -1366,9 +1378,21 @@ typedef enum hawk_log_mask_t hawk_log_mask_t;
|
|||||||
#define HAWK_HAVE_BUILTIN_EXPECT
|
#define HAWK_HAVE_BUILTIN_EXPECT
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if __has_builtin(__sync_fetch_and_add)
|
||||||
|
#define HAWK_HAVE_SYNC_FETCH_AND_ADD
|
||||||
|
#endif
|
||||||
|
#if __has_builtin(__sync_fetch_and_and)
|
||||||
|
#define HAWK_HAVE_SYNC_FETCH_AND_AND
|
||||||
|
#endif
|
||||||
#if __has_builtin(__sync_fetch_and_or)
|
#if __has_builtin(__sync_fetch_and_or)
|
||||||
#define HAWK_HAVE_SYNC_FETCH_AND_OR
|
#define HAWK_HAVE_SYNC_FETCH_AND_OR
|
||||||
#endif
|
#endif
|
||||||
|
#if __has_builtin(__sync_fetch_and_sub)
|
||||||
|
#define HAWK_HAVE_SYNC_FETCH_AND_SUB
|
||||||
|
#endif
|
||||||
|
#if __has_builtin(__sync_fetch_and_xor)
|
||||||
|
#define HAWK_HAVE_SYNC_FETCH_AND_XOR
|
||||||
|
#endif
|
||||||
#if __has_builtin(__sync_lock_test_and_set)
|
#if __has_builtin(__sync_lock_test_and_set)
|
||||||
#define HAWK_HAVE_SYNC_LOCK_TEST_AND_SET
|
#define HAWK_HAVE_SYNC_LOCK_TEST_AND_SET
|
||||||
#endif
|
#endif
|
||||||
@@ -1400,7 +1424,11 @@ typedef enum hawk_log_mask_t hawk_log_mask_t;
|
|||||||
#elif defined(__GNUC__) && defined(__GNUC_MINOR__)
|
#elif defined(__GNUC__) && defined(__GNUC_MINOR__)
|
||||||
|
|
||||||
#if (__GNUC__ >= 4)
|
#if (__GNUC__ >= 4)
|
||||||
|
#define HAWK_HAVE_SYNC_FETCH_AND_ADD
|
||||||
|
#define HAWK_HAVE_SYNC_FETCH_AND_AND
|
||||||
#define HAWK_HAVE_SYNC_FETCH_AND_OR
|
#define HAWK_HAVE_SYNC_FETCH_AND_OR
|
||||||
|
#define HAWK_HAVE_SYNC_FETCH_AND_SUB
|
||||||
|
#define HAWK_HAVE_SYNC_FETCH_AND_XOR
|
||||||
#define HAWK_HAVE_SYNC_LOCK_TEST_AND_SET
|
#define HAWK_HAVE_SYNC_LOCK_TEST_AND_SET
|
||||||
#define HAWK_HAVE_SYNC_LOCK_RELEASE
|
#define HAWK_HAVE_SYNC_LOCK_RELEASE
|
||||||
#define HAWK_HAVE_SYNC_SYNCHRONIZE
|
#define HAWK_HAVE_SYNC_SYNCHRONIZE
|
||||||
@@ -1435,7 +1463,11 @@ typedef enum hawk_log_mask_t hawk_log_mask_t;
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if (__GNUC__ >= 5) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7)
|
#if (__GNUC__ >= 5) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7)
|
||||||
|
#define HAWK_HAVE_ATOMIC_FETCH_ADD
|
||||||
|
#define HAWK_HAVE_ATOMIC_FETCH_AND
|
||||||
#define HAWK_HAVE_ATOMIC_FETCH_OR
|
#define HAWK_HAVE_ATOMIC_FETCH_OR
|
||||||
|
#define HAWK_HAVE_ATOMIC_FETCH_SUB
|
||||||
|
#define HAWK_HAVE_ATOMIC_FETCH_XOR
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if (__GNUC__ >= 5) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
|
#if (__GNUC__ >= 5) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
|
||||||
@@ -1472,7 +1504,7 @@ typedef enum hawk_log_mask_t hawk_log_mask_t;
|
|||||||
|
|
||||||
#if defined(HAWK_HAVE_ATOMIC_FETCH_ADD)
|
#if defined(HAWK_HAVE_ATOMIC_FETCH_ADD)
|
||||||
# define HAWK_ATOMIC_FETCH_ADD(ptr,val,mo) __atomic_fetch_add((ptr),(val),(mo))
|
# define HAWK_ATOMIC_FETCH_ADD(ptr,val,mo) __atomic_fetch_add((ptr),(val),(mo))
|
||||||
#elif defined(HAWK_HAVE_SYNC_FETCH_AND_AND)
|
#elif defined(HAWK_HAVE_SYNC_FETCH_AND_ADD)
|
||||||
# define HAWK_ATOMIC_FETCH_ADD(ptr,val,mo) __sync_fetch_and_add((ptr),(val))
|
# define HAWK_ATOMIC_FETCH_ADD(ptr,val,mo) __sync_fetch_and_add((ptr),(val))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -1490,7 +1522,7 @@ typedef enum hawk_log_mask_t hawk_log_mask_t;
|
|||||||
|
|
||||||
#if defined(HAWK_HAVE_ATOMIC_FETCH_SUB)
|
#if defined(HAWK_HAVE_ATOMIC_FETCH_SUB)
|
||||||
# define HAWK_ATOMIC_FETCH_SUB(ptr,val,mo) __atomic_fetch_sub((ptr),(val),(mo))
|
# define HAWK_ATOMIC_FETCH_SUB(ptr,val,mo) __atomic_fetch_sub((ptr),(val),(mo))
|
||||||
#elif defined(HAWK_HAVE_SYNC_FETCH_AND_AND)
|
#elif defined(HAWK_HAVE_SYNC_FETCH_AND_SUB)
|
||||||
# define HAWK_ATOMIC_FETCH_SUB(ptr,val,mo) __sync_fetch_and_sub((ptr),(val))
|
# define HAWK_ATOMIC_FETCH_SUB(ptr,val,mo) __sync_fetch_and_sub((ptr),(val))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -192,6 +192,81 @@ typedef struct hawk_tree_t hawk_tree_t;
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
enum hawk_fbc_opcode_t
|
||||||
|
{
|
||||||
|
HAWK_FBC_OP_NOP = 0,
|
||||||
|
HAWK_FBC_OP_LOAD_CONST_INT,
|
||||||
|
HAWK_FBC_OP_LOAD_CONST_NIL,
|
||||||
|
HAWK_FBC_OP_LOAD_CONST_TRUE,
|
||||||
|
HAWK_FBC_OP_LOAD_CONST_FALSE,
|
||||||
|
HAWK_FBC_OP_LOAD_GBL,
|
||||||
|
HAWK_FBC_OP_LOAD_LCL,
|
||||||
|
HAWK_FBC_OP_LOAD_ARG,
|
||||||
|
HAWK_FBC_OP_STORE_GBL,
|
||||||
|
HAWK_FBC_OP_STORE_LCL,
|
||||||
|
HAWK_FBC_OP_STORE_ARG,
|
||||||
|
HAWK_FBC_OP_STORE_POP_GBL,
|
||||||
|
HAWK_FBC_OP_STORE_POP_LCL,
|
||||||
|
HAWK_FBC_OP_STORE_POP_ARG,
|
||||||
|
HAWK_FBC_OP_ADD,
|
||||||
|
HAWK_FBC_OP_SUB,
|
||||||
|
HAWK_FBC_OP_MUL,
|
||||||
|
HAWK_FBC_OP_DIV,
|
||||||
|
HAWK_FBC_OP_IDIV,
|
||||||
|
HAWK_FBC_OP_MOD,
|
||||||
|
HAWK_FBC_OP_EXP,
|
||||||
|
HAWK_FBC_OP_CONCAT,
|
||||||
|
HAWK_FBC_OP_RSHIFT,
|
||||||
|
HAWK_FBC_OP_LSHIFT,
|
||||||
|
HAWK_FBC_OP_BAND,
|
||||||
|
HAWK_FBC_OP_BXOR,
|
||||||
|
HAWK_FBC_OP_BOR,
|
||||||
|
|
||||||
|
HAWK_FBC_OP_TEQ,
|
||||||
|
HAWK_FBC_OP_TNE,
|
||||||
|
HAWK_FBC_OP_EQ,
|
||||||
|
HAWK_FBC_OP_NE,
|
||||||
|
HAWK_FBC_OP_GT,
|
||||||
|
HAWK_FBC_OP_GE,
|
||||||
|
HAWK_FBC_OP_LT,
|
||||||
|
HAWK_FBC_OP_LE,
|
||||||
|
|
||||||
|
HAWK_FBC_OP_NEG,
|
||||||
|
HAWK_FBC_OP_SWAP,
|
||||||
|
HAWK_FBC_OP_DUP,
|
||||||
|
HAWK_FBC_OP_JMP,
|
||||||
|
HAWK_FBC_OP_JZ,
|
||||||
|
HAWK_FBC_OP_CALL,
|
||||||
|
HAWK_FBC_OP_RET,
|
||||||
|
HAWK_FBC_OP_POP,
|
||||||
|
HAWK_FBC_OP_RUN_AST_STMT,
|
||||||
|
HAWK_FBC_OP_RET_AST_EXPR,
|
||||||
|
HAWK_FBC_OP_RET_NIL
|
||||||
|
};
|
||||||
|
typedef enum hawk_fbc_opcode_t hawk_fbc_opcode_t;
|
||||||
|
|
||||||
|
typedef struct hawk_fbc_ins_t hawk_fbc_ins_t;
|
||||||
|
struct hawk_fbc_ins_t
|
||||||
|
{
|
||||||
|
hawk_fbc_opcode_t opcode;
|
||||||
|
union
|
||||||
|
{
|
||||||
|
hawk_nde_t* nde;
|
||||||
|
hawk_int_t iv;
|
||||||
|
hawk_oow_t idx;
|
||||||
|
} u;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct hawk_fbc_t
|
||||||
|
{
|
||||||
|
hawk_fbc_ins_t* code;
|
||||||
|
hawk_oow_t len;
|
||||||
|
hawk_oow_t capa;
|
||||||
|
|
||||||
|
hawk_oow_t nargs;
|
||||||
|
hawk_oow_t nlocals;
|
||||||
|
hawk_oow_t stack_max;
|
||||||
|
};
|
||||||
|
|
||||||
struct hawk_tree_t
|
struct hawk_tree_t
|
||||||
{
|
{
|
||||||
@@ -425,6 +500,14 @@ struct hawk_var_xinfo_t
|
|||||||
hawk_loc_t loc;
|
hawk_loc_t loc;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef struct hawk_fbc_eval_stack_t hawk_fbc_eval_stack_t;
|
||||||
|
struct hawk_fbc_eval_stack_t
|
||||||
|
{
|
||||||
|
hawk_val_t** ptr;
|
||||||
|
hawk_oow_t len;
|
||||||
|
hawk_oow_t capa;
|
||||||
|
};
|
||||||
|
|
||||||
struct hawk_rtx_t
|
struct hawk_rtx_t
|
||||||
{
|
{
|
||||||
HAWK_RTX_HDR;
|
HAWK_RTX_HDR;
|
||||||
@@ -435,6 +518,9 @@ struct hawk_rtx_t
|
|||||||
hawk_oow_t stack_top;
|
hawk_oow_t stack_top;
|
||||||
hawk_oow_t stack_base;
|
hawk_oow_t stack_base;
|
||||||
hawk_oow_t stack_limit;
|
hawk_oow_t stack_limit;
|
||||||
|
|
||||||
|
hawk_fbc_eval_stack_t fbc_eval_stack;
|
||||||
|
|
||||||
int exit_level;
|
int exit_level;
|
||||||
int init_called;
|
int init_called;
|
||||||
|
|
||||||
|
|||||||
+17
-1
@@ -24,6 +24,12 @@
|
|||||||
|
|
||||||
#include "hawk-prv.h"
|
#include "hawk-prv.h"
|
||||||
|
|
||||||
|
static void free_funbc (hawk_t* hawk, hawk_fbc_t* bc)
|
||||||
|
{
|
||||||
|
if (bc->code) hawk_freemem(hawk, bc->code);
|
||||||
|
hawk_freemem(hawk, bc);
|
||||||
|
}
|
||||||
|
|
||||||
static void free_fun (hawk_htb_t* map, void* vptr, hawk_oow_t vlen)
|
static void free_fun (hawk_htb_t* map, void* vptr, hawk_oow_t vlen)
|
||||||
{
|
{
|
||||||
hawk_t* hawk = *(hawk_t**)hawk_htb_getxtn(map);
|
hawk_t* hawk = *(hawk_t**)hawk_htb_getxtn(map);
|
||||||
@@ -33,6 +39,7 @@ static void free_fun (hawk_htb_t* map, void* vptr, hawk_oow_t vlen)
|
|||||||
/*hawk_freemem(hawk, f->name);*/
|
/*hawk_freemem(hawk, f->name);*/
|
||||||
|
|
||||||
if (f->argspec) hawk_freemem(hawk, f->argspec);
|
if (f->argspec) hawk_freemem(hawk, f->argspec);
|
||||||
|
if (f->bc) free_funbc(hawk, f->bc);
|
||||||
hawk_clrpt(hawk, f->body);
|
hawk_clrpt(hawk, f->body);
|
||||||
hawk_freemem(hawk, f);
|
hawk_freemem(hawk, f);
|
||||||
}
|
}
|
||||||
@@ -43,6 +50,7 @@ static void free_ifun (hawk_arr_t* arr, void* dptr, hawk_oow_t dlen)
|
|||||||
hawk_fun_t* f = (hawk_fun_t*)dptr;
|
hawk_fun_t* f = (hawk_fun_t*)dptr;
|
||||||
|
|
||||||
if (f->argspec) hawk_freemem(hawk, f->argspec);
|
if (f->argspec) hawk_freemem(hawk, f->argspec);
|
||||||
|
if (f->bc) free_funbc(hawk, f->bc);
|
||||||
hawk_clrpt(hawk, f->body);
|
hawk_clrpt(hawk, f->body);
|
||||||
hawk_freemem(hawk, f);
|
hawk_freemem(hawk, f);
|
||||||
}
|
}
|
||||||
@@ -459,7 +467,15 @@ void hawk_clear (hawk_t* hawk)
|
|||||||
hawk->parse.depth.loop = 0;
|
hawk->parse.depth.loop = 0;
|
||||||
hawk->parse.depth.expr = 0;
|
hawk->parse.depth.expr = 0;
|
||||||
hawk->parse.depth.incl = 0;
|
hawk->parse.depth.incl = 0;
|
||||||
hawk->parse.pragma.trait = (hawk->opt.trait & (HAWK_IMPLICIT | HAWK_MULTILINESTR | HAWK_PEDANTIC | HAWK_RWPIPE | HAWK_PIPECLOEXEC | HAWK_STRIPRECSPC | HAWK_STRIPSTRSPC)); /* implicit on if you didn't mask it off in hawk->opt.trait with hawk_setopt */
|
|
||||||
|
/* hawk initializes hawk->opt.trait to HAWK_MODERN.
|
||||||
|
* the options beloning to HAWK_MODERN are on if you don't
|
||||||
|
* mask them off with hawk_setopt(). the listed options
|
||||||
|
* here affected the compile-time pragma. */
|
||||||
|
hawk->parse.pragma.trait = hawk->opt.trait &
|
||||||
|
(HAWK_BUILDBC | HAWK_IMPLICIT | HAWK_MULTILINESTR | HAWK_PEDANTIC | HAWK_RWPIPE |
|
||||||
|
HAWK_PIPECLOEXEC | HAWK_STRIPRECSPC | HAWK_STRIPSTRSPC | HAWK_XCALL);
|
||||||
|
|
||||||
hawk->parse.pragma.rtx_stack_limit = 0;
|
hawk->parse.pragma.rtx_stack_limit = 0;
|
||||||
hawk->parse.pragma.entry[0] = '\0';
|
hawk->parse.pragma.entry[0] = '\0';
|
||||||
|
|
||||||
|
|||||||
@@ -524,6 +524,8 @@ struct hawk_nde_t
|
|||||||
* The hawk_fun_t type defines a structure to maintain functions
|
* The hawk_fun_t type defines a structure to maintain functions
|
||||||
* defined with the keyword 'function'.
|
* defined with the keyword 'function'.
|
||||||
*/
|
*/
|
||||||
|
typedef struct hawk_fbc_t hawk_fbc_t;
|
||||||
|
|
||||||
struct hawk_fun_t
|
struct hawk_fun_t
|
||||||
{
|
{
|
||||||
hawk_oocs_t name;
|
hawk_oocs_t name;
|
||||||
@@ -532,6 +534,7 @@ struct hawk_fun_t
|
|||||||
hawk_oow_t argspeclen; /* the length of argspec. it can be different from nargs if there are call-by-value parameters after the last call-by-reference parameter or variadic arguments are supported */
|
hawk_oow_t argspeclen; /* the length of argspec. it can be different from nargs if there are call-by-value parameters after the last call-by-reference parameter or variadic arguments are supported */
|
||||||
int variadic;
|
int variadic;
|
||||||
hawk_nde_t* body;
|
hawk_nde_t* body;
|
||||||
|
hawk_fbc_t* bc; /* function bytecode */
|
||||||
};
|
};
|
||||||
typedef struct hawk_fun_t hawk_fun_t;
|
typedef struct hawk_fun_t hawk_fun_t;
|
||||||
|
|
||||||
@@ -1443,6 +1446,12 @@ enum hawk_trait_t
|
|||||||
*/
|
*/
|
||||||
HAWK_XCALL = (1 << 21),
|
HAWK_XCALL = (1 << 21),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* enables experimental function-body bytecode build/run path
|
||||||
|
* for selected functions.
|
||||||
|
*/
|
||||||
|
HAWK_BUILDBC = (1 << 22),
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* makes #hawk_t to behave compatibly with classical AWK
|
* makes #hawk_t to behave compatibly with classical AWK
|
||||||
|
|||||||
+1164
File diff suppressed because it is too large
Load Diff
@@ -79,6 +79,8 @@ static void fini_rtx (hawk_rtx_t* rtx, int fini_globals);
|
|||||||
static int init_globals (hawk_rtx_t* rtx);
|
static int init_globals (hawk_rtx_t* rtx);
|
||||||
static void refdown_globals (hawk_rtx_t* rtx, int pop);
|
static void refdown_globals (hawk_rtx_t* rtx, int pop);
|
||||||
|
|
||||||
|
static void fbc_eval_stack_fini (hawk_rtx_t* rtx, hawk_fbc_eval_stack_t* stack);
|
||||||
|
|
||||||
static int run_pblocks (hawk_rtx_t* rtx);
|
static int run_pblocks (hawk_rtx_t* rtx);
|
||||||
static int run_pblock_chain (hawk_rtx_t* rtx, hawk_chain_t* cha);
|
static int run_pblock_chain (hawk_rtx_t* rtx, hawk_chain_t* cha);
|
||||||
static int run_pblock (hawk_rtx_t* rtx, hawk_chain_t* cha, hawk_oow_t bno);
|
static int run_pblock (hawk_rtx_t* rtx, hawk_chain_t* cha, hawk_oow_t bno);
|
||||||
@@ -99,6 +101,7 @@ static int run_delete (hawk_rtx_t* rtx, hawk_nde_delete_t* nde);
|
|||||||
static int run_reset (hawk_rtx_t* rtx, hawk_nde_reset_t* nde);
|
static int run_reset (hawk_rtx_t* rtx, hawk_nde_reset_t* nde);
|
||||||
static int run_print (hawk_rtx_t* rtx, hawk_nde_print_t* nde);
|
static int run_print (hawk_rtx_t* rtx, hawk_nde_print_t* nde);
|
||||||
static int run_printf (hawk_rtx_t* rtx, hawk_nde_print_t* nde);
|
static int run_printf (hawk_rtx_t* rtx, hawk_nde_print_t* nde);
|
||||||
|
static int run_funbc (hawk_rtx_t* rtx, hawk_fun_t* fun);
|
||||||
|
|
||||||
static int output_formatted (hawk_rtx_t* rtx, hawk_out_type_t out_type, const hawk_ooch_t* dst, const hawk_ooch_t* fmt, hawk_oow_t fmt_len, hawk_nde_t* args);
|
static int output_formatted (hawk_rtx_t* rtx, hawk_out_type_t out_type, const hawk_ooch_t* dst, const hawk_ooch_t* fmt, hawk_oow_t fmt_len, hawk_nde_t* args);
|
||||||
static int output_formatted_bytes (hawk_rtx_t* rtx, hawk_out_type_t out_type, const hawk_ooch_t* dst, const hawk_bch_t* fmt, hawk_oow_t fmt_len, hawk_nde_t* args);
|
static int output_formatted_bytes (hawk_rtx_t* rtx, hawk_out_type_t out_type, const hawk_ooch_t* dst, const hawk_bch_t* fmt, hawk_oow_t fmt_len, hawk_nde_t* args);
|
||||||
@@ -1340,6 +1343,8 @@ static void fini_rtx (hawk_rtx_t* rtx, int fini_globals)
|
|||||||
rtx->stack_limit = 0;
|
rtx->stack_limit = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fbc_eval_stack_fini(rtx, &rtx->fbc_eval_stack);
|
||||||
|
|
||||||
/* destroy named variables */
|
/* destroy named variables */
|
||||||
hawk_htb_close(rtx->named);
|
hawk_htb_close(rtx->named);
|
||||||
|
|
||||||
@@ -7484,6 +7489,472 @@ static hawk_val_t* eval_fncall_var (hawk_rtx_t* rtx, hawk_nde_t* nde)
|
|||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void fbc_eval_stack_unwind (hawk_rtx_t* rtx, hawk_fbc_eval_stack_t* stack, hawk_oow_t base)
|
||||||
|
{
|
||||||
|
while (stack->len > base)
|
||||||
|
{
|
||||||
|
hawk_rtx_refdownval(rtx, stack->ptr[--stack->len]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void fbc_eval_stack_fini (hawk_rtx_t* rtx, hawk_fbc_eval_stack_t* stack)
|
||||||
|
{
|
||||||
|
while (stack->len > 0)
|
||||||
|
{
|
||||||
|
hawk_rtx_refdownval(rtx, stack->ptr[--stack->len]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stack->ptr) hawk_rtx_freemem(rtx, stack->ptr);
|
||||||
|
stack->ptr = HAWK_NULL;
|
||||||
|
stack->len = 0;
|
||||||
|
stack->capa = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int fbc_eval_stack_reserve (hawk_rtx_t* rtx, hawk_fbc_eval_stack_t* stack, hawk_oow_t n)
|
||||||
|
{
|
||||||
|
hawk_val_t** tmp;
|
||||||
|
hawk_oow_t req, capa;
|
||||||
|
|
||||||
|
req = stack->len + n;
|
||||||
|
if (req <= stack->len) goto oops_eoverflow;
|
||||||
|
if (req <= stack->capa) return 0;
|
||||||
|
|
||||||
|
capa = HAWK_ALIGN_POW2(req, 16);
|
||||||
|
if (capa < req) goto oops_eoverflow;
|
||||||
|
if (capa > HAWK_TYPE_MAX(hawk_oow_t) / HAWK_SIZEOF(*tmp)) goto oops_eoverflow;
|
||||||
|
|
||||||
|
tmp = (hawk_val_t**)hawk_rtx_reallocmem(rtx, stack->ptr, capa * HAWK_SIZEOF(*tmp));
|
||||||
|
if (HAWK_UNLIKELY(!tmp)) return -1;
|
||||||
|
|
||||||
|
stack->ptr = tmp;
|
||||||
|
stack->capa = capa;
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
oops_eoverflow:
|
||||||
|
hawk_rtx_seterrnum(rtx, HAWK_NULL, HAWK_ENOMEM);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int fbc_eval_stack_push (hawk_rtx_t* rtx, hawk_fbc_eval_stack_t* stack, hawk_val_t* val)
|
||||||
|
{
|
||||||
|
if (fbc_eval_stack_reserve(rtx, stack, 1) <= -1) return -1;
|
||||||
|
stack->ptr[stack->len++] = val;
|
||||||
|
hawk_rtx_refupval(rtx, val);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static hawk_val_t* fbc_eval_stack_pop (hawk_fbc_eval_stack_t* stack)
|
||||||
|
{
|
||||||
|
return (stack->len <= 0)? HAWK_NULL: stack->ptr[--stack->len];
|
||||||
|
}
|
||||||
|
|
||||||
|
static int fbc_eval_binop (
|
||||||
|
hawk_rtx_t* rtx,
|
||||||
|
hawk_fbc_eval_stack_t* stack,
|
||||||
|
hawk_val_t* (*evalfn)(hawk_rtx_t*,hawk_val_t*,hawk_val_t*))
|
||||||
|
{
|
||||||
|
hawk_val_t* right;
|
||||||
|
hawk_val_t* left;
|
||||||
|
hawk_val_t* res;
|
||||||
|
|
||||||
|
if (stack->len < 2)
|
||||||
|
{
|
||||||
|
hawk_rtx_seterrnum(rtx, HAWK_NULL, HAWK_EINTERN);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
right = fbc_eval_stack_pop(stack);
|
||||||
|
left = fbc_eval_stack_pop(stack);
|
||||||
|
HAWK_ASSERT(right != HAWK_NULL && left != HAWK_NULL);
|
||||||
|
|
||||||
|
res = evalfn(rtx, left, right);
|
||||||
|
hawk_rtx_refdownval(rtx, right);
|
||||||
|
hawk_rtx_refdownval(rtx, left);
|
||||||
|
if (HAWK_UNLIKELY(!res)) return -1;
|
||||||
|
|
||||||
|
if (fbc_eval_stack_push(rtx, stack, res) <= -1) return -1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int run_funbc (hawk_rtx_t* rtx, hawk_fun_t* fun)
|
||||||
|
{
|
||||||
|
hawk_fbc_t* bc;
|
||||||
|
hawk_nde_blk_t* blk;
|
||||||
|
hawk_oow_t pc;
|
||||||
|
hawk_fbc_eval_stack_t* evstk;
|
||||||
|
hawk_oow_t evstk_base;
|
||||||
|
int n = 0;
|
||||||
|
|
||||||
|
/* the caller must not call this function if the function doesn't
|
||||||
|
* have the associated bytecode emitted */
|
||||||
|
HAWK_ASSERT(fun != HAWK_NULL);
|
||||||
|
HAWK_ASSERT(fun->bc != HAWK_NULL);
|
||||||
|
HAWK_ASSERT(fun->bc->len > 0);
|
||||||
|
HAWK_ASSERT(fun->body != HAWK_NULL);
|
||||||
|
HAWK_ASSERT(fun->body->type == HAWK_NDE_BLK);
|
||||||
|
|
||||||
|
evstk_base = rtx->fbc_eval_stack.len;
|
||||||
|
evstk = &rtx->fbc_eval_stack;
|
||||||
|
|
||||||
|
bc = fun->bc;
|
||||||
|
blk = (hawk_nde_blk_t*)fun->body;
|
||||||
|
|
||||||
|
if (blk->nlcls > 0)
|
||||||
|
{
|
||||||
|
hawk_oow_t tmp = blk->nlcls;
|
||||||
|
|
||||||
|
if (HAWK_UNLIKELY(HAWK_RTX_STACK_AVAIL(rtx) < tmp))
|
||||||
|
{
|
||||||
|
hawk_rtx_seterrbfmt(rtx, &blk->loc, HAWK_ESTACK,
|
||||||
|
"stack full(avail=%zu, limit=%zu) for %zu local variables",
|
||||||
|
HAWK_RTX_STACK_AVAIL(rtx), rtx->stack_limit, tmp);
|
||||||
|
goto oops;
|
||||||
|
}
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
--tmp;
|
||||||
|
HAWK_RTX_STACK_PUSH(rtx, hawk_val_nil);
|
||||||
|
}
|
||||||
|
while (tmp > 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (pc = 0; pc < bc->len && rtx->exit_level == EXIT_NONE; )
|
||||||
|
{
|
||||||
|
hawk_fbc_ins_t* ins = &bc->code[pc];
|
||||||
|
hawk_val_t* val;
|
||||||
|
|
||||||
|
/*hawk_logbfmt(rtx->hawk, HAWK_LOG_STDERR, "opcode = 0x%x [%d]\n", ins->opcode, ins->opcode);*/
|
||||||
|
switch (ins->opcode)
|
||||||
|
{
|
||||||
|
case HAWK_FBC_OP_NOP:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case HAWK_FBC_OP_LOAD_CONST_INT:
|
||||||
|
val = hawk_rtx_makeintval(rtx, ins->u.iv);
|
||||||
|
if (HAWK_UNLIKELY(!val)) goto oops;
|
||||||
|
if (fbc_eval_stack_push(rtx, evstk, val) <= -1) goto oops;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case HAWK_FBC_OP_LOAD_CONST_NIL:
|
||||||
|
if (fbc_eval_stack_push(rtx, evstk, hawk_val_nil) <= -1) goto oops;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case HAWK_FBC_OP_LOAD_CONST_TRUE:
|
||||||
|
if (fbc_eval_stack_push(rtx, evstk, hawk_val_true) <= -1) goto oops;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case HAWK_FBC_OP_LOAD_CONST_FALSE:
|
||||||
|
if (fbc_eval_stack_push(rtx, evstk, hawk_val_false) <= -1) goto oops;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case HAWK_FBC_OP_LOAD_GBL:
|
||||||
|
case HAWK_FBC_OP_LOAD_LCL:
|
||||||
|
case HAWK_FBC_OP_LOAD_ARG:
|
||||||
|
{
|
||||||
|
hawk_nde_var_t* var = (hawk_nde_var_t*)ins->u.nde;
|
||||||
|
|
||||||
|
if (!var)
|
||||||
|
{
|
||||||
|
hawk_rtx_seterrnum(rtx, HAWK_NULL, HAWK_EINTERN);
|
||||||
|
goto oops;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (ins->opcode)
|
||||||
|
{
|
||||||
|
case HAWK_FBC_OP_LOAD_GBL: val = HAWK_RTX_STACK_GBL(rtx, var->id.idxa); break;
|
||||||
|
case HAWK_FBC_OP_LOAD_LCL: val = HAWK_RTX_STACK_LCL(rtx, var->id.idxa); break;
|
||||||
|
default: val = HAWK_RTX_STACK_ARG(rtx, var->id.idxa); break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fbc_eval_stack_push(rtx, evstk, val) <= -1) goto oops;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case HAWK_FBC_OP_STORE_GBL:
|
||||||
|
case HAWK_FBC_OP_STORE_LCL:
|
||||||
|
case HAWK_FBC_OP_STORE_ARG:
|
||||||
|
case HAWK_FBC_OP_STORE_POP_GBL:
|
||||||
|
case HAWK_FBC_OP_STORE_POP_LCL:
|
||||||
|
case HAWK_FBC_OP_STORE_POP_ARG:
|
||||||
|
{
|
||||||
|
hawk_nde_var_t* var = (hawk_nde_var_t*)ins->u.nde;
|
||||||
|
hawk_val_t* res;
|
||||||
|
int keep_result;
|
||||||
|
|
||||||
|
val = fbc_eval_stack_pop(evstk);
|
||||||
|
if (!val)
|
||||||
|
{
|
||||||
|
hawk_rtx_seterrnum(rtx, HAWK_NULL, HAWK_EINTERN);
|
||||||
|
goto oops;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!var)
|
||||||
|
{
|
||||||
|
hawk_rtx_refdownval(rtx, val);
|
||||||
|
hawk_rtx_seterrnum(rtx, HAWK_NULL, HAWK_EINTERN);
|
||||||
|
goto oops;
|
||||||
|
}
|
||||||
|
|
||||||
|
keep_result =
|
||||||
|
(ins->opcode == HAWK_FBC_OP_STORE_GBL ||
|
||||||
|
ins->opcode == HAWK_FBC_OP_STORE_LCL ||
|
||||||
|
ins->opcode == HAWK_FBC_OP_STORE_ARG);
|
||||||
|
|
||||||
|
res = do_assignment(rtx, (hawk_nde_t*)var, val, 0);
|
||||||
|
if (HAWK_UNLIKELY(!res))
|
||||||
|
{
|
||||||
|
hawk_rtx_refdownval(rtx, val);
|
||||||
|
goto oops;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (keep_result && fbc_eval_stack_push(rtx, evstk, res) <= -1)
|
||||||
|
{
|
||||||
|
hawk_rtx_refdownval(rtx, val);
|
||||||
|
goto oops;
|
||||||
|
}
|
||||||
|
|
||||||
|
hawk_rtx_refdownval(rtx, val);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case HAWK_FBC_OP_ADD:
|
||||||
|
if (HAWK_UNLIKELY(fbc_eval_binop(rtx, evstk, eval_binop_plus) <= -1)) goto oops;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case HAWK_FBC_OP_SUB:
|
||||||
|
if (HAWK_UNLIKELY(fbc_eval_binop(rtx, evstk, eval_binop_minus) <= -1)) goto oops;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case HAWK_FBC_OP_MUL:
|
||||||
|
if (HAWK_UNLIKELY(fbc_eval_binop(rtx, evstk, eval_binop_mul) <= -1)) goto oops;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case HAWK_FBC_OP_DIV:
|
||||||
|
if (HAWK_UNLIKELY(fbc_eval_binop(rtx, evstk, eval_binop_div) <= -1)) goto oops;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case HAWK_FBC_OP_IDIV:
|
||||||
|
if (HAWK_UNLIKELY(fbc_eval_binop(rtx, evstk, eval_binop_idiv) <= -1)) goto oops;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case HAWK_FBC_OP_MOD:
|
||||||
|
if (HAWK_UNLIKELY(fbc_eval_binop(rtx, evstk, eval_binop_mod) <= -1)) goto oops;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case HAWK_FBC_OP_EXP:
|
||||||
|
if (HAWK_UNLIKELY(fbc_eval_binop(rtx, evstk, eval_binop_exp) <= -1)) goto oops;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case HAWK_FBC_OP_CONCAT:
|
||||||
|
if (HAWK_UNLIKELY(fbc_eval_binop(rtx, evstk, eval_binop_concat) <= -1)) goto oops;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case HAWK_FBC_OP_RSHIFT:
|
||||||
|
if (HAWK_UNLIKELY(fbc_eval_binop(rtx, evstk, eval_binop_rshift) <= -1)) goto oops;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case HAWK_FBC_OP_LSHIFT:
|
||||||
|
if (HAWK_UNLIKELY(fbc_eval_binop(rtx, evstk, eval_binop_lshift) <= -1)) goto oops;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case HAWK_FBC_OP_BAND:
|
||||||
|
if (HAWK_UNLIKELY(fbc_eval_binop(rtx, evstk, eval_binop_band) <= -1)) goto oops;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case HAWK_FBC_OP_BXOR:
|
||||||
|
if (HAWK_UNLIKELY(fbc_eval_binop(rtx, evstk, eval_binop_bxor) <= -1)) goto oops;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case HAWK_FBC_OP_BOR:
|
||||||
|
if (HAWK_UNLIKELY(fbc_eval_binop(rtx, evstk, eval_binop_bor) <= -1)) goto oops;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case HAWK_FBC_OP_TEQ:
|
||||||
|
if (HAWK_UNLIKELY(fbc_eval_binop(rtx, evstk, eval_binop_teq) <= -1)) goto oops;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case HAWK_FBC_OP_TNE:
|
||||||
|
if (HAWK_UNLIKELY(fbc_eval_binop(rtx, evstk, eval_binop_tne) <= -1)) goto oops;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case HAWK_FBC_OP_EQ:
|
||||||
|
if (HAWK_UNLIKELY(fbc_eval_binop(rtx, evstk, eval_binop_eq) <= -1)) goto oops;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case HAWK_FBC_OP_NE:
|
||||||
|
if (HAWK_UNLIKELY(fbc_eval_binop(rtx, evstk, eval_binop_ne) <= -1)) goto oops;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case HAWK_FBC_OP_GT:
|
||||||
|
if (HAWK_UNLIKELY(fbc_eval_binop(rtx, evstk, eval_binop_gt) <= -1)) goto oops;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case HAWK_FBC_OP_GE:
|
||||||
|
if (HAWK_UNLIKELY(fbc_eval_binop(rtx, evstk, eval_binop_ge) <= -1)) goto oops;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case HAWK_FBC_OP_LT:
|
||||||
|
if (HAWK_UNLIKELY(fbc_eval_binop(rtx, evstk, eval_binop_lt) <= -1)) goto oops;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case HAWK_FBC_OP_LE:
|
||||||
|
if (HAWK_UNLIKELY(fbc_eval_binop(rtx, evstk, eval_binop_le) <= -1)) goto oops;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case HAWK_FBC_OP_NEG:
|
||||||
|
{
|
||||||
|
int n;
|
||||||
|
hawk_int_t l;
|
||||||
|
hawk_flt_t r;
|
||||||
|
hawk_val_t* res;
|
||||||
|
|
||||||
|
val = fbc_eval_stack_pop(evstk);
|
||||||
|
if (!val)
|
||||||
|
{
|
||||||
|
hawk_rtx_seterrbfmt(rtx, HAWK_NULL, HAWK_EINTERN, "eval stack underflow");
|
||||||
|
goto oops;
|
||||||
|
}
|
||||||
|
|
||||||
|
n = hawk_rtx_valtonum(rtx, val, &l, &r);
|
||||||
|
if (HAWK_UNLIKELY(n <= -1))
|
||||||
|
{
|
||||||
|
hawk_rtx_refdownval(rtx, val);
|
||||||
|
goto oops;
|
||||||
|
}
|
||||||
|
|
||||||
|
res = (n == 0)? hawk_rtx_makeintval(rtx, -l): hawk_rtx_makefltval(rtx, -r);
|
||||||
|
hawk_rtx_refdownval(rtx, val);
|
||||||
|
if (HAWK_UNLIKELY(!res)) goto oops;
|
||||||
|
if (fbc_eval_stack_push(rtx, evstk, res) <= -1) goto oops;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case HAWK_FBC_OP_SWAP:
|
||||||
|
if (evstk->len < 2)
|
||||||
|
{
|
||||||
|
hawk_rtx_seterrnum(rtx, HAWK_NULL, HAWK_EINTERN);
|
||||||
|
goto oops;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
hawk_val_t* tmp = evstk->ptr[evstk->len - 1];
|
||||||
|
evstk->ptr[evstk->len - 1] = evstk->ptr[evstk->len - 2];
|
||||||
|
evstk->ptr[evstk->len - 2] = tmp;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case HAWK_FBC_OP_DUP:
|
||||||
|
if (evstk->len <= 0)
|
||||||
|
{
|
||||||
|
hawk_rtx_seterrnum(rtx, HAWK_NULL, HAWK_EINTERN);
|
||||||
|
goto oops;
|
||||||
|
}
|
||||||
|
if (fbc_eval_stack_push(rtx, evstk, evstk->ptr[evstk->len - 1]) <= -1) goto oops;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case HAWK_FBC_OP_JMP:
|
||||||
|
if (ins->u.idx > bc->len)
|
||||||
|
{
|
||||||
|
hawk_rtx_seterrnum(rtx, HAWK_NULL, HAWK_EINTERN);
|
||||||
|
goto oops;
|
||||||
|
}
|
||||||
|
pc = ins->u.idx;
|
||||||
|
continue;
|
||||||
|
|
||||||
|
case HAWK_FBC_OP_JZ:
|
||||||
|
val = fbc_eval_stack_pop(evstk);
|
||||||
|
if (!val)
|
||||||
|
{
|
||||||
|
hawk_rtx_seterrnum(rtx, HAWK_NULL, HAWK_EINTERN);
|
||||||
|
goto oops;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!hawk_rtx_valtobool(rtx, val))
|
||||||
|
{
|
||||||
|
hawk_rtx_refdownval(rtx, val);
|
||||||
|
if (ins->u.idx > bc->len)
|
||||||
|
{
|
||||||
|
hawk_rtx_seterrnum(rtx, HAWK_NULL, HAWK_EINTERN);
|
||||||
|
goto oops;
|
||||||
|
}
|
||||||
|
pc = ins->u.idx;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
hawk_rtx_refdownval(rtx, val);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case HAWK_FBC_OP_RET:
|
||||||
|
val = fbc_eval_stack_pop(evstk);
|
||||||
|
if (!val)
|
||||||
|
{
|
||||||
|
hawk_rtx_seterrnum(rtx, HAWK_NULL, HAWK_EINTERN);
|
||||||
|
goto oops;
|
||||||
|
}
|
||||||
|
hawk_rtx_refdownval(rtx, HAWK_RTX_STACK_RETVAL(rtx));
|
||||||
|
HAWK_RTX_STACK_RETVAL(rtx) = val;
|
||||||
|
hawk_rtx_refupval(rtx, val);
|
||||||
|
hawk_rtx_refdownval(rtx, val);
|
||||||
|
rtx->exit_level = EXIT_FUNCTION;
|
||||||
|
goto done;
|
||||||
|
|
||||||
|
case HAWK_FBC_OP_POP:
|
||||||
|
val = fbc_eval_stack_pop(evstk);
|
||||||
|
if (!val)
|
||||||
|
{
|
||||||
|
hawk_rtx_seterrnum(rtx, HAWK_NULL, HAWK_EINTERN);
|
||||||
|
goto oops;
|
||||||
|
}
|
||||||
|
hawk_rtx_refdownval(rtx, val);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case HAWK_FBC_OP_RUN_AST_STMT:
|
||||||
|
if (HAWK_UNLIKELY(run_statement(rtx, ins->u.nde) <= -1)) goto oops;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case HAWK_FBC_OP_RET_AST_EXPR:
|
||||||
|
val = eval_expression(rtx, ins->u.nde);
|
||||||
|
if (HAWK_UNLIKELY(!val)) goto oops;
|
||||||
|
|
||||||
|
hawk_rtx_refdownval(rtx, HAWK_RTX_STACK_RETVAL(rtx));
|
||||||
|
HAWK_RTX_STACK_RETVAL(rtx) = val;
|
||||||
|
hawk_rtx_refupval(rtx, val);
|
||||||
|
|
||||||
|
rtx->exit_level = EXIT_FUNCTION;
|
||||||
|
goto done;
|
||||||
|
|
||||||
|
case HAWK_FBC_OP_RET_NIL:
|
||||||
|
rtx->exit_level = EXIT_FUNCTION;
|
||||||
|
goto done;
|
||||||
|
|
||||||
|
default:
|
||||||
|
hawk_rtx_seterrnum(rtx, HAWK_NULL, HAWK_ENOIMPL);
|
||||||
|
goto oops;
|
||||||
|
}
|
||||||
|
|
||||||
|
pc++;
|
||||||
|
}
|
||||||
|
|
||||||
|
done:
|
||||||
|
if (blk->nlcls > 0)
|
||||||
|
{
|
||||||
|
hawk_oow_t tmp = blk->nlcls;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
--tmp;
|
||||||
|
hawk_rtx_refdownval(rtx, HAWK_RTX_STACK_LCL(rtx, tmp));
|
||||||
|
HAWK_RTX_STACK_POP(rtx);
|
||||||
|
}
|
||||||
|
while (tmp > 0);
|
||||||
|
}
|
||||||
|
fbc_eval_stack_unwind(rtx, evstk, evstk_base);
|
||||||
|
return n;
|
||||||
|
|
||||||
|
oops:
|
||||||
|
n = -1;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
hawk_val_t* hawk_rtx_evalcall (
|
hawk_val_t* hawk_rtx_evalcall (
|
||||||
hawk_rtx_t* rtx, hawk_nde_fncall_t* call, hawk_fun_t* fun,
|
hawk_rtx_t* rtx, hawk_nde_fncall_t* call, hawk_fun_t* fun,
|
||||||
hawk_oow_t(*argpusher)(hawk_rtx_t*,hawk_nde_fncall_t*,void*), void* apdata,
|
hawk_oow_t(*argpusher)(hawk_rtx_t*,hawk_nde_fncall_t*,void*), void* apdata,
|
||||||
@@ -7540,7 +8011,7 @@ hawk_val_t* hawk_rtx_evalcall (
|
|||||||
saved_stack_top = rtx->stack_top;
|
saved_stack_top = rtx->stack_top;
|
||||||
|
|
||||||
#if defined(DEBUG_RUN)
|
#if defined(DEBUG_RUN)
|
||||||
hawk_logbfmt(hawk_rtx_gethawk(rtx), "setting up function stack frame top=%zd base=%zd\n", (hawk_oow_t)rtx->stack_top, (hawk_oow_t)rtx->stack_base);
|
hawk_logbfmt(hawk_rtx_gethawk(rtx), HAWK_LOG_DEBUG, "setting up function stack frame top=%zd base=%zd\n", (hawk_oow_t)rtx->stack_top, (hawk_oow_t)rtx->stack_base);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* make a new stack frame */
|
/* make a new stack frame */
|
||||||
@@ -7592,15 +8063,22 @@ hawk_val_t* hawk_rtx_evalcall (
|
|||||||
HAWK_RTX_STACK_NARGS(rtx) = (void*)nargs;
|
HAWK_RTX_STACK_NARGS(rtx) = (void*)nargs;
|
||||||
|
|
||||||
#if defined(DEBUG_RUN)
|
#if defined(DEBUG_RUN)
|
||||||
hawk_logbfmt(hawk_rtx_gethawk(rtx), "running function body\n");
|
hawk_logbfmt(hawk_rtx_gethawk(rtx), HAWK_LOG_DEBUG, "running function body\n");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (fun)
|
if (fun)
|
||||||
{
|
{
|
||||||
/* normal hawk function */
|
/* normal hawk function */
|
||||||
|
if ((rtx->hawk->opt.trait & HAWK_BUILDBC) && fun->bc && fun->bc->len > 0)
|
||||||
|
{
|
||||||
|
n = run_funbc(rtx, fun);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
HAWK_ASSERT(fun->body->type == HAWK_NDE_BLK);
|
HAWK_ASSERT(fun->body->type == HAWK_NDE_BLK);
|
||||||
n = run_block(rtx, (hawk_nde_blk_t*)fun->body);
|
n = run_block(rtx, (hawk_nde_blk_t*)fun->body);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
n = 0;
|
n = 0;
|
||||||
@@ -7618,7 +8096,7 @@ hawk_val_t* hawk_rtx_evalcall (
|
|||||||
/* refdown args in the rtx.stack */
|
/* refdown args in the rtx.stack */
|
||||||
nargs = (hawk_oow_t)HAWK_RTX_STACK_NARGS(rtx);
|
nargs = (hawk_oow_t)HAWK_RTX_STACK_NARGS(rtx);
|
||||||
#if defined(DEBUG_RUN)
|
#if defined(DEBUG_RUN)
|
||||||
hawk_logbfmt(hawk_rtx_gethawk(rtx), "block rtx complete nargs = %d\n", (int)nargs);
|
hawk_logbfmt(hawk_rtx_gethawk(rtx), HAWK_LOG_DEBUG, "block rtx complete nargs = %d\n", (int)nargs);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
i = 0;
|
i = 0;
|
||||||
@@ -7745,7 +8223,7 @@ hawk_val_t* hawk_rtx_evalcall (
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if defined(DEBUG_RUN)
|
#if defined(DEBUG_RUN)
|
||||||
hawk_logbfmt(hawk_rtx_gethawk(rtx), "got return value\n");
|
hawk_logbfmt(hawk_rtx_gethawk(rtx), HAWK_LOG_DEBUG, "got return value\n");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
v = HAWK_RTX_STACK_RETVAL(rtx);
|
v = HAWK_RTX_STACK_RETVAL(rtx);
|
||||||
@@ -7800,7 +8278,7 @@ hawk_val_t* hawk_rtx_evalcall (
|
|||||||
if (rtx->exit_level == EXIT_FUNCTION) rtx->exit_level = EXIT_NONE;
|
if (rtx->exit_level == EXIT_FUNCTION) rtx->exit_level = EXIT_NONE;
|
||||||
|
|
||||||
#if defined(DEBUG_RUN)
|
#if defined(DEBUG_RUN)
|
||||||
hawk_logbfmt(hawk_rtx_gethawk(rtx), "returning from function top=%zd, base=%zd\n", (hawk_oow_t)rtx->stack_top, (hawk_oow_t)rtx->stack_base);
|
hawk_logbfmt(hawk_rtx_gethawk(rtx), HAWK_LOG_DEBUG, "returning from function top=%zd, base=%zd\n", (hawk_oow_t)rtx->stack_top, (hawk_oow_t)rtx->stack_base);
|
||||||
#endif
|
#endif
|
||||||
return (n <= -1)? HAWK_NULL: v;
|
return (n <= -1)? HAWK_NULL: v;
|
||||||
|
|
||||||
|
|||||||
@@ -1155,6 +1155,7 @@ hawk_val_t* hawk_rtx_makearrval (hawk_rtx_t* rtx, hawk_ooi_t init_capa)
|
|||||||
int retried = 0;
|
int retried = 0;
|
||||||
#endif
|
#endif
|
||||||
hawk_val_arr_t* val;
|
hawk_val_arr_t* val;
|
||||||
|
int x;
|
||||||
|
|
||||||
#if defined(HAWK_ENABLE_GC)
|
#if defined(HAWK_ENABLE_GC)
|
||||||
retry:
|
retry:
|
||||||
@@ -1172,7 +1173,8 @@ retry:
|
|||||||
val->arr = (hawk_arr_t*)(val + 1);
|
val->arr = (hawk_arr_t*)(val + 1);
|
||||||
|
|
||||||
if (init_capa < 0) init_capa = 64; /* TODO: what is the best initial value? */
|
if (init_capa < 0) init_capa = 64; /* TODO: what is the best initial value? */
|
||||||
if (HAWK_UNLIKELY(hawk_arr_init(val->arr, hawk_rtx_getgem(rtx), init_capa) <= -1))
|
x = hawk_arr_init(val->arr, hawk_rtx_getgem(rtx), init_capa);
|
||||||
|
if (HAWK_UNLIKELY(x <= -1))
|
||||||
{
|
{
|
||||||
#if defined(HAWK_ENABLE_GC)
|
#if defined(HAWK_ENABLE_GC)
|
||||||
gc_free_val(rtx, (hawk_val_t*)val);
|
gc_free_val(rtx, (hawk_val_t*)val);
|
||||||
@@ -1263,6 +1265,7 @@ hawk_val_t* hawk_rtx_makemapval (hawk_rtx_t* rtx)
|
|||||||
int retried = 0;
|
int retried = 0;
|
||||||
#endif
|
#endif
|
||||||
hawk_val_map_t* val;
|
hawk_val_map_t* val;
|
||||||
|
int x;
|
||||||
|
|
||||||
#if defined(HAWK_ENABLE_GC)
|
#if defined(HAWK_ENABLE_GC)
|
||||||
retry:
|
retry:
|
||||||
@@ -1279,7 +1282,8 @@ retry:
|
|||||||
val->v_gc = 0;
|
val->v_gc = 0;
|
||||||
val->map = (hawk_map_t*)(val + 1);
|
val->map = (hawk_map_t*)(val + 1);
|
||||||
|
|
||||||
if (HAWK_UNLIKELY(hawk_map_init(val->map, hawk_rtx_getgem(rtx), 256, 70, HAWK_SIZEOF(hawk_ooch_t), 1) <= -1))
|
x = hawk_map_init(val->map, hawk_rtx_getgem(rtx), 256, 70, HAWK_SIZEOF(hawk_ooch_t), 1);
|
||||||
|
if (HAWK_UNLIKELY(x <= -1))
|
||||||
{
|
{
|
||||||
#if defined(HAWK_ENABLE_GC)
|
#if defined(HAWK_ENABLE_GC)
|
||||||
gc_free_val(rtx, (hawk_val_t*)val);
|
gc_free_val(rtx, (hawk_val_t*)val);
|
||||||
|
|||||||
+4
-3
@@ -17,7 +17,7 @@ check_SCRIPTS =
|
|||||||
if ENABLE_WIDE_CHAR
|
if ENABLE_WIDE_CHAR
|
||||||
check_SCRIPTS += h-001.hawk h-002.hawk
|
check_SCRIPTS += h-001.hawk h-002.hawk
|
||||||
endif
|
endif
|
||||||
check_SCRIPTS += h-003.hawk h-004.hawk h-009.hawk h-010.hawk h-011.hawk h-012.hawk h-013.hawk h-014.hawk h-015.hawk h-016.hawk h-017.hawk h-018.hawk
|
check_SCRIPTS += h-003.hawk h-004.hawk h-009.hawk h-010.hawk h-011.hawk h-012.hawk h-013.hawk h-014.hawk h-015.hawk h-016.hawk h-017.hawk h-018.hawk h-019.hawk
|
||||||
|
|
||||||
check_SCRIPTS += regress-filename.sh
|
check_SCRIPTS += regress-filename.sh
|
||||||
|
|
||||||
@@ -103,13 +103,14 @@ TEST_EXTENSIONS = .hawk .err .sh
|
|||||||
|
|
||||||
# override these from environment when needed.
|
# override these from environment when needed.
|
||||||
# e.g.
|
# e.g.
|
||||||
# make check HAWK_TEST_COMPILER=../samples/hawk51 HAWK_TEST_MODLIBDIRS_OPT=
|
# make check HAWK_TEST_COMPILER=../samples/hawk51 HAWK_TEST_OPTS=
|
||||||
HAWK_TEST_COMPILER ?= ../bin/hawk
|
HAWK_TEST_COMPILER ?= ../bin/hawk
|
||||||
HAWK_TEST_MODLIBDIRS_OPT ?= --modlibdirs=../lib/.libs:../mod/.libs
|
HAWK_TEST_MODLIBDIRS_OPT ?= --modlibdirs=../lib/.libs:../mod/.libs
|
||||||
|
HAWK_TEST_OPTS ?=
|
||||||
|
|
||||||
HAWK_LOG_DRIVER = $(LOG_DRIVER)
|
HAWK_LOG_DRIVER = $(LOG_DRIVER)
|
||||||
HAWK_LOG_COMPILER = $(HAWK_TEST_COMPILER)
|
HAWK_LOG_COMPILER = $(HAWK_TEST_COMPILER)
|
||||||
AM_HAWK_LOG_FLAGS = -vTDIR=${abs_srcdir} $(HAWK_TEST_MODLIBDIRS_OPT) -f
|
AM_HAWK_LOG_FLAGS = -vTDIR=${abs_srcdir} $(HAWK_TEST_MODLIBDIRS_OPT) $(HAWK_TEST_OPTS) -f
|
||||||
|
|
||||||
ERR_LOG_DRIVER = $(SHELL) $(top_srcdir)/ac/test-driver
|
ERR_LOG_DRIVER = $(SHELL) $(top_srcdir)/ac/test-driver
|
||||||
ERR_LOG_COMPILER = $(SHELL) $(abs_srcdir)/err.sh ../bin/hawk -vTDIR=${abs_srcdir} --modlibdirs=../lib/.libs:../mod/.libs -f
|
ERR_LOG_COMPILER = $(SHELL) $(abs_srcdir)/err.sh ../bin/hawk -vTDIR=${abs_srcdir} --modlibdirs=../lib/.libs:../mod/.libs -f
|
||||||
|
|||||||
+3
-2
@@ -649,7 +649,7 @@ LDFLAGS_COMMON = -L$(abs_builddir)/../lib -L$(libdir)
|
|||||||
LIBADD_COMMON = ../lib/libhawk.la $(LIBM)
|
LIBADD_COMMON = ../lib/libhawk.la $(LIBM)
|
||||||
check_SCRIPTS = $(am__append_1) h-003.hawk h-004.hawk h-009.hawk \
|
check_SCRIPTS = $(am__append_1) h-003.hawk h-004.hawk h-009.hawk \
|
||||||
h-010.hawk h-011.hawk h-012.hawk h-013.hawk h-014.hawk \
|
h-010.hawk h-011.hawk h-012.hawk h-013.hawk h-014.hawk \
|
||||||
h-015.hawk h-016.hawk h-017.hawk h-018.hawk \
|
h-015.hawk h-016.hawk h-017.hawk h-018.hawk h-019.hawk \
|
||||||
regress-filename.sh
|
regress-filename.sh
|
||||||
check_ERRORS = e-001.err
|
check_ERRORS = e-001.err
|
||||||
EXTRA_DIST = $(check_SCRIPTS) $(check_ERRORS) tap.inc err.sh \
|
EXTRA_DIST = $(check_SCRIPTS) $(check_ERRORS) tap.inc err.sh \
|
||||||
@@ -711,9 +711,10 @@ TESTS = $(check_PROGRAMS) $(check_SCRIPTS) $(check_ERRORS)
|
|||||||
TEST_EXTENSIONS = .hawk .err .sh
|
TEST_EXTENSIONS = .hawk .err .sh
|
||||||
HAWK_TEST_COMPILER ?= ../bin/hawk
|
HAWK_TEST_COMPILER ?= ../bin/hawk
|
||||||
HAWK_TEST_MODLIBDIRS_OPT ?= --modlibdirs=../lib/.libs:../mod/.libs
|
HAWK_TEST_MODLIBDIRS_OPT ?= --modlibdirs=../lib/.libs:../mod/.libs
|
||||||
|
HAWK_TEST_OPTS ?= --modlibdirs=../lib/.libs:../mod/.libs
|
||||||
HAWK_LOG_DRIVER = $(LOG_DRIVER)
|
HAWK_LOG_DRIVER = $(LOG_DRIVER)
|
||||||
HAWK_LOG_COMPILER = $(HAWK_TEST_COMPILER)
|
HAWK_LOG_COMPILER = $(HAWK_TEST_COMPILER)
|
||||||
AM_HAWK_LOG_FLAGS = -vTDIR=${abs_srcdir} $(HAWK_TEST_MODLIBDIRS_OPT) -f
|
AM_HAWK_LOG_FLAGS = -vTDIR=${abs_srcdir} $(HAWK_TEST_MODLIBDIRS_OPT) $(HAWK_TEST_OPTS) -f
|
||||||
ERR_LOG_DRIVER = $(SHELL) $(top_srcdir)/ac/test-driver
|
ERR_LOG_DRIVER = $(SHELL) $(top_srcdir)/ac/test-driver
|
||||||
ERR_LOG_COMPILER = $(SHELL) $(abs_srcdir)/err.sh ../bin/hawk -vTDIR=${abs_srcdir} --modlibdirs=../lib/.libs:../mod/.libs -f
|
ERR_LOG_COMPILER = $(SHELL) $(abs_srcdir)/err.sh ../bin/hawk -vTDIR=${abs_srcdir} --modlibdirs=../lib/.libs:../mod/.libs -f
|
||||||
AM_ERR_LOG_FLAGS =
|
AM_ERR_LOG_FLAGS =
|
||||||
|
|||||||
+6
-2
@@ -11,7 +11,7 @@ function dummy()
|
|||||||
|
|
||||||
function main()
|
function main()
|
||||||
{
|
{
|
||||||
@local m, a;
|
@local m, a, tmp;
|
||||||
|
|
||||||
m = hawk::map();
|
m = hawk::map();
|
||||||
a = hawk::array();
|
a = hawk::array();
|
||||||
@@ -39,6 +39,11 @@ function main()
|
|||||||
tap_ensure(@false === 0, 0, @SCRIPTNAME, @SCRIPTLINE);
|
tap_ensure(@false === 0, 0, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
tap_ensure(@true !== 1, 1, @SCRIPTNAME, @SCRIPTLINE);
|
tap_ensure(@true !== 1, 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
|
||||||
|
tmp = (@false === 0)
|
||||||
|
tap_ensure(tmp, 0, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
tmp = (@true === 1)
|
||||||
|
tap_ensure(tmp, 0, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
|
||||||
tap_ensure(@true == 1.0, 1, @SCRIPTNAME, @SCRIPTLINE);
|
tap_ensure(@true == 1.0, 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
tap_ensure(@false == 0.0, 1, @SCRIPTNAME, @SCRIPTLINE);
|
tap_ensure(@false == 0.0, 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
tap_ensure(@true < 2.5, 1, @SCRIPTNAME, @SCRIPTLINE);
|
tap_ensure(@true < 2.5, 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
@@ -133,7 +138,6 @@ function main()
|
|||||||
tap_ensure(sprintf("%v", a), "<ARRAY>", @SCRIPTNAME, @SCRIPTLINE);
|
tap_ensure(sprintf("%v", a), "<ARRAY>", @SCRIPTNAME, @SCRIPTLINE);
|
||||||
tap_ensure(sprintf("%v", dummy), "<FUN:dummy>", @SCRIPTNAME, @SCRIPTLINE);
|
tap_ensure(sprintf("%v", dummy), "<FUN:dummy>", @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
|
||||||
print "AAAAAAA";
|
|
||||||
tap_ensure(@true - 20, -19, @SCRIPTNAME, @SCRIPTLINE);
|
tap_ensure(@true - 20, -19, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
tap_ensure(@false - 20, -20, @SCRIPTNAME, @SCRIPTLINE);
|
tap_ensure(@false - 20, -20, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
tap_ensure(@true + 20, 21, @SCRIPTNAME, @SCRIPTLINE);
|
tap_ensure(@true + 20, 21, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
|||||||
@@ -0,0 +1,46 @@
|
|||||||
|
@pragma implicit off
|
||||||
|
@pragma pedantic on
|
||||||
|
@pragma entry main
|
||||||
|
|
||||||
|
@include "tap.inc";
|
||||||
|
|
||||||
|
@global i;
|
||||||
|
|
||||||
|
function t(v)
|
||||||
|
{
|
||||||
|
i += 1;
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
@local a, b, c, d, e, f, g, h, j, k, l;
|
||||||
|
|
||||||
|
i = 0;
|
||||||
|
|
||||||
|
a = (0 || t(0));
|
||||||
|
b = i;
|
||||||
|
c = (1 || t(1));
|
||||||
|
d = i;
|
||||||
|
e = (1 && t(0));
|
||||||
|
f = i;
|
||||||
|
g = (0 && t(1));
|
||||||
|
h = i;
|
||||||
|
j = (1? t(10): t(20));
|
||||||
|
k = (0? t(30): t(40));
|
||||||
|
l = i;
|
||||||
|
|
||||||
|
tap_ensure(a, 0, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
tap_ensure(b, 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
tap_ensure(c, 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
tap_ensure(d, 1, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
tap_ensure(e, 0, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
tap_ensure(f, 2, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
tap_ensure(g, 0, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
tap_ensure(h, 2, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
tap_ensure(j, 10, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
tap_ensure(k, 40, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
tap_ensure(l, 4, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
tap_ensure(i, 4, @SCRIPTNAME, @SCRIPTLINE);
|
||||||
|
|
||||||
|
tap_end();
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user