2020-03-28 08:04:37 +00:00
/*
2020-04-16 03:42:30 +00:00
Copyright ( c ) 2006 - 2020 Chung , Hyung - Hwan . All rights reserved .
2020-03-28 08:04:37 +00:00
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 .
*/
# include "mod-hawk.h"
# include "hawk-prv.h"
2020-12-28 17:23:33 +00:00
# include <hawk-mtx.h>
2020-03-28 08:04:37 +00:00
2020-12-28 17:23:33 +00:00
struct mod_data_t
{
hawk_mtx_t mq_mtx ;
} ;
typedef struct mod_data_t mod_data_t ;
2020-12-12 17:07:25 +00:00
/* ----------------------------------------------------------------- */
2020-04-13 08:41:16 +00:00
/*
* function abc ( a , b , c ) { return a + b + c ; }
* BEGIN { print hawk : : call ( " abc " , 10 , 20 , 30 ) ; }
*/
2020-04-12 18:23:44 +00:00
struct pafs_t
{
2022-04-06 15:49:23 +00:00
int is_fun ;
const hawk_ooch_t * argspec_ptr ;
hawk_oow_t argspec_len ;
2020-04-12 18:23:44 +00:00
hawk_oow_t stack_base ;
hawk_oow_t start_index ;
hawk_oow_t end_index ;
} ;
static hawk_oow_t push_args_from_stack ( hawk_rtx_t * rtx , hawk_nde_fncall_t * call , void * data )
{
struct pafs_t * pasf = ( struct pafs_t * ) data ;
2022-04-06 15:49:23 +00:00
hawk_oow_t org_stack_base , i , j ;
2020-04-12 18:23:44 +00:00
hawk_val_t * v ;
if ( HAWK_RTX_STACK_AVAIL ( rtx ) < pasf - > end_index - pasf - > start_index + 1 )
{
hawk_rtx_seterrnum ( rtx , & call - > loc , HAWK_ESTACK ) ;
return ( hawk_oow_t ) - 1 ;
}
org_stack_base = rtx - > stack_base ;
2020-04-13 08:41:16 +00:00
for ( i = pasf - > start_index , j = 0 ; i < = pasf - > end_index ; i + + , j + + )
2020-04-12 18:23:44 +00:00
{
2020-04-14 11:45:52 +00:00
hawk_ooch_t spec ;
2020-04-12 18:23:44 +00:00
rtx - > stack_base = pasf - > stack_base ;
v = HAWK_RTX_STACK_ARG ( rtx , i ) ;
rtx - > stack_base = org_stack_base ;
2020-04-14 11:45:52 +00:00
/* if not sufficient number of spec characters given, take the last value and use it */
2022-04-06 15:49:23 +00:00
spec = ( pasf - > argspec_len < = 0 ) ? ' \0 ' : pasf - > argspec_ptr [ ( ( j < pasf - > argspec_len ) ? j : pasf - > argspec_len - 1 ) ] ;
2020-04-14 11:45:52 +00:00
if ( HAWK_RTX_GETVALTYPE ( rtx , v ) = = HAWK_VAL_REF )
{
2022-04-06 15:49:23 +00:00
if ( pasf - > is_fun )
{
/* take out the actual value and pass it to the callee
* only if the callee is a user - defined function */
v = hawk_rtx_getrefval ( rtx , ( hawk_val_ref_t * ) v ) ;
}
2020-04-14 11:45:52 +00:00
}
else
2020-04-13 08:41:16 +00:00
{
2022-04-08 03:42:20 +00:00
if ( spec = = ' r ' ) /* 'R' allows a normal value. so only checking 'r' here */
2020-04-14 11:45:52 +00:00
{
hawk_rtx_seterrnum ( rtx , & call - > loc , HAWK_ENOTREF ) ;
return ( hawk_oow_t ) - 1 ;
}
2020-04-13 08:41:16 +00:00
}
2020-04-12 18:23:44 +00:00
HAWK_RTX_STACK_PUSH ( rtx , v ) ;
hawk_rtx_refupval ( rtx , v ) ;
}
return pasf - > end_index - pasf - > start_index + 1 ;
}
static int fnc_call ( hawk_rtx_t * rtx , const hawk_fnc_info_t * fi )
{
hawk_fun_t * fun ;
2022-04-08 10:52:15 +00:00
hawk_oow_t nargs , f_nargs ;
2020-04-12 18:23:44 +00:00
hawk_nde_fncall_t call ;
struct pafs_t pafs ;
2020-04-13 08:41:16 +00:00
hawk_val_t * v ;
2020-04-12 18:23:44 +00:00
/* this function is similar to hawk_rtx_callfun() but it is more simplified */
2022-04-06 15:49:23 +00:00
HAWK_MEMSET ( & call , 0 , HAWK_SIZEOF ( call ) ) ;
nargs = hawk_rtx_getnargs ( rtx ) ;
2022-04-08 10:52:15 +00:00
f_nargs = nargs - 1 ;
2020-04-12 18:23:44 +00:00
2020-04-13 08:41:16 +00:00
fun = hawk_rtx_valtofun ( rtx , hawk_rtx_getarg ( rtx , 0 ) ) ;
2022-04-06 15:49:23 +00:00
if ( fun )
{
2022-04-08 10:52:15 +00:00
if ( f_nargs > fun - > nargs )
2022-04-06 15:49:23 +00:00
{
hawk_rtx_seterrnum ( rtx , HAWK_NULL , HAWK_EARGTM ) ;
return - 1 ; /* hard failure */
}
2020-04-12 18:23:44 +00:00
2022-04-06 15:49:23 +00:00
/* user-defined function call */
call . type = HAWK_NDE_FNCALL_FUN ;
call . u . fun . name = fun - > name ;
pafs . is_fun = 1 ;
pafs . argspec_ptr = fun - > argspec ;
pafs . argspec_len = fun - > argspec ? hawk_count_oocstr ( fun - > argspec ) : 0 ;
}
else
2020-04-12 18:23:44 +00:00
{
2022-04-06 15:49:23 +00:00
/* find the name in the modules */
2022-04-08 10:52:15 +00:00
hawk_fnc_t fnc , * fncp ;
2022-04-06 15:49:23 +00:00
mod_data_t * md ;
md = ( mod_data_t * ) fi - > mod - > ctx ;
2022-04-08 10:52:15 +00:00
/* hawk_querymodulewithname() called by hawk_rtx_valtofnc()
* may update some shared data under the hawk object .
* use a mutex for shared data safety */
/* TODO: this mutex protection is wrong in that if a call to hawk_querymodulewithname()
* is made outside this hawk module , the call is not protected under
* the same mutex . FIX THIS */
2022-04-06 15:49:23 +00:00
hawk_mtx_lock ( & md - > mq_mtx , HAWK_NULL ) ;
2022-04-08 10:52:15 +00:00
fncp = hawk_rtx_valtofnc ( rtx , hawk_rtx_getarg ( rtx , 0 ) , & fnc ) ;
2022-04-06 15:49:23 +00:00
hawk_mtx_unlock ( & md - > mq_mtx ) ;
2022-04-08 10:52:15 +00:00
if ( ! fncp ) return - 1 ; /* hard failure */
2022-04-06 15:49:23 +00:00
2022-04-08 10:52:15 +00:00
if ( f_nargs < fnc . spec . arg . min | | f_nargs > fnc . spec . arg . max )
{
hawk_rtx_seterrnum ( rtx , HAWK_NULL , HAWK_EARGTM ) ;
return - 1 ;
}
2022-04-06 15:49:23 +00:00
call . type = HAWK_NDE_FNCALL_FNC ;
2022-04-08 10:52:15 +00:00
call . u . fnc . info . name . ptr = fnc . name . ptr ;
call . u . fnc . info . name . len = fnc . name . len ;
call . u . fnc . info . mod = fnc . mod ;
call . u . fnc . spec = fnc . spec ;
2022-04-06 15:49:23 +00:00
pafs . is_fun = 0 ;
pafs . argspec_ptr = call . u . fnc . spec . arg . spec ;
pafs . argspec_len = call . u . fnc . spec . arg . spec ? hawk_count_oocstr ( call . u . fnc . spec . arg . spec ) : 0 ;
2020-04-12 18:23:44 +00:00
}
2022-04-08 10:52:15 +00:00
call . nargs = f_nargs ;
2020-04-12 18:23:44 +00:00
/* keep HAWK_NULL in call.args so that hawk_rtx_evalcall() knows it's a fake call structure */
2020-04-13 08:41:16 +00:00
call . arg_base = rtx - > stack_base + 5 ; /* 5 = 4(stack frame prologue) + 1(the first argument to hawk::call()) */
2020-04-12 18:23:44 +00:00
pafs . stack_base = rtx - > stack_base ;
2020-04-13 08:41:16 +00:00
pafs . start_index = 1 ;
2020-04-12 18:23:44 +00:00
pafs . end_index = nargs - 1 ;
v = hawk_rtx_evalcall ( rtx , & call , fun , push_args_from_stack , ( void * ) & pafs , HAWK_NULL , HAWK_NULL ) ;
2020-04-13 08:41:16 +00:00
if ( HAWK_UNLIKELY ( ! v ) ) return - 1 ; /* hard failure */
2020-04-12 18:23:44 +00:00
2020-04-13 08:41:16 +00:00
hawk_rtx_setretval ( rtx , v ) ;
2020-04-12 18:23:44 +00:00
return 0 ;
}
2020-12-28 07:10:17 +00:00
/* hawk::function_exists("xxxx");
* hawk : : function_exists ( " sys::getpid " ) */
2020-04-13 13:56:09 +00:00
static int fnc_function_exists ( hawk_rtx_t * rtx , const hawk_fnc_info_t * fi )
{
hawk_val_t * a0 ;
2020-12-28 07:10:17 +00:00
hawk_oocs_t name ;
2020-04-13 13:56:09 +00:00
int rx ;
a0 = hawk_rtx_getarg ( rtx , 0 ) ;
2020-12-28 07:10:17 +00:00
name . ptr = hawk_rtx_getvaloocstr ( rtx , a0 , & name . len ) ;
if ( HAWK_UNLIKELY ( ! name . ptr ) )
2020-04-13 13:56:09 +00:00
{
rx = 0 ;
}
else
{
2020-12-28 07:10:17 +00:00
if ( hawk_count_oocstr ( name . ptr ) ! = name . len ) rx = 0 ;
else
{
rx = ( hawk_rtx_findfunwithoocstr ( rtx , name . ptr ) ! = HAWK_NULL ) ;
if ( ! rx )
{
2022-04-08 23:57:23 +00:00
rx = ( hawk_findfncwithoocs ( hawk_rtx_gethawk ( rtx ) , & name ) ! = HAWK_NULL ) ;
if ( ! rx )
{
hawk_mod_sym_t sym ;
mod_data_t * md ;
md = ( mod_data_t * ) fi - > mod - > ctx ;
/* hawk_query_module_with_name() may update some shared data under
* the hawk object . use a mutex for shared data safety */
hawk_mtx_lock ( & md - > mq_mtx , HAWK_NULL ) ;
2022-06-03 06:01:52 +00:00
rx = ( hawk_querymodulewithname ( hawk_rtx_gethawk ( rtx ) , name . ptr , & sym ) ! = HAWK_NULL ) ;
2022-04-08 23:57:23 +00:00
hawk_mtx_unlock ( & md - > mq_mtx ) ;
}
2020-12-28 07:10:17 +00:00
}
}
hawk_rtx_freevaloocstr ( rtx , a0 , name . ptr ) ;
2020-04-13 13:56:09 +00:00
}
hawk_rtx_setretval ( rtx , hawk_rtx_makeintval ( rtx , rx ) ) ;
return 0 ;
}
2020-12-11 12:14:48 +00:00
/* -------------------------------------------------------------------------- */
static int fnc_cmgr_exists ( hawk_rtx_t * rtx , const hawk_fnc_info_t * fi )
{
hawk_val_t * a0 ;
hawk_ooch_t * str ;
hawk_oow_t len ;
int rx ;
a0 = hawk_rtx_getarg ( rtx , 0 ) ;
str = hawk_rtx_getvaloocstr ( rtx , a0 , & len ) ;
if ( HAWK_UNLIKELY ( ! str ) )
{
rx = 0 ;
}
else
{
rx = ( hawk_get_cmgr_by_name ( str ) ! = HAWK_NULL ) ;
hawk_rtx_freevaloocstr ( rtx , a0 , str ) ;
}
hawk_rtx_setretval ( rtx , hawk_rtx_makeintval ( rtx , rx ) ) ;
return 0 ;
}
2020-04-13 13:56:09 +00:00
2020-04-20 15:34:59 +00:00
/* -------------------------------------------------------------------------- */
2020-03-28 08:04:37 +00:00
/*
hawk : : gc ( ) ;
hawk : : gc_get_threshold ( gen )
2020-04-12 18:23:44 +00:00
hawk : : gc_set_threshold ( gen , threshold )
2020-03-28 08:04:37 +00:00
hawk : : GC_NUM_GENS
*/
static int fnc_gc ( hawk_rtx_t * rtx , const hawk_fnc_info_t * fi )
{
hawk_int_t gen = - 1 ;
2020-11-02 09:54:12 +00:00
# if defined(HAWK_ENABLE_GC)
2020-03-28 08:04:37 +00:00
if ( hawk_rtx_getnargs ( rtx ) > = 1 & & hawk_rtx_valtoint ( rtx , hawk_rtx_getarg ( rtx , 0 ) , & gen ) < = - 1 ) gen = - 1 ;
gen = hawk_rtx_gc ( rtx , gen ) ;
2020-11-02 09:54:12 +00:00
# endif
2020-03-28 08:04:37 +00:00
2024-04-16 02:13:21 +00:00
HAWK_ASSERT ( HAWK_IN_INT_RANGE ( gen ) ) ;
2020-03-28 08:04:37 +00:00
hawk_rtx_setretval ( rtx , hawk_rtx_makeintval ( rtx , gen ) ) ;
return 0 ;
}
2024-04-22 15:22:59 +00:00
static int fnc_gc_get_pressure ( hawk_rtx_t * rtx , const hawk_fnc_info_t * fi )
{
hawk_int_t gen ;
hawk_int_t pressure ;
if ( hawk_rtx_valtoint ( rtx , hawk_rtx_getarg ( rtx , 0 ) , & gen ) < = - 1 ) gen = 0 ;
if ( gen < 0 ) gen = 0 ;
else if ( gen > = HAWK_COUNTOF ( rtx - > gc . g ) ) gen = HAWK_COUNTOF ( rtx - > gc . g ) - 1 ;
pressure = rtx - > gc . pressure [ gen ] ;
HAWK_ASSERT ( HAWK_IN_INT_RANGE ( pressure ) ) ;
hawk_rtx_setretval ( rtx , hawk_rtx_makeintval ( rtx , pressure ) ) ;
return 0 ;
}
2020-03-28 08:04:37 +00:00
static int fnc_gc_get_threshold ( hawk_rtx_t * rtx , const hawk_fnc_info_t * fi )
{
hawk_int_t gen ;
hawk_int_t threshold ;
if ( hawk_rtx_valtoint ( rtx , hawk_rtx_getarg ( rtx , 0 ) , & gen ) < = - 1 ) gen = 0 ;
if ( gen < 0 ) gen = 0 ;
else if ( gen > = HAWK_COUNTOF ( rtx - > gc . g ) ) gen = HAWK_COUNTOF ( rtx - > gc . g ) - 1 ;
threshold = rtx - > gc . threshold [ gen ] ;
2024-04-16 02:13:21 +00:00
HAWK_ASSERT ( HAWK_IN_INT_RANGE ( threshold ) ) ;
2020-03-28 08:04:37 +00:00
hawk_rtx_setretval ( rtx , hawk_rtx_makeintval ( rtx , threshold ) ) ;
return 0 ;
}
static int fnc_gc_set_threshold ( hawk_rtx_t * rtx , const hawk_fnc_info_t * fi )
{
hawk_int_t gen ;
hawk_int_t threshold ;
if ( hawk_rtx_valtoint ( rtx , hawk_rtx_getarg ( rtx , 0 ) , & gen ) < = - 1 ) gen = 0 ;
if ( gen < 0 ) gen = 0 ;
else if ( gen > = HAWK_COUNTOF ( rtx - > gc . g ) ) gen = HAWK_COUNTOF ( rtx - > gc . g ) - 1 ;
if ( hawk_rtx_valtoint ( rtx , hawk_rtx_getarg ( rtx , 1 ) , & threshold ) < = - 1 ) threshold = - 1 ;
if ( threshold > = 0 )
{
2024-04-16 02:13:21 +00:00
if ( threshold > = HAWK_INT_MAX ) threshold = HAWK_INT_MAX ;
2020-03-28 08:04:37 +00:00
rtx - > gc . threshold [ gen ] = threshold ; /* update */
}
else
{
threshold = rtx - > gc . threshold [ gen ] ; /* no update. but retrieve the existing value */
}
2024-04-16 02:13:21 +00:00
HAWK_ASSERT ( HAWK_IN_INT_RANGE ( threshold ) ) ;
2020-03-28 08:04:37 +00:00
hawk_rtx_setretval ( rtx , hawk_rtx_makeintval ( rtx , threshold ) ) ;
return 0 ;
}
2020-04-24 17:27:56 +00:00
static int fnc_gcrefs ( hawk_rtx_t * rtx , const hawk_fnc_info_t * fi )
{
hawk_val_t * a0 ;
a0 = hawk_rtx_getarg ( rtx , 0 ) ;
hawk_rtx_setretval ( rtx , hawk_rtx_makeintval ( rtx , HAWK_VTR_IS_POINTER ( a0 ) ? a0 - > v_refs : 0 ) ) ;
return 0 ;
}
2020-04-20 15:34:59 +00:00
/* -------------------------------------------------------------------------- */
2020-04-23 07:25:33 +00:00
static int fnc_array ( hawk_rtx_t * rtx , const hawk_fnc_info_t * fi )
2020-04-20 15:34:59 +00:00
{
hawk_val_t * tmp ;
2020-05-03 15:49:31 +00:00
hawk_oow_t nargs , i ;
2020-04-20 15:34:59 +00:00
2020-05-03 15:49:31 +00:00
nargs = hawk_rtx_getnargs ( rtx ) ;
2020-04-29 13:03:02 +00:00
2020-05-03 15:49:31 +00:00
tmp = hawk_rtx_makearrval ( rtx , ( ( nargs > 0 ) ? nargs : - 1 ) ) ;
if ( HAWK_UNLIKELY ( ! tmp ) ) return - 1 ; /* hard failure */
2020-04-29 13:03:02 +00:00
2020-05-03 15:49:31 +00:00
for ( i = 0 ; i < nargs ; i + + )
2020-04-29 13:03:02 +00:00
{
2020-05-03 15:49:31 +00:00
if ( HAWK_UNLIKELY ( hawk_rtx_setarrvalfld ( rtx , tmp , i + 1 , hawk_rtx_getarg ( rtx , i ) ) = = HAWK_NULL ) )
{
hawk_rtx_freeval ( rtx , tmp , 0 ) ;
return - 1 ;
}
2020-04-29 13:03:02 +00:00
}
2020-05-03 15:49:31 +00:00
hawk_rtx_setretval ( rtx , tmp ) ;
2020-04-29 13:03:02 +00:00
return 0 ;
}
2020-05-03 15:49:31 +00:00
static int fnc_map ( hawk_rtx_t * rtx , const hawk_fnc_info_t * fi )
2020-04-29 13:03:02 +00:00
{
2020-05-03 15:49:31 +00:00
hawk_val_t * tmp ;
hawk_oow_t nargs , i ;
hawk_ooch_t idxbuf [ HAWK_IDX_BUF_SIZE ] ;
2020-04-29 13:03:02 +00:00
2020-05-03 15:49:31 +00:00
tmp = hawk_rtx_makemapval ( rtx ) ;
if ( HAWK_UNLIKELY ( ! tmp ) ) return - 1 ; /* hard failure */
nargs = hawk_rtx_getnargs ( rtx ) ;
2020-04-29 13:03:02 +00:00
2020-05-03 15:49:31 +00:00
for ( i = 0 ; i < nargs ; i + + )
2020-04-29 13:03:02 +00:00
{
2020-05-03 15:49:31 +00:00
hawk_rtx_valtostr_out_t out ;
hawk_val_t * v ;
v = hawk_rtx_getarg ( rtx , i ) ;
out . type = HAWK_RTX_VALTOSTR_CPLCPY ;
out . u . cplcpy . ptr = idxbuf ;
out . u . cplcpy . len = HAWK_COUNTOF ( idxbuf ) ;
if ( hawk_rtx_valtostr ( rtx , v , & out ) < = - 1 )
{
out . type = HAWK_RTX_VALTOSTR_CPLDUP ;
if ( hawk_rtx_valtostr ( rtx , v , & out ) < = - 1 )
{
hawk_rtx_freeval ( rtx , tmp , 0 ) ;
return - 1 ;
}
}
2020-04-29 13:03:02 +00:00
2020-05-03 15:49:31 +00:00
v = ( + + i > = nargs ) ? hawk_val_nil : hawk_rtx_getarg ( rtx , i ) ;
v = hawk_rtx_setmapvalfld ( rtx , tmp , out . u . cpldup . ptr , out . u . cpldup . len , v ) ;
if ( out . u . cpldup . ptr ! = idxbuf ) hawk_rtx_freemem ( rtx , out . u . cpldup . ptr ) ;
2020-04-29 13:03:02 +00:00
2020-05-03 15:49:31 +00:00
if ( HAWK_UNLIKELY ( ! v ) )
{
hawk_rtx_freeval ( rtx , tmp , 0 ) ;
return - 1 ;
}
2020-04-23 07:25:33 +00:00
2020-05-03 15:49:31 +00:00
/* if (i >= nargs) break; this check is probably not needed. another i++ in the 3rd segment of the for statement should be mostly harmless. potential overflow issue is not a real issue as the number of arguments can be so high. */
}
2020-04-23 07:25:33 +00:00
2020-04-20 15:34:59 +00:00
hawk_rtx_setretval ( rtx , tmp ) ;
return 0 ;
}
/* -------------------------------------------------------------------------- */
2020-04-24 17:27:56 +00:00
static int fnc_isnil ( hawk_rtx_t * rtx , const hawk_fnc_info_t * fi )
{
hawk_val_t * a0 ;
hawk_val_t * r ;
a0 = hawk_rtx_getarg ( rtx , 0 ) ;
r = hawk_rtx_makeintval ( rtx , HAWK_RTX_GETVALTYPE ( rtx , a0 ) = = HAWK_VAL_NIL ) ;
2020-12-01 14:44:53 +00:00
if ( HAWK_UNLIKELY ( ! r ) ) return - 1 ;
2020-04-24 17:27:56 +00:00
hawk_rtx_setretval ( rtx , r ) ;
return 0 ;
}
static int fnc_ismap ( hawk_rtx_t * rtx , const hawk_fnc_info_t * fi )
{
hawk_val_t * a0 ;
hawk_val_t * r ;
a0 = hawk_rtx_getarg ( rtx , 0 ) ;
r = hawk_rtx_makeintval ( rtx , HAWK_RTX_GETVALTYPE ( rtx , a0 ) = = HAWK_VAL_MAP ) ;
if ( HAWK_UNLIKELY ( ! r ) ) return - 1 ;
hawk_rtx_setretval ( rtx , r ) ;
return 0 ;
}
static int fnc_isarr ( hawk_rtx_t * rtx , const hawk_fnc_info_t * fi )
{
hawk_val_t * a0 ;
hawk_val_t * r ;
a0 = hawk_rtx_getarg ( rtx , 0 ) ;
r = hawk_rtx_makeintval ( rtx , HAWK_RTX_GETVALTYPE ( rtx , a0 ) = = HAWK_VAL_ARR ) ;
if ( HAWK_UNLIKELY ( ! r ) ) return - 1 ;
hawk_rtx_setretval ( rtx , r ) ;
return 0 ;
}
2020-12-01 14:44:53 +00:00
static int fnc_modlibdirs ( hawk_rtx_t * rtx , const hawk_fnc_info_t * fi )
{
hawk_t * hawk = hawk_rtx_gethawk ( rtx ) ;
hawk_val_t * r ;
2022-06-16 13:31:34 +00:00
r = hawk_rtx_makestrvalwithoocstr ( rtx , ( hawk - > opt . mod [ 0 ] . len > 0 ) ? ( const hawk_ooch_t * ) hawk - > opt . mod [ 0 ] . ptr : ( const hawk_ooch_t * ) HAWK_T ( HAWK_DEFAULT_MODLIBDIRS ) ) ;
2020-12-01 14:44:53 +00:00
if ( HAWK_UNLIKELY ( ! r ) ) return - 1 ;
hawk_rtx_setretval ( rtx , r ) ;
return 0 ;
}
2024-04-16 03:33:13 +00:00
static int fnc_type ( hawk_rtx_t * rtx , const hawk_fnc_info_t * fi )
{
hawk_val_t * a0 ;
hawk_val_t * r ;
int _type ;
a0 = hawk_rtx_getarg ( rtx , 0 ) ;
_type = hawk_rtx_getvaltype ( rtx , a0 ) ;
r = hawk_rtx_makeintval ( rtx , _type ) ;
if ( HAWK_UNLIKELY ( ! r ) ) return - 1 ;
hawk_rtx_setretval ( rtx , r ) ;
return 0 ;
}
2020-04-24 17:27:56 +00:00
static int fnc_typename ( hawk_rtx_t * rtx , const hawk_fnc_info_t * fi )
{
hawk_val_t * a0 ;
hawk_val_t * r ;
const hawk_ooch_t * name ;
a0 = hawk_rtx_getarg ( rtx , 0 ) ;
name = hawk_rtx_getvaltypename ( rtx , a0 ) ;
r = hawk_rtx_makestrvalwithoocstr ( rtx , name ) ;
2020-12-01 14:44:53 +00:00
if ( HAWK_UNLIKELY ( ! r ) ) return - 1 ;
2020-04-24 17:27:56 +00:00
hawk_rtx_setretval ( rtx , r ) ;
return 0 ;
}
2020-12-11 12:14:48 +00:00
2023-07-02 16:42:14 +00:00
/* -------------------------------------------------------------------------- */
2024-05-02 13:36:50 +00:00
2023-07-02 16:42:14 +00:00
static int fnc_hash ( hawk_rtx_t * rtx , const hawk_fnc_info_t * fi )
{
hawk_val_t * a0 ;
hawk_int_t v ;
const hawk_ooch_t * name ;
a0 = hawk_rtx_getarg ( rtx , 0 ) ;
v = hawk_rtx_hashval ( rtx , a0 ) ; /* ignore v <= -1 which is an error */
hawk_rtx_setretval ( rtx , hawk_rtx_makeintval ( rtx , v ) ) ;
return 0 ;
}
2020-12-09 18:07:20 +00:00
/* -------------------------------------------------------------------------- */
2020-12-12 17:07:25 +00:00
2020-12-12 18:18:37 +00:00
# define A_MAX HAWK_TYPE_MAX(hawk_oow_t)
2020-03-28 08:04:37 +00:00
2020-12-18 14:43:30 +00:00
static hawk_mod_fnc_tab_t fnctab [ ] =
2020-03-28 08:04:37 +00:00
{
/* keep this table sorted for binary search in query(). */
2020-12-09 18:07:20 +00:00
{ HAWK_T ( " array " ) , { { 0 , A_MAX , HAWK_NULL } , fnc_array , 0 } } ,
2020-04-13 08:41:16 +00:00
{ HAWK_T ( " call " ) , { { 1 , A_MAX , HAWK_T ( " vR " ) } , fnc_call , 0 } } ,
2020-12-11 12:14:48 +00:00
{ HAWK_T ( " cmgr_exists " ) , { { 1 , 1 , HAWK_NULL } , fnc_cmgr_exists , 0 } } ,
2020-04-13 13:56:09 +00:00
{ HAWK_T ( " function_exists " ) , { { 1 , 1 , HAWK_NULL } , fnc_function_exists , 0 } } ,
2020-04-12 18:23:44 +00:00
{ HAWK_T ( " gc " ) , { { 0 , 1 , HAWK_NULL } , fnc_gc , 0 } } ,
2024-04-22 15:22:59 +00:00
{ HAWK_T ( " gc_get_pressure " ) , { { 1 , 1 , HAWK_NULL } , fnc_gc_get_pressure , 0 } } ,
2020-04-12 18:23:44 +00:00
{ HAWK_T ( " gc_get_threshold " ) , { { 1 , 1 , HAWK_NULL } , fnc_gc_get_threshold , 0 } } ,
2020-04-20 15:34:59 +00:00
{ HAWK_T ( " gc_set_threshold " ) , { { 2 , 2 , HAWK_NULL } , fnc_gc_set_threshold , 0 } } ,
2021-01-30 09:50:47 +00:00
{ HAWK_T ( " gcrefs " ) , { { 1 , 1 , HAWK_NULL } , fnc_gcrefs , 0 } } ,
2023-07-02 16:42:14 +00:00
{ HAWK_T ( " hash " ) , { { 1 , 1 , HAWK_NULL } , fnc_hash , 0 } } ,
2020-04-24 17:27:56 +00:00
{ HAWK_T ( " isarray " ) , { { 1 , 1 , HAWK_NULL } , fnc_isarr , 0 } } ,
{ HAWK_T ( " ismap " ) , { { 1 , 1 , HAWK_NULL } , fnc_ismap , 0 } } ,
{ HAWK_T ( " isnil " ) , { { 1 , 1 , HAWK_NULL } , fnc_isnil , 0 } } ,
{ HAWK_T ( " map " ) , { { 0 , A_MAX , HAWK_NULL } , fnc_map , 0 } } ,
2020-12-01 14:44:53 +00:00
{ HAWK_T ( " modlibdirs " ) , { { 0 , 0 , HAWK_NULL } , fnc_modlibdirs , 0 } } ,
2024-04-16 03:33:13 +00:00
{ HAWK_T ( " type " ) , { { 1 , 1 , HAWK_NULL } , fnc_type , 0 } } ,
2020-12-12 18:18:37 +00:00
{ HAWK_T ( " typename " ) , { { 1 , 1 , HAWK_NULL } , fnc_typename , 0 } }
2020-03-28 08:04:37 +00:00
} ;
2020-12-18 14:43:30 +00:00
static hawk_mod_int_tab_t inttab [ ] =
2020-03-28 08:04:37 +00:00
{
/* keep this table sorted for binary search in query(). */
2024-04-16 03:33:13 +00:00
{ HAWK_T ( " GC_NUM_GENS " ) , { HAWK_GC_NUM_GENS } } ,
/* synchronize this table with enum hawk_val_type_t in hawk.h */
/* the names follow the val_type_name table in val.c */
{ HAWK_T ( " VAL_ARRAY " ) , { HAWK_VAL_ARR } } ,
{ HAWK_T ( " VAL_BCHAR " ) , { HAWK_VAL_BCHR } } ,
{ HAWK_T ( " VAL_CHAR " ) , { HAWK_VAL_CHAR } } ,
{ HAWK_T ( " VAL_FLT " ) , { HAWK_VAL_FLT } } ,
{ HAWK_T ( " VAL_FUN " ) , { HAWK_VAL_FUN } } ,
{ HAWK_T ( " VAL_INT " ) , { HAWK_VAL_INT } } ,
{ HAWK_T ( " VAL_MAP " ) , { HAWK_VAL_MAP } } ,
{ HAWK_T ( " VAL_MBS " ) , { HAWK_VAL_MBS } } ,
{ HAWK_T ( " VAL_NIL " ) , { HAWK_VAL_NIL } } ,
{ HAWK_T ( " VAL_STR " ) , { HAWK_VAL_STR } } ,
{ HAWK_T ( " VAL_REF " ) , { HAWK_VAL_REF } } ,
{ HAWK_T ( " VAL_REX " ) , { HAWK_VAL_REX } }
2020-03-28 08:04:37 +00:00
} ;
2020-04-16 03:42:30 +00:00
static int query ( hawk_mod_t * mod , hawk_t * hawk , const hawk_ooch_t * name , hawk_mod_sym_t * sym )
2020-03-28 08:04:37 +00:00
{
2020-12-22 17:53:51 +00:00
if ( hawk_findmodsymfnc_noseterr ( hawk , fnctab , HAWK_COUNTOF ( fnctab ) , name , sym ) > = 0 ) return 0 ;
2020-12-18 14:43:30 +00:00
return hawk_findmodsymint ( hawk , inttab , HAWK_COUNTOF ( inttab ) , name , sym ) ;
2020-03-28 08:04:37 +00:00
}
static int init ( hawk_mod_t * mod , hawk_rtx_t * rtx )
{
2020-12-12 18:18:37 +00:00
/* nothing to do */
2020-03-28 08:04:37 +00:00
return 0 ;
}
static void fini ( hawk_mod_t * mod , hawk_rtx_t * rtx )
{
2020-12-12 18:18:37 +00:00
/* nothing to do */
2020-03-28 08:04:37 +00:00
}
2020-04-16 03:42:30 +00:00
static void unload ( hawk_mod_t * mod , hawk_t * hawk )
2020-03-28 08:04:37 +00:00
{
2020-12-28 17:23:33 +00:00
mod_data_t * md = ( mod_data_t * ) mod - > ctx ;
hawk_mtx_fini ( & md - > mq_mtx ) ;
hawk_freemem ( hawk , md ) ;
2020-03-28 08:04:37 +00:00
}
2020-04-16 03:42:30 +00:00
int hawk_mod_hawk ( hawk_mod_t * mod , hawk_t * hawk )
2020-03-28 08:04:37 +00:00
{
2020-12-28 17:23:33 +00:00
mod_data_t * md ;
md = hawk_allocmem ( hawk , HAWK_SIZEOF ( * md ) ) ;
if ( HAWK_UNLIKELY ( ! md ) ) return - 1 ;
hawk_mtx_init ( & md - > mq_mtx , hawk_getgem ( hawk ) ) ;
2020-03-28 08:04:37 +00:00
mod - > query = query ;
mod - > unload = unload ;
mod - > init = init ;
mod - > fini = fini ;
2020-12-28 17:23:33 +00:00
mod - > ctx = md ;
2020-03-28 08:04:37 +00:00
return 0 ;
}