Decouple Obj-C literals generator from context and single LLVM module

This commit is contained in:
Svyatoslav Scherbina
2019-10-11 12:28:00 +03:00
committed by SvyatoslavScherbina
parent fde7265dae
commit cf06b6eb35
@@ -246,32 +246,48 @@ internal class ObjCDataGenerator(val codegen: CodeGenerator) {
context.llvm.compilerUsedGlobals += global.llvmGlobal context.llvm.compilerUsedGlobals += global.llvmGlobal
} }
private val classNames = private val classNames = CStringLiteralsTable(classNameGenerator)
CStringLiteralsTable("OBJC_CLASS_NAME_", "__TEXT,__objc_classname,cstring_literals")
private val selectors = private val selectors = CStringLiteralsTable(selectorGenerator)
CStringLiteralsTable("OBJC_METH_VAR_NAME_", "__TEXT,__objc_methname,cstring_literals")
private val encodings = private val encodings = CStringLiteralsTable(encodingGenerator)
CStringLiteralsTable("OBJC_METH_VAR_TYPE_", "__TEXT,__objc_methtype,cstring_literals")
private inner class CStringLiteralsTable(val label: String, val section: String) { private inner class CStringLiteralsTable(val generator: CStringLiteralsGenerator) {
private val literals = mutableMapOf<String, ConstPointer>() private val literals = mutableMapOf<String, ConstPointer>()
fun get(value: String) = literals.getOrPut(value) { fun get(value: String) = literals.getOrPut(value) {
val globalPointer = generator.generate(context.llvmModule!!, value)
context.llvm.compilerUsedGlobals += globalPointer.llvm
globalPointer.getElementPtr(0)
}
}
companion object {
val classNameGenerator =
CStringLiteralsGenerator("OBJC_CLASS_NAME_", "__TEXT,__objc_classname,cstring_literals")
val selectorGenerator =
CStringLiteralsGenerator("OBJC_METH_VAR_NAME_", "__TEXT,__objc_methname,cstring_literals")
private val encodingGenerator =
CStringLiteralsGenerator("OBJC_METH_VAR_TYPE_", "__TEXT,__objc_methtype,cstring_literals")
}
class CStringLiteralsGenerator(val label: String, val section: String) {
fun generate(module: LLVMModuleRef, value: String): ConstPointer {
val bytes = value.toByteArray(Charsets.UTF_8).map { Int8(it) } + Int8(0) val bytes = value.toByteArray(Charsets.UTF_8).map { Int8(it) } + Int8(0)
val global = context.llvm.staticData.placeGlobalArray(label, int8Type, bytes) val initializer = ConstArray(int8Type, bytes)
val llvmGlobal = LLVMAddGlobal(module, initializer.llvmType, label)!!
LLVMSetInitializer(llvmGlobal, initializer.llvm)
global.setConstant(true) LLVMSetGlobalConstant(llvmGlobal, 1)
global.setLinkage(LLVMLinkage.LLVMPrivateLinkage) LLVMSetLinkage(llvmGlobal, LLVMLinkage.LLVMPrivateLinkage)
global.setSection(section) LLVMSetSection(llvmGlobal, section)
LLVMSetUnnamedAddr(global.llvmGlobal, 1) LLVMSetUnnamedAddr(llvmGlobal, 1)
global.setAlignment(1) LLVMSetAlignment(llvmGlobal, 1)
context.llvm.compilerUsedGlobals += global.llvmGlobal return constPointer(llvmGlobal)
global.pointer.getElementPtr(0)
} }
} }
} }