translator: erase nullable type in LLVMSingleValue
This commit is contained in:
@@ -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>", "")
|
||||
+1
-1
@@ -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,
|
||||
|
||||
+3
-3
@@ -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 ""
|
||||
|
||||
Reference in New Issue
Block a user