STATIC ffi_type *get_ffi_type(mp_obj_t o_in) { if (MP_OBJ_IS_STR(o_in)) { mp_uint_t len; const char *s = mp_obj_str_get_data(o_in, &len); ffi_type *t = char2ffi_type(*s); if (t != NULL) { return t; } } // TODO: Support actual libffi type objects nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "Unknown type")); }
static SQInteger sq_lib_bind_func(HSQUIRRELVM v) { void **modbuf; void *mod; void *sym; const SQChar *symname; const char *rettype; sq_getuserdata(v, 1, (void**)&modbuf, NULL); mod = *modbuf; sq_getstring(v, 2, &rettype); sq_getstring(v, 3, &symname); sym = GET_SYM(mod, symname); if (!sym) return sq_throwerror(v, "Cannot find symbol"); int nparam = sq_getsize(v, 4); int size = sizeof(FFIFunc) + sizeof(ffi_type*) * nparam; FFIFunc *ffibuf = (FFIFunc*)sq_newuserdata(v, size); sq_push_delegate_table(v, FFI_LIB_FUNC_TAG); sq_setdelegate(v, -2); // printf("Allocated %d bytes at %p\n", size, ffibuf); ffibuf->func = sym; ffibuf->rettype = *rettype; int i; for (i = 0; i < nparam; i++) { sq_pushinteger(v, i); sq_get(v, 4); ffibuf->params[i] = get_ffi_type(v, -1); if (!ffibuf->params[i]) return SQ_ERROR; sq_poptop(v); } int res = ffi_prep_cif(&ffibuf->cif, FFI_DEFAULT_ABI, nparam, char2ffi_type(*rettype), ffibuf->params); if (res != FFI_OK) return sq_throwerror(v, "Error in ffi_prep_cif"); return 1; }
static ffi_type *get_ffi_type(HSQUIRRELVM v, int idx) { int type = sq_gettype(v, idx); void *p; const SQChar *s; ffi_type *t; switch (type) { case OT_USERPOINTER: sq_getuserpointer(v, idx, &p); return (ffi_type*)p; case OT_STRING: sq_getstring(v, idx, &s); t = char2ffi_type(*s); if (t) return t; default: sq_throwerror(v, "Type spec must be string or ffi_type"); return NULL; } }