diff --git a/bin/hawk.c b/bin/hawk.c index 4b189561..27c94ba1 100644 --- a/bin/hawk.c +++ b/bin/hawk.c @@ -31,6 +31,13 @@ #include #include +#if !defined(_GNU_SOURCE) +# define _GNU_SOURCE +#endif +#if !defined(_XOPEN_SOURCE) +# define _XOPEN_SOURCE 700 +#endif + #include #include #include @@ -38,7 +45,7 @@ #include #include -// #define ENABLE_CALLBACK TODO: enable this back +/* #define ENABLE_CALLBACK TODO: enable this back */ #define ABORT(label) goto label #if defined(_WIN32) @@ -436,7 +443,7 @@ static void dprint_return (hawk_rtx_t* rtx, hawk_val_t* ret) } else { - str = hawk_rtx_valtooocstrdup (rtx, ret, &len); + str = hawk_rtx_valtooocstrdup(rtx, ret, &len); if (str == HAWK_NULL) { hawk_logfmt (hawk, HAWK_LOG_STDERR,HAWK_T("[RETURN] - ***OUT OF MEMORY***\n")); diff --git a/bin/sed.c b/bin/sed.c index cdffaf15..5cb5a1e4 100644 --- a/bin/sed.c +++ b/bin/sed.c @@ -31,6 +31,13 @@ #include #include +#if !defined(_GNU_SOURCE) +# define _GNU_SOURCE +#endif +#if !defined(_XOPEN_SOURCE) +# define _XOPEN_SOURCE 700 +#endif + #include #include #include diff --git a/lib/gem-nwif.c b/lib/gem-nwif.c index 773e9932..c9ba9eb3 100644 --- a/lib/gem-nwif.c +++ b/lib/gem-nwif.c @@ -31,6 +31,9 @@ #elif defined(__DOS__) /* TODO: */ #else +# if !defined(_GNU_SOURCE) +# define _GNU_SOURCE +# endif # include "syscall.h" # include # if defined(HAVE_SYS_IOCTL_H) @@ -152,7 +155,7 @@ int hawk_gem_bcstrtoifindex (hawk_gem_t* gem, const hawk_bch_t* ptr, unsigned in if (x >= 0) { - #if defined(HAVE_STRUCT_IFREQ_IFR_IFINDEX) + #if defined(HAVE_STRUCT_IFREQ_IFR_IFINDEX) || defined(ifr_ifindex) *index = ifr.ifr_ifindex; #else *index = ifr.ifr_index; @@ -242,7 +245,7 @@ int hawk_gem_bcharstoifindex (hawk_gem_t* gem, const hawk_bch_t* ptr, hawk_oow_t if (x >= 0) { - #if defined(HAVE_STRUCT_IFREQ_IFR_IFINDEX) + #if defined(HAVE_STRUCT_IFREQ_IFR_IFINDEX) || defined(ifr_ifindex) *index = ifr.ifr_ifindex; #else *index = ifr.ifr_index; @@ -326,7 +329,7 @@ int hawk_gem_ucstrtoifindex (hawk_gem_t* gem, const hawk_uch_t* ptr, unsigned in if (x >= 0) { - #if defined(HAVE_STRUCT_IFREQ_IFR_IFINDEX) + #if defined(HAVE_STRUCT_IFREQ_IFR_IFINDEX) || defined(ifr_ifindex) *index = ifr.ifr_ifindex; #else *index = ifr.ifr_index; @@ -419,7 +422,7 @@ int hawk_gem_ucharstoifindex (hawk_gem_t* gem, const hawk_uch_t* ptr, hawk_oow_t if (x >= 0) { - #if defined(HAVE_STRUCT_IFREQ_IFR_IFINDEX) + #if defined(HAVE_STRUCT_IFREQ_IFR_IFINDEX) || defined(ifr_ifindex) *index = ifr.ifr_ifindex; #else *index = ifr.ifr_index; @@ -506,7 +509,7 @@ int hawk_gem_ifindextobcstr (hawk_gem_t* gem, unsigned int index, hawk_bch_t* bu } HAWK_MEMSET (&ifr, 0, HAWK_SIZEOF(ifr)); - #if defined(HAVE_STRUCT_IFREQ_IFR_IFINDEX) + #if defined(HAVE_STRUCT_IFREQ_IFR_IFINDEX) || defined(ifr_ifindex) ifr.ifr_ifindex = index; #else ifr.ifr_index = index; @@ -587,7 +590,7 @@ int hawk_gem_ifindextoucstr (hawk_gem_t* gem, unsigned int index, hawk_uch_t* bu } HAWK_MEMSET (&ifr, 0, HAWK_SIZEOF(ifr)); - #if defined(HAVE_STRUCT_IFREQ_IFR_IFINDEX) + #if defined(HAVE_STRUCT_IFREQ_IFR_IFINDEX) || defined(ifr_ifindex) ifr.ifr_ifindex = index; #else ifr.ifr_index = index; diff --git a/lib/gem-nwif2.c b/lib/gem-nwif2.c index 926c888c..5eda25e8 100644 --- a/lib/gem-nwif2.c +++ b/lib/gem-nwif2.c @@ -23,6 +23,8 @@ */ #if 1 + +#define _GNU_SOURCE #include "hawk-prv.h" #include "skad-prv.h" #include @@ -50,6 +52,9 @@ #elif defined(__DOS__) /* TODO: */ #else +# if !defined(_GNU_SOURCE) +# define _GNU_SOURCE +# endif # include "syscall.h" # include # include @@ -639,7 +644,7 @@ static int get_ifcfg (hawk_gem_t* gem, int s, hawk_ifcfg_t* cfg, struct ifreq* i return -1; } - #if defined(HAVE_STRUCT_IFREQ_IFR_IFINDEX) + #if defined(HAVE_STRUCT_IFREQ_IFR_IFINDEX) || defined(ifr_ifindex) cfg->index = ifr->ifr_ifindex; #else cfg->index = ifr->ifr_index; diff --git a/lib/hawk-cmn.h b/lib/hawk-cmn.h index 54212c57..b0d35f28 100644 --- a/lib/hawk-cmn.h +++ b/lib/hawk-cmn.h @@ -122,6 +122,10 @@ # define HAWK_UNUSED #endif +#if !defined(__has_builtin) +# define __has_builtin(v) 0 +#endif + /* ========================================================================= * STATIC ASSERTION * =========================================================================*/ @@ -729,8 +733,16 @@ struct hawk_ntime_t * The HAWK_ALIGNOF() macro returns the alignment size of a structure. * Note that this macro may not work reliably depending on the type given. */ -#define HAWK_ALIGNOF(type) HAWK_OFFSETOF(struct { hawk_uint8_t d1; type d2; }, d2) - /*(sizeof(struct { hawk_uint8_t d1; type d2; }) - sizeof(type))*/ +#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 202311L) /* C23 */ +#define HAWK_ALIGNOF(type) alignof(type) +#elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L) /* C11 */ +#define HAWK_ALIGNOF(type) _Alignof(type) +#elif defined(__cplusplus) && (__cplusplus >= 201103L) /* C++11 */ +#define HAWK_ALIGNOF(type) alignof(type) +#else +#define HAWK_ALIGNOF(type) HAWK_OFFSETOF(struct { hcl_uint8_t d1; type d2; }, d2) + /*(sizeof(struct { hcl_uint8_t d1; type d2; }) - sizeof(type))*/ +#endif #if defined(__cplusplus) # if (__cplusplus >= 201103L) /* C++11 */ @@ -1222,6 +1234,16 @@ typedef enum hawk_log_mask_t hawk_log_mask_t; #define HAWK_IS_UNALIGNED_POW2(x,y) ((x) & ((y) - 1)) #define HAWK_IS_ALIGNED_POW2(x,y) (!HAWK_IS_UNALIGNED_POW2(x,y)) +#if defined(__cplusplus) || (defined(__STDC_VERSION__) && (__STDC_VERSION__>=199901L)) +/* array index */ +#define HAWK_AID(x) [x]= +/* struct field name */ +#define HAWK_SFN(x) .x= +#else +#define HAWK_AID(x) +#define HAWK_SFN(x) +#endif + /* ========================================================================= * COMPILER FEATURE TEST MACROS * =========================================================================*/ diff --git a/lib/hawk-prv.h b/lib/hawk-prv.h index 3509d57e..d5f07be8 100644 --- a/lib/hawk-prv.h +++ b/lib/hawk-prv.h @@ -598,11 +598,10 @@ static HAWK_INLINE void HAWK_RTX_STACK_POP (hawk_rtx_t* rtx) #define HAWK_RTX_STACK_POP(rtx) ((rtx)->stack_top--) #endif - #define HAWK_RTX_INIT_REF_VAL(refval, _id, _adr, _nrefs) \ do { \ - (refval)->v_type = HAWK_VAL_REF; \ (refval)->v_refs = (_nrefs); \ + (refval)->v_type = HAWK_VAL_REF; \ (refval)->v_static = 0; \ (refval)->v_nstr = 0; \ (refval)->v_gc = 0; \ diff --git a/lib/hawk.h b/lib/hawk.h index fab9f7bd..01c7db70 100644 --- a/lib/hawk.h +++ b/lib/hawk.h @@ -157,26 +157,40 @@ static HAWK_INLINE hawk_gch_t* hawk_val_to_gch(hawk_val_t* v) /** * The #HAWK_VAL_HDR defines the common header for a value. * Three common fields are: - * - v_type - type of a value from #hawk_val_type_t * - v_refs - reference count + * - v_type - type of a value from #hawk_val_type_t * - v_static - static value indicator * - v_nstr - numeric string marker, 1 -> integer, 2 -> floating-point number * - v_gc - used for garbage collection together with v_refs + * + * [IMPORTANT] + * if you change the order of these fields, you must ensure that statically + * defined values follow this order strictly. for example, hawk_nil, hawk_zls, + * hawk_zlbs are defined statically in val.c */ /* #define HAWK_VAL_HDR \ - unsigned int v_type: 4; \ unsigned int v_refs: 24; \ + unsigned int v_type: 4; \ unsigned int v_static: 1; \ unsigned int v_nstr: 2; \ unsigned int v_gc: 1 -*/ + #define HAWK_VAL_HDR \ - hawk_uintptr_t v_type: 4; \ hawk_uintptr_t v_refs: ((HAWK_SIZEOF_UINTPTR_T * 8) - 8); \ + hawk_uintptr_t v_type: 4; \ hawk_uintptr_t v_static: 1; \ hawk_uintptr_t v_nstr: 2; \ hawk_uintptr_t v_gc: 1 +*/ + +/* regardless of architecture, use 4-byte reference count */ +#define HAWK_VAL_HDR \ + hawk_uint32_t v_refs; \ + hawk_uint8_t v_type: 4; \ + hawk_uint8_t v_static: 1; \ + hawk_uint8_t v_nstr: 2; \ + hawk_uint8_t v_gc: 1 /** * The hawk_val_t type is an abstract value type. A value commonly contains: diff --git a/lib/mod-math.c b/lib/mod-math.c index c440374f..83bdf7a6 100644 --- a/lib/mod-math.c +++ b/lib/mod-math.c @@ -25,6 +25,9 @@ #include "mod-math.h" #include "hawk-prv.h" +#if !defined(_GNU_SOURCE) +# define _GNU_SOURCE +#endif #include #include #include diff --git a/lib/mtx.c b/lib/mtx.c index bd46bd2f..97ec9153 100644 --- a/lib/mtx.c +++ b/lib/mtx.c @@ -40,6 +40,9 @@ /* implement this */ #else +# if !defined(_GNU_SOURCE) +# define _GNU_SOURCE +# endif # include "syscall.h" # if defined(AIX) && defined(__GNUC__) typedef int crid_t; diff --git a/lib/pio.c b/lib/pio.c index fdac09dc..b8cd1637 100644 --- a/lib/pio.c +++ b/lib/pio.c @@ -37,6 +37,9 @@ # include # include #else +# if !defined(_GNU_SOURCE) +# define _GNU_SOURCE +# endif # include "syscall.h" # if defined(HAVE_SPAWN_H) # include diff --git a/lib/utl-sys.c b/lib/utl-sys.c index 38b3a912..a1562b27 100644 --- a/lib/utl-sys.c +++ b/lib/utl-sys.c @@ -39,6 +39,9 @@ # include # include #else +# if !defined(_GNU_SOURCE) +# define _GNU_SOURCE +# endif # include "syscall.h" # if defined(HAVE_SYS_TIME_H) # include diff --git a/lib/val.c b/lib/val.c index da849816..c97216be 100644 --- a/lib/val.c +++ b/lib/val.c @@ -26,11 +26,35 @@ #define CHUNKSIZE HAWK_VAL_CHUNK_SIZE -static hawk_val_nil_t hawk_nil = { HAWK_VAL_NIL, 0, 1, 0, 0 }; +/* this isn't necessary as the implemenation is context(rtx)-centric + * leave it here for experiment. +#define USE_ATOMIC_REFCNT */ + +static hawk_val_nil_t hawk_nil = { + HAWK_SFN(v_refs) 0, + HAWK_SFN(v_type) HAWK_VAL_NIL, + HAWK_SFN(v_static) 1, + HAWK_SFN(v_nstr) 0, + HAWK_SFN(v_gc) 0 +}; /* zero-length string */ -static hawk_val_str_t hawk_zls = { HAWK_VAL_STR, 0, 1, 0, 0, { HAWK_T(""), 0 } }; +static hawk_val_str_t hawk_zls = { + HAWK_SFN(v_refs) 0, + HAWK_SFN(v_type) HAWK_VAL_STR, + HAWK_SFN(v_static) 1, + HAWK_SFN(v_nstr) 0, + HAWK_SFN(v_gc) 0, + HAWK_SFN(val) { HAWK_T(""), 0 } +}; /* zero-length byte string */ -static hawk_val_mbs_t hawk_zlbs = { HAWK_VAL_MBS, 0, 1, 0, 0, { HAWK_BT(""), 0 } }; +static hawk_val_mbs_t hawk_zlbs = { + HAWK_SFN(v_refs) 0, + HAWK_SFN(v_type) HAWK_VAL_MBS, + HAWK_SFN(v_static) 1, + HAWK_SFN(v_nstr) 0, + HAWK_SFN(v_gc) 0, + HAWK_SFN(val) { HAWK_BT(""), 0 } +}; hawk_val_t* hawk_val_nil = (hawk_val_t*)&hawk_nil; hawk_val_t* hawk_val_zls = (hawk_val_t*)&hawk_zls; @@ -1635,7 +1659,12 @@ void hawk_rtx_refupval (hawk_rtx_t* rtx, hawk_val_t* val) #if defined(DEBUG_VAL) hawk_logfmt (hawk_rtx_gethawk(rtx), HAWK_LOG_STDERR, HAWK_T("ref up [ptr=%p] [count=%d] - [%O]\n"), val, (int)val->v_refs, val); #endif + + #if defined(USE_ATOMIC_REFCNT) && __has_builtin(__atomic_fetch_add) + __atomic_fetch_add(&val->v_refs, 1, __ATOMIC_RELAXED); + #else val->v_refs++; + #endif } } @@ -1652,11 +1681,18 @@ void hawk_rtx_refdownval (hawk_rtx_t* rtx, hawk_val_t* val) /* the reference count of a value should be greater than zero for it to be decremented. check the source code for any bugs */ HAWK_ASSERT (val->v_refs > 0); + #if defined(USE_ATOMIC_REFCNT) && __has_builtin(__atomic_fetch_sub) + if (__atomic_fetch_sub(&val->v_refs, 1, __ATOMIC_RELAXED) == 1) + { + hawk_rtx_freeval (rtx, val, HAWK_RTX_FREEVAL_CACHE); + } + #else val->v_refs--; if (val->v_refs <= 0) { hawk_rtx_freeval (rtx, val, HAWK_RTX_FREEVAL_CACHE); } + #endif } } @@ -1669,7 +1705,11 @@ void hawk_rtx_refdownval_nofree (hawk_rtx_t* rtx, hawk_val_t* val) /* the reference count of a value should be greater than zero for it to be decremented. check the source code for any bugs */ HAWK_ASSERT (val->v_refs > 0); + #if defined(USE_ATOMIC_REFCNT) && __has_builtin(__atomic_fetch_sub) + __atomic_fetch_sub(&val->v_refs, 1, __ATOMIC_RELAXED); + #else val->v_refs--; + #endif } }