summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWayne Meissner <wmeissner@gmail.com>2009-10-09 13:03:06 +1000
committerWayne Meissner <wmeissner@gmail.com>2009-10-09 13:03:06 +1000
commit0ab5f11400024c4f9804e84a33840ac549a87772 (patch)
treeab51241dce8427164a86b1565c0ae2969aaa3453
parente5e67f4e91c0c017264d7957b3ef5580670a88c6 (diff)
downloadffi-0ab5f11400024c4f9804e84a33840ac549a87772.tar.gz
Use alloca to allocate the result space. Should fix by-value returns from varargs functions, and github issue #5
-rw-r--r--ext/ffi_c/Variadic.c26
1 files changed, 7 insertions, 19 deletions
diff --git a/ext/ffi_c/Variadic.c b/ext/ffi_c/Variadic.c
index 16ce7a6..7160253 100644
--- a/ext/ffi_c/Variadic.c
+++ b/ext/ffi_c/Variadic.c
@@ -145,28 +145,12 @@ variadic_initialize(VALUE self, VALUE rbFunction, VALUE rbParameterTypes, VALUE
return retval;
}
-
-static inline VALUE
-ffi_invoke(ffi_cif* cif, void* function, Type* returnType, void** ffiValues,
- VALUE rbReturnType, VALUE rbEnums)
-{
- FFIStorage retval;
-
-#ifdef USE_RAW
- ffi_raw_call(cif, function, &retval, (ffi_raw *) ffiValues[0]);
-#else
- ffi_call(cif, function, &retval, ffiValues);
-#endif
- rbffi_save_errno();
-
- return rbffi_NativeValue_ToRuby(returnType, rbReturnType, &retval, rbEnums);
-}
-
static VALUE
variadic_invoke(VALUE self, VALUE parameterTypes, VALUE parameterValues)
{
VariadicInvoker* invoker;
FFIStorage* params;
+ void* retval;
ffi_cif cif;
void** ffiValues;
ffi_type** ffiParamTypes;
@@ -186,6 +170,7 @@ variadic_invoke(VALUE self, VALUE parameterTypes, VALUE parameterValues)
params = ALLOCA_N(FFIStorage, paramCount);
ffiValues = ALLOCA_N(void*, paramCount);
argv = ALLOCA_N(VALUE, paramCount);
+ retval = alloca(MAX(invoker->returnType->ffiType->size, FFI_SIZEOF_ARG));
for (i = 0; i < paramCount; ++i) {
VALUE entry = rb_ary_entry(parameterTypes, i);
@@ -241,8 +226,11 @@ variadic_invoke(VALUE self, VALUE parameterTypes, VALUE parameterValues)
rbffi_SetupCallParams(paramCount, argv, -1, paramTypes, params,
ffiValues, NULL, 0, invoker->rbEnums);
- return ffi_invoke(&cif, invoker->function, invoker->returnType,
- ffiValues, invoker->rbReturnType, invoker->rbEnums);
+ ffi_call(&cif, invoker->function, retval, ffiValues);
+
+ rbffi_save_errno();
+
+ return rbffi_NativeValue_ToRuby(invoker->returnType, invoker->rbReturnType, retval, invoker->rbEnums);
}