translator: erase nullable type in LLVMSingleValue

This commit is contained in:
Alexey Stepanov
2016-08-30 16:10:43 +03:00
parent 6d5b505d11
commit c8d7f53e64
14 changed files with 83 additions and 88 deletions
@@ -47,7 +47,7 @@ abstract class BlockCodegen(val state: TranslationState, val variableManager: Va
codeBuilder.addReturnOperator(result)
}
}
else -> codeBuilder.addAnyReturn(result.type!!, result.toString())
else -> codeBuilder.addAnyReturn(result.type, result.toString())
}
wasReturnOnTopLevel = true
@@ -155,7 +155,7 @@ abstract class BlockCodegen(val state: TranslationState, val variableManager: Va
val result = codeBuilder.getNewVariable(expectedType, pointer = 2)
codeBuilder.allocStaticVar(result, pointer = true)
val condition = left.type!!.operatorEq(loadedLeft, LLVMVariable("", LLVMNullType()))
val condition = left.type.operatorEq(loadedLeft, LLVMVariable("", LLVMNullType()))
val thenLabel = codeBuilder.getNewLabel(prefix = "safe.access")
val elseLabel = codeBuilder.getNewLabel(prefix = "safe.access")
val endLabel = codeBuilder.getNewLabel(prefix = "safe.access")
@@ -351,7 +351,7 @@ abstract class BlockCodegen(val state: TranslationState, val variableManager: Va
val names = parseValueArguments(callMaker.valueArguments, scope)
val methodName = "$targetClassName.$arrayActionType${LLVMType.mangleFunctionArguments(names)}"
val type = receiver.type as LLVMReferenceType
val type = receiver.type
val clazz = resolveClassOrObjectLocation(type) ?: throw UnexpectedException(type.toString())
val method = clazz.methods[methodName] ?: throw UnexpectedException(expr.text)
@@ -720,36 +720,36 @@ abstract class BlockCodegen(val state: TranslationState, val variableManager: Va
return when (operator) {
"||",
"or" -> firstNativeOp.type!!.operatorOr(firstNativeOp, secondNativeOp)
"xor" -> firstNativeOp.type!!.operatorXor(firstNativeOp, secondNativeOp)
"or" -> firstNativeOp.type.operatorOr(firstNativeOp, secondNativeOp)
"xor" -> firstNativeOp.type.operatorXor(firstNativeOp, secondNativeOp)
"&&",
"and" -> firstNativeOp.type!!.operatorAnd(firstNativeOp, secondNativeOp)
"%" -> firstNativeOp.type!!.operatorMod(firstNativeOp, secondNativeOp)
"shl" -> firstNativeOp.type!!.operatorShl(firstNativeOp, codeBuilder.convertVariableToType(secondNativeOp, firstNativeOp.type!!))
"shr" -> firstNativeOp.type!!.operatorShr(firstNativeOp, codeBuilder.convertVariableToType(secondNativeOp, firstNativeOp.type!!))
"ushr" -> firstNativeOp.type!!.operatorUshr(firstNativeOp, codeBuilder.convertVariableToType(secondNativeOp, firstNativeOp.type!!))
"and" -> firstNativeOp.type.operatorAnd(firstNativeOp, secondNativeOp)
"%" -> firstNativeOp.type.operatorMod(firstNativeOp, secondNativeOp)
"shl" -> firstNativeOp.type.operatorShl(firstNativeOp, codeBuilder.convertVariableToType(secondNativeOp, firstNativeOp.type))
"shr" -> firstNativeOp.type.operatorShr(firstNativeOp, codeBuilder.convertVariableToType(secondNativeOp, firstNativeOp.type))
"ushr" -> firstNativeOp.type.operatorUshr(firstNativeOp, codeBuilder.convertVariableToType(secondNativeOp, firstNativeOp.type))
"+=" -> {
val resultOp = codeBuilder.storeExpression(firstOp, firstNativeOp.type!!.operatorPlus(firstNativeOp, secondNativeOp))
return LLVMExpression(resultOp.type, "load ${firstOp.getType()} $firstOp, align ${firstOp.type!!.align}")
val resultOp = codeBuilder.storeExpression(firstOp, firstNativeOp.type.operatorPlus(firstNativeOp, secondNativeOp))
return LLVMExpression(resultOp.type, "load ${firstOp.pointedType} $firstOp, align ${firstOp.type.align}")
}
"-=" -> {
val resultOp = codeBuilder.storeExpression(firstOp, firstNativeOp.type!!.operatorMinus(firstNativeOp, secondNativeOp))
return LLVMExpression(resultOp.type, "load ${firstOp.getType()} $firstOp, align ${firstOp.type!!.align}")
val resultOp = codeBuilder.storeExpression(firstOp, firstNativeOp.type.operatorMinus(firstNativeOp, secondNativeOp))
return LLVMExpression(resultOp.type, "load ${firstOp.pointedType} $firstOp, align ${firstOp.type.align}")
}
"*=" -> {
val resultOp = codeBuilder.storeExpression(firstOp, firstNativeOp.type!!.operatorTimes(firstNativeOp, secondNativeOp))
return LLVMExpression(resultOp.type, "load ${firstOp.getType()} $firstOp, align ${firstOp.type!!.align}")
val resultOp = codeBuilder.storeExpression(firstOp, firstNativeOp.type.operatorTimes(firstNativeOp, secondNativeOp))
return LLVMExpression(resultOp.type, "load ${firstOp.pointedType} $firstOp, align ${firstOp.type.align}")
}
"%=" -> {
val resultOp = codeBuilder.storeExpression(firstOp, firstNativeOp.type!!.operatorMod(firstNativeOp, secondNativeOp))
return LLVMExpression(resultOp.type, "load ${firstOp.getType()} $firstOp, align ${firstOp.type!!.align}")
val resultOp = codeBuilder.storeExpression(firstOp, firstNativeOp.type.operatorMod(firstNativeOp, secondNativeOp))
return LLVMExpression(resultOp.type, "load ${firstOp.pointedType} $firstOp, align ${firstOp.type.align}")
}
".." -> {
val descriptor = state.classes["kotlin.ranges.IntRange"]
val arguments = listOf(firstOp, secondNativeOp)
val detectedConstructor = LLVMType.mangleFunctionTypes(arguments.map { it.type!! })
val detectedConstructor = LLVMType.mangleFunctionTypes(arguments.map { it.type })
val result = evaluateConstructorCallExpression(LLVMVariable(descriptor!!.fullName + detectedConstructor, descriptor.type, scope = LLVMVariableScope()), arguments)
return LLVMExpression(result!!.type!!, "load ${descriptor.type}** $result, align ${descriptor.type.align}", pointer = 1)
return LLVMExpression(result!!.type, "load ${descriptor.type}** $result, align ${descriptor.type.align}", pointer = 1)
}
else -> throw UnsupportedOperationException("Unknown binary operator: $operator(${firstNativeOp.type}, ${secondNativeOp.type})")
}
@@ -760,38 +760,38 @@ abstract class BlockCodegen(val state: TranslationState, val variableManager: Va
val secondNativeOp = codeBuilder.receiveNativeValue(secondOp)
val llvmExpression = when (operator) {
KtTokens.PLUS -> firstOp.type!!.operatorPlus(firstNativeOp, secondNativeOp)
KtTokens.MINUS -> firstOp.type!!.operatorMinus(firstNativeOp, secondNativeOp)
KtTokens.MUL -> firstOp.type!!.operatorTimes(firstNativeOp, secondNativeOp)
KtTokens.DIV -> firstOp.type!!.operatorDiv(firstNativeOp, secondNativeOp)
KtTokens.LT -> firstOp.type!!.operatorLt(firstNativeOp, secondNativeOp)
KtTokens.GT -> firstOp.type!!.operatorGt(firstNativeOp, secondNativeOp)
KtTokens.LTEQ -> firstOp.type!!.operatorLeq(firstNativeOp, secondNativeOp)
KtTokens.GTEQ -> firstOp.type!!.operatorGeq(firstNativeOp, secondNativeOp)
KtTokens.PLUS -> firstOp.type.operatorPlus(firstNativeOp, secondNativeOp)
KtTokens.MINUS -> firstOp.type.operatorMinus(firstNativeOp, secondNativeOp)
KtTokens.MUL -> firstOp.type.operatorTimes(firstNativeOp, secondNativeOp)
KtTokens.DIV -> firstOp.type.operatorDiv(firstNativeOp, secondNativeOp)
KtTokens.LT -> firstOp.type.operatorLt(firstNativeOp, secondNativeOp)
KtTokens.GT -> firstOp.type.operatorGt(firstNativeOp, secondNativeOp)
KtTokens.LTEQ -> firstOp.type.operatorLeq(firstNativeOp, secondNativeOp)
KtTokens.GTEQ -> firstOp.type.operatorGeq(firstNativeOp, secondNativeOp)
KtTokens.EQEQ ->
if (LLVMType.isReferredType(firstOp.type) && LLVMType.isReferredType(secondOp.type)) {
val firstPointedArgument = codeBuilder.receivePointedArgument(firstOp, 1)
val secondPointedArgument = codeBuilder.receivePointedArgument(secondOp, 1)
firstOp.type!!.operatorEq(firstPointedArgument, secondPointedArgument)
firstOp.type.operatorEq(firstPointedArgument, secondPointedArgument)
} else
firstOp.type!!.operatorEq(firstNativeOp, secondNativeOp)
firstOp.type.operatorEq(firstNativeOp, secondNativeOp)
KtTokens.EQEQEQ -> {
val firstPointedArgument = codeBuilder.receivePointedArgument(firstOp, 1)
val secondPointedArgument = codeBuilder.receivePointedArgument(secondOp, 1)
firstOp.type!!.operatorEq(firstPointedArgument, secondPointedArgument)
firstOp.type.operatorEq(firstPointedArgument, secondPointedArgument)
}
KtTokens.EXCLEQ -> {
if (LLVMType.isReferredType(firstOp.type) && LLVMType.isReferredType(secondOp.type)) {
val firstPointedArgument = codeBuilder.receivePointedArgument(firstOp, 1)
val secondPointedArgument = codeBuilder.receivePointedArgument(secondOp, 1)
firstOp.type!!.operatorNeq(firstPointedArgument, secondPointedArgument)
firstOp.type.operatorNeq(firstPointedArgument, secondPointedArgument)
} else
firstOp.type!!.operatorNeq(firstNativeOp, secondNativeOp)
firstOp.type.operatorNeq(firstNativeOp, secondNativeOp)
}
KtTokens.EXCLEQEQEQ -> {
val firstPointedArgument = codeBuilder.receivePointedArgument(firstOp, 1)
val secondPointedArgument = codeBuilder.receivePointedArgument(secondOp, 1)
firstOp.type!!.operatorNeq(firstPointedArgument, secondPointedArgument)
firstOp.type.operatorNeq(firstPointedArgument, secondPointedArgument)
}
KtTokens.EQ -> {
if (secondOp.type is LLVMNullType) {
@@ -801,8 +801,8 @@ abstract class BlockCodegen(val state: TranslationState, val variableManager: Va
val result = firstOp as LLVMVariable
val sourceArgument: LLVMSingleValue
if ((firstOp.pointer == 2) && secondOp.type!!.isPrimitive && (secondOp.pointer == 0)) {
sourceArgument = codeBuilder.getNewVariable(secondOp.type!!, 1)
if ((firstOp.pointer == 2) && secondOp.type.isPrimitive && (secondOp.pointer == 0)) {
sourceArgument = codeBuilder.getNewVariable(secondOp.type, 1)
codeBuilder.allocStaticVar(sourceArgument, asValue = true)
codeBuilder.storeVariable(sourceArgument, secondOp)
} else {
@@ -137,12 +137,12 @@ class FunctionCodegen(state: TranslationState,
private fun generateLoadArguments() {
args.forEach(fun(it: LLVMVariable) {
if (it.type is LLVMFunctionType || (it.type is LLVMReferenceType && (it.type as LLVMReferenceType).byRef)) {
if (it.type is LLVMFunctionType || (it.type is LLVMReferenceType && it.type.byRef)) {
variableManager.addVariable(it.label, LLVMVariable(it.label, it.type, it.label, LLVMRegisterScope(), pointer = 1), topLevel)
return
}
if (it.type !is LLVMReferenceType || (it.type as LLVMReferenceType).byRef) {
if (it.type !is LLVMReferenceType || it.type.byRef) {
val loadVariable = LLVMVariable(it.label, it.type, it.label, LLVMRegisterScope(), pointer = it.pointer)
val allocVar = codeBuilder.loadArgument(loadVariable)
variableManager.addVariable(it.label, allocVar, topLevel)
@@ -243,7 +243,7 @@ abstract class StructCodegen(val state: TranslationState,
val result = LLVMInstanceOfStandardType(fieldName, ktType, LLVMRegisterScope(), state = state)
if (result.type is LLVMReferenceType) {
val type = result.type as LLVMReferenceType
val type = result.type
type.prefix = "class"
type.byRef = true
}
@@ -93,8 +93,8 @@ class LLVMBuilder(val arm: Boolean = false) {
result = loadVariable(result as LLVMVariable)
}
if ((value.type is LLVMStringType) && (!(value.type as LLVMStringType).isLoaded)) {
val newVariable = getNewVariable(value.type!!, pointer = result.pointer + 1)
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 = loadVariable(newVariable)
@@ -104,7 +104,7 @@ class LLVMBuilder(val arm: Boolean = false) {
}
fun downLoadArgument(value: LLVMSingleValue, pointer: Int): LLVMSingleValue =
loadOneArgumentIfRequired(value, LLVMVariable("", value.type!!, pointer = pointer))
loadOneArgumentIfRequired(value, LLVMVariable("", value.type, pointer = pointer))
fun clean() {
localCode = StringBuilder()
@@ -134,10 +134,10 @@ class LLVMBuilder(val arm: Boolean = false) {
addLLVMCodeToGlobalPlace("$variable = private unnamed_addr constant ${(variable.type as LLVMStringType).fullArrayType} c\"${value.replace("\"", "\\\"")}\\00\", align 1")
fun convertVariableToType(variable: LLVMSingleValue, targetType: LLVMType): LLVMSingleValue {
fun convertVariableToType(variable: LLVMSingleValue, tarpointedType: LLVMType): LLVMSingleValue {
var resultVariable = variable
if (variable.type != targetType) {
val convertedExpression = targetType.convertFrom(variable)
if (variable.type != tarpointedType) {
val convertedExpression = tarpointedType.convertFrom(variable)
resultVariable = getNewVariable(convertedExpression.variableType)
addAssignment(resultVariable, convertedExpression)
}
@@ -146,20 +146,20 @@ class LLVMBuilder(val arm: Boolean = false) {
fun addGlobalInitialize(target: LLVMVariable, fields: ArrayList<LLVMVariable>, initializers: Map<LLVMVariable, String>, classType: LLVMType) {
val code = "$target = internal global $classType { ${
fields.map { it.getType() + " " + if (initializers.containsKey(it)) initializers[it] else "0" }.joinToString()
fields.map { it.pointedType + " " + if (initializers.containsKey(it)) initializers[it] else "0" }.joinToString()
} }, align ${classType.align}"
globalCode.appendln(code)
}
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.getType()} $target, align ${source.type.align}"
"${(source.type as LLVMStringType).fullArrayType}* $source, i32 0, i32 $offset), ${target.pointedType} $target, align ${source.type.align}"
(target.type as LLVMStringType).isLoaded = true
localCode.appendln(code)
}
fun loadClassField(target: LLVMVariable, source: LLVMVariable, offset: Int) =
addLLVMCodeToLocalPlace("$target = getelementptr inbounds ${source.getType()} $source, i32 0, i32 $offset")
addLLVMCodeToLocalPlace("$target = getelementptr inbounds ${source.pointedType} $source, i32 0, i32 $offset")
fun markWithLabel(label: LLVMLabel?) {
if (label != null)
@@ -167,10 +167,10 @@ class LLVMBuilder(val arm: Boolean = false) {
}
fun storeVariable(target: LLVMSingleValue, source: LLVMSingleValue) {
if ((source.type is LLVMStringType) && (!(source.type as LLVMStringType).isLoaded)) {
if ((source.type is LLVMStringType) && !(source.type.isLoaded)) {
storeString(target as LLVMVariable, source as LLVMVariable, 0)
} else {
addLLVMCodeToLocalPlace("store ${source.getType()} $source, ${target.getType()} $target, align ${source.type?.align!!}")
addLLVMCodeToLocalPlace("store ${source.pointedType} $source, ${target.pointedType} $target, align ${source.type.align}")
}
}
@@ -183,13 +183,13 @@ class LLVMBuilder(val arm: Boolean = false) {
}
fun storeNull(result: LLVMVariable) =
addLLVMCodeToLocalPlace("store ${result.getType().dropLast(1)} null, ${result.getType()} $result, align ${TranslationState.pointerAlign}")
addLLVMCodeToLocalPlace("store ${result.pointedType.dropLast(1)} null, ${result.pointedType} $result, align ${TranslationState.pointerAlign}")
fun nullCheck(variable: LLVMVariable): LLVMVariable {
val result = getNewVariable(LLVMBooleanType(), pointer = 0)
val loaded = loadVariable(variable)
addLLVMCodeToLocalPlace("$result = icmp eq ${loaded.getType()} null, $loaded")
addLLVMCodeToLocalPlace("$result = icmp eq ${loaded.pointedType} null, $loaded")
return result
}
@@ -204,13 +204,13 @@ class LLVMBuilder(val arm: Boolean = false) {
var from = source
if (source.pointer > 0) {
from = getNewVariable(source.type, source.pointer)
addLLVMCodeToLocalPlace("$from = load ${source.getType()} $source, align ${from.type.align}")
addLLVMCodeToLocalPlace("$from = load ${source.pointedType} $source, align ${from.type.align}")
}
addLLVMCodeToLocalPlace("store ${target.type} $from, ${target.getType()} $target, align ${from.type.align}")
addLLVMCodeToLocalPlace("store ${target.type} $from, ${target.pointedType} $target, align ${from.type.align}")
}
fun copyVariable(from: LLVMVariable, to: LLVMVariable) = when (from.type) {
is LLVMStringType -> if ((from.type as LLVMStringType).isLoaded) copyVariableValue(to, from) else storeString(to, from, 0)
is LLVMStringType -> if (from.type.isLoaded) copyVariableValue(to, from) else storeString(to, from, 0)
else -> copyVariableValue(to, from)
}
@@ -222,12 +222,12 @@ class LLVMBuilder(val arm: Boolean = false) {
fun loadVariable(source: LLVMVariable): LLVMVariable {
val target = getNewVariable(source.type, pointer = source.pointer - 1)
addLLVMCodeToLocalPlace("$target = load ${source.getType()} $source, align ${target.type.align}")
addLLVMCodeToLocalPlace("$target = load ${source.pointedType} $source, align ${target.type.align}")
return target
}
fun allocStackVar(target: LLVMVariable, asValue: Boolean = false, pointer: Boolean = false) {
val type = if (asValue) target.type.toString() else target.getType()
val type = if (asValue) target.type.toString() else target.pointedType
addLLVMCodeToLocalPlace("$target = alloca ${if (pointer) type.removeSuffix("*") else type}, align ${target.type.align}")
}
@@ -237,19 +237,19 @@ class LLVMBuilder(val arm: Boolean = false) {
val size = if ((target.pointer >= 2) || (target.pointer >= 1 && !pointer)) TranslationState.pointerSize else target.type.size
addLLVMCodeToLocalPlace("$allocated = call i8* @malloc_heap(i32 $size)")
addLLVMCodeToLocalPlace("$target = bitcast ${allocated.getType()} $allocated to ${if (asValue) target.type.toString() else target.getType()}" + if (pointer) "" else "*")
addLLVMCodeToLocalPlace("$target = bitcast ${allocated.pointedType} $allocated to ${if (asValue) target.type.toString() else target.pointedType}" + if (pointer) "" else "*")
}
fun addVariableByRef(targetVariable: LLVMVariable, sourceVariable: LLVMVariable, store: Boolean) {
addLLVMCodeToLocalPlace("$targetVariable = alloca ${sourceVariable.getType()}, align ${sourceVariable.type.align}")
addLLVMCodeToLocalPlace("$targetVariable = alloca ${sourceVariable.pointedType}, align ${sourceVariable.type.align}")
if (store) {
addLLVMCodeToLocalPlace("store ${sourceVariable.getType()} $sourceVariable, ${targetVariable.getType()} $targetVariable, align ${targetVariable.type.align}")
addLLVMCodeToLocalPlace("store ${sourceVariable.pointedType} $sourceVariable, ${targetVariable.pointedType} $targetVariable, align ${targetVariable.type.align}")
}
}
fun defineGlobalVariable(variable: LLVMVariable, defaultValue: String = variable.type.defaultValue) =
addLLVMCodeToLocalPlace("$variable = global ${variable.getType()} $defaultValue, align ${variable.type.align}")
addLLVMCodeToLocalPlace("$variable = global ${variable.pointedType} $defaultValue, align ${variable.type.align}")
fun makeStructInitializer(args: List<LLVMVariable>, values: List<String>)
@@ -258,12 +258,12 @@ class LLVMBuilder(val arm: Boolean = false) {
fun loadAndGetVariable(source: LLVMVariable): LLVMVariable {
assert(source.pointer > 0)
val target = getNewVariable(source.type, source.pointer - 1, source.kotlinName)
addLLVMCodeToLocalPlace("$target = load ${source.getType()} $source, align ${target.type.align}")
addLLVMCodeToLocalPlace("$target = load ${source.pointedType} $source, align ${target.type.align}")
return target
}
fun addCondition(condition: LLVMSingleValue, thenLabel: LLVMLabel, elseLabel: LLVMLabel) =
addLLVMCodeToLocalPlace("br ${condition.getType()} $condition, label $thenLabel, label $elseLabel")
addLLVMCodeToLocalPlace("br ${condition.pointedType} $condition, label $thenLabel, label $elseLabel")
fun addUnconditionalJump(label: LLVMLabel) =
@@ -271,12 +271,12 @@ class LLVMBuilder(val arm: Boolean = false) {
fun createClass(name: String, fields: List<LLVMVariable>) =
addLLVMCodeToGlobalPlace("%class.$name = type { ${fields.map { it.getType() }.joinToString()} }")
addLLVMCodeToGlobalPlace("%class.$name = type { ${fields.map { it.pointedType }.joinToString()} }")
fun bitcast(src: LLVMVariable, llvmType: LLVMVariable): LLVMVariable {
val empty = getNewVariable(llvmType.type, pointer = llvmType.pointer)
addLLVMCodeToLocalPlace("$empty = bitcast ${src.getType()} $src to ${llvmType.getType()}")
addLLVMCodeToLocalPlace("$empty = bitcast ${src.pointedType} $src to ${llvmType.pointedType}")
return empty
}
@@ -5,5 +5,5 @@ import org.kotlinnative.translator.llvm.types.LLVMType
class LLVMCall(val returnType: LLVMType, val name: String, val arguments: Collection<LLVMSingleValue>) : LLVMSingleValue(returnType) {
override fun toString(): String =
"call $returnType $name(${arguments.joinToString { "${it.getType()} ${it.toString()}" }})"
"call $returnType $name(${arguments.joinToString { "${it.pointedType} ${it.toString()}" }})"
}
@@ -3,16 +3,15 @@ package org.kotlinnative.translator.llvm
import org.kotlinnative.translator.llvm.types.LLVMType
open class LLVMConstant(value: String,
type: LLVMType? = null,
type: LLVMType,
pointer: Int = 0) : LLVMSingleValue(type, pointer) {
val value: String
init {
this.value = type?.parseArg(value) ?: value
this.value = type.parseArg(value)
}
override fun getType(): String = type.toString() + "*".repeat(pointer)
override fun toString(): String = value
}
}
@@ -1,10 +1,10 @@
package org.kotlinnative.translator.llvm
import org.kotlinnative.translator.exceptions.UnimplementedException
import org.kotlinnative.translator.llvm.types.LLVMType
open class LLVMSingleValue(open val type: LLVMType? = null, open var pointer: Int = 0) : LLVMNode() {
open class LLVMSingleValue(val type: LLVMType, var pointer: Int = 0) : LLVMNode() {
open fun getType(): String = throw UnimplementedException()
open val pointedType: String
get() = type.toString() + "*".repeat(pointer)
}
}
@@ -3,13 +3,11 @@ package org.kotlinnative.translator.llvm
import org.kotlinnative.translator.llvm.types.LLVMType
open class LLVMVariable(val label: String,
override val type: LLVMType,
type: LLVMType,
var kotlinName: String? = null,
val scope: LLVMScope = LLVMRegisterScope(),
pointer: Int = 0) : LLVMSingleValue(type, pointer) {
override fun getType(): String = type.toString() + "*".repeat(pointer)
override fun toString(): String = "$scope$label"
}
@@ -1,7 +1,6 @@
package org.kotlinnative.translator.llvm
import org.jetbrains.kotlin.builtins.isFunctionTypeOrSubtype
import org.jetbrains.kotlin.cfg.pseudocode.getSubtypesPredicate
import org.jetbrains.kotlin.js.descriptorUtils.nameIfStandardType
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
@@ -14,7 +13,7 @@ import org.kotlinnative.translator.llvm.types.*
fun LLVMFunctionDescriptor(name: String, argTypes: List<LLVMVariable>?, returnType: LLVMType, declare: Boolean = false) =
"${if (declare) "declare" else "define weak"} $returnType @$name(${
argTypes?.mapIndexed { i: Int, s: LLVMVariable ->
"${s.getType()} ${if (s.type is LLVMReferenceType && !(s.type as LLVMReferenceType).byRef) "byval" else ""} %${s.label}"
"${s.pointedType} ${if (s.type is LLVMReferenceType && !s.type.byRef) "byval" else ""} %${s.label}"
}?.joinToString()}) #0"
fun LLVMInstanceOfStandardType(name: String, type: KotlinType, scope: LLVMScope = LLVMRegisterScope(), state: TranslationState): LLVMVariable {
@@ -58,6 +57,5 @@ fun String.indexOfOrLast(str: Char, startIndex: Int = 0): Int {
return if (pos < 0) this.length else pos
}
fun FqName.convertToNativeName(): String =
this.asString().replace(".<init>", "")
@@ -26,7 +26,7 @@ class LLVMFunctionType(type: KotlinType, state: TranslationState) : LLVMType() {
fun mangleArgs() = LLVMType.mangleFunctionArguments(arguments)
override fun toString() =
"${returnType.type} (${arguments.map { it.getType() }.joinToString()})"
"${returnType.type} (${arguments.map { it.pointedType }.joinToString()})"
override fun equals(other: Any?) =
(other is LLVMFunctionType) && (mangle == other.mangle)
@@ -15,7 +15,7 @@ class LLVMIntType() : LLVMType() {
override val isPrimitive = true
override fun convertFrom(source: LLVMSingleValue) =
when (source.type!!) {
when (source.type) {
is LLVMBooleanType,
is LLVMByteType,
is LLVMCharType,
@@ -15,7 +15,7 @@ class LLVMLongType() : LLVMType() {
override val isPrimitive = true
override fun convertFrom(source: LLVMSingleValue) =
when (source.type!!) {
when (source.type) {
is LLVMBooleanType,
is LLVMByteType,
is LLVMCharType,
@@ -4,7 +4,7 @@ import org.kotlinnative.translator.TranslationState
import org.kotlinnative.translator.llvm.LLVMExpression
import org.kotlinnative.translator.llvm.LLVMSingleValue
import org.kotlinnative.translator.llvm.addAfterIfNotEmpty
import java.util.*
class LLVMReferenceType(val type: String,
var prefix: String = "",
@@ -19,10 +19,10 @@ class LLVMReferenceType(val type: String,
override fun toString() = "%$typename"
override fun operatorEq(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) =
LLVMExpression(LLVMBooleanType(), "icmp eq ${firstOp.getType()} $firstOp, ${if (secondOp.type is LLVMNullType) "null" else "$secondOp"}")
LLVMExpression(LLVMBooleanType(), "icmp eq ${firstOp.pointedType} $firstOp, ${if (secondOp.type is LLVMNullType) "null" else "$secondOp"}")
override fun operatorNeq(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) =
LLVMExpression(LLVMBooleanType(), "icmp ne ${firstOp.getType()} $firstOp, ${if (secondOp.type is LLVMNullType) "null" else "$secondOp"}")
LLVMExpression(LLVMBooleanType(), "icmp ne ${firstOp.pointedType} $firstOp, ${if (secondOp.type is LLVMNullType) "null" else "$secondOp"}")
override fun equals(other: Any?) =
(other is LLVMReferenceType) and (typename.equals((other as LLVMReferenceType).typename))
@@ -8,7 +8,7 @@ abstract class LLVMType() : Cloneable {
companion object {
fun mangleFunctionArguments(names: List<LLVMSingleValue>) =
mangleFunctionTypes(names.map { it.type!! })
mangleFunctionTypes(names.map { it.type })
fun mangleFunctionTypes(names: List<LLVMType>) =
if (names.size > 0) "_${names.joinToString(separator = "_", transform = { it.mangle })}" else ""