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
|
@ExportForCompiler
|
||||||
private fun invokeImplUnitRet(ptr: COpaquePointer, vararg args: Any?): Unit = memScoped {
|
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
|
@ExportForCompiler
|
||||||
@@ -77,48 +77,48 @@ private fun invokeImplBooleanRet(ptr: COpaquePointer, vararg args: Any?): Boolea
|
|||||||
@ExportForCompiler
|
@ExportForCompiler
|
||||||
private fun invokeImplByteRet(ptr: COpaquePointer, vararg args: Any?): Byte = memScoped {
|
private fun invokeImplByteRet(ptr: COpaquePointer, vararg args: Any?): Byte = memScoped {
|
||||||
val resultBuffer = allocFfiReturnValueBuffer<ByteVar>(ByteVar)
|
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
|
resultBuffer.value
|
||||||
}
|
}
|
||||||
|
|
||||||
@ExportForCompiler
|
@ExportForCompiler
|
||||||
private fun invokeImplShortRet(ptr: COpaquePointer, vararg args: Any?): Short = memScoped {
|
private fun invokeImplShortRet(ptr: COpaquePointer, vararg args: Any?): Short = memScoped {
|
||||||
val resultBuffer = allocFfiReturnValueBuffer<ShortVar>(ShortVar)
|
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
|
resultBuffer.value
|
||||||
}
|
}
|
||||||
|
|
||||||
@ExportForCompiler
|
@ExportForCompiler
|
||||||
private fun invokeImplIntRet(ptr: COpaquePointer, vararg args: Any?): Int = memScoped {
|
private fun invokeImplIntRet(ptr: COpaquePointer, vararg args: Any?): Int = memScoped {
|
||||||
val resultBuffer = allocFfiReturnValueBuffer<IntVar>(IntVar)
|
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
|
resultBuffer.value
|
||||||
}
|
}
|
||||||
|
|
||||||
@ExportForCompiler
|
@ExportForCompiler
|
||||||
private fun invokeImplLongRet(ptr: COpaquePointer, vararg args: Any?): Long = memScoped {
|
private fun invokeImplLongRet(ptr: COpaquePointer, vararg args: Any?): Long = memScoped {
|
||||||
val resultBuffer = allocFfiReturnValueBuffer<LongVar>(LongVar)
|
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
|
resultBuffer.value
|
||||||
}
|
}
|
||||||
|
|
||||||
@ExportForCompiler
|
@ExportForCompiler
|
||||||
private fun invokeImplFloatRet(ptr: COpaquePointer, vararg args: Any?): Float = memScoped {
|
private fun invokeImplFloatRet(ptr: COpaquePointer, vararg args: Any?): Float = memScoped {
|
||||||
val resultBuffer = allocFfiReturnValueBuffer<FloatVar>(FloatVar)
|
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
|
resultBuffer.value
|
||||||
}
|
}
|
||||||
|
|
||||||
@ExportForCompiler
|
@ExportForCompiler
|
||||||
private fun invokeImplDoubleRet(ptr: COpaquePointer, vararg args: Any?): Double = memScoped {
|
private fun invokeImplDoubleRet(ptr: COpaquePointer, vararg args: Any?): Double = memScoped {
|
||||||
val resultBuffer = allocFfiReturnValueBuffer<DoubleVar>(DoubleVar)
|
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
|
resultBuffer.value
|
||||||
}
|
}
|
||||||
|
|
||||||
@ExportForCompiler
|
@ExportForCompiler
|
||||||
private fun invokeImplPointerRet(ptr: COpaquePointer, vararg args: Any?): COpaquePointer? = memScoped {
|
private fun invokeImplPointerRet(ptr: COpaquePointer, vararg args: Any?): COpaquePointer? = memScoped {
|
||||||
val resultBuffer = allocFfiReturnValueBuffer<COpaquePointerVar>(COpaquePointerVar)
|
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
|
resultBuffer.value
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -95,10 +95,10 @@ inline fun <reified T : CVariable> NativePlacement.allocFfiReturnValueBuffer(ty
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun callWithVarargs(codePtr: NativePtr, returnValuePtr: NativePtr, returnTypeKind: FfiTypeKind,
|
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) {
|
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:
|
// All supported arguments take at most 8 bytes each:
|
||||||
val argumentsStorage = argumentsPlacement.allocArray<LongVar>(totalArgumentsNumber)
|
val argumentsStorage = argumentsPlacement.allocArray<LongVar>(totalArgumentsNumber)
|
||||||
@@ -122,17 +122,30 @@ fun callWithVarargs(codePtr: NativePtr, returnValuePtr: NativePtr, returnTypeKin
|
|||||||
addArgument(argument, isVariadic = false)
|
addArgument(argument, isVariadic = false)
|
||||||
}
|
}
|
||||||
|
|
||||||
for (argument in variadicArguments) {
|
val variadicArgumentsNumber: Int
|
||||||
addArgument(argument, isVariadic = true)
|
|
||||||
|
if (variadicArguments != null) {
|
||||||
|
for (argument in variadicArguments) {
|
||||||
|
addArgument(argument, isVariadic = true)
|
||||||
|
}
|
||||||
|
variadicArgumentsNumber = variadicArguments.size
|
||||||
|
} else {
|
||||||
|
variadicArgumentsNumber = -1
|
||||||
}
|
}
|
||||||
|
|
||||||
assert (index == totalArgumentsNumber)
|
assert (index == totalArgumentsNumber)
|
||||||
|
|
||||||
callWithVarargs(codePtr, returnValuePtr, returnTypeKind, arguments.rawValue, types.rawValue,
|
callFunctionPointer(codePtr, returnValuePtr, returnTypeKind, arguments.rawValue, types.rawValue,
|
||||||
fixedArguments.size, totalArgumentsNumber)
|
totalArgumentsNumber, variadicArgumentsNumber)
|
||||||
}
|
}
|
||||||
|
|
||||||
@SymbolName("Kotlin_Interop_callWithVarargs")
|
@SymbolName("Kotlin_Interop_callFunctionPointer")
|
||||||
private external fun callWithVarargs(codePtr: NativePtr, returnValuePtr: NativePtr, returnTypeKind: FfiTypeKind,
|
private external fun callFunctionPointer(
|
||||||
arguments: NativePtr, argumentTypeKinds: NativePtr,
|
codePtr: NativePtr,
|
||||||
fixedArgumentsNumber: Int, totalArgumentsNumber: Int)
|
returnValuePtr: NativePtr,
|
||||||
|
returnTypeKind: FfiTypeKind,
|
||||||
|
arguments: NativePtr,
|
||||||
|
argumentTypeKinds: NativePtr,
|
||||||
|
totalArgumentsNumber: Int,
|
||||||
|
variadicArgumentsNumber: Int
|
||||||
|
)
|
||||||
|
|||||||
@@ -61,9 +61,9 @@ ffi_type* convertFfiTypeKindToType(FfiTypeKind typeKind) {
|
|||||||
|
|
||||||
extern "C" {
|
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,
|
void** arguments, intptr_t* argumentTypeKinds,
|
||||||
int fixedArgumentsNumber, int totalArgumentsNumber) {
|
int totalArgumentsNumber, int variadicArgumentsNumber) {
|
||||||
#ifdef KONAN_NO_FFI
|
#ifdef KONAN_NO_FFI
|
||||||
RuntimeAssert(false, "Vararg calls are not supported on this platform");
|
RuntimeAssert(false, "Vararg calls are not supported on this platform");
|
||||||
#else
|
#else
|
||||||
@@ -72,11 +72,18 @@ void Kotlin_Interop_callWithVarargs(void* codePtr, void* returnValuePtr, FfiType
|
|||||||
for (int i = 0; i < totalArgumentsNumber; ++i) {
|
for (int i = 0; i < totalArgumentsNumber; ++i) {
|
||||||
argumentTypes[i] = convertFfiTypeKindToType((FfiTypeKind) argumentTypeKinds[i]);
|
argumentTypes[i] = convertFfiTypeKindToType((FfiTypeKind) argumentTypeKinds[i]);
|
||||||
}
|
}
|
||||||
|
ffi_type* returnType = convertFfiTypeKindToType(returnTypeKind);
|
||||||
|
|
||||||
ffi_cif cif;
|
ffi_cif cif;
|
||||||
ffi_prep_cif_var(&cif, FFI_DEFAULT_ABI,
|
if (variadicArgumentsNumber < 0) {
|
||||||
fixedArgumentsNumber, totalArgumentsNumber,
|
// Non-variadic.
|
||||||
convertFfiTypeKindToType(returnTypeKind), argumentTypes);
|
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);
|
ffi_call(&cif, (void (*)())codePtr, returnValuePtr, arguments);
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user