예제 #1
0
파일: sq_ffi.cpp 프로젝트: gdos/squilu-1
static SQInteger sq_lib_bind_var(HSQUIRRELVM v)
{
    void **modbuf;
    void *mod;
    void *sym;
    const SQChar *symname;
    const char *type;

    sq_getuserdata(v, 1, (void**)&modbuf, NULL);
    mod = *modbuf;

    sq_getstring(v, 2, &type);

    sq_getstring(v, 3, &symname);
    sym = GET_SYM(mod, symname);
    if (!sym)
        return sq_throwerror(v, "Cannot find symbol");

    FFIVar *ffibuf = (FFIVar*)sq_newuserdata(v, sizeof(FFIVar));
    sq_push_delegate_table(v, FFI_LIB_VAR_TAG);
    sq_setdelegate(v, -2);

    ffibuf->var = sym;
    ffibuf->type = *type;

    return 1;
}
예제 #2
0
	inline SQInteger DefSQAdvancedNonStaticCallback(HSQUIRRELVM vm)
	{
		/* Find the amount of params we got */
		int nparam = sq_gettop(vm);
		SQUserPointer ptr = NULL;
		SQUserPointer real_instance = NULL;
		HSQOBJECT instance;

		/* Get the 'SQ' instance of this class */
		Squirrel::GetInstance(vm, &instance);

		/* Protect against calls to a non-static method in a static way */
		sq_pushroottable(vm);
		sq_pushstring(vm, OTTD2SQ(Tcls::GetClassName()), -1);
		sq_get(vm, -2);
		sq_pushobject(vm, instance);
		if (sq_instanceof(vm) != SQTrue) return sq_throwerror(vm, _SC("class method is non-static"));
		sq_pop(vm, 3);

		/* Get the 'real' instance of this class */
		sq_getinstanceup(vm, 1, &real_instance, 0);
		/* Get the real function pointer */
		sq_getuserdata(vm, nparam, &ptr, 0);
		if (real_instance == NULL) return sq_throwerror(vm, _SC("couldn't detect real instance of class for non-static call"));
		/* Remove the userdata from the stack */
		sq_pop(vm, 1);

		/* Call the function, which its only param is always the VM */
		return (SQInteger)(((Tcls *)real_instance)->*(*(Tmethod *)ptr))(vm);
	}
예제 #3
0
	inline SQInteger DefSQNonStaticCallback(HSQUIRRELVM vm)
	{
		/* Find the amount of params we got */
		int nparam = sq_gettop(vm);
		SQUserPointer ptr = NULL;
		SQUserPointer real_instance = NULL;
		HSQOBJECT instance;

		/* Get the 'SQ' instance of this class */
		Squirrel::GetInstance(vm, &instance);

		/* Protect against calls to a non-static method in a static way */
		sq_pushroottable(vm);
		sq_pushstring(vm, OTTD2SQ(Tcls::GetClassName()), -1);
		sq_get(vm, -2);
		sq_pushobject(vm, instance);
		if (sq_instanceof(vm) != SQTrue) return sq_throwerror(vm, _SC("class method is non-static"));
		sq_pop(vm, 3);

		/* Get the 'real' instance of this class */
		sq_getinstanceup(vm, 1, &real_instance, 0);
		/* Get the real function pointer */
		sq_getuserdata(vm, nparam, &ptr, 0);
		if (real_instance == NULL) return sq_throwerror(vm, _SC("couldn't detect real instance of class for non-static call"));
		/* Remove the userdata from the stack */
		sq_pop(vm, 1);

		try {
			/* Delegate it to a template that can handle this specific function */
			return HelperT<Tmethod>::SQCall((Tcls *)real_instance, *(Tmethod *)ptr, vm);
		} catch (SQInteger e) {
			sq_pop(vm, nparam);
			return e;
		}
	}
예제 #4
0
 static void demarshal(HSQUIRRELVM vm, IndexPack<I...> indices)
 {
   T* instance = nullptr;
   void (T::**method)(A...) = nullptr;
   sq_getinstanceup(vm, 1, (SQUserPointer*) &instance, nullptr);
   sq_getuserdata(vm, -1, (SQUserPointer*) &method, nullptr);
   (instance->**method)(detail::get<A>(vm, I + 2)...);
 }
예제 #5
0
	inline SQInteger DefSQStaticCallback(HSQUIRRELVM vm)
	{
		/* Find the amount of params we got */
		int nparam = sq_gettop(vm);
		SQUserPointer ptr = NULL;

		/* Get the real function pointer */
		sq_getuserdata(vm, nparam, &ptr, 0);

		try {
			/* Delegate it to a template that can handle this specific function */
			return HelperT<Tmethod>::SQCall((Tcls *)NULL, *(Tmethod *)ptr, vm);
		} catch (SQInteger e) {
			sq_pop(vm, nparam);
			return e;
		}
	}
예제 #6
0
파일: sq_ffi.cpp 프로젝트: gdos/squilu-1
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;
}
예제 #7
0
파일: sq_ffi.cpp 프로젝트: gdos/squilu-1
static SQInteger sq_func__call(HSQUIRRELVM v)
{
    FFIFunc *ffibuf;
    sq_getuserdata(v, 1, (void**)&ffibuf, NULL);
    int top = sq_gettop(v);
//    printf("ffibuf %p top %d\n", ffibuf, top);

    if (ffibuf->cif.nargs != ((unsigned)(top - EXTRA_PARAMS)))
        return sq_throwerror(v, "Wrong number of args");

    SQInteger values[top - EXTRA_PARAMS];
    void *valueptrs[top - EXTRA_PARAMS];
    int i;
    for (i = EXTRA_PARAMS + 1; i <= top; i++) {
        #define pi (i - (EXTRA_PARAMS + 1))
        switch (sq_gettype(v, i)) {
        case OT_INTEGER:
            sq_getinteger(v, i, (SQInteger*)&values[pi]);
            break;
        case OT_STRING:
            sq_getstring(v, i, (const char**)&values[pi]);
            break;
        case OT_INSTANCE: {
            if (SQ_FAILED(sqstd_getblob(v, i, (SQUserPointer*)&values[pi])))
                return SQ_ERROR;
            break;
        }
        default:
            return sq_throwerror(v, "Unimplemented type");
        }
        valueptrs[pi] = &values[pi];
    }

    ptrdiff_t rc;
//    printf("Before call, %p\n", ffibuf->func);
    ffi_call(&ffibuf->cif, (void(*)())ffibuf->func, &rc, valueptrs);
    return_ffi_value(v, rc, ffibuf->rettype);
    return 1;
}
예제 #8
0
파일: sq_ffi.cpp 프로젝트: gdos/squilu-1
static SQInteger sq_var_get(HSQUIRRELVM v)
{
    FFIVar *ffibuf;
    sq_getuserdata(v, 1, (void**)&ffibuf, NULL);
    void *pval = ffibuf->var;
    switch (ffibuf->type) {
    case 's':
        sq_pushstring(v, *(char**)pval, -1);
        break;
    case 'i':
        sq_pushinteger(v, *(int*)pval);
        break;
    case 'I':
        sq_pushinteger(v, *(unsigned int*)pval);
        break;
    case 'h':
        sq_pushinteger(v, *(short*)pval);
        break;
    case 'H':
        sq_pushinteger(v, *(unsigned short*)pval);
        break;
    case 'l':
        sq_pushinteger(v, *(long*)pval);
        break;
    case 'L':
        sq_pushinteger(v, *(unsigned long*)pval);
        break;
    case 'b':
        sq_pushinteger(v, *(char*)pval);
        break;
    case 'B':
        sq_pushinteger(v, *(unsigned char*)pval);
        break;
    default:
        sq_pushinteger(v, *(int*)pval);
    }
    return 1;
}
예제 #9
0
 static void demarshal(HSQUIRRELVM vm, IndexPack<I...> indices)
 {
   void (**function)(A...) = nullptr;
   sq_getuserdata(vm, -1, (SQUserPointer*) &function, nullptr);
   (*function)(detail::get<A>(vm, I + 1)...);
 }