@@ -5,10 +5,12 @@ buildscript {
|
|||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
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: 'java'
|
||||||
apply plugin: 'kotlin'
|
apply plugin: 'kotlin'
|
||||||
apply plugin: org.jetbrains.kotlin.NativeInteropPlugin
|
apply plugin: org.jetbrains.kotlin.NativeInteropPlugin
|
||||||
@@ -40,7 +42,8 @@ allprojects {
|
|||||||
|
|
||||||
sourceSets {
|
sourceSets {
|
||||||
compiler {
|
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/'
|
kotlin.srcDir 'compiler/ir/backend.native/src/'
|
||||||
}
|
}
|
||||||
cli_bc {
|
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() {
|
String[] linkerOpts1() {
|
||||||
def libs = ['-lLLVMX86Disassembler',
|
def libs = ['-lLLVMX86Disassembler',
|
||||||
'-lLLVMX86AsmParser',
|
'-lLLVMX86AsmParser',
|
||||||
@@ -132,6 +141,9 @@ configurations {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
|
|
||||||
|
compilerCompile "com.google.protobuf:protobuf-java:3.0.0"
|
||||||
|
|
||||||
compilerCompile kotlinCompilerModule
|
compilerCompile kotlinCompilerModule
|
||||||
compilerCompile kotlinNativeInterop['llvm'].configuration
|
compilerCompile kotlinNativeInterop['llvm'].configuration
|
||||||
compilerCompile kotlinNativeInterop['hash'].configuration
|
compilerCompile kotlinNativeInterop['hash'].configuration
|
||||||
@@ -178,3 +190,12 @@ task jars {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protobuf {
|
||||||
|
protoc {
|
||||||
|
artifact = 'com.google.protobuf:protoc:3.0.0'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+17
@@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
+2
@@ -71,6 +71,7 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid
|
|||||||
|
|
||||||
val generator = CodeGenerator(context)
|
val generator = CodeGenerator(context)
|
||||||
val logger = Logger(generator, 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) {
|
override fun visitFunction(declaration: IrFunction) {
|
||||||
generator.function(declaration)
|
generator.function(declaration)
|
||||||
|
metadator.function(declaration)
|
||||||
declaration.acceptChildrenVoid(this)
|
declaration.acceptChildrenVoid(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
+7
@@ -3,6 +3,7 @@ package org.jetbrains.kotlin.backend.native.llvm
|
|||||||
import kotlin_native.interop.asCString
|
import kotlin_native.interop.asCString
|
||||||
import llvm.LLVMPrintModuleToString
|
import llvm.LLVMPrintModuleToString
|
||||||
import llvm.LLVMPrintValueToString
|
import llvm.LLVMPrintValueToString
|
||||||
|
import llvm.LLVMOpaqueValue
|
||||||
import org.jetbrains.kotlin.backend.native.llvm.Context
|
import org.jetbrains.kotlin.backend.native.llvm.Context
|
||||||
import org.jetbrains.kotlin.backend.native.llvm.ContextUtils
|
import org.jetbrains.kotlin.backend.native.llvm.ContextUtils
|
||||||
import org.jetbrains.kotlin.ir.IrElement
|
import org.jetbrains.kotlin.ir.IrElement
|
||||||
@@ -36,3 +37,9 @@ fun ir2string(ir: IrElement?): String {
|
|||||||
ir?.accept(DumpIrTreeVisitor(strWriter), "")
|
ir?.accept(DumpIrTreeVisitor(strWriter), "")
|
||||||
return strWriter.toString().takeWhile { it != '\n' }
|
return strWriter.toString().takeWhile { it != '\n' }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun llvm2string(value: LLVMOpaqueValue?): String {
|
||||||
|
if (value == null) return "<null>"
|
||||||
|
return LLVMPrintValueToString(value)!!.asCString().toString()
|
||||||
|
}
|
||||||
|
|
||||||
+79
@@ -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?>): 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Reference in New Issue
Block a user