Always use at least register-sized buffer for return value in ffi_call

As required by the libffi docs.
This commit is contained in:
Svyatoslav Scherbina
2017-05-11 11:27:14 +03:00
committed by SvyatoslavScherbina
parent 8f53018653
commit 8c6718ab91
2 changed files with 20 additions and 1 deletions
@@ -69,6 +69,24 @@ private tailrec fun convertArgument(
else -> throw Error("unsupported argument: $argument")
}
inline fun <reified T : CVariable> NativePlacement.allocFfiReturnValueBuffer(type: CVariable.Type): T {
var size = type.size
var align = type.align
// libffi requires return value buffer to be no smaller than system register size;
// TODO: system register size is not exactly the same as pointer size.
if (size < pointerSize) {
size = pointerSize.toLong()
}
if (align < pointerSize) {
align = pointerSize
}
return this.alloc(size, align).reinterpret<T>()
}
fun callWithVarargs(codePtr: NativePtr, returnValuePtr: NativePtr, returnTypeKind: FfiTypeKind,
fixedArguments: Array<out Any?>, variadicArguments: Array<out Any?>,
argumentsPlacement: NativePlacement) {
@@ -891,7 +891,8 @@ class StubGenerator(
val returnValueMirror = mirror(func.returnType)
block(header) {
val resultPtr = if (!func.returnsVoid()) {
out("val resultVar = alloc<${returnValueMirror.pointedTypeName}>()")
val returnType = returnValueMirror.pointedTypeName
out("val resultVar = allocFfiReturnValueBuffer<$returnType>($returnType)")
"resultVar.rawPtr"
} else {
"nativeNullPtr"