/* The various native call argument types. */ #define MVM_NATIVECALL_ARG_VOID 0 #define MVM_NATIVECALL_ARG_CHAR 2 #define MVM_NATIVECALL_ARG_SHORT 4 #define MVM_NATIVECALL_ARG_INT 6 #define MVM_NATIVECALL_ARG_LONG 8 #define MVM_NATIVECALL_ARG_LONGLONG 10 #define MVM_NATIVECALL_ARG_FLOAT 12 #define MVM_NATIVECALL_ARG_DOUBLE 14 #define MVM_NATIVECALL_ARG_ASCIISTR 16 #define MVM_NATIVECALL_ARG_UTF8STR 18 #define MVM_NATIVECALL_ARG_UTF16STR 20 #define MVM_NATIVECALL_ARG_CSTRUCT 22 #define MVM_NATIVECALL_ARG_CARRAY 24 #define MVM_NATIVECALL_ARG_CALLBACK 26 #define MVM_NATIVECALL_ARG_CPOINTER 28 #define MVM_NATIVECALL_ARG_VMARRAY 30 #define MVM_NATIVECALL_ARG_UCHAR 32 #define MVM_NATIVECALL_ARG_USHORT 34 #define MVM_NATIVECALL_ARG_UINT 36 #define MVM_NATIVECALL_ARG_ULONG 38 #define MVM_NATIVECALL_ARG_ULONGLONG 40 #define MVM_NATIVECALL_ARG_CUNION 42 #define MVM_NATIVECALL_ARG_CPPSTRUCT 44 #define MVM_NATIVECALL_ARG_TYPE_MASK 62 /* Flag for whether we should free a string after passing it or not. */ #define MVM_NATIVECALL_ARG_NO_FREE_STR 0 #define MVM_NATIVECALL_ARG_FREE_STR 1 #define MVM_NATIVECALL_ARG_FREE_STR_MASK 1 /* Flag for whether we need to refresh a CArray after passing or not. */ #define MVM_NATIVECALL_ARG_NO_REFRESH 0 #define MVM_NATIVECALL_ARG_REFRESH 1 #define MVM_NATIVECALL_ARG_REFRESH_MASK 1 #define MVM_NATIVECALL_ARG_NO_RW 0 #define MVM_NATIVECALL_ARG_RW 256 #define MVM_NATIVECALL_ARG_RW_MASK 256 #define MVM_NATIVECALL_UNMARSHAL_KIND_GENERIC -1 #define MVM_NATIVECALL_UNMARSHAL_KIND_RETURN -2 #define MVM_NATIVECALL_UNMARSHAL_KIND_NATIVECAST -3 /* Native callback entry. Hung off MVMNativeCallbackCacheHead, which is * a hash owned by the ThreadContext. All MVMNativeCallbacks in a linked * list have the same cuid, which is the key to the CacheHead hash. */ struct MVMNativeCallback { /* The dyncall/libffi callback object. */ void *cb; /* The code handle that we will call. */ MVMCode *target; /* The VM instance. */ MVMInstance *instance; /* Return and argument type flags. */ MVMint16 *typeinfos; /* Return and argument types themselves. */ MVMObject **types; /* The number of entries in typeinfos/types. */ MVMint32 num_types; /* The MoarVM callsite object for this call. */ MVMCallsite *cs; #ifdef HAVE_LIBFFI ffi_abi convention; ffi_type **ffi_arg_types; ffi_type *ffi_ret_type; #endif /* The next entry in the linked list */ MVMNativeCallback *next; }; /* A hash of nativecall callbacks. Each entry is a linked * list of MVMNativeCallback sharing the same cuid. * Multiple callbacks with the same cuid get created when * closures are taken and need to be differentiated. */ struct MVMNativeCallbackCacheHead { struct MVMStrHashHandle hash_handle; MVMNativeCallback *head; }; /* Functions for working with native callsites. */ MVMNativeCallBody * MVM_nativecall_get_nc_body(MVMThreadContext *tc, MVMObject *obj); MVMint16 MVM_nativecall_get_arg_type(MVMThreadContext *tc, MVMObject *info, MVMint16 is_return); MVMint8 MVM_nativecall_build(MVMThreadContext *tc, MVMObject *site, MVMString *lib, MVMString *sym, MVMString *conv, MVMObject *arg_spec, MVMObject *ret_spec); void MVM_nativecall_setup(MVMThreadContext *tc, MVMNativeCallBody *body, unsigned int interval_id); void MVM_nativecall_restore_library(MVMThreadContext *tc, MVMNativeCallBody *body, MVMObject *root); MVMObject * MVM_nativecall_invoke(MVMThreadContext *tc, MVMObject *res_type, MVMObject *site, MVMObject *args); void MVM_nativecall_dispatch(MVMThreadContext *tc, MVMObject *res_type, MVMObject *site, MVMArgs args); MVMObject * MVM_nativecall_global(MVMThreadContext *tc, MVMString *lib, MVMString *sym, MVMObject *target_spec, MVMObject *target_type); MVMObject * MVM_nativecall_cast(MVMThreadContext *tc, MVMObject *target_spec, MVMObject *res_type, MVMObject *obj); MVMint64 MVM_nativecall_sizeof(MVMThreadContext *tc, MVMObject *obj); void MVM_nativecall_refresh(MVMThreadContext *tc, MVMObject *cthingy); MVMObject * MVM_nativecall_make_cstruct(MVMThreadContext *tc, MVMObject *type, void *cstruct); MVMObject * MVM_nativecall_make_cppstruct(MVMThreadContext *tc, MVMObject *type, void *cppstruct); MVMObject * MVM_nativecall_make_cunion(MVMThreadContext *tc, MVMObject *type, void *cunion); MVMObject * MVM_nativecall_make_cpointer(MVMThreadContext *tc, MVMObject *type, void *ptr); MVMObject * MVM_nativecall_make_carray(MVMThreadContext *tc, MVMObject *type, void *carray); MVMObject * MVM_nativecall_make_int(MVMThreadContext *tc, MVMObject *type, MVMint64 value); MVMObject * MVM_nativecall_make_uint(MVMThreadContext *tc, MVMObject *type, MVMuint64 value); MVMObject * MVM_nativecall_make_num(MVMThreadContext *tc, MVMObject *type, MVMnum64 value); MVMObject * MVM_nativecall_make_str(MVMThreadContext *tc, MVMObject *type, MVMint16 ret_type, char *cstring); signed char MVM_nativecall_unmarshal_char(MVMThreadContext *tc, MVMObject *value); signed short MVM_nativecall_unmarshal_short(MVMThreadContext *tc, MVMObject *value); signed int MVM_nativecall_unmarshal_int(MVMThreadContext *tc, MVMObject *value); signed long MVM_nativecall_unmarshal_long(MVMThreadContext *tc, MVMObject *value); signed long long MVM_nativecall_unmarshal_longlong(MVMThreadContext *tc, MVMObject *value); unsigned char MVM_nativecall_unmarshal_uchar(MVMThreadContext *tc, MVMObject *value); unsigned short MVM_nativecall_unmarshal_ushort(MVMThreadContext *tc, MVMObject *value); unsigned int MVM_nativecall_unmarshal_uint(MVMThreadContext *tc, MVMObject *value); unsigned long MVM_nativecall_unmarshal_ulong(MVMThreadContext *tc, MVMObject *value); unsigned long long MVM_nativecall_unmarshal_ulonglong(MVMThreadContext *tc, MVMObject *value); float MVM_nativecall_unmarshal_float(MVMThreadContext *tc, MVMObject *value); double MVM_nativecall_unmarshal_double(MVMThreadContext *tc, MVMObject *value); char * MVM_nativecall_encode_string(MVMThreadContext *tc, MVMString *value_str, MVMint16 type, MVMint16 *free, MVMint16 unmarshal_kind, const MVMREPROps *repr); char * MVM_nativecall_unmarshal_string(MVMThreadContext *tc, MVMObject *value, MVMint16 type, MVMint16 *free, MVMint16 unmarshal_kind); void * MVM_nativecall_unmarshal_cstruct(MVMThreadContext *tc, MVMObject *value, MVMint16 unmarshal_kind); void * MVM_nativecall_unmarshal_cppstruct(MVMThreadContext *tc, MVMObject *value, MVMint16 unmarshal_kind); void * MVM_nativecall_unmarshal_cpointer(MVMThreadContext *tc, MVMObject *value, MVMint16 unmarshal_kind); void * MVM_nativecall_unmarshal_carray(MVMThreadContext *tc, MVMObject *value, MVMint16 unmarshal_kind); void * MVM_nativecall_unmarshal_vmarray(MVMThreadContext *tc, MVMObject *value, MVMint16 unmarshal_kind); void * MVM_nativecall_unmarshal_cunion(MVMThreadContext *tc, MVMObject *value, MVMint16 unmarshal_kind); /* Locate the thread that a callback should be run on. */ MVM_STATIC_INLINE MVMThreadContext * MVM_nativecall_find_thread_context(MVMInstance *instance) { MVMThreadContext *tc = MVM_get_running_threads_context(); if (!tc) MVM_panic(1, "native callback ran on thread (%"PRId64") unknown to MoarVM", MVM_platform_thread_id()); return tc; } MVMJitGraph *MVM_nativecall_jit_graph_for_caller_code( MVMThreadContext *tc, MVMSpeshGraph *sg, MVMNativeCallBody *body, MVMint16 restype, MVMint16 dst, MVMSpeshIns **arg_ins );