841 lines
22 KiB
C
841 lines
22 KiB
C
/*
|
|
Copyright (c) 2006-2020 Chung, Hyung-Hwan. All rights reserved.
|
|
|
|
Redistribution and use in source and binary forms, with or without
|
|
modification, are permitted provided that the following conditions
|
|
are met:
|
|
1. Redistributions of source code must retain the above copyright
|
|
notice, this list of conditions and the following disclaimer.
|
|
2. Redistributions in binary form must reproduce the above copyright
|
|
notice, this list of conditions and the following disclaimer in the
|
|
documentation and/or other materials provided with the distribution.
|
|
|
|
THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
|
|
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
|
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
|
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
|
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
|
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
*/
|
|
|
|
#ifndef _HAWK_PRV_H_
|
|
#define _HAWK_PRV_H_
|
|
|
|
#include <hawk-cmn.h>
|
|
#include <hawk-arr.h>
|
|
#include <hawk-chr.h>
|
|
#include <hawk-ecs.h>
|
|
#include <hawk-fmt.h>
|
|
#include <hawk-htb.h>
|
|
#include <hawk-mtx.h>
|
|
#include <hawk-rbt.h>
|
|
#include <hawk-utl.h>
|
|
|
|
typedef struct hawk_chain_t hawk_chain_t;
|
|
typedef struct hawk_tree_t hawk_tree_t;
|
|
|
|
#include <hawk.h>
|
|
|
|
/* ------------------------------------------------------------------------ */
|
|
|
|
#define HAWK_ENABLE_GC
|
|
#define HAWK_ENABLE_STR_CACHE
|
|
#define HAWK_ENABLE_MBS_CACHE
|
|
|
|
/* [NOTE] the function value support implemented is very limited.
|
|
* it supports very primitive way to call a function via a variable.
|
|
* only user-defined functions are supported. neither builtin functions
|
|
* nor module functions are not supported yet.
|
|
* -----------------------------------------------------
|
|
* function x(a,b,c) { print a, b, c; }
|
|
* BEGIN { q = x; q(1, 2, 3); } # this works
|
|
* BEGIN { q[1]=x; q[1](1,2,3); } # this doesn't work. same as q[1] %% (1, 2, 3) or q[1] %% 3
|
|
* BEGIN { q[1]=x; y=q[1]; y(1,2,3); } # this works.
|
|
* -----------------------------------------------------
|
|
* function __printer(a,b,c) { print a, b, c; }
|
|
* function show(printer, a,b,c) { printer(a, b, c); }
|
|
* BEGIN { show(__printer, 10, 20, 30); } ## passing the function value as an argumnet is ok.
|
|
*/
|
|
#define HAWK_ENABLE_FUN_AS_VALUE
|
|
|
|
#if defined(HAWK_ATOMIC_EXCHANGE) && \
|
|
defined(HAWK_ATOMIC_FETCH_OR) && \
|
|
defined(HAWK_ATOMIC_LOAD) && \
|
|
defined(HAWK_ATOMIC_STORE)
|
|
#define HAWK_ENABLE_ATOMIC_SIG
|
|
#endif
|
|
|
|
/* this part is kept for preservation of experiment only.
|
|
#if defined(HAVE_UCONTEXT_H)
|
|
#include <ucontext.h>
|
|
#define HAWK_ENABLE_UCONTEXT
|
|
#endif
|
|
*/
|
|
|
|
/* Use iterative (heap-stack) expression evaluation instead of C recursion.
|
|
* eval_expression, eval_expression0, and hawk_rtx_evalcall automatically
|
|
* route through the xstack variants when this is defined. Comment out to
|
|
* revert to the purely recursive implementation. */
|
|
/*#define HAWK_ENABLE_XSTACK_EVAL*/
|
|
|
|
|
|
/* ------------------------------------------------------------------------ */
|
|
|
|
/* private headers. some files are affected by feature macros above */
|
|
#include "tree-prv.h"
|
|
#include "fnc-prv.h"
|
|
#include "parse-prv.h"
|
|
#include "run-prv.h"
|
|
#include "rio-prv.h"
|
|
#include "val-prv.h"
|
|
#include "err-prv.h"
|
|
#include "misc-prv.h"
|
|
|
|
|
|
/* ------------------------------------------------------------------------ */
|
|
|
|
/* gc configuration */
|
|
#define HAWK_GC_NUM_GENS (3)
|
|
|
|
/* string cache configuration */
|
|
#define HAWK_STR_CACHE_NUM_BLOCKS (16)
|
|
#define HAWK_STR_CACHE_BLOCK_UNIT (16)
|
|
#define HAWK_STR_CACHE_BLOCK_SIZE (128)
|
|
|
|
/* byte string cache configuration */
|
|
#define HAWK_MBS_CACHE_NUM_BLOCKS (16)
|
|
#define HAWK_MBS_CACHE_BLOCK_UNIT (16)
|
|
#define HAWK_MBS_CACHE_BLOCK_SIZE (128)
|
|
|
|
/* maximum number of globals, locals, parameters allowed in parsing.
|
|
* HAWK_MAX_LCLS must not exceed HAWK_TYPE_MAX(hawk_oohw_t) */
|
|
#define HAWK_MAX_GBLS (9999)
|
|
#define HAWK_MAX_LCLS (9999)
|
|
#define HAWK_MAX_PARAMS (9999)
|
|
#define HAWK_MAX_FUN_LEVEL (1024)
|
|
|
|
/* runtime stack limit */
|
|
#define HAWK_DFL_RTX_STACK_LIMIT (5120)
|
|
#define HAWK_MIN_RTX_STACK_LIMIT (512)
|
|
#if (HAWK_SIZEOF_VOID_P <= 4)
|
|
# define HAWK_MAX_RTX_STACK_LIMIT ((hawk_oow_t)1 << (HAWK_SIZEOF_VOID_P * 4 + 1))
|
|
#else
|
|
# define HAWK_MAX_RTX_STACK_LIMIT ((hawk_oow_t)1 << (HAWK_SIZEOF_VOID_P * 4))
|
|
#endif
|
|
|
|
/* Don't forget to grow HAWK_IDX_BUF_SIZE if hawk_int_t is very large */
|
|
#if (HAWK_SIZEOF_INT_T <= 16) /* 128 bits */
|
|
# define HAWK_IDX_BUF_SIZE 64
|
|
#elif (HAWK_SIZEOF_INT_T <= 32) /* 256 bits */
|
|
# define HAWK_IDX_BUF_SIZE 128
|
|
#elif (HAWK_SIZEOF_INT_T <= 64) /* 512 bits */
|
|
# define HAWK_IDX_BUF_SIZE 192
|
|
#elif (HAWK_SIZEOF_INT_T <= 128) /* 1024 bits */
|
|
# define HAWK_IDX_BUF_SIZE 384
|
|
#elif (HAWK_SIZEOF_INT_T <= 256) /* 2048 bits */
|
|
# define HAWK_IDX_BUF_SIZE 640
|
|
#else
|
|
# error unsupported. hawk_int_t too big
|
|
#endif
|
|
|
|
/* ------------------------------------------------------------------------ */
|
|
|
|
|
|
#define HAWK_BYTE_PRINTABLE(x) ((x) <= 0x7F && (x) != '\\' && hawk_is_bch_print(x))
|
|
|
|
#if defined(__has_builtin)
|
|
|
|
# if (!__has_builtin(__builtin_memset) || !__has_builtin(__builtin_memcpy) || !__has_builtin(__builtin_memmove) || !__has_builtin(__builtin_memcmp))
|
|
# include <string.h>
|
|
# endif
|
|
|
|
# if __has_builtin(__builtin_memset)
|
|
# define HAWK_MEMSET(dst,src,size) __builtin_memset(dst,src,size)
|
|
# else
|
|
# define HAWK_MEMSET(dst,src,size) memset(dst,src,size)
|
|
# endif
|
|
# if __has_builtin(__builtin_memcpy)
|
|
# define HAWK_MEMCPY(dst,src,size) __builtin_memcpy(dst,src,size)
|
|
# else
|
|
# define HAWK_MEMCPY(dst,src,size) memcpy(dst,src,size)
|
|
# endif
|
|
# if __has_builtin(__builtin_memmove)
|
|
# define HAWK_MEMMOVE(dst,src,size) __builtin_memmove(dst,src,size)
|
|
# else
|
|
# define HAWK_MEMMOVE(dst,src,size) memmove(dst,src,size)
|
|
# endif
|
|
# if __has_builtin(__builtin_memcmp)
|
|
# define HAWK_MEMCMP(dst,src,size) __builtin_memcmp(dst,src,size)
|
|
# else
|
|
# define HAWK_MEMCMP(dst,src,size) memcmp(dst,src,size)
|
|
# endif
|
|
|
|
#else
|
|
|
|
/* g++ 2.95 had a problem with __builtin_memxxx functions:
|
|
* implicit declaration of function `int HAWK::__builtin_memset(...)' */
|
|
# if defined(__cplusplus) && defined(__GNUC__) && (__GNUC__ <= 2)
|
|
# undef HAVE___BUILTIN_MEMSET
|
|
# undef HAVE___BUILTIN_MEMCPY
|
|
# undef HAVE___BUILTIN_MEMMOVE
|
|
# undef HAVE___BUILTIN_MEMCMP
|
|
# endif
|
|
|
|
# if !defined(HAVE___BUILTIN_MEMSET) || \
|
|
!defined(HAVE___BUILTIN_MEMCPY) || \
|
|
!defined(HAVE___BUILTIN_MEMMOVE) || \
|
|
!defined(HAVE___BUILTIN_MEMCMP)
|
|
# include <string.h>
|
|
# endif
|
|
|
|
# if defined(HAVE___BUILTIN_MEMSET)
|
|
# define HAWK_MEMSET(dst,src,size) __builtin_memset(dst,src,size)
|
|
# else
|
|
# define HAWK_MEMSET(dst,src,size) memset(dst,src,size)
|
|
# endif
|
|
# if defined(HAVE___BUILTIN_MEMCPY)
|
|
# define HAWK_MEMCPY(dst,src,size) __builtin_memcpy(dst,src,size)
|
|
# else
|
|
# define HAWK_MEMCPY(dst,src,size) memcpy(dst,src,size)
|
|
# endif
|
|
# if defined(HAVE___BUILTIN_MEMMOVE)
|
|
# define HAWK_MEMMOVE(dst,src,size) __builtin_memmove(dst,src,size)
|
|
# else
|
|
# define HAWK_MEMMOVE(dst,src,size) memmove(dst,src,size)
|
|
# endif
|
|
# if defined(HAVE___BUILTIN_MEMCMP)
|
|
# define HAWK_MEMCMP(dst,src,size) __builtin_memcmp(dst,src,size)
|
|
# else
|
|
# define HAWK_MEMCMP(dst,src,size) memcmp(dst,src,size)
|
|
# endif
|
|
|
|
#endif
|
|
|
|
struct hawk_tree_t
|
|
{
|
|
hawk_oow_t ngbls; /* total number of globals */
|
|
hawk_oow_t ngbls_base; /* number of intrinsic globals */
|
|
hawk_oocs_t cur_fun;
|
|
hawk_htb_t* funs; /* hawk function map */
|
|
hawk_arr_t* ifuns; /* inline function list */
|
|
|
|
hawk_nde_t* init; /* internally generated block made of @global/@const initilization */
|
|
hawk_nde_t* init_tail;
|
|
|
|
hawk_nde_t* begin;
|
|
hawk_nde_t* begin_tail;
|
|
|
|
hawk_nde_t* end;
|
|
hawk_nde_t* end_tail;
|
|
|
|
hawk_chain_t* chain;
|
|
hawk_chain_t* chain_tail;
|
|
hawk_oow_t chain_size; /* number of nodes in the chain */
|
|
|
|
int ok;
|
|
};
|
|
|
|
typedef struct hawk_tok_t hawk_tok_t;
|
|
struct hawk_tok_t
|
|
{
|
|
int type;
|
|
int flags;
|
|
hawk_ooecs_t* name;
|
|
hawk_loc_t loc;
|
|
};
|
|
|
|
struct hawk_sbuf_t
|
|
{
|
|
hawk_ooch_t* ptr;
|
|
hawk_oow_t len;
|
|
hawk_oow_t capa;
|
|
};
|
|
typedef struct hawk_sbuf_t hawk_sbuf_t;
|
|
|
|
struct hawk_t
|
|
{
|
|
/* exposed fields via hawk_alt_t */
|
|
HAWK_HDR;
|
|
|
|
/* primitive functions */
|
|
hawk_prm_t prm;
|
|
|
|
/* options */
|
|
struct
|
|
{
|
|
int trait;
|
|
hawk_oocs_t mod[3];
|
|
hawk_oocs_t includedirs;
|
|
|
|
union
|
|
{
|
|
hawk_oow_t a[7]; /**< to access the elements of the #s field as an array */
|
|
struct
|
|
{
|
|
hawk_oow_t incl;
|
|
hawk_oow_t block_parse;
|
|
hawk_oow_t block_run;
|
|
hawk_oow_t expr_parse;
|
|
hawk_oow_t expr_run;
|
|
hawk_oow_t rex_build;
|
|
hawk_oow_t rex_match;
|
|
} s; /**< defines the maximum nesting depths */
|
|
} depth;
|
|
|
|
hawk_oow_t rtx_stack_limit;
|
|
hawk_oow_t log_mask;
|
|
hawk_oow_t log_maxcapa;
|
|
} opt;
|
|
|
|
/* some temporary workspace */
|
|
hawk_sbuf_t sbuf[HAWK_SBUF_COUNT];
|
|
|
|
/* parse tree */
|
|
hawk_tree_t tree;
|
|
|
|
/* temporary information that the parser needs */
|
|
struct
|
|
{
|
|
struct
|
|
{
|
|
int block;
|
|
int loop;
|
|
int stmt; /* statement */
|
|
} id;
|
|
|
|
struct
|
|
{
|
|
hawk_oow_t block;
|
|
hawk_oow_t loop;
|
|
hawk_oow_t expr; /* expression */
|
|
hawk_oow_t incl;
|
|
hawk_oow_t swtch; /* switch */
|
|
} depth;
|
|
|
|
/* current pragma values */
|
|
struct
|
|
{
|
|
int trait;
|
|
hawk_oow_t rtx_stack_limit;
|
|
hawk_ooch_t entry[128];
|
|
} pragma;
|
|
|
|
/* function calls */
|
|
hawk_htb_t* funs;
|
|
|
|
/* named variables */
|
|
hawk_htb_t* named;
|
|
|
|
/* parser-known named variables in slot order */
|
|
hawk_arr_t* nameds;
|
|
|
|
/* global variables */
|
|
hawk_arr_t* gbls;
|
|
|
|
/* local variables */
|
|
hawk_arr_t* lcls;
|
|
|
|
/* parameters to a function */
|
|
hawk_arr_t* params;
|
|
|
|
/* some information required to handle nested function literals */
|
|
hawk_ooi_t fun_level;
|
|
hawk_oow_t lcl_bases[HAWK_MAX_FUN_LEVEL];
|
|
hawk_oow_t param_bases[HAWK_MAX_FUN_LEVEL];
|
|
hawk_oow_t lcl_base;
|
|
hawk_oow_t param_base;
|
|
|
|
/* maximum number of local variables */
|
|
hawk_oow_t nlcls_max;
|
|
|
|
/* some data to find if an expression is
|
|
* enclosed in parentheses or not.
|
|
* see parse_primary_lparen() and parse_print() in parse.c
|
|
*/
|
|
hawk_oow_t lparen_seq;
|
|
hawk_oow_t lparen_last_closed;
|
|
|
|
struct
|
|
{
|
|
hawk_uint8_t* ptr;
|
|
hawk_oow_t count;
|
|
hawk_oow_t capa;
|
|
} incl_hist;
|
|
} parse;
|
|
|
|
/* source code management */
|
|
struct
|
|
{
|
|
hawk_sio_impl_t inf;
|
|
hawk_sio_impl_t outf;
|
|
|
|
hawk_sio_lxc_t last;
|
|
|
|
hawk_oow_t nungots;
|
|
hawk_sio_lxc_t ungot[5];
|
|
|
|
hawk_sio_arg_t arg; /* for the top level source */
|
|
hawk_sio_arg_t* inp; /* current input argument. */
|
|
} sio;
|
|
hawk_link_t* sio_names;
|
|
|
|
/* previous token */
|
|
hawk_tok_t ptok;
|
|
/* current token */
|
|
hawk_tok_t tok;
|
|
/* look-ahead token */
|
|
hawk_tok_t ntok;
|
|
|
|
/* intrinsic functions */
|
|
struct
|
|
{
|
|
hawk_fnc_t* sys;
|
|
hawk_htb_t* user;
|
|
} fnc;
|
|
|
|
struct
|
|
{
|
|
hawk_ooch_t fmt[1024];
|
|
} tmp;
|
|
|
|
/* housekeeping */
|
|
hawk_ooch_t errmsg_backup[HAWK_ERRMSG_CAPA];
|
|
|
|
struct
|
|
{
|
|
hawk_ooch_t* ptr;
|
|
hawk_oow_t len;
|
|
hawk_oow_t capa;
|
|
hawk_bitmask_t last_mask;
|
|
hawk_bitmask_t default_type_mask;
|
|
} log;
|
|
int shuterr;
|
|
|
|
int haltall;
|
|
hawk_ecb_t* ecb;
|
|
|
|
hawk_htb_t* static_mods; /* per-instance static modules */
|
|
hawk_rbt_t* modtab; /* resolved modules at compile-time. rtx specific one is at rtx->modtab */
|
|
hawk_mtx_t* modmtx;
|
|
};
|
|
|
|
struct hawk_chain_t
|
|
{
|
|
hawk_nde_t* pattern;
|
|
hawk_nde_t* action;
|
|
hawk_chain_t* next;
|
|
};
|
|
|
|
typedef struct hawk_ctos_b_t hawk_ctos_b_t;
|
|
struct hawk_ctos_b_t
|
|
{
|
|
hawk_oochu_t c[2]; /* ensure the unsigned type to hold not only a character but also a free slot index */
|
|
};
|
|
|
|
typedef struct hawk_bctos_b_t hawk_bctos_b_t;
|
|
struct hawk_bctos_b_t
|
|
{
|
|
hawk_bchu_t c[2]; /* ensure the unsigned type to hold not only a byte character but also a free slot index */
|
|
};
|
|
|
|
|
|
typedef struct hawk_var_xinfo_t hawk_var_xinfo_t;
|
|
struct hawk_var_xinfo_t
|
|
{
|
|
hawk_uint8_t used;
|
|
hawk_uint8_t is_const;
|
|
hawk_loc_t loc;
|
|
};
|
|
|
|
struct hawk_exec_stack_t
|
|
{
|
|
int state;
|
|
hawk_nde_t* nde;
|
|
hawk_nde_t* ptr; /* next statement in block (EXEC_STATE_BLK_STEP) */
|
|
hawk_oow_t iv; /* current forin index (EXEC_STATE_FORIN_*) */
|
|
hawk_oow_t base; /* forin snapshot base (EXEC_STATE_FORIN_*) */
|
|
};
|
|
|
|
typedef struct hawk_exec_stack_t hawk_exec_stack_t;
|
|
|
|
/* expression frame states for eval_expression0_xstack */
|
|
enum hawk_ef_state_t
|
|
{
|
|
HAWK_EF_EVAL = 0, /* dispatch on nde->type */
|
|
HAWK_EF_BIN_LEFT, /* binary: awaiting left result */
|
|
HAWK_EF_BIN_RIGHT, /* binary: left done (val=left refupped), awaiting right */
|
|
HAWK_EF_UNARY, /* unary: awaiting operand result */
|
|
HAWK_EF_CND, /* conditional: awaiting test result */
|
|
HAWK_EF_ASS_RHS, /* assignment: awaiting RHS result */
|
|
HAWK_EF_ASS_LHS, /* compound assign: RHS in val (refupped), awaiting LHS */
|
|
HAWK_EF_LAND_LEFT, /* logical AND: awaiting left result */
|
|
HAWK_EF_LAND_RIGHT, /* logical AND: left done and true (val=left), awaiting right */
|
|
HAWK_EF_LOR_LEFT, /* logical OR: awaiting left result */
|
|
HAWK_EF_LOR_RIGHT, /* logical OR: left done and false (val=left), awaiting right */
|
|
#if defined(HAWK_ENABLE_XSTACK_EVAL)
|
|
HAWK_EF_FNCALL_FUN_AWAIT /* user fn body executing on exec_stack; aux=exec_body_base */
|
|
#endif
|
|
};
|
|
typedef enum hawk_ef_state_t hawk_ef_state_t;
|
|
|
|
struct hawk_eframe_t
|
|
{
|
|
hawk_ef_state_t state;
|
|
hawk_nde_t* nde; /* composite node being processed */
|
|
hawk_val_t* val; /* intermediate value (refcount incremented) */
|
|
hawk_oow_t aux; /* FNCALL_FUN_AWAIT: exec_stack size when body frames were pushed */
|
|
};
|
|
typedef struct hawk_eframe_t hawk_eframe_t;
|
|
|
|
#if defined(HAWK_ENABLE_XSTACK_EVAL)
|
|
/* call frame: saves context for a user-defined function call made from within
|
|
* expression evaluation. stored in the call_stack. */
|
|
struct hawk_call_frame_t
|
|
{
|
|
hawk_nde_fncall_t* call; /* call-site node */
|
|
hawk_fun_t* fun; /* resolved function */
|
|
hawk_oow_t saved_stack_top; /* rtx->stack_top before the call */
|
|
hawk_oow_t saved_stack_base;/* rtx->stack_base before the call */
|
|
hawk_oow_t nargs; /* actual argument count pushed */
|
|
};
|
|
typedef struct hawk_call_frame_t hawk_call_frame_t;
|
|
#endif
|
|
|
|
struct hawk_rtx_t
|
|
{
|
|
HAWK_RTX_HDR;
|
|
|
|
hawk_htb_t* named;
|
|
hawk_val_t** named_slots;
|
|
hawk_oow_t named_slot_count;
|
|
hawk_oow_t named_slot_capa;
|
|
|
|
void** stack;
|
|
hawk_oow_t stack_top;
|
|
hawk_oow_t stack_base;
|
|
hawk_oow_t stack_limit;
|
|
|
|
/* heap-based stack for iterative statement execution */
|
|
hawk_exec_stack_t* exec_stack;
|
|
hawk_oow_t exec_stack_size;
|
|
hawk_oow_t exec_stack_limit;
|
|
|
|
/* heap-based stack for iterative expression evaluation (xstack variant) */
|
|
hawk_eframe_t* eframe_stack;
|
|
hawk_oow_t eframe_stack_size;
|
|
hawk_oow_t eframe_stack_limit;
|
|
|
|
#if defined(HAWK_ENABLE_XSTACK_EVAL)
|
|
/* heap-based call frame stack: user-defined function calls from eframe evaluation */
|
|
hawk_call_frame_t* call_stack;
|
|
hawk_oow_t call_stack_size;
|
|
hawk_oow_t call_stack_limit;
|
|
/* result register: eframe eval result delivered to exec AFTER_EVAL frames */
|
|
hawk_val_t* driver_eval_result;
|
|
#endif
|
|
|
|
#if defined(HAWK_ENABLE_UCONTEXT)
|
|
/* pool of reusable C stacks for coroutine-based function calls */
|
|
struct
|
|
{
|
|
char* pool[16];
|
|
hawk_oow_t pool_size;
|
|
/* arguments for the next coroutine invocation */
|
|
hawk_nde_blk_t* pending_body;
|
|
int* pending_result;
|
|
/* depth at which the current C stack segment started */
|
|
hawk_oow_t stack_base;
|
|
/* nonzero when executing on a heap-allocated coroutine stack */
|
|
int in_coroutine;
|
|
} co;
|
|
#endif
|
|
|
|
int exit_level;
|
|
int init_called;
|
|
|
|
hawk_val_ref_t* rcache[128];
|
|
hawk_oow_t rcache_count;
|
|
|
|
#if defined(HAWK_ENABLE_STR_CACHE)
|
|
hawk_val_str_t* str_cache[HAWK_STR_CACHE_NUM_BLOCKS][HAWK_STR_CACHE_BLOCK_SIZE];
|
|
hawk_oow_t str_cache_count[HAWK_STR_CACHE_NUM_BLOCKS];
|
|
#endif
|
|
|
|
#if defined(HAWK_ENABLE_MBS_CACHE)
|
|
hawk_val_mbs_t* mbs_cache[HAWK_MBS_CACHE_NUM_BLOCKS][HAWK_MBS_CACHE_BLOCK_SIZE];
|
|
hawk_oow_t mbs_cache_count[HAWK_MBS_CACHE_NUM_BLOCKS];
|
|
#endif
|
|
|
|
struct
|
|
{
|
|
hawk_val_int_t* ifree;
|
|
hawk_val_chunk_t* ichunk;
|
|
hawk_val_flt_t* rfree;
|
|
hawk_val_chunk_t* rchunk;
|
|
} vmgr;
|
|
|
|
struct
|
|
{
|
|
#if defined(HAWK_OOCH_IS_UCH)
|
|
hawk_ctos_b_t b[512];
|
|
#else
|
|
hawk_ctos_b_t b[256]; /* it must not be larger than 256 */
|
|
#endif
|
|
hawk_oow_t fi;
|
|
} ctos; /* char/nil to string conversion */
|
|
|
|
struct
|
|
{
|
|
hawk_bctos_b_t b[256];
|
|
hawk_oow_t fi;
|
|
} bctos;
|
|
|
|
struct
|
|
{
|
|
/* lists of values under gc management */
|
|
hawk_gch_t g[HAWK_GC_NUM_GENS];
|
|
|
|
/*
|
|
* Pressure imposed on each generation before gc is triggered
|
|
* pressure[0] - number of allocation attempt since the last gc
|
|
* pressure[N] - nubmer of collections performed for generation N - 1.
|
|
*/
|
|
hawk_oow_t pressure[HAWK_GC_NUM_GENS + 1];
|
|
|
|
/* threshold to trigger generational collection. */
|
|
hawk_oow_t threshold[HAWK_GC_NUM_GENS];
|
|
} gc;
|
|
|
|
hawk_nde_blk_t* active_block;
|
|
hawk_uint8_t* pattern_range_state;
|
|
|
|
struct
|
|
{
|
|
hawk_ooch_t buf[1024];
|
|
hawk_oow_t buf_pos;
|
|
hawk_oow_t buf_len;
|
|
int eof;
|
|
|
|
hawk_ooecs_t line; /* entire line */
|
|
hawk_ooecs_t linew; /* line for manipulation, if necessary */
|
|
hawk_ooecs_t lineg; /* line buffer for getline */
|
|
hawk_becs_t linegb; /* line buffer for getline mbs */
|
|
|
|
hawk_val_t* d0; /* $0 */
|
|
|
|
hawk_oow_t maxflds;
|
|
hawk_oow_t nflds; /* NF */
|
|
struct
|
|
{
|
|
const hawk_ooch_t* ptr;
|
|
hawk_oow_t len;
|
|
hawk_val_t* val; /* $1 .. $NF */
|
|
}* flds;
|
|
} inrec;
|
|
|
|
hawk_nrflt_t nrflt;
|
|
|
|
struct
|
|
{
|
|
void* rs[2];
|
|
void* fs[2];
|
|
hawk_int8_t ignorecase;
|
|
hawk_int8_t striprecspc;
|
|
hawk_int8_t stripstrspc;
|
|
hawk_int8_t numstrdetect;
|
|
hawk_int8_t pipecloexec;
|
|
|
|
hawk_int_t nr;
|
|
hawk_int_t fnr;
|
|
|
|
hawk_oocs_t convfmt;
|
|
hawk_oocs_t ofmt;
|
|
hawk_oocs_t ofs;
|
|
hawk_oocs_t ors;
|
|
hawk_oocs_t subsep;
|
|
} gbl;
|
|
|
|
/* rio chain */
|
|
struct
|
|
{
|
|
hawk_rio_impl_t handler[HAWK_RIO_NUM];
|
|
hawk_rtx_env_mk_t env_mk;
|
|
hawk_rio_arg_t* chain;
|
|
} rio;
|
|
|
|
struct
|
|
{
|
|
hawk_ooecs_t fmt;
|
|
hawk_ooecs_t out;
|
|
|
|
/* some buffers used by val_flt_to_str() */
|
|
hawk_ooecs_t fltfmt;
|
|
hawk_ooecs_t fltout;
|
|
|
|
struct
|
|
{
|
|
hawk_ooch_t* ptr;
|
|
hawk_oow_t len; /* length */
|
|
hawk_oow_t inc; /* increment */
|
|
} tmp;
|
|
} format;
|
|
|
|
struct
|
|
{
|
|
hawk_becs_t fmt;
|
|
hawk_becs_t out;
|
|
|
|
struct
|
|
{
|
|
hawk_bch_t* ptr;
|
|
hawk_oow_t len; /* length */
|
|
hawk_oow_t inc; /* increment */
|
|
} tmp;
|
|
} formatmbs;
|
|
|
|
struct
|
|
{
|
|
hawk_becs_t bout;
|
|
hawk_ooecs_t oout;
|
|
} fnc; /* output buffer simple functions like gsub, sub, match*/
|
|
|
|
struct
|
|
{
|
|
hawk_oow_t block;
|
|
hawk_oow_t expr; /* expression */
|
|
} depth;
|
|
|
|
struct
|
|
{
|
|
hawk_val_t** ptr;
|
|
hawk_oow_t size;
|
|
hawk_oow_t capa;
|
|
} forin; /* keys for for (x in y) ... */
|
|
|
|
#define HAWK_SIG_WORD_BITS (HAWK_SIZEOF_UINTPTR_T * 8)
|
|
#define HAWK_SIG_WORD_COUNT ((HAWK_NSIG + HAWK_SIG_WORD_BITS - 1) / HAWK_SIG_WORD_BITS)
|
|
|
|
hawk_fun_t* sig_handler[HAWK_NSIG];
|
|
int sig_handling;
|
|
#if defined(HAWK_ENABLE_ATOMIC_SIG)
|
|
hawk_uintptr_t sig_pending[HAWK_SIG_WORD_COUNT];
|
|
hawk_uintptr_t sig_pending_any;
|
|
#else
|
|
hawk_mtx_t sig_mtx;
|
|
int sig_mtx_inited;
|
|
int sig_pending_any;
|
|
struct
|
|
{
|
|
int count;
|
|
int tab[HAWK_NSIG];
|
|
int pos[HAWK_NSIG];
|
|
} sig_raise[2];
|
|
#endif
|
|
|
|
hawk_ooch_t errmsg_backup[HAWK_ERRMSG_CAPA];
|
|
hawk_rtx_ecb_t* ecb;
|
|
hawk_oow_t ecb_stmt_count;
|
|
hawk_oow_t ecb_gblset_count;
|
|
|
|
hawk_rbt_t* modtab; /* rtx-specifi module table in addition to hawk->modtab */
|
|
};
|
|
|
|
typedef struct hawk_mod_data_t hawk_mod_data_t;
|
|
struct hawk_mod_data_t
|
|
{
|
|
void* handle;
|
|
hawk_mod_t mod;
|
|
};
|
|
|
|
|
|
#define HAWK_RTX_STACK_AT(rtx,n) ((rtx)->stack[(rtx)->stack_base+(n)])
|
|
#define HAWK_RTX_STACK_NARGS(rtx) HAWK_RTX_STACK_AT(rtx,3)
|
|
#define HAWK_RTX_STACK_ARG(rtx,n) HAWK_RTX_STACK_AT(rtx,3+1+(n))
|
|
#define HAWK_RTX_STACK_LCL(rtx,n) HAWK_RTX_STACK_AT(rtx,3+(hawk_oow_t)HAWK_RTX_STACK_NARGS(rtx)+1+(n))
|
|
#define HAWK_RTX_STACK_RETVAL(rtx) HAWK_RTX_STACK_AT(rtx,2)
|
|
#define HAWK_RTX_STACK_GBL(rtx,n) ((rtx)->stack[(n)])
|
|
#define HAWK_RTX_STACK_NAMED(rtx,n) ((rtx)->named_slots[(n)])
|
|
#define HAWK_RTX_STACK_RETVAL_GBL(rtx) ((rtx)->stack[(rtx)->hawk->tree.ngbls+2])
|
|
|
|
#define HAWK_RTX_STACK_AVAIL(rtx) ((rtx)->stack_limit - (rtx)->stack_top)
|
|
|
|
#if defined(HAWK_HAVE_INLINE)
|
|
static HAWK_INLINE void HAWK_RTX_STACK_PUSH (hawk_rtx_t* rtx, hawk_val_t* val)
|
|
{
|
|
/*HAWK_ASSERT (rtx->stack_top < rtx->stack_limit);*/
|
|
rtx->stack[rtx->stack_top++] = val;
|
|
}
|
|
|
|
static HAWK_INLINE void HAWK_RTX_STACK_POP (hawk_rtx_t* rtx)
|
|
{
|
|
/*HAWK_ASSERT (rtx->stack_top > rtx->stack_base);*/
|
|
rtx->stack_top--;
|
|
}
|
|
#else
|
|
#define HAWK_RTX_STACK_PUSH(rtx,val) ((rtx)->stack[(rtx)->stack_top++] = val)
|
|
#define HAWK_RTX_STACK_POP(rtx) ((rtx)->stack_top--)
|
|
#endif
|
|
|
|
#define HAWK_RTX_INIT_REF_VAL(refval, _id, _adr, _nrefs) \
|
|
do { \
|
|
(refval)->v_refs = (_nrefs); \
|
|
(refval)->v_type = HAWK_VAL_REF; \
|
|
(refval)->v_static = 0; \
|
|
(refval)->v_nstr = 0; \
|
|
(refval)->v_gc = 0; \
|
|
(refval)->id = (_id); \
|
|
(refval)->adr = (_adr); \
|
|
} while(0);
|
|
|
|
|
|
#define HAWK_RTX_IS_NUMSTRDETECT_ON(rtx) ((rtx)->gbl.numstrdetect > 0 || ((rtx)->gbl.numstrdetect < 0 && ((rtx)->hawk->parse.pragma.trait & HAWK_NUMSTRDETECT)))
|
|
#define HAWK_RTX_IS_PIPECLOEXEC_ON(rtx) ((rtx)->gbl.pipecloexec > 0 || ((rtx)->gbl.pipecloexec < 0 && ((rtx)->hawk->parse.pragma.trait & HAWK_PIPECLOEXEC)))
|
|
#define HAWK_RTX_IS_STRIPRECSPC_ON(rtx) ((rtx)->gbl.striprecspc > 0 || ((rtx)->gbl.striprecspc < 0 && ((rtx)->hawk->parse.pragma.trait & HAWK_STRIPRECSPC)))
|
|
#define HAWK_RTX_IS_STRIPSTRSPC_ON(rtx) ((rtx)->gbl.stripstrspc > 0 || ((rtx)->gbl.stripstrspc < 0 && ((rtx)->hawk->parse.pragma.trait & HAWK_STRIPSTRSPC)))
|
|
|
|
#if !defined(HAWK_DEFAULT_MODLIBDIRS)
|
|
# define HAWK_DEFAULT_MODLIBDIRS ""
|
|
#endif
|
|
|
|
#if !defined(HAWK_DEFAULT_MODPREFIX)
|
|
# if defined(_WIN32)
|
|
# define HAWK_DEFAULT_MODPREFIX "hawk-"
|
|
# elif defined(__OS2__)
|
|
# define HAWK_DEFAULT_MODPREFIX "hawk"
|
|
# elif defined(__DOS__)
|
|
# define HAWK_DEFAULT_MODPREFIX "hawk"
|
|
# else
|
|
# define HAWK_DEFAULT_MODPREFIX "libhawk-"
|
|
# endif
|
|
#endif
|
|
|
|
#if !defined(HAWK_DEFAULT_MODPOSTFIX)
|
|
# define HAWK_DEFAULT_MODPOSTFIX ""
|
|
#endif
|
|
|
|
#if defined(__cplusplus)
|
|
extern "C" {
|
|
#endif
|
|
|
|
int hawk_init (hawk_t* hawk, hawk_mmgr_t* mmgr, hawk_cmgr_t* cmgr, const hawk_prm_t* prm);
|
|
void hawk_fini (hawk_t* hawk);
|
|
|
|
hawk_rbt_walk_t hawk_modtab_unload_module (hawk_rbt_t* rbt, hawk_rbt_pair_t* pair, void* ctx);
|
|
int hawk_rtx_setnamedval (hawk_rtx_t* rtx, hawk_oow_t id, hawk_val_t* val);
|
|
|
|
void* hawk_rtx_commit_environ (
|
|
hawk_rtx_t* rtx,
|
|
int gbl_id,
|
|
hawk_rtx_env_mk_type_t env_mk_type
|
|
);
|
|
|
|
#if defined(__cplusplus)
|
|
}
|
|
#endif
|
|
|
|
#endif
|