Compare commits

...

8 Commits

Author SHA1 Message Date
hyung-hwan b0a0746f02 added some missing atomic macro checks
continuous-integration/drone/push Build is passing
2026-03-01 15:10:24 +09:00
hyung-hwan eab345b1e2 fixed some go code issues 2026-02-26 01:08:06 +09:00
hyung-hwan b79c24dd17 implemented bc for && and || 2026-02-26 01:08:06 +09:00
hyung-hwan 0d312f57bf implemented bc for some simple flow control statements 2026-02-26 01:08:06 +09:00
hyung-hwan 36bf278632 added STORE_POP 2026-02-26 01:08:06 +09:00
hyung-hwan 06655bccde some simple handling for inc/dec op 2026-02-26 01:08:06 +09:00
hyung-hwan 830945ab51 added more instructions and a bytecode dumper 2026-02-26 01:08:06 +09:00
hyung-hwan 407713e7a3 initial code to implement bytecode vm 2026-02-26 01:08:06 +09:00
21 changed files with 2044 additions and 175 deletions
+5
View File
@@ -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
View File
@@ -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() }
+18 -11
View File
@@ -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
View File
@@ -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
+86
View File
@@ -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
View File
@@ -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';
+9
View File
@@ -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
View File
File diff suppressed because it is too large Load Diff
+483 -5
View File
@@ -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;
+6 -2
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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);
+46
View File
@@ -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();
}