diff --git a/backend.native/build.gradle b/backend.native/build.gradle index 300b8294b9d..eab4f5fe8d0 100644 --- a/backend.native/build.gradle +++ b/backend.native/build.gradle @@ -5,10 +5,12 @@ buildscript { dependencies { classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" + classpath "com.google.protobuf:protobuf-gradle-plugin:0.8.0" } } +apply plugin: "com.google.protobuf" apply plugin: 'java' apply plugin: 'kotlin' apply plugin: org.jetbrains.kotlin.NativeInteropPlugin @@ -40,7 +42,8 @@ allprojects { sourceSets { compiler { - java.srcDir 'compiler/ir/backend.native/src/' + proto.srcDir 'compiler/ir/backend.native/src/' + java.srcDirs 'compiler/ir/backend.native/src/', 'build/generated/source/proto/compiler/java/' kotlin.srcDir 'compiler/ir/backend.native/src/' } cli_bc { @@ -53,6 +56,12 @@ sourceSets { } } +// The protobuf plugin specifies this dependency for java by itself, +// but not for Kotlin. +compileCompilerKotlin { + dependsOn('generateCompilerProto') +} + String[] linkerOpts1() { def libs = ['-lLLVMX86Disassembler', '-lLLVMX86AsmParser', @@ -132,6 +141,9 @@ configurations { } dependencies { + + compilerCompile "com.google.protobuf:protobuf-java:3.0.0" + compilerCompile kotlinCompilerModule compilerCompile kotlinNativeInterop['llvm'].configuration compilerCompile kotlinNativeInterop['hash'].configuration @@ -178,3 +190,12 @@ task jars { } } } + + +protobuf { + protoc { + artifact = 'com.google.protobuf:protoc:3.0.0' + } +} + + diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/native/DescriptorUtils.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/DescriptorUtils.kt similarity index 100% rename from backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/native/DescriptorUtils.kt rename to backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/DescriptorUtils.kt diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/native/ModuleIndex.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ModuleIndex.kt similarity index 100% rename from backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/native/ModuleIndex.kt rename to backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ModuleIndex.kt diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/native/NativeBackendFacade.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/NativeBackendFacade.kt similarity index 100% rename from backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/native/NativeBackendFacade.kt rename to backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/NativeBackendFacade.kt diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/native/NativeIrCodegenFactory.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/NativeIrCodegenFactory.kt similarity index 100% rename from backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/native/NativeIrCodegenFactory.kt rename to backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/NativeIrCodegenFactory.kt diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/BinaryLinkdata.proto b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/BinaryLinkdata.proto new file mode 100644 index 00000000000..158243a0676 --- /dev/null +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/BinaryLinkdata.proto @@ -0,0 +1,17 @@ + +syntax="proto2"; +package org.jetbrains.kotlin.backend.konan.llvm; + +option java_outer_classname = "BinaryLinkdata"; + +message TypeLinkdata { + required string name = 1; +} + +message FunLinkdata { + required string hash = 1; + required string name = 2; + required TypeLinkdata returnType = 3; + repeated TypeLinkdata arg = 4; +} + diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/native/llvm/CodeGenerator.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/CodeGenerator.kt similarity index 100% rename from backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/native/llvm/CodeGenerator.kt rename to backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/CodeGenerator.kt diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/native/llvm/Context.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/Context.kt similarity index 100% rename from backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/native/llvm/Context.kt rename to backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/Context.kt diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/native/llvm/ContextUtils.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/ContextUtils.kt similarity index 100% rename from backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/native/llvm/ContextUtils.kt rename to backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/ContextUtils.kt diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/native/llvm/DataLayout.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/DataLayout.kt similarity index 100% rename from backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/native/llvm/DataLayout.kt rename to backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/DataLayout.kt diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/native/llvm/HashUtils.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/HashUtils.kt similarity index 100% rename from backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/native/llvm/HashUtils.kt rename to backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/HashUtils.kt diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/native/llvm/IrToBitcode.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/IrToBitcode.kt similarity index 99% rename from backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/native/llvm/IrToBitcode.kt rename to backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/IrToBitcode.kt index 6441b5ec699..4226eb73548 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/native/llvm/IrToBitcode.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/IrToBitcode.kt @@ -71,6 +71,7 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid val generator = CodeGenerator(context) val logger = Logger(generator, context) + val metadator = MetadataGenerator(context) //-------------------------------------------------------------------------// @@ -140,6 +141,7 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid override fun visitFunction(declaration: IrFunction) { generator.function(declaration) + metadator.function(declaration) declaration.acceptChildrenVoid(this) } diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/native/llvm/LlvmUtils.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/LlvmUtils.kt similarity index 100% rename from backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/native/llvm/LlvmUtils.kt rename to backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/LlvmUtils.kt diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/native/llvm/Logger.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/Logger.kt similarity index 87% rename from backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/native/llvm/Logger.kt rename to backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/Logger.kt index 4c228f315a8..7cd8c664aaa 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/native/llvm/Logger.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/Logger.kt @@ -3,6 +3,7 @@ package org.jetbrains.kotlin.backend.native.llvm import kotlin_native.interop.asCString import llvm.LLVMPrintModuleToString import llvm.LLVMPrintValueToString +import llvm.LLVMOpaqueValue import org.jetbrains.kotlin.backend.native.llvm.Context import org.jetbrains.kotlin.backend.native.llvm.ContextUtils import org.jetbrains.kotlin.ir.IrElement @@ -36,3 +37,9 @@ fun ir2string(ir: IrElement?): String { ir?.accept(DumpIrTreeVisitor(strWriter), "") return strWriter.toString().takeWhile { it != '\n' } } + +fun llvm2string(value: LLVMOpaqueValue?): String { + if (value == null) return "" + return LLVMPrintValueToString(value)!!.asCString().toString() +} + diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/MetadataGenerator.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/MetadataGenerator.kt new file mode 100644 index 00000000000..bd3c306f2af --- /dev/null +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/MetadataGenerator.kt @@ -0,0 +1,79 @@ +package org.jetbrains.kotlin.backend.native.llvm + + +import kotlin_native.interop.* +import llvm.* +import org.jetbrains.kotlin.ir.declarations.IrFunction +import org.jetbrains.kotlin.backend.konan.llvm.BinaryLinkdata.* +import org.jetbrains.kotlin.types.KotlinType + +internal class MetadataGenerator(override val context: Context): ContextUtils { + + private fun metadataString(str: String): LLVMOpaqueValue { + return LLVMMDString(str, str.length)!! + } + + private fun metadataNode(args: List): LLVMOpaqueValue { + memScoped { + val references = alloc(array[args.size](Ref to LLVMOpaqueValue)) + args.forEachIndexed { i, llvmOpaqueValue -> references[i].value = args[i]} + return LLVMMDNode(references[0], args.size)!! + } + } + + private fun metadataFun(fn: LLVMOpaqueValue?, info: String): LLVMOpaqueValue { + val args = listOf(fn, metadataString(info)); + val md = metadataNode(args) + return md + } + + private fun emitModuleMetadata(name: String, md: LLVMOpaqueValue?) { + LLVMAddNamedMetadataOperand(context.llvmModule, name, md) + } + + private fun protobufType(type:KotlinType): TypeLinkdata { + val builder = TypeLinkdata.newBuilder() + val name = type.toString() + val proto = builder + .setName(name) + .build() + + return proto + } + + private fun serializeFunSignature(declaration: IrFunction): String { + val func = declaration.descriptor + + val hash = "0x123456 some hash" + val name = func.name.asString() + + val kotlinType = func.getReturnType()!! + val returnType = protobufType(kotlinType) + + val parameters = func.getValueParameters() + val argumentTypes = parameters.map{ protobufType(it.getType()) } + + val proto = FunLinkdata.newBuilder() + .setHash(hash) + .setName(name) + .setReturnType(returnType) + .addAllArg(argumentTypes) + .build() + + // Convert it to ProtoBuf's TextFormat representation. + // Use TextFormat.merge(str, builder) to parse it back + val str = proto.toString() + return str + } + + internal fun function(declaration: IrFunction) { + val fn = declaration.descriptor.llvmFunction.getLlvmValue() + + val proto = serializeFunSignature(declaration) + + val md = metadataFun(fn, proto) + emitModuleMetadata("kfun", md); + } +} + + diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/native/llvm/NameUtils.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/NameUtils.kt similarity index 100% rename from backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/native/llvm/NameUtils.kt rename to backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/NameUtils.kt diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/native/llvm/RTTIGenerator.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/RTTIGenerator.kt similarity index 100% rename from backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/native/llvm/RTTIGenerator.kt rename to backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/RTTIGenerator.kt diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/native/llvm/Runtime.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/Runtime.kt similarity index 100% rename from backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/native/llvm/Runtime.kt rename to backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/Runtime.kt