Fix calling function pointers with FP arguments on arm32
This commit is contained in:
committed by
SvyatoslavScherbina
parent
043e6c54ca
commit
73379a6d59
@@ -67,7 +67,7 @@ import konan.internal.ExportForCompiler
|
||||
|
||||
@ExportForCompiler
|
||||
private fun invokeImplUnitRet(ptr: COpaquePointer, vararg args: Any?): Unit = memScoped {
|
||||
callWithVarargs(ptr.rawValue, nativeNullPtr, FFI_TYPE_KIND_VOID, args, emptyArray(), memScope)
|
||||
callWithVarargs(ptr.rawValue, nativeNullPtr, FFI_TYPE_KIND_VOID, args, null, memScope)
|
||||
}
|
||||
|
||||
@ExportForCompiler
|
||||
@@ -77,48 +77,48 @@ private fun invokeImplBooleanRet(ptr: COpaquePointer, vararg args: Any?): Boolea
|
||||
@ExportForCompiler
|
||||
private fun invokeImplByteRet(ptr: COpaquePointer, vararg args: Any?): Byte = memScoped {
|
||||
val resultBuffer = allocFfiReturnValueBuffer<ByteVar>(ByteVar)
|
||||
callWithVarargs(ptr.rawValue, resultBuffer.rawPtr, FFI_TYPE_KIND_SINT8, args, emptyArray(), memScope)
|
||||
callWithVarargs(ptr.rawValue, resultBuffer.rawPtr, FFI_TYPE_KIND_SINT8, args, null, memScope)
|
||||
resultBuffer.value
|
||||
}
|
||||
|
||||
@ExportForCompiler
|
||||
private fun invokeImplShortRet(ptr: COpaquePointer, vararg args: Any?): Short = memScoped {
|
||||
val resultBuffer = allocFfiReturnValueBuffer<ShortVar>(ShortVar)
|
||||
callWithVarargs(ptr.rawValue, resultBuffer.rawPtr, FFI_TYPE_KIND_SINT16, args, emptyArray(), memScope)
|
||||
callWithVarargs(ptr.rawValue, resultBuffer.rawPtr, FFI_TYPE_KIND_SINT16, args, null, memScope)
|
||||
resultBuffer.value
|
||||
}
|
||||
|
||||
@ExportForCompiler
|
||||
private fun invokeImplIntRet(ptr: COpaquePointer, vararg args: Any?): Int = memScoped {
|
||||
val resultBuffer = allocFfiReturnValueBuffer<IntVar>(IntVar)
|
||||
callWithVarargs(ptr.rawValue, resultBuffer.rawPtr, FFI_TYPE_KIND_SINT32, args, emptyArray(), memScope)
|
||||
callWithVarargs(ptr.rawValue, resultBuffer.rawPtr, FFI_TYPE_KIND_SINT32, args, null, memScope)
|
||||
resultBuffer.value
|
||||
}
|
||||
|
||||
@ExportForCompiler
|
||||
private fun invokeImplLongRet(ptr: COpaquePointer, vararg args: Any?): Long = memScoped {
|
||||
val resultBuffer = allocFfiReturnValueBuffer<LongVar>(LongVar)
|
||||
callWithVarargs(ptr.rawValue, resultBuffer.rawPtr, FFI_TYPE_KIND_SINT64, args, emptyArray(), memScope)
|
||||
callWithVarargs(ptr.rawValue, resultBuffer.rawPtr, FFI_TYPE_KIND_SINT64, args, null, memScope)
|
||||
resultBuffer.value
|
||||
}
|
||||
|
||||
@ExportForCompiler
|
||||
private fun invokeImplFloatRet(ptr: COpaquePointer, vararg args: Any?): Float = memScoped {
|
||||
val resultBuffer = allocFfiReturnValueBuffer<FloatVar>(FloatVar)
|
||||
callWithVarargs(ptr.rawValue, resultBuffer.rawPtr, FFI_TYPE_KIND_FLOAT, args, emptyArray(), memScope)
|
||||
callWithVarargs(ptr.rawValue, resultBuffer.rawPtr, FFI_TYPE_KIND_FLOAT, args, null, memScope)
|
||||
resultBuffer.value
|
||||
}
|
||||
|
||||
@ExportForCompiler
|
||||
private fun invokeImplDoubleRet(ptr: COpaquePointer, vararg args: Any?): Double = memScoped {
|
||||
val resultBuffer = allocFfiReturnValueBuffer<DoubleVar>(DoubleVar)
|
||||
callWithVarargs(ptr.rawValue, resultBuffer.rawPtr, FFI_TYPE_KIND_DOUBLE, args, emptyArray(), memScope)
|
||||
callWithVarargs(ptr.rawValue, resultBuffer.rawPtr, FFI_TYPE_KIND_DOUBLE, args, null, memScope)
|
||||
resultBuffer.value
|
||||
}
|
||||
|
||||
@ExportForCompiler
|
||||
private fun invokeImplPointerRet(ptr: COpaquePointer, vararg args: Any?): COpaquePointer? = memScoped {
|
||||
val resultBuffer = allocFfiReturnValueBuffer<COpaquePointerVar>(COpaquePointerVar)
|
||||
callWithVarargs(ptr.rawValue, resultBuffer.rawPtr, FFI_TYPE_KIND_POINTER, args, emptyArray(), memScope)
|
||||
callWithVarargs(ptr.rawValue, resultBuffer.rawPtr, FFI_TYPE_KIND_POINTER, args, null, memScope)
|
||||
resultBuffer.value
|
||||
}
|
||||
|
||||
@@ -95,10 +95,10 @@ inline fun <reified T : CVariable> NativePlacement.allocFfiReturnValueBuffer(ty
|
||||
}
|
||||
|
||||
fun callWithVarargs(codePtr: NativePtr, returnValuePtr: NativePtr, returnTypeKind: FfiTypeKind,
|
||||
fixedArguments: Array<out Any?>, variadicArguments: Array<out Any?>,
|
||||
fixedArguments: Array<out Any?>, variadicArguments: Array<out Any?>?,
|
||||
argumentsPlacement: AutofreeScope) {
|
||||
|
||||
val totalArgumentsNumber = fixedArguments.size + variadicArguments.size
|
||||
val totalArgumentsNumber = fixedArguments.size + if (variadicArguments == null) 0 else variadicArguments.size
|
||||
|
||||
// All supported arguments take at most 8 bytes each:
|
||||
val argumentsStorage = argumentsPlacement.allocArray<LongVar>(totalArgumentsNumber)
|
||||
@@ -122,17 +122,30 @@ fun callWithVarargs(codePtr: NativePtr, returnValuePtr: NativePtr, returnTypeKin
|
||||
addArgument(argument, isVariadic = false)
|
||||
}
|
||||
|
||||
for (argument in variadicArguments) {
|
||||
addArgument(argument, isVariadic = true)
|
||||
val variadicArgumentsNumber: Int
|
||||
|
||||
if (variadicArguments != null) {
|
||||
for (argument in variadicArguments) {
|
||||
addArgument(argument, isVariadic = true)
|
||||
}
|
||||
variadicArgumentsNumber = variadicArguments.size
|
||||
} else {
|
||||
variadicArgumentsNumber = -1
|
||||
}
|
||||
|
||||
assert (index == totalArgumentsNumber)
|
||||
|
||||
callWithVarargs(codePtr, returnValuePtr, returnTypeKind, arguments.rawValue, types.rawValue,
|
||||
fixedArguments.size, totalArgumentsNumber)
|
||||
callFunctionPointer(codePtr, returnValuePtr, returnTypeKind, arguments.rawValue, types.rawValue,
|
||||
totalArgumentsNumber, variadicArgumentsNumber)
|
||||
}
|
||||
|
||||
@SymbolName("Kotlin_Interop_callWithVarargs")
|
||||
private external fun callWithVarargs(codePtr: NativePtr, returnValuePtr: NativePtr, returnTypeKind: FfiTypeKind,
|
||||
arguments: NativePtr, argumentTypeKinds: NativePtr,
|
||||
fixedArgumentsNumber: Int, totalArgumentsNumber: Int)
|
||||
@SymbolName("Kotlin_Interop_callFunctionPointer")
|
||||
private external fun callFunctionPointer(
|
||||
codePtr: NativePtr,
|
||||
returnValuePtr: NativePtr,
|
||||
returnTypeKind: FfiTypeKind,
|
||||
arguments: NativePtr,
|
||||
argumentTypeKinds: NativePtr,
|
||||
totalArgumentsNumber: Int,
|
||||
variadicArgumentsNumber: Int
|
||||
)
|
||||
|
||||
@@ -61,9 +61,9 @@ ffi_type* convertFfiTypeKindToType(FfiTypeKind typeKind) {
|
||||
|
||||
extern "C" {
|
||||
|
||||
void Kotlin_Interop_callWithVarargs(void* codePtr, void* returnValuePtr, FfiTypeKind returnTypeKind,
|
||||
void Kotlin_Interop_callFunctionPointer(void* codePtr, void* returnValuePtr, FfiTypeKind returnTypeKind,
|
||||
void** arguments, intptr_t* argumentTypeKinds,
|
||||
int fixedArgumentsNumber, int totalArgumentsNumber) {
|
||||
int totalArgumentsNumber, int variadicArgumentsNumber) {
|
||||
#ifdef KONAN_NO_FFI
|
||||
RuntimeAssert(false, "Vararg calls are not supported on this platform");
|
||||
#else
|
||||
@@ -72,11 +72,18 @@ void Kotlin_Interop_callWithVarargs(void* codePtr, void* returnValuePtr, FfiType
|
||||
for (int i = 0; i < totalArgumentsNumber; ++i) {
|
||||
argumentTypes[i] = convertFfiTypeKindToType((FfiTypeKind) argumentTypeKinds[i]);
|
||||
}
|
||||
ffi_type* returnType = convertFfiTypeKindToType(returnTypeKind);
|
||||
|
||||
ffi_cif cif;
|
||||
ffi_prep_cif_var(&cif, FFI_DEFAULT_ABI,
|
||||
fixedArgumentsNumber, totalArgumentsNumber,
|
||||
convertFfiTypeKindToType(returnTypeKind), argumentTypes);
|
||||
if (variadicArgumentsNumber < 0) {
|
||||
// Non-variadic.
|
||||
ffi_prep_cif(&cif, FFI_DEFAULT_ABI, totalArgumentsNumber, returnType, argumentTypes);
|
||||
} else {
|
||||
int fixedArgumentsNumber = totalArgumentsNumber - variadicArgumentsNumber;
|
||||
ffi_prep_cif_var(&cif, FFI_DEFAULT_ABI,
|
||||
fixedArgumentsNumber, totalArgumentsNumber,
|
||||
returnType, argumentTypes);
|
||||
}
|
||||
|
||||
ffi_call(&cif, (void (*)())codePtr, returnValuePtr, arguments);
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user