translator-bc: takeplacers for bc/ir generators (to move from desktop to laptop)

This commit is contained in:
Vasily Levchenko
2016-09-23 18:18:41 +03:00
parent 8ed1b7b083
commit f6c9a4ad6b
3 changed files with 513 additions and 221 deletions
@@ -1,252 +1,299 @@
package org.kotlinnative.translator.llvm
import org.kotlinnative.translator.TranslationState
import org.kotlinnative.translator.llvm.bc.BcLlvmBuilder
import org.kotlinnative.translator.llvm.ir.IrLlvmBuilder
import org.kotlinnative.translator.llvm.types.*
import java.rmi.UnexpectedException
import java.util.*
class LLVMBuilder(arm: Boolean = false) {
private val localCode: StringBuilder = StringBuilder()
private val globalCode: StringBuilder = StringBuilder()
private var variableCount = 0
private var labelCount = 0
private val exceptions = mapOf(
Pair("KotlinNullPointerException", initializeExceptionString("Exception in thread main kotlin.KotlinNullPointerException")))
val ir = IrLlvmBuilder()
val bc = BcLlvmBuilder()
init {
val declares = arrayOf(
"declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture readonly, i64, i32, i1)",
"declare i8* @malloc_heap(i32)",
"declare i32 @printf(i8*, ...)",
"declare void @abort()",
"%class.Nothing = type { }")
fun addComment(comment: String) {
ir.comment(comment)
bc.comment(comment)
//addLLVMCodeToLocalPlace("; " + comment)
}
declares.forEach { addLLVMCodeToGlobalPlace(it) }
fun addStartExpression() {
ir.startExpression()
bc.startExpression()
//addLLVMCodeToLocalPlace("{")
}
if (arm) {
val functionAttributes = """attributes #0 = { nounwind "stack-protector-buffer-size"="8" "target-cpu"="cortex-m3" "target-features"="+hwdiv,+strict-align" }"""
addLLVMCodeToGlobalPlace(functionAttributes)
fun addEndExpression() {
ir.endExpression()
bc.endExpression()
//addLLVMCodeToLocalPlace("unreachable\n}")
}
fun addAssignment(lhs: LLVMVariable, rhs: LLVMNode) {
ir.assignment(lhs, rhs)
bc.assignment(lhs, rhs)
//addLLVMCodeToLocalPlace("$lhs = $rhs")
}
fun addReturnOperator(llvmVariable: LLVMSingleValue) {
ir.returnOperation(llvmVariable)
bc.returnOperation(llvmVariable)
//addLLVMCodeToLocalPlace("ret ${llvmVariable.type} $llvmVariable")
}
fun addAnyReturn(type: LLVMType, value: String = type.defaultValue, pointer: Int = 0) {
ir.anyReturn(type, value, pointer)
bc.anyReturn(type, value, pointer)
//addLLVMCodeToLocalPlace("ret $type${"*".repeat(pointer)} $value")
}
fun addStringConstant(variable: LLVMVariable, value: String) {
ir.stringConstant(variable, value)
bc.stringConstant(variable, value)
//addLLVMCodeToGlobalPlace("$variable = private unnamed_addr constant ${(variable.type as LLVMStringType).fullArrayType} c\"${value.replace("\"", "\\\"")}\\00\", align 1")
}
fun addCondition(condition: LLVMSingleValue, thenLabel: LLVMLabel, elseLabel: LLVMLabel) {
ir.conditionalBranch(condition, thenLabel, elseLabel)
bc.conditionalBranch(condition, thenLabel, elseLabel)
//addLLVMCodeToLocalPlace("br ${condition.pointedType} $condition, label $thenLabel, label $elseLabel")
}
}
fun addLLVMCodeToLocalPlace(code: String) =
localCode.appendln(code)
fun addLLVMCodeToGlobalPlace(code: String) =
globalCode.appendln(code)
fun addComment(comment: String) =
addLLVMCodeToLocalPlace("; " + comment)
fun addStartExpression() =
addLLVMCodeToLocalPlace("{")
fun addEndExpression() =
addLLVMCodeToLocalPlace("unreachable\n}")
fun addAssignment(lhs: LLVMVariable, rhs: LLVMNode) =
addLLVMCodeToLocalPlace("$lhs = $rhs")
fun addReturnOperator(llvmVariable: LLVMSingleValue) =
addLLVMCodeToLocalPlace("ret ${llvmVariable.type} $llvmVariable")
fun addAnyReturn(type: LLVMType, value: String = type.defaultValue, pointer: Int = 0) =
addLLVMCodeToLocalPlace("ret $type${"*".repeat(pointer)} $value")
fun addStringConstant(variable: LLVMVariable, value: String) =
addLLVMCodeToGlobalPlace("$variable = private unnamed_addr constant ${(variable.type as LLVMStringType).fullArrayType} c\"${value.replace("\"", "\\\"")}\\00\", align 1")
fun addCondition(condition: LLVMSingleValue, thenLabel: LLVMLabel, elseLabel: LLVMLabel) =
addLLVMCodeToLocalPlace("br ${condition.pointedType} $condition, label $thenLabel, label $elseLabel")
fun addUnconditionalJump(label: LLVMLabel) =
addLLVMCodeToLocalPlace("br label $label")
fun addExceptionCall(exceptionName: String) {
val exception = exceptions[exceptionName]
val printResult = getNewVariable(LLVMIntType(), pointer = 0)
addLLVMCodeToLocalPlace("$printResult = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds (${(exception!!.type as LLVMStringType).fullArrayType}* $exception, i32 0, i32 0))")
addFunctionCall(LLVMVariable("abort", LLVMVoidType(), scope = LLVMVariableScope()), emptyList())
}
fun addFunctionCall(functionName: LLVMVariable, arguments: List<LLVMVariable>) =
addLLVMCodeToLocalPlace("call ${functionName.type} $functionName(${arguments.joinToString { it -> "${it.type} $it" }})")
fun allocStackVar(target: LLVMVariable, asValue: Boolean = false, pointer: Boolean = false) {
val type = if (asValue) target.type.toString() else target.pointedType
addLLVMCodeToLocalPlace("$target = alloca ${if (pointer) type.removeSuffix("*") else type}, align ${target.type.align}")
}
fun allocStaticVar(target: LLVMVariable, asValue: Boolean = false, pointer: Boolean = false) {
val allocated = getNewVariable(LLVMCharType(), pointer = 1)
val size = if ((target.pointer >= 2) || (target.pointer >= 1 && !pointer)) TranslationState.POINTER_SIZE else target.type.size
addLLVMCodeToLocalPlace("$allocated = call i8* @malloc_heap(i32 $size)")
addLLVMCodeToLocalPlace("$target = bitcast ${allocated.pointedType} $allocated to ${if (asValue) target.type.toString() else target.pointedType}" + if (pointer) "" else "*")
}
fun addGlobalInitialize(target: LLVMVariable, fields: ArrayList<LLVMClassVariable>, initializers: Map<LLVMVariable, String>, classType: LLVMType) {
val code = "$target = internal global $classType { ${
fields.map { it.pointedType + " " + if (initializers.containsKey(it)) initializers[it] else "0" }.joinToString()
} }, align ${classType.align}"
addLLVMCodeToGlobalPlace(code)
}
fun bitcast(src: LLVMVariable, llvmType: LLVMType, pointer: Int): LLVMVariable {
val empty = getNewVariable(llvmType, pointer = pointer)
addLLVMCodeToLocalPlace("$empty = bitcast ${src.pointedType} $src to ${llvmType.toString() + "*".repeat(pointer)}")
return empty
}
fun convertVariableToType(variable: LLVMSingleValue, targetType: LLVMType): LLVMSingleValue {
var resultVariable = variable
if (variable.type != targetType) {
val convertedExpression = targetType.convertFrom(variable)
resultVariable = saveExpression(convertedExpression)
fun addUnconditionalJump(label: LLVMLabel) {
ir.unconditionalBranch(label)
bc.unconditionalBranch(label)
//addLLVMCodeToLocalPlace("br label $label")
}
return resultVariable
}
fun copyVariable(from: LLVMVariable, to: LLVMVariable) =
when {
from.type is LLVMStringType && !from.type.isLoaded -> storeString(to, from, 0)
else -> copyVariableValue(to, from)
fun addExceptionCall(exceptionName: String) {
ir.abort(exceptionName)
bc.abort(exceptionName)
/*
val exception = exceptions[exceptionName]
val printResult = getNewVariable(LLVMIntType(), pointer = 0)
addLLVMCodeToLocalPlace("$printResult = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds (${(exception!!.type as LLVMStringType).fullArrayType}* $exception, i32 0, i32 0))")
addFunctionCall(LLVMVariable("abort", LLVMVoidType(), scope = LLVMVariableScope()), emptyList())
*/
}
fun addFunctionCall(functionName: LLVMVariable, arguments: List<LLVMVariable>) {
ir.call(functionName, arguments)
bc.call(functionName, arguments)
//addLLVMCodeToLocalPlace("call ${functionName.type} $functionName(${arguments.joinToString { it -> "${it.type} $it" }})")
}
fun allocStackVar(target: LLVMVariable, asValue: Boolean = false, pointer: Boolean = false) {
ir.alloca(target, asValue, pointer)
bc.alloca(target, asValue, pointer)
/*
val type = if (asValue) target.type.toString() else target.pointedType
addLLVMCodeToLocalPlace("$target = alloca ${if (pointer) type.removeSuffix("*") else type}, align ${target.type.align}")
*/
}
fun allocStaticVar(target: LLVMVariable, asValue: Boolean = false, pointer: Boolean = false) {
ir.heapAndCast(target, asValue, pointer)
bc.heapAndCall(target, asValue, pointer)
/*
val allocated = getNewVariable(LLVMCharType(), pointer = 1)
val size = if ((target.pointer >= 2) || (target.pointer >= 1 && !pointer)) TranslationState.POINTER_SIZE else target.type.size
addLLVMCodeToLocalPlace("$allocated = call i8* @malloc_heap(i32 $size)")
addLLVMCodeToLocalPlace("$target = bitcast ${allocated.pointedType} $allocated to ${if (asValue) target.type.toString() else target.pointedType}" + if (pointer) "" else "*")
*/
}
fun addGlobalInitialize(target: LLVMVariable, fields: ArrayList<LLVMClassVariable>, initializers: Map<LLVMVariable, String>, classType: LLVMType) {
ir.globalinitialize(target, fields, initializers, classType)
bc.globalInitialize(target, fields, initializers, classType)
/*
val code = "$target = internal global $classType { ${
fields.map { it.pointedType + " " + if (initializers.containsKey(it)) initializers[it] else "0" }.joinToString()
} }, align ${classType.align}"
addLLVMCodeToGlobalPlace(code)
*/
}
fun bitcast(src: LLVMVariable, llvmType: LLVMType, pointer: Int): LLVMVariable {
ir.bitcast(src, llvmType, pointer)
bc.bitcast(src, llvmType, pointer)
/*
val empty = getNewVariable(llvmType, pointer = pointer)
addLLVMCodeToLocalPlace("$empty = bitcast ${src.pointedType} $src to ${llvmType.toString() + "*".repeat(pointer)}")
return empty
*/
}
fun convertVariableToType(variable: LLVMSingleValue, targetType: LLVMType): LLVMSingleValue {
var resultVariable = variable
if (variable.type != targetType) {
val convertedExpression = targetType.convertFrom(variable)
resultVariable = saveExpression(convertedExpression)
}
return resultVariable
}
fun copyVariable(from: LLVMVariable, to: LLVMVariable) =
when {
from.type is LLVMStringType && !from.type.isLoaded -> storeString(to, from, 0)
else -> copyVariableValue(to, from)
}
fun createClass(name: String, fields: List<LLVMVariable>) {
ir.classDeclaration(name, fields)
bc.classDeclaration(name, fields)
//addLLVMCodeToGlobalPlace("%class.$name = type { ${fields.map { it.pointedType }.joinToString()} }")
}
fun declareEntryPoint(name: String) {
TODO("not that it's required")
/*
addLLVMCodeToLocalPlace("define weak void @main()")
addStartExpression()
addFunctionCall(LLVMVariable(name, LLVMVoidType(), scope = LLVMVariableScope()), listOf())
addAnyReturn(LLVMVoidType())
addEndExpression()
*/
}
fun defineGlobalVariable(variable: LLVMVariable, defaultValue: String = variable.type.defaultValue) {
ir.globalDeclaration(variable, defaultValue)
bc.globalDeclaration(variable, defaultValue)
//addLLVMCodeToLocalPlace("$variable = global ${variable.pointedType} $defaultValue, align ${variable.type.align}")
}
fun getNewVariable(type: LLVMType, pointer: Int = 0, kotlinName: String? = null, scope: LLVMScope = LLVMRegisterScope(), prefix: String = "var"): LLVMVariable {
variableCount++
return LLVMVariable("$prefix$variableCount", type, kotlinName, scope, pointer)
}
fun getNewLabel(scope: LLVMScope = LLVMRegisterScope(), prefix: String): LLVMLabel {
labelCount++
return LLVMLabel("label.$prefix.$labelCount", scope)
}
fun loadArgsIfRequired(names: List<LLVMSingleValue>, args: List<LLVMVariable>) =
names.mapIndexed(fun(i: Int, value: LLVMSingleValue): LLVMSingleValue {
return receivePointedArgument(value, args[i].pointer)
}).toList()
fun loadArgument(llvmVariable: LLVMVariable, store: Boolean = true): LLVMVariable {
val allocVar = LLVMVariable("${llvmVariable.label}.addr", llvmVariable.type, llvmVariable.kotlinName, LLVMRegisterScope(), pointer = llvmVariable.pointer + 1)
allocStackVar(allocVar, asValue = false, pointer = true)
if (store) {
storeVariable(allocVar, llvmVariable)
}
return allocVar
}
fun loadClassField(target: LLVMVariable, source: LLVMVariable, offset: Int) {
ir.loadClassField(target, source, offset)
bc.loadClassField(target, source, offset)
//addLLVMCodeToLocalPlace("$target = getelementptr inbounds ${source.pointedType} $source, i32 0, i32 $offset")
}
fun loadVariableOffset(target: LLVMVariable, source: LLVMVariable, index: LLVMConstant) {
ir.loadVariableOffset(target, source, index)
bc.loadVariableOffset(target, source, index)
//addLLVMCodeToLocalPlace("$target = getelementptr inbounds ${source.type} $source, ${index.type} ${index.value}")
}
fun loadAndGetVariable(source: LLVMVariable): LLVMVariable {
assert(source.pointer > 0)
val target = getNewVariable(source.type, source.pointer - 1, source.kotlinName)
ir.load(source)
bc.load(source)
//addLLVMCodeToLocalPlace("$target = load ${source.pointedType} $source, align ${target.type.align}")
return target
}
fun makeStructInitializer(args: List<LLVMVariable>, values: List<String>) {
ir.structInitializer(args, values)
bc.structInitializer(args, values)
// = "{ ${args.mapIndexed { i: Int, variable: LLVMVariable -> "${variable.type} ${values[i]}" }.joinToString()} }"
}
fun markWithLabel(label: LLVMLabel?) {
label ?: return
ir.label(label)
bc.label(label)
//addLLVMCodeToLocalPlace("${label.label}:")
}
fun memcpy(castedDst: LLVMVariable, castedSrc: LLVMVariable, size: Int, align: Int = 4, volatile: Boolean = false) {
//addLLVMCodeToLocalPlace("call void @llvm.memcpy.p0i8.p0i8.i64(i8* $castedDst, i8* $castedSrc, i64 $size, i32 $align, i1 $volatile)")
ir.memcpy(castedDst, castedSrc, size, align, volatile)
bc.memcpy(castedDst, castedSrc, size, align, volatile)
}
fun nullCheck(variable: LLVMVariable): LLVMVariable {
val result = getNewVariable(LLVMBooleanType(), pointer = 0)
val loaded = loadAndGetVariable(variable)
addLLVMCodeToLocalPlace("$result = icmp eq ${loaded.pointedType} null, $loaded")
return result
}
fun receiveNativeValue(firstOp: LLVMSingleValue): LLVMSingleValue =
when {
firstOp is LLVMConstant || firstOp.pointer == 0 -> firstOp
firstOp is LLVMVariable -> loadAndGetVariable(firstOp)
else -> throw UnexpectedException("Unknown inheritor of LLVMSingleValue")
}
fun receivePointedArgument(value: LLVMSingleValue, requirePointer: Int): LLVMSingleValue {
var result = value
while (result.pointer > requirePointer) {
result = receiveNativeValue(result)
}
fun createClass(name: String, fields: List<LLVMVariable>) =
addLLVMCodeToGlobalPlace("%class.$name = type { ${fields.map { it.pointedType }.joinToString()} }")
fun declareEntryPoint(name: String) {
addLLVMCodeToLocalPlace("define weak void @main()")
addStartExpression()
addFunctionCall(LLVMVariable(name, LLVMVoidType(), scope = LLVMVariableScope()), listOf())
addAnyReturn(LLVMVoidType())
addEndExpression()
}
fun defineGlobalVariable(variable: LLVMVariable, defaultValue: String = variable.type.defaultValue) =
addLLVMCodeToLocalPlace("$variable = global ${variable.pointedType} $defaultValue, align ${variable.type.align}")
fun getNewVariable(type: LLVMType, pointer: Int = 0, kotlinName: String? = null, scope: LLVMScope = LLVMRegisterScope(), prefix: String = "var"): LLVMVariable {
variableCount++
return LLVMVariable("$prefix$variableCount", type, kotlinName, scope, pointer)
}
fun getNewLabel(scope: LLVMScope = LLVMRegisterScope(), prefix: String): LLVMLabel {
labelCount++
return LLVMLabel("label.$prefix.$labelCount", scope)
}
fun loadArgsIfRequired(names: List<LLVMSingleValue>, args: List<LLVMVariable>) =
names.mapIndexed(fun(i: Int, value: LLVMSingleValue): LLVMSingleValue {
return receivePointedArgument(value, args[i].pointer)
}).toList()
fun loadArgument(llvmVariable: LLVMVariable, store: Boolean = true): LLVMVariable {
val allocVar = LLVMVariable("${llvmVariable.label}.addr", llvmVariable.type, llvmVariable.kotlinName, LLVMRegisterScope(), pointer = llvmVariable.pointer + 1)
allocStackVar(allocVar, asValue = false, pointer = true)
if (store) {
storeVariable(allocVar, llvmVariable)
}
return allocVar
}
fun loadClassField(target: LLVMVariable, source: LLVMVariable, offset: Int) =
addLLVMCodeToLocalPlace("$target = getelementptr inbounds ${source.pointedType} $source, i32 0, i32 $offset")
fun loadVariableOffset(target: LLVMVariable, source: LLVMVariable, index: LLVMConstant) =
addLLVMCodeToLocalPlace("$target = getelementptr inbounds ${source.type} $source, ${index.type} ${index.value}")
fun loadAndGetVariable(source: LLVMVariable): LLVMVariable {
assert(source.pointer > 0)
val target = getNewVariable(source.type, source.pointer - 1, source.kotlinName)
addLLVMCodeToLocalPlace("$target = load ${source.pointedType} $source, align ${target.type.align}")
return target
}
fun makeStructInitializer(args: List<LLVMVariable>, values: List<String>)
= "{ ${args.mapIndexed { i: Int, variable: LLVMVariable -> "${variable.type} ${values[i]}" }.joinToString()} }"
fun markWithLabel(label: LLVMLabel?) {
if (label != null)
addLLVMCodeToLocalPlace("${label.label}:")
}
fun memcpy(castedDst: LLVMVariable, castedSrc: LLVMVariable, size: Int, align: Int = 4, volatile: Boolean = false) =
addLLVMCodeToLocalPlace("call void @llvm.memcpy.p0i8.p0i8.i64(i8* $castedDst, i8* $castedSrc, i64 $size, i32 $align, i1 $volatile)")
fun nullCheck(variable: LLVMVariable): LLVMVariable {
val result = getNewVariable(LLVMBooleanType(), pointer = 0)
val loaded = loadAndGetVariable(variable)
addLLVMCodeToLocalPlace("$result = icmp eq ${loaded.pointedType} null, $loaded")
return result
}
fun receiveNativeValue(firstOp: LLVMSingleValue): LLVMSingleValue =
when {
firstOp is LLVMConstant || firstOp.pointer == 0 -> firstOp
firstOp is LLVMVariable -> loadAndGetVariable(firstOp)
else -> throw UnexpectedException("Unknown inheritor of LLVMSingleValue")
if ((value.type is LLVMStringType) && !(value.type.isLoaded)) {
val newVariable = getNewVariable(value.type, pointer = result.pointer + 1)
allocStackVar(newVariable, asValue = true)
copyVariable(result as LLVMVariable, newVariable)
result = loadAndGetVariable(newVariable)
}
fun receivePointedArgument(value: LLVMSingleValue, requirePointer: Int): LLVMSingleValue {
var result = value
while (result.pointer > requirePointer) {
result = receiveNativeValue(result)
return result
}
if ((value.type is LLVMStringType) && !(value.type.isLoaded)) {
val newVariable = getNewVariable(value.type, pointer = result.pointer + 1)
allocStackVar(newVariable, asValue = true)
copyVariable(result as LLVMVariable, newVariable)
result = loadAndGetVariable(newVariable)
fun storeString(target: LLVMVariable, source: LLVMVariable, offset: Int) {
val code = "store ${target.type} getelementptr inbounds (" +
"${(source.type as LLVMStringType).fullArrayType}* $source, i32 0, i32 $offset), ${target.pointedType} $target, align ${source.type.align}"
(target.type as LLVMStringType).isLoaded = true
addLLVMCodeToLocalPlace(code)
}
return result
}
fun storeVariable(target: LLVMSingleValue, source: LLVMSingleValue) {
if ((source.type is LLVMStringType) && !(source.type.isLoaded)) {
storeString(target as LLVMVariable, source as LLVMVariable, 0)
} else {
addLLVMCodeToLocalPlace("store ${source.pointedType} $source, ${target.pointedType} $target, align ${source.type.align}")
}
}
fun storeString(target: LLVMVariable, source: LLVMVariable, offset: Int) {
val code = "store ${target.type} getelementptr inbounds (" +
"${(source.type as LLVMStringType).fullArrayType}* $source, i32 0, i32 $offset), ${target.pointedType} $target, align ${source.type.align}"
(target.type as LLVMStringType).isLoaded = true
addLLVMCodeToLocalPlace(code)
}
fun saveExpression(expression: LLVMSingleValue): LLVMVariable {
val resultOp = getNewVariable(expression.type, pointer = expression.pointer)
addAssignment(resultOp, expression)
return resultOp
}
fun storeVariable(target: LLVMSingleValue, source: LLVMSingleValue) {
if ((source.type is LLVMStringType) && !(source.type.isLoaded)) {
storeString(target as LLVMVariable, source as LLVMVariable, 0)
} else {
addLLVMCodeToLocalPlace("store ${source.pointedType} $source, ${target.pointedType} $target, align ${source.type.align}")
fun storeNull(result: LLVMVariable) =
addLLVMCodeToLocalPlace("store ${result.pointedType.dropLast(1)} null, ${result.pointedType} $result, align ${TranslationState.POINTER_ALIGN}")
override fun toString() = globalCode.toString() + localCode.toString()
private fun copyVariableValue(target: LLVMVariable, source: LLVMVariable) {
var from = source
if (source.pointer > 0) {
from = getNewVariable(source.type, source.pointer)
addLLVMCodeToLocalPlace("$from = load ${source.pointedType} $source, align ${from.type.align}")
}
addLLVMCodeToLocalPlace("store ${target.type} $from, ${target.pointedType} $target, align ${from.type.align}")
}
}
fun saveExpression(expression: LLVMSingleValue): LLVMVariable {
val resultOp = getNewVariable(expression.type, pointer = expression.pointer)
addAssignment(resultOp, expression)
return resultOp
}
fun storeNull(result: LLVMVariable) =
addLLVMCodeToLocalPlace("store ${result.pointedType.dropLast(1)} null, ${result.pointedType} $result, align ${TranslationState.POINTER_ALIGN}")
override fun toString() = globalCode.toString() + localCode.toString()
private fun copyVariableValue(target: LLVMVariable, source: LLVMVariable) {
var from = source
if (source.pointer > 0) {
from = getNewVariable(source.type, source.pointer)
addLLVMCodeToLocalPlace("$from = load ${source.pointedType} $source, align ${from.type.align}")
}
addLLVMCodeToLocalPlace("store ${target.type} $from, ${target.pointedType} $target, align ${from.type.align}")
}
private fun initializeExceptionString(string: String): LLVMVariable {
val result = getNewVariable(LLVMStringType(string.length), pointer = 0, scope = LLVMVariableScope(), prefix = "exceptions.str.")
addStringConstant(result, string)
return result
}
}
@@ -0,0 +1,104 @@
package org.kotlinnative.translator.llvm.bc
import org.kotlinnative.translator.llvm.*
import org.kotlinnative.translator.llvm.types.LLVMType
import java.util.*
/**
* Created by minamoto on 23/09/2016.
*/
class BcLlvmBuilder {
fun comment(comment: String) {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
fun startExpression() {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
fun endExpression() {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
fun assignment(lhs: LLVMVariable, rhs: LLVMNode) {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
fun returnOperation(llvmVariable: LLVMSingleValue) {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
fun anyReturn(type: LLVMType, value: String, pointer: Int) {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
fun stringConstant(variable: LLVMVariable, value: String) {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
fun conditionalBranch(condition: LLVMSingleValue, thenLabel: LLVMLabel, elseLabel: LLVMLabel) {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
fun unconditionalBranch(label: LLVMLabel) {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
fun abort(exceptionName: String) {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
fun call(functionName: LLVMVariable, arguments: List<LLVMVariable>) {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
fun alloca(target: LLVMVariable, asValue: Boolean, pointer: Boolean) {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
fun heapAndCall(target: LLVMVariable, asValue: Boolean, pointer: Boolean) {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
fun globalInitialize(target: LLVMVariable, fields: ArrayList<LLVMClassVariable>, initializers: Map<LLVMVariable, String>, classType: LLVMType) {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
fun bitcast(src: LLVMVariable, llvmType: LLVMType, pointer: Int) {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
fun classDeclaration(name: String, fields: List<LLVMVariable>) {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
fun globalDeclaration(variable: LLVMVariable, defaultValue: String) {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
fun loadClassField(target: LLVMVariable, source: LLVMVariable, offset: Int) {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
fun loadVariableOffset(target: LLVMVariable, source: LLVMVariable, index: LLVMConstant) {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
fun load(source: LLVMVariable) {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
fun label(label: LLVMLabel) {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
fun structInitializer(args: List<LLVMVariable>, values: List<String>) {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
fun memcpy(castedDst: LLVMVariable, castedSrc: LLVMVariable, size: Int, align: Int, volatile: Boolean) {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
}
@@ -0,0 +1,141 @@
package org.kotlinnative.translator.llvm.ir
import org.kotlinnative.translator.llvm.*
import org.kotlinnative.translator.llvm.types.LLVMStringType
import org.kotlinnative.translator.llvm.types.LLVMType
import java.util.*
/**
* Created by minamoto on 23/09/2016.
*/
class IrLlvmBuilder {
private val localCode: StringBuilder = StringBuilder()
private val globalCode: StringBuilder = StringBuilder()
private val arm = true /* architecture specific TBD */
private val exceptions = mapOf(
Pair("KotlinNullPointerException", initializeExceptionString("Exception in thread main kotlin.KotlinNullPointerException")))
init {
val declares = arrayOf(
"declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture readonly, i64, i32, i1)",
"declare i8* @malloc_heap(i32)",
"declare i32 @printf(i8*, ...)",
"declare void @abort()",
"%class.Nothing = type { }")
declares.forEach { addLLVMCodeToGlobalPlace(it) }
if (arm) {
val functionAttributes = """attributes #0 = { nounwind "stack-protector-buffer-size"="8" "target-cpu"="cortex-m3" "target-features"="+hwdiv,+strict-align" }"""
addLLVMCodeToGlobalPlace(functionAttributes)
}
}
fun addLLVMCodeToLocalPlace(code: String) =
localCode.appendln(code)
fun addLLVMCodeToGlobalPlace(code: String) =
globalCode.appendln(code)
private fun initializeExceptionString(string: String): LLVMVariable {
TODO()
/*
val result = getNewVariable(LLVMStringType(string.length), pointer = 0, scope = LLVMVariableScope(), prefix = "exceptions.str.")
addStringConstant(result, string)
return result
*/
}
fun comment(comment: String) {
TODO()
}
fun startExpression() {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
fun endExpression() {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
fun assignment(lhs: LLVMVariable, rhs: LLVMNode) {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
fun returnOperation(llvmVariable: LLVMSingleValue) {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
fun anyReturn(type: LLVMType, value: String, pointer: Int) {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
fun stringConstant(variable: LLVMVariable, value: String) {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
fun conditionalBranch(condition: LLVMSingleValue, thenLabel: LLVMLabel, elseLabel: LLVMLabel) {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
fun unconditionalBranch(label: LLVMLabel) {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
fun abort(exceptionName: String) {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
fun call(functionName: LLVMVariable, arguments: List<LLVMVariable>) {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
fun alloca(target: LLVMVariable, asValue: Boolean, pointer: Boolean) {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
fun heapAndCast(target: LLVMVariable, asValue: Boolean, pointer: Boolean) {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
fun globalinitialize(target: LLVMVariable, fields: ArrayList<LLVMClassVariable>, initializers: Map<LLVMVariable, String>, classType: LLVMType) {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
fun bitcast(src: LLVMVariable, llvmType: LLVMType, pointer: Int) {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
fun classDeclaration(name: String, fields: List<LLVMVariable>) {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
fun globalDeclaration(variable: LLVMVariable, defaultValue: String) {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
fun loadClassField(target: LLVMVariable, source: LLVMVariable, offset: Int) {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
fun loadVariableOffset(target: LLVMVariable, source: LLVMVariable, index: LLVMConstant) {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
fun load(source: LLVMVariable) {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
fun label(label: LLVMLabel) {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
fun structInitializer(args: List<LLVMVariable>, values: List<String>) {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
fun memcpy(castedDst: LLVMVariable, castedSrc: LLVMVariable, size: Int, align: Int, volatile: Boolean) {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
}