Interop: improve by using callbacks in Indexer
This commit is contained in:
@@ -17,12 +17,6 @@ def compilerArgsForJniIncludes = ["", "linux", "darwin"].collect { "-I$javaHome/
|
||||
|
||||
model {
|
||||
components {
|
||||
callback(NativeLibrarySpec) {
|
||||
binaries.all {
|
||||
cCompiler.args compilerArgsForJniIncludes
|
||||
}
|
||||
}
|
||||
|
||||
clangbridge(NativeLibrarySpec) {
|
||||
sources {
|
||||
c.source.srcDir 'prebuilt/nativeInteropStubs/c'
|
||||
@@ -59,9 +53,8 @@ dependencies {
|
||||
}
|
||||
|
||||
task nativelibs(type: Copy) {
|
||||
dependsOn 'callbackSharedLibrary', 'clangbridgeSharedLibrary'
|
||||
dependsOn 'clangbridgeSharedLibrary'
|
||||
|
||||
from "$buildDir/libs/callback/shared/"
|
||||
from "$buildDir/libs/clangbridge/shared/"
|
||||
into "$buildDir/nativelibs/"
|
||||
}
|
||||
|
||||
@@ -1256,9 +1256,9 @@ fun clang_getIBOutletCollectionType(arg0: CXCursor, retValPlacement: Placement):
|
||||
return NativePtr.byValue(res).asRef(CXType)!!
|
||||
}
|
||||
|
||||
fun clang_visitChildren(parent: CXCursor, visitor: NativePtr?, client_data: NativePtr?): Int {
|
||||
fun clang_visitChildren(parent: CXCursor, visitor: ((CXCursor, CXCursor, NativePtr?) -> CXChildVisitResult)?, client_data: NativePtr?): Int {
|
||||
val _parent = parent.getNativePtr().asLong()
|
||||
val _visitor = visitor.asLong()
|
||||
val _visitor = visitor?.staticAsNative(NativeFunctionType1).asLong()
|
||||
val _client_data = client_data.asLong()
|
||||
val res = externals.clang_visitChildren(_parent, _visitor, _client_data)
|
||||
return res
|
||||
@@ -1636,8 +1636,8 @@ fun clang_enableStackTraces(): Unit {
|
||||
return res
|
||||
}
|
||||
|
||||
fun clang_executeOnThread(fn: NativePtr?, user_data: NativePtr?, stack_size: Int): Unit {
|
||||
val _fn = fn.asLong()
|
||||
fun clang_executeOnThread(fn: ((NativePtr?) -> Unit)?, user_data: NativePtr?, stack_size: Int): Unit {
|
||||
val _fn = fn?.staticAsNative(NativeFunctionType2).asLong()
|
||||
val _user_data = user_data.asLong()
|
||||
val res = externals.clang_executeOnThread(_fn, _user_data, stack_size)
|
||||
return res
|
||||
@@ -1790,9 +1790,9 @@ fun clang_toggleCrashRecovery(isEnabled: Int): Unit {
|
||||
return res
|
||||
}
|
||||
|
||||
fun clang_getInclusions(tu: CXTranslationUnitImpl?, visitor: NativePtr?, client_data: NativePtr?): Unit {
|
||||
fun clang_getInclusions(tu: CXTranslationUnitImpl?, visitor: ((NativePtr?, CXSourceLocation?, Int, NativePtr?) -> Unit)?, client_data: NativePtr?): Unit {
|
||||
val _tu = tu.getNativePtr().asLong()
|
||||
val _visitor = visitor.asLong()
|
||||
val _visitor = visitor?.staticAsNative(NativeFunctionType3).asLong()
|
||||
val _client_data = client_data.asLong()
|
||||
val res = externals.clang_getInclusions(_tu, _visitor, _client_data)
|
||||
return res
|
||||
@@ -1986,9 +1986,9 @@ fun clang_indexLoc_getCXSourceLocation(loc: CXIdxLoc, retValPlacement: Placement
|
||||
return NativePtr.byValue(res).asRef(CXSourceLocation)!!
|
||||
}
|
||||
|
||||
fun clang_Type_visitFields(T: CXType, visitor: NativePtr?, client_data: NativePtr?): Int {
|
||||
fun clang_Type_visitFields(T: CXType, visitor: ((CXCursor, NativePtr?) -> CXVisitorResult)?, client_data: NativePtr?): Int {
|
||||
val _T = T.getNativePtr().asLong()
|
||||
val _visitor = visitor.asLong()
|
||||
val _visitor = visitor?.staticAsNative(NativeFunctionType4).asLong()
|
||||
val _client_data = client_data.asLong()
|
||||
val res = externals.clang_Type_visitFields(_T, _visitor, _client_data)
|
||||
return res
|
||||
@@ -2006,7 +2006,7 @@ class __darwin_pthread_handler_rec(ptr: NativePtr) : NativeStruct(ptr) {
|
||||
|
||||
companion object : Type<__darwin_pthread_handler_rec>(24, ::__darwin_pthread_handler_rec)
|
||||
|
||||
val __routine by NativePtrBox at 0
|
||||
val __routine by NativeFunctionType2.ref at 0
|
||||
val __arg by NativePtrBox at 8
|
||||
val __next by __darwin_pthread_handler_rec.ref at 16
|
||||
}
|
||||
@@ -2266,7 +2266,7 @@ class CXCursorAndRangeVisitor(ptr: NativePtr) : NativeStruct(ptr) {
|
||||
companion object : Type<CXCursorAndRangeVisitor>(16, ::CXCursorAndRangeVisitor)
|
||||
|
||||
val context by NativePtrBox at 0
|
||||
val visit by NativePtrBox at 8
|
||||
val visit by NativeFunctionType5.ref at 8
|
||||
}
|
||||
|
||||
class CXIdxLoc(ptr: NativePtr) : NativeStruct(ptr) {
|
||||
@@ -2446,14 +2446,14 @@ class IndexerCallbacks(ptr: NativePtr) : NativeStruct(ptr) {
|
||||
|
||||
companion object : Type<IndexerCallbacks>(64, ::IndexerCallbacks)
|
||||
|
||||
val abortQuery by NativePtrBox at 0
|
||||
val diagnostic by NativePtrBox at 8
|
||||
val enteredMainFile by NativePtrBox at 16
|
||||
val ppIncludedFile by NativePtrBox at 24
|
||||
val importedASTFile by NativePtrBox at 32
|
||||
val startedTranslationUnit by NativePtrBox at 40
|
||||
val indexDeclaration by NativePtrBox at 48
|
||||
val indexEntityReference by NativePtrBox at 56
|
||||
val abortQuery by NativeFunctionType6.ref at 0
|
||||
val diagnostic by NativeFunctionType7.ref at 8
|
||||
val enteredMainFile by NativeFunctionType8.ref at 16
|
||||
val ppIncludedFile by NativeFunctionType9.ref at 24
|
||||
val importedASTFile by NativeFunctionType10.ref at 32
|
||||
val startedTranslationUnit by NativeFunctionType11.ref at 40
|
||||
val indexDeclaration by NativeFunctionType12.ref at 48
|
||||
val indexEntityReference by NativeFunctionType13.ref at 56
|
||||
}
|
||||
|
||||
enum class CXErrorCode(val value: Int) {
|
||||
@@ -3570,6 +3570,92 @@ enum class CXIndexOptFlags(val value: Int) {
|
||||
}
|
||||
}
|
||||
|
||||
object NativeFunctionType1 : NativeFunctionType<(CXCursor, CXCursor, NativePtr?) -> CXChildVisitResult>(UInt32, Struct(UInt32, SInt32, Pointer), Struct(UInt32, SInt32, Pointer), Pointer) {
|
||||
override fun invoke(function: (CXCursor, CXCursor, NativePtr?) -> CXChildVisitResult, args: NativeArray<NativePtrBox>, ret: NativePtr) {
|
||||
val res = function(args[0].value.asRef(CXCursor)!!, args[1].value.asRef(CXCursor)!!, args[2].value.asRef(NativePtrBox)!!.value)
|
||||
CXChildVisitResult.ref.byPtr(ret).value = res
|
||||
}
|
||||
}
|
||||
|
||||
object NativeFunctionType2 : NativeFunctionType<(NativePtr?) -> Unit>(Void, Pointer) {
|
||||
override fun invoke(function: (NativePtr?) -> Unit, args: NativeArray<NativePtrBox>, ret: NativePtr) {
|
||||
val res = function(args[0].value.asRef(NativePtrBox)!!.value)
|
||||
}
|
||||
}
|
||||
|
||||
object NativeFunctionType3 : NativeFunctionType<(NativePtr?, CXSourceLocation?, Int, NativePtr?) -> Unit>(Void, Pointer, Pointer, UInt32, Pointer) {
|
||||
override fun invoke(function: (NativePtr?, CXSourceLocation?, Int, NativePtr?) -> Unit, args: NativeArray<NativePtrBox>, ret: NativePtr) {
|
||||
val res = function(args[0].value.asRef(NativePtrBox)!!.value, args[1].value.asRef(CXSourceLocation.ref)!!.value, args[2].value.asRef(Int32Box)!!.value, args[3].value.asRef(NativePtrBox)!!.value)
|
||||
}
|
||||
}
|
||||
|
||||
object NativeFunctionType4 : NativeFunctionType<(CXCursor, NativePtr?) -> CXVisitorResult>(UInt32, Struct(UInt32, SInt32, Pointer), Pointer) {
|
||||
override fun invoke(function: (CXCursor, NativePtr?) -> CXVisitorResult, args: NativeArray<NativePtrBox>, ret: NativePtr) {
|
||||
val res = function(args[0].value.asRef(CXCursor)!!, args[1].value.asRef(NativePtrBox)!!.value)
|
||||
CXVisitorResult.ref.byPtr(ret).value = res
|
||||
}
|
||||
}
|
||||
|
||||
object NativeFunctionType5 : NativeFunctionType<(NativePtr?, CXCursor, CXSourceRange) -> CXVisitorResult>(UInt32, Pointer, Struct(UInt32, SInt32, Pointer), Struct(Pointer, UInt32, UInt32)) {
|
||||
override fun invoke(function: (NativePtr?, CXCursor, CXSourceRange) -> CXVisitorResult, args: NativeArray<NativePtrBox>, ret: NativePtr) {
|
||||
val res = function(args[0].value.asRef(NativePtrBox)!!.value, args[1].value.asRef(CXCursor)!!, args[2].value.asRef(CXSourceRange)!!)
|
||||
CXVisitorResult.ref.byPtr(ret).value = res
|
||||
}
|
||||
}
|
||||
|
||||
object NativeFunctionType6 : NativeFunctionType<(NativePtr?, NativePtr?) -> Int>(SInt32, Pointer, Pointer) {
|
||||
override fun invoke(function: (NativePtr?, NativePtr?) -> Int, args: NativeArray<NativePtrBox>, ret: NativePtr) {
|
||||
val res = function(args[0].value.asRef(NativePtrBox)!!.value, args[1].value.asRef(NativePtrBox)!!.value)
|
||||
Int32Box.byPtr(ret).value = res
|
||||
}
|
||||
}
|
||||
|
||||
object NativeFunctionType7 : NativeFunctionType<(NativePtr?, NativePtr?, NativePtr?) -> Unit>(Void, Pointer, Pointer, Pointer) {
|
||||
override fun invoke(function: (NativePtr?, NativePtr?, NativePtr?) -> Unit, args: NativeArray<NativePtrBox>, ret: NativePtr) {
|
||||
val res = function(args[0].value.asRef(NativePtrBox)!!.value, args[1].value.asRef(NativePtrBox)!!.value, args[2].value.asRef(NativePtrBox)!!.value)
|
||||
}
|
||||
}
|
||||
|
||||
object NativeFunctionType8 : NativeFunctionType<(NativePtr?, NativePtr?, NativePtr?) -> NativePtr?>(Pointer, Pointer, Pointer, Pointer) {
|
||||
override fun invoke(function: (NativePtr?, NativePtr?, NativePtr?) -> NativePtr?, args: NativeArray<NativePtrBox>, ret: NativePtr) {
|
||||
val res = function(args[0].value.asRef(NativePtrBox)!!.value, args[1].value.asRef(NativePtrBox)!!.value, args[2].value.asRef(NativePtrBox)!!.value)
|
||||
NativePtrBox.byPtr(ret).value = res
|
||||
}
|
||||
}
|
||||
|
||||
object NativeFunctionType9 : NativeFunctionType<(NativePtr?, CXIdxIncludedFileInfo?) -> NativePtr?>(Pointer, Pointer, Pointer) {
|
||||
override fun invoke(function: (NativePtr?, CXIdxIncludedFileInfo?) -> NativePtr?, args: NativeArray<NativePtrBox>, ret: NativePtr) {
|
||||
val res = function(args[0].value.asRef(NativePtrBox)!!.value, args[1].value.asRef(CXIdxIncludedFileInfo.ref)!!.value)
|
||||
NativePtrBox.byPtr(ret).value = res
|
||||
}
|
||||
}
|
||||
|
||||
object NativeFunctionType10 : NativeFunctionType<(NativePtr?, CXIdxImportedASTFileInfo?) -> NativePtr?>(Pointer, Pointer, Pointer) {
|
||||
override fun invoke(function: (NativePtr?, CXIdxImportedASTFileInfo?) -> NativePtr?, args: NativeArray<NativePtrBox>, ret: NativePtr) {
|
||||
val res = function(args[0].value.asRef(NativePtrBox)!!.value, args[1].value.asRef(CXIdxImportedASTFileInfo.ref)!!.value)
|
||||
NativePtrBox.byPtr(ret).value = res
|
||||
}
|
||||
}
|
||||
|
||||
object NativeFunctionType11 : NativeFunctionType<(NativePtr?, NativePtr?) -> NativePtr?>(Pointer, Pointer, Pointer) {
|
||||
override fun invoke(function: (NativePtr?, NativePtr?) -> NativePtr?, args: NativeArray<NativePtrBox>, ret: NativePtr) {
|
||||
val res = function(args[0].value.asRef(NativePtrBox)!!.value, args[1].value.asRef(NativePtrBox)!!.value)
|
||||
NativePtrBox.byPtr(ret).value = res
|
||||
}
|
||||
}
|
||||
|
||||
object NativeFunctionType12 : NativeFunctionType<(NativePtr?, CXIdxDeclInfo?) -> Unit>(Void, Pointer, Pointer) {
|
||||
override fun invoke(function: (NativePtr?, CXIdxDeclInfo?) -> Unit, args: NativeArray<NativePtrBox>, ret: NativePtr) {
|
||||
val res = function(args[0].value.asRef(NativePtrBox)!!.value, args[1].value.asRef(CXIdxDeclInfo.ref)!!.value)
|
||||
}
|
||||
}
|
||||
|
||||
object NativeFunctionType13 : NativeFunctionType<(NativePtr?, CXIdxEntityRefInfo?) -> Unit>(Void, Pointer, Pointer) {
|
||||
override fun invoke(function: (NativePtr?, CXIdxEntityRefInfo?) -> Unit, args: NativeArray<NativePtrBox>, ret: NativePtr) {
|
||||
val res = function(args[0].value.asRef(NativePtrBox)!!.value, args[1].value.asRef(CXIdxEntityRefInfo.ref)!!.value)
|
||||
}
|
||||
}
|
||||
|
||||
object externals {
|
||||
init { System.loadLibrary("clangbridge") }
|
||||
external fun asctime(arg0: Long): Long
|
||||
|
||||
@@ -1,49 +0,0 @@
|
||||
#include <jni.h>
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
|
||||
static JavaVM *vm = NULL;
|
||||
|
||||
// Returns the JNI env which can be used by the caller.
|
||||
// If current thread is not attached to JVM, then it gets attached as daemon.
|
||||
static JNIEnv* getCurrentEnv() {
|
||||
JNIEnv* env;
|
||||
assert (vm != NULL);
|
||||
jint res = (*vm)->GetEnv(vm, (void**)&env, JNI_VERSION_1_1);
|
||||
if (res != JNI_OK) {
|
||||
assert (res == JNI_EDETACHED);
|
||||
res = (*vm)->AttachCurrentThreadAsDaemon(vm, (void**)&env, NULL);
|
||||
assert (res == JNI_OK);
|
||||
}
|
||||
return env;
|
||||
}
|
||||
|
||||
jint JNI_OnLoad(JavaVM *vm_, void *reserved) {
|
||||
vm = vm_;
|
||||
return JNI_VERSION_1_1;
|
||||
}
|
||||
|
||||
// The implementation of native callback.
|
||||
void indexDeclarationNativeCallback(void* arg1, void* arg2) {
|
||||
JNIEnv* env = getCurrentEnv();
|
||||
|
||||
static jclass cls = NULL;
|
||||
static jmethodID entryFromNative = NULL;
|
||||
|
||||
if (cls == NULL) {
|
||||
cls = (*env)->FindClass(env, "org/jetbrains/kotlin/native/interop/indexer/indexDeclarationCallback");
|
||||
assert(cls != NULL);
|
||||
entryFromNative = (*env)->GetStaticMethodID(env, cls, "entryFromNative", "(J)V");
|
||||
assert(entryFromNative != NULL);
|
||||
}
|
||||
|
||||
(*env)->CallStaticVoidMethod(env, cls, entryFromNative, (jlong) arg2);
|
||||
if ((*env)->ExceptionCheck(env)) {
|
||||
(*env)->ExceptionDescribe(env);
|
||||
assert(0);
|
||||
}
|
||||
}
|
||||
|
||||
JNIEXPORT jlong JNICALL Java_org_jetbrains_kotlin_native_interop_indexer_indexDeclarationCallback_nativeCallbackPtr(JNIEnv *env, jobject obj) {
|
||||
return (jlong) indexDeclarationNativeCallback;
|
||||
}
|
||||
-55
@@ -1,55 +0,0 @@
|
||||
package org.jetbrains.kotlin.native.interop.indexer
|
||||
|
||||
import clang.CXIdxDeclInfo
|
||||
import kotlin_native.interop.NativePtr
|
||||
|
||||
/**
|
||||
* This object helps to create native callbacks with signature `void (CXClientData, const CXIdxDeclInfo *)`.
|
||||
* At any time only one instance of native callback can exist.
|
||||
*/
|
||||
internal object indexDeclarationCallback {
|
||||
|
||||
/**
|
||||
* The Kotlin function to be called when native callback is called.
|
||||
*/
|
||||
private var function: ((CXIdxDeclInfo)->Unit)? = null
|
||||
|
||||
/**
|
||||
* Creates instance of native callback with given Kotlin implementation.
|
||||
*
|
||||
* To create another one, this instance must be destroyed using [reset].
|
||||
*/
|
||||
fun setUp(func: (CXIdxDeclInfo)->Unit): NativePtr {
|
||||
assert (function == null)
|
||||
function = func
|
||||
return nativeCallbackPtr
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroys the (only) instance of native callback.
|
||||
*/
|
||||
fun reset() {
|
||||
assert (function != null)
|
||||
function = null
|
||||
}
|
||||
|
||||
/**
|
||||
* This function is called from native callback implementation.
|
||||
*/
|
||||
@JvmStatic
|
||||
private fun entryFromNative(info: Long) {
|
||||
function!!(CXIdxDeclInfo(NativePtr.Companion.byValue(info)!!))
|
||||
}
|
||||
|
||||
private val nativeCallbackPtr: NativePtr
|
||||
|
||||
init {
|
||||
System.loadLibrary("callback")
|
||||
nativeCallbackPtr = NativePtr.byValue(nativeCallbackPtr())!!
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the pointer to native callback.
|
||||
*/
|
||||
private external fun nativeCallbackPtr(): Long
|
||||
}
|
||||
+37
-13
@@ -10,7 +10,9 @@ private class StructDeclImpl(spelling: String) : StructDecl(spelling) {
|
||||
override var def: StructDefImpl? = null
|
||||
}
|
||||
|
||||
private class StructDefImpl(size: Long, decl: StructDecl) : StructDef(size, decl) {
|
||||
private class StructDefImpl(size: Long, decl: StructDecl, hasNaturalLayout: Boolean) :
|
||||
StructDef(size, decl, hasNaturalLayout) {
|
||||
|
||||
override val fields = mutableListOf<Field>()
|
||||
}
|
||||
|
||||
@@ -92,6 +94,22 @@ private class NativeIndexImpl : NativeIndex() {
|
||||
return res
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes [StructDef.hasNaturalLayout] property.
|
||||
*/
|
||||
fun structHasNaturalLayout(structDefCursor: CXCursor): Boolean {
|
||||
val hasAttributes = malloc(Int32Box)
|
||||
hasAttributes.value = 0
|
||||
clang_visitChildren(structDefCursor, { cursor, parent, clientData ->
|
||||
if (clang_isAttribute(cursor.kind.value) != 0) {
|
||||
clientData.asRef(Int32Box)!!.value = 1
|
||||
}
|
||||
CXChildVisitResult.CXChildVisit_Continue
|
||||
}, hasAttributes.ptr)
|
||||
|
||||
return hasAttributes.value == 0
|
||||
}
|
||||
|
||||
fun convertType(type: CXType): Type {
|
||||
val kind = type.kind.value
|
||||
return when (kind) {
|
||||
@@ -104,6 +122,7 @@ private class NativeIndexImpl : NativeIndex() {
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: is e.g. CXType_Int guaranteed to be int32_t?
|
||||
CXType_Void -> VoidType
|
||||
|
||||
CXType_Char_U, CXType_UChar -> UInt8Type
|
||||
@@ -182,7 +201,8 @@ private class NativeIndexImpl : NativeIndex() {
|
||||
val structDecl = getStructDeclAt(cursor)
|
||||
if (clang_isCursorDefinition(cursor) != 0) {
|
||||
val size = clang_Type_getSizeOf(clang_getCursorType(cursor, arena))
|
||||
structDecl.def = StructDefImpl(size, structDecl)
|
||||
val hasNaturalLayout = structHasNaturalLayout(cursor)
|
||||
structDecl.def = StructDefImpl(size, structDecl, hasNaturalLayout)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -241,28 +261,32 @@ fun buildNativeIndexImpl(headerFile: File, args: List<String>): NativeIndex {
|
||||
|
||||
val res = NativeIndexImpl()
|
||||
try {
|
||||
val indexDeclarationNativeCallback = indexDeclarationCallback.setUp({ res.indexDeclaration(it) })
|
||||
val nativeIndexPtr = StableObjPtr.create(res)
|
||||
val clientData = nativeIndexPtr.value
|
||||
|
||||
try {
|
||||
with(callbacks) {
|
||||
abortQuery.value = null
|
||||
diagnostic.value = null
|
||||
enteredMainFile.value = null
|
||||
ppIncludedFile.value = null
|
||||
importedASTFile.value = null
|
||||
startedTranslationUnit.value = null
|
||||
indexDeclaration.value = indexDeclarationNativeCallback
|
||||
indexEntityReference.value = null
|
||||
abortQuery.setStatic(null)
|
||||
diagnostic.setStatic(null)
|
||||
enteredMainFile.setStatic(null)
|
||||
ppIncludedFile.setStatic(null)
|
||||
importedASTFile.setStatic(null)
|
||||
startedTranslationUnit.setStatic(null)
|
||||
indexDeclaration.setStatic { clientData, info ->
|
||||
val index = StableObjPtr.fromValue(clientData!!).get() as NativeIndexImpl
|
||||
index.indexDeclaration(info!!)
|
||||
}
|
||||
indexEntityReference.setStatic(null)
|
||||
}
|
||||
|
||||
clang_indexSourceFile(indexAction, null, callbacks, IndexerCallbacks.Companion.size, 0, headerFile.path,
|
||||
clang_indexSourceFile(indexAction, clientData, callbacks, IndexerCallbacks.size, 0, headerFile.path,
|
||||
mallocNativeArrayOf(Int8Box.Companion, *args1)[0], args1.size, null, 0, null, 0)
|
||||
|
||||
|
||||
return res
|
||||
|
||||
} finally {
|
||||
indexDeclarationCallback.reset()
|
||||
nativeIndexPtr.dispose()
|
||||
}
|
||||
} finally {
|
||||
res.clearNativeMem()
|
||||
|
||||
+4
-1
@@ -31,8 +31,11 @@ abstract class StructDecl(val spelling: String) {
|
||||
|
||||
/**
|
||||
* C struct definition.
|
||||
*
|
||||
* @param hasNaturalLayout must be `false` if the struct has unnatural layout, e.g. it is `packed`.
|
||||
* May be `false` even if the struct has natural layout.
|
||||
*/
|
||||
abstract class StructDef(val size: Long, val decl: StructDecl) {
|
||||
abstract class StructDef(val size: Long, val decl: StructDecl, val hasNaturalLayout: Boolean) {
|
||||
|
||||
abstract val fields: List<Field>
|
||||
}
|
||||
|
||||
+9
-4
@@ -590,10 +590,15 @@ class StubGenerator(
|
||||
is IntPtrType, is UIntPtrType, // TODO
|
||||
is PointerType, is ArrayType -> "Pointer"
|
||||
is EnumType -> getFfiType(type.def.baseType)
|
||||
// FIXME: check that alignment is natural
|
||||
is RecordType -> "Struct(" + type.decl.def!!.fields.map {
|
||||
getFfiType(it.type)
|
||||
}.joinToString(", ") + ")"
|
||||
is RecordType -> {
|
||||
val def = type.decl.def!!
|
||||
if (!def.hasNaturalLayout) {
|
||||
throw NotImplementedError() // TODO: represent pointer to function as NativePtr instead
|
||||
}
|
||||
"Struct(" + def.fields.map {
|
||||
getFfiType(it.type)
|
||||
}.joinToString(", ") + ")"
|
||||
}
|
||||
else -> throw NotImplementedError(type.toString())
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user