Interop/Indexer: simplify native memory management by using memScoped
This commit is contained in:
committed by
SvyatoslavScherbina
parent
a52a51b7fa
commit
53b347b75a
+66
-88
@@ -22,10 +22,6 @@ private class EnumDefImpl(spelling: String, type: PrimitiveType) : EnumDef(spell
|
|||||||
|
|
||||||
private class NativeIndexImpl : NativeIndex() {
|
private class NativeIndexImpl : NativeIndex() {
|
||||||
|
|
||||||
val arena = Arena()
|
|
||||||
|
|
||||||
fun clearNativeMem() = arena.clear()
|
|
||||||
|
|
||||||
private data class DeclarationID(val usr: String)
|
private data class DeclarationID(val usr: String)
|
||||||
|
|
||||||
val structById = mutableMapOf<DeclarationID, StructDeclImpl>()
|
val structById = mutableMapOf<DeclarationID, StructDeclImpl>()
|
||||||
@@ -48,33 +44,22 @@ private class NativeIndexImpl : NativeIndex() {
|
|||||||
override val functions: List<FunctionDecl>
|
override val functions: List<FunctionDecl>
|
||||||
get() = functionByName.values.toList()
|
get() = functionByName.values.toList()
|
||||||
|
|
||||||
fun getDeclarationId(cursor: CXCursor) = DeclarationID(clang_getCursorUSR(cursor, arena).convertAndDispose())
|
fun getDeclarationId(cursor: CXCursor): DeclarationID = memScoped {
|
||||||
|
val usr = clang_getCursorUSR(cursor, memScope).convertAndDispose()
|
||||||
fun getStructTypeDecl(type: CXType): StructDeclImpl {
|
DeclarationID(usr)
|
||||||
assert (type.kind.value == CXType_Record)
|
|
||||||
return getStructDeclAt(clang_getTypeDeclaration(type, arena))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getStructDeclAt(cursor: CXCursor): StructDeclImpl {
|
fun getStructDeclAt(cursor: CXCursor): StructDeclImpl {
|
||||||
val declId = getDeclarationId(cursor)
|
val declId = getDeclarationId(cursor)
|
||||||
|
|
||||||
val decl = structById[declId]
|
return structById.getOrPut(declId) {
|
||||||
if (decl != null) {
|
memScoped {
|
||||||
return decl
|
val cursorType = clang_getCursorType(cursor, memScope)
|
||||||
|
val typeSpelling = clang_getTypeSpelling(cursorType, memScope).convertAndDispose()
|
||||||
|
|
||||||
|
StructDeclImpl(typeSpelling)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val cursorType = clang_getCursorType(cursor, arena)
|
|
||||||
val typeSpelling = clang_getTypeSpelling(cursorType, arena).convertAndDispose()
|
|
||||||
|
|
||||||
val res = StructDeclImpl(typeSpelling)
|
|
||||||
structById[declId] = res
|
|
||||||
return res
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getEnumTypeDef(type: CXType): EnumDefImpl {
|
|
||||||
assert (type.kind.value == CXType_Enum)
|
|
||||||
val declCursor = clang_getTypeDeclaration(type, arena)
|
|
||||||
return getEnumDefAt(declCursor)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getEnumDefAt(cursor: CXCursor): EnumDefImpl {
|
fun getEnumDefAt(cursor: CXCursor): EnumDefImpl {
|
||||||
@@ -84,19 +69,16 @@ private class NativeIndexImpl : NativeIndex() {
|
|||||||
|
|
||||||
val declId = getDeclarationId(cursor)
|
val declId = getDeclarationId(cursor)
|
||||||
|
|
||||||
val enum = enumById[declId]
|
return enumById.getOrPut(declId) {
|
||||||
if (enum != null) {
|
memScoped {
|
||||||
return enum
|
val cursorType = clang_getCursorType(cursor, memScope)
|
||||||
|
val typeSpelling = clang_getTypeSpelling(cursorType, memScope).convertAndDispose()
|
||||||
|
|
||||||
|
val baseType = convertType(clang_getEnumDeclIntegerType(cursor, memScope)) as PrimitiveType
|
||||||
|
|
||||||
|
EnumDefImpl(typeSpelling, baseType)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val cursorType = clang_getCursorType(cursor, arena)
|
|
||||||
val typeSpelling = clang_getTypeSpelling(cursorType, arena).convertAndDispose()
|
|
||||||
|
|
||||||
val baseType = convertType(clang_getEnumDeclIntegerType(cursor, arena)) as PrimitiveType
|
|
||||||
|
|
||||||
val res = EnumDefImpl(typeSpelling, baseType)
|
|
||||||
enumById[declId] = res
|
|
||||||
return res
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun builtinVaListType(type: CXType, name: String, underlying: Type): Type {
|
private fun builtinVaListType(type: CXType, name: String, underlying: Type): Type {
|
||||||
@@ -117,11 +99,11 @@ private class NativeIndexImpl : NativeIndex() {
|
|||||||
return ConstArrayType(RecordType(structDeclaration), 1)
|
return ConstArrayType(RecordType(structDeclaration), 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getTypedef(type: CXType): Type {
|
fun getTypedef(type: CXType): Type = memScoped {
|
||||||
val declCursor = clang_getTypeDeclaration(type, arena)
|
val declCursor = clang_getTypeDeclaration(type, memScope)
|
||||||
val name = clang_getCursorSpelling(declCursor, arena).convertAndDispose()
|
val name = clang_getCursorSpelling(declCursor, memScope).convertAndDispose()
|
||||||
|
|
||||||
val underlying = convertType(clang_getTypedefDeclUnderlyingType(declCursor, arena))
|
val underlying = convertType(clang_getTypedefDeclUnderlyingType(declCursor, memScope))
|
||||||
|
|
||||||
if (name == "__builtin_va_list") {
|
if (name == "__builtin_va_list") {
|
||||||
// On some platforms (e.g. macOS) libclang reports `__builtin_va_list` to be defined as array using
|
// On some platforms (e.g. macOS) libclang reports `__builtin_va_list` to be defined as array using
|
||||||
@@ -160,8 +142,8 @@ private class NativeIndexImpl : NativeIndex() {
|
|||||||
|
|
||||||
CXCursorKind.CXCursor_UnionDecl -> return false
|
CXCursorKind.CXCursor_UnionDecl -> return false
|
||||||
|
|
||||||
CXCursorKind.CXCursor_StructDecl -> {
|
CXCursorKind.CXCursor_StructDecl -> memScoped {
|
||||||
val hasAttributes = arena.alloc<CInt32Var>()
|
val hasAttributes = memScope.alloc<CInt32Var>()
|
||||||
hasAttributes.value = 0
|
hasAttributes.value = 0
|
||||||
clang_visitChildren(structDefCursor, staticCFunction { cursor, parent, clientData ->
|
clang_visitChildren(structDefCursor, staticCFunction { cursor, parent, clientData ->
|
||||||
if (clang_isAttribute(cursor.kind.value) != 0) {
|
if (clang_isAttribute(cursor.kind.value) != 0) {
|
||||||
@@ -178,11 +160,11 @@ private class NativeIndexImpl : NativeIndex() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun convertType(type: CXType): Type {
|
fun convertType(type: CXType): Type = memScoped {
|
||||||
val kind = type.kind.value
|
val kind = type.kind.value
|
||||||
return when (kind) {
|
return when (kind) {
|
||||||
CXType_Unexposed -> {
|
CXType_Unexposed -> {
|
||||||
val canonicalType = clang_getCanonicalType(type, arena)
|
val canonicalType = clang_getCanonicalType(type, memScope)
|
||||||
if (canonicalType.kind.value != CXType_Unexposed) {
|
if (canonicalType.kind.value != CXType_Unexposed) {
|
||||||
convertType(canonicalType)
|
convertType(canonicalType)
|
||||||
} else {
|
} else {
|
||||||
@@ -210,19 +192,19 @@ private class NativeIndexImpl : NativeIndex() {
|
|||||||
|
|
||||||
CXType_Typedef -> getTypedef(type)
|
CXType_Typedef -> getTypedef(type)
|
||||||
|
|
||||||
CXType_Record -> RecordType(getStructTypeDecl(type))
|
CXType_Record -> RecordType(getStructDeclAt(clang_getTypeDeclaration(type, memScope)))
|
||||||
CXType_Enum -> EnumType(getEnumTypeDef(type))
|
CXType_Enum -> EnumType(getEnumDefAt(clang_getTypeDeclaration(type, memScope)))
|
||||||
|
|
||||||
CXType_Pointer -> PointerType(convertType(clang_getPointeeType(type, arena)))
|
CXType_Pointer -> PointerType(convertType(clang_getPointeeType(type, memScope)))
|
||||||
|
|
||||||
CXType_ConstantArray -> {
|
CXType_ConstantArray -> {
|
||||||
val elemType = convertType(clang_getArrayElementType(type, arena))
|
val elemType = convertType(clang_getArrayElementType(type, memScope))
|
||||||
val length = clang_getArraySize(type)
|
val length = clang_getArraySize(type)
|
||||||
ConstArrayType(elemType, length)
|
ConstArrayType(elemType, length)
|
||||||
}
|
}
|
||||||
|
|
||||||
CXType_IncompleteArray -> {
|
CXType_IncompleteArray -> {
|
||||||
val elemType = convertType(clang_getArrayElementType(type, arena))
|
val elemType = convertType(clang_getArrayElementType(type, memScope))
|
||||||
IncompleteArrayType(elemType)
|
IncompleteArrayType(elemType)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -230,10 +212,10 @@ private class NativeIndexImpl : NativeIndex() {
|
|||||||
if (clang_isFunctionTypeVariadic(type) != 0) {
|
if (clang_isFunctionTypeVariadic(type) != 0) {
|
||||||
UnsupportedType
|
UnsupportedType
|
||||||
} else {
|
} else {
|
||||||
val returnType = convertType(clang_getResultType(type, arena))
|
val returnType = convertType(clang_getResultType(type, memScope))
|
||||||
val numArgs = clang_getNumArgTypes(type)
|
val numArgs = clang_getNumArgTypes(type)
|
||||||
val paramTypes = (0..numArgs - 1).map {
|
val paramTypes = (0..numArgs - 1).map {
|
||||||
convertType(clang_getArgType(type, it, arena))
|
convertType(clang_getArgType(type, it, memScope))
|
||||||
}
|
}
|
||||||
FunctionType(paramTypes, returnType)
|
FunctionType(paramTypes, returnType)
|
||||||
}
|
}
|
||||||
@@ -243,7 +225,7 @@ private class NativeIndexImpl : NativeIndex() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun indexDeclaration(info: CXIdxDeclInfo) {
|
fun indexDeclaration(info: CXIdxDeclInfo): Unit = memScoped {
|
||||||
val cursor = info.cursor
|
val cursor = info.cursor
|
||||||
val entityInfo = info.entityInfo.pointed!!
|
val entityInfo = info.entityInfo.pointed!!
|
||||||
val entityName = entityInfo.name.value?.asCString()?.toString()
|
val entityName = entityInfo.name.value?.asCString()?.toString()
|
||||||
@@ -252,7 +234,7 @@ private class NativeIndexImpl : NativeIndex() {
|
|||||||
when (kind) {
|
when (kind) {
|
||||||
CXIdxEntity_Field -> {
|
CXIdxEntity_Field -> {
|
||||||
val name = entityName!!
|
val name = entityName!!
|
||||||
val type = convertType(clang_getCursorType(cursor, arena))
|
val type = convertType(clang_getCursorType(cursor, memScope))
|
||||||
val offset = clang_Cursor_getOffsetOfField(cursor)
|
val offset = clang_Cursor_getOffsetOfField(cursor)
|
||||||
|
|
||||||
val container = info.semanticContainer.pointed!!
|
val container = info.semanticContainer.pointed!!
|
||||||
@@ -263,9 +245,9 @@ private class NativeIndexImpl : NativeIndex() {
|
|||||||
CXIdxEntity_Struct, CXIdxEntity_Union -> {
|
CXIdxEntity_Struct, CXIdxEntity_Union -> {
|
||||||
val structDecl = getStructDeclAt(cursor)
|
val structDecl = getStructDeclAt(cursor)
|
||||||
if (clang_isCursorDefinition(cursor) != 0) {
|
if (clang_isCursorDefinition(cursor) != 0) {
|
||||||
val type = clang_getCursorType(cursor, arena)
|
val type = clang_getCursorType(cursor, memScope)
|
||||||
val size = clang_Type_getSizeOf(type)
|
val size = clang_Type_getSizeOf(type)
|
||||||
val align = clang_Type_getAlignOf(clang_getCursorType(cursor, arena)).toInt()
|
val align = clang_Type_getAlignOf(clang_getCursorType(cursor, memScope)).toInt()
|
||||||
val hasNaturalLayout = structHasNaturalLayout(cursor)
|
val hasNaturalLayout = structHasNaturalLayout(cursor)
|
||||||
structDecl.def = StructDefImpl(size, align, structDecl, hasNaturalLayout)
|
structDecl.def = StructDefImpl(size, align, structDecl, hasNaturalLayout)
|
||||||
}
|
}
|
||||||
@@ -273,12 +255,12 @@ private class NativeIndexImpl : NativeIndex() {
|
|||||||
|
|
||||||
CXIdxEntity_Function -> {
|
CXIdxEntity_Function -> {
|
||||||
val name = entityName!!
|
val name = entityName!!
|
||||||
val returnType = convertType(clang_getCursorResultType(cursor, arena))
|
val returnType = convertType(clang_getCursorResultType(cursor, memScope))
|
||||||
val argNum = clang_Cursor_getNumArguments(cursor)
|
val argNum = clang_Cursor_getNumArguments(cursor)
|
||||||
val args = (0 .. argNum - 1).map {
|
val args = (0 .. argNum - 1).map {
|
||||||
val argCursor = clang_Cursor_getArgument(cursor, it, arena)
|
val argCursor = clang_Cursor_getArgument(cursor, it, memScope)
|
||||||
val argName = clang_getCursorSpelling(argCursor, arena).convertAndDispose()
|
val argName = clang_getCursorSpelling(argCursor, memScope).convertAndDispose()
|
||||||
val type = convertType(clang_getCursorType(argCursor, arena))
|
val type = convertType(clang_getCursorType(argCursor, memScope))
|
||||||
Parameter(argName, type)
|
Parameter(argName, type)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -326,37 +308,33 @@ fun buildNativeIndexImpl(headerFile: File, args: List<String>): NativeIndex {
|
|||||||
val callbacks = nativeHeap.alloc<IndexerCallbacks>()
|
val callbacks = nativeHeap.alloc<IndexerCallbacks>()
|
||||||
|
|
||||||
val res = NativeIndexImpl()
|
val res = NativeIndexImpl()
|
||||||
|
val nativeIndexPtr = StableObjPtr.create(res)
|
||||||
|
val clientData = nativeIndexPtr.value
|
||||||
|
|
||||||
try {
|
try {
|
||||||
val nativeIndexPtr = StableObjPtr.create(res)
|
with(callbacks) {
|
||||||
val clientData = nativeIndexPtr.value
|
abortQuery.value = null
|
||||||
|
diagnostic.value = null
|
||||||
try {
|
enteredMainFile.value = null
|
||||||
with(callbacks) {
|
ppIncludedFile.value = null
|
||||||
abortQuery.value = null
|
importedASTFile.value = null
|
||||||
diagnostic.value = null
|
startedTranslationUnit.value = null
|
||||||
enteredMainFile.value = null
|
indexDeclaration.value = staticCFunction { clientData, info ->
|
||||||
ppIncludedFile.value = null
|
val nativeIndex = StableObjPtr.fromValue(clientData!!).get() as NativeIndexImpl
|
||||||
importedASTFile.value = null
|
nativeIndex.indexDeclaration(info!!.pointed)
|
||||||
startedTranslationUnit.value = null
|
|
||||||
indexDeclaration.value = staticCFunction { clientData, info ->
|
|
||||||
val nativeIndex = StableObjPtr.fromValue(clientData!!).get() as NativeIndexImpl
|
|
||||||
nativeIndex.indexDeclaration(info!!.pointed)
|
|
||||||
}
|
|
||||||
indexEntityReference.value = null
|
|
||||||
}
|
}
|
||||||
|
indexEntityReference.value = null
|
||||||
val commandLineArgs = nativeHeap.allocArrayOfPointersTo(*args1)[0].ptr
|
|
||||||
|
|
||||||
clang_indexSourceFile(indexAction, clientData, callbacks.ptr, IndexerCallbacks.size.toInt(),
|
|
||||||
0, headerFile.path, commandLineArgs, args1.size, null, 0, null, 0)
|
|
||||||
|
|
||||||
|
|
||||||
return res
|
|
||||||
|
|
||||||
} finally {
|
|
||||||
nativeIndexPtr.dispose()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val commandLineArgs = nativeHeap.allocArrayOfPointersTo(*args1)[0].ptr
|
||||||
|
|
||||||
|
clang_indexSourceFile(indexAction, clientData, callbacks.ptr, IndexerCallbacks.size.toInt(),
|
||||||
|
0, headerFile.path, commandLineArgs, args1.size, null, 0, null, 0)
|
||||||
|
|
||||||
|
|
||||||
|
return res
|
||||||
|
|
||||||
} finally {
|
} finally {
|
||||||
res.clearNativeMem()
|
nativeIndexPtr.dispose()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user