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)
|
codeBuilder.addReturnOperator(result)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else -> codeBuilder.addAnyReturn(result.type!!, result.toString())
|
else -> codeBuilder.addAnyReturn(result.type, result.toString())
|
||||||
}
|
}
|
||||||
|
|
||||||
wasReturnOnTopLevel = true
|
wasReturnOnTopLevel = true
|
||||||
@@ -155,7 +155,7 @@ abstract class BlockCodegen(val state: TranslationState, val variableManager: Va
|
|||||||
val result = codeBuilder.getNewVariable(expectedType, pointer = 2)
|
val result = codeBuilder.getNewVariable(expectedType, pointer = 2)
|
||||||
codeBuilder.allocStaticVar(result, pointer = true)
|
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 thenLabel = codeBuilder.getNewLabel(prefix = "safe.access")
|
||||||
val elseLabel = codeBuilder.getNewLabel(prefix = "safe.access")
|
val elseLabel = codeBuilder.getNewLabel(prefix = "safe.access")
|
||||||
val endLabel = 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 names = parseValueArguments(callMaker.valueArguments, scope)
|
||||||
val methodName = "$targetClassName.$arrayActionType${LLVMType.mangleFunctionArguments(names)}"
|
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 clazz = resolveClassOrObjectLocation(type) ?: throw UnexpectedException(type.toString())
|
||||||
|
|
||||||
val method = clazz.methods[methodName] ?: throw UnexpectedException(expr.text)
|
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) {
|
return when (operator) {
|
||||||
"||",
|
"||",
|
||||||
"or" -> firstNativeOp.type!!.operatorOr(firstNativeOp, secondNativeOp)
|
"or" -> firstNativeOp.type.operatorOr(firstNativeOp, secondNativeOp)
|
||||||
"xor" -> firstNativeOp.type!!.operatorXor(firstNativeOp, secondNativeOp)
|
"xor" -> firstNativeOp.type.operatorXor(firstNativeOp, secondNativeOp)
|
||||||
"&&",
|
"&&",
|
||||||
"and" -> firstNativeOp.type!!.operatorAnd(firstNativeOp, secondNativeOp)
|
"and" -> firstNativeOp.type.operatorAnd(firstNativeOp, secondNativeOp)
|
||||||
"%" -> firstNativeOp.type!!.operatorMod(firstNativeOp, secondNativeOp)
|
"%" -> firstNativeOp.type.operatorMod(firstNativeOp, secondNativeOp)
|
||||||
"shl" -> firstNativeOp.type!!.operatorShl(firstNativeOp, codeBuilder.convertVariableToType(secondNativeOp, firstNativeOp.type!!))
|
"shl" -> firstNativeOp.type.operatorShl(firstNativeOp, codeBuilder.convertVariableToType(secondNativeOp, firstNativeOp.type))
|
||||||
"shr" -> firstNativeOp.type!!.operatorShr(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!!))
|
"ushr" -> firstNativeOp.type.operatorUshr(firstNativeOp, codeBuilder.convertVariableToType(secondNativeOp, firstNativeOp.type))
|
||||||
"+=" -> {
|
"+=" -> {
|
||||||
val resultOp = codeBuilder.storeExpression(firstOp, firstNativeOp.type!!.operatorPlus(firstNativeOp, secondNativeOp))
|
val resultOp = codeBuilder.storeExpression(firstOp, firstNativeOp.type.operatorPlus(firstNativeOp, secondNativeOp))
|
||||||
return LLVMExpression(resultOp.type, "load ${firstOp.getType()} $firstOp, align ${firstOp.type!!.align}")
|
return LLVMExpression(resultOp.type, "load ${firstOp.pointedType} $firstOp, align ${firstOp.type.align}")
|
||||||
}
|
}
|
||||||
"-=" -> {
|
"-=" -> {
|
||||||
val resultOp = codeBuilder.storeExpression(firstOp, firstNativeOp.type!!.operatorMinus(firstNativeOp, secondNativeOp))
|
val resultOp = codeBuilder.storeExpression(firstOp, firstNativeOp.type.operatorMinus(firstNativeOp, secondNativeOp))
|
||||||
return LLVMExpression(resultOp.type, "load ${firstOp.getType()} $firstOp, align ${firstOp.type!!.align}")
|
return LLVMExpression(resultOp.type, "load ${firstOp.pointedType} $firstOp, align ${firstOp.type.align}")
|
||||||
}
|
}
|
||||||
"*=" -> {
|
"*=" -> {
|
||||||
val resultOp = codeBuilder.storeExpression(firstOp, firstNativeOp.type!!.operatorTimes(firstNativeOp, secondNativeOp))
|
val resultOp = codeBuilder.storeExpression(firstOp, firstNativeOp.type.operatorTimes(firstNativeOp, secondNativeOp))
|
||||||
return LLVMExpression(resultOp.type, "load ${firstOp.getType()} $firstOp, align ${firstOp.type!!.align}")
|
return LLVMExpression(resultOp.type, "load ${firstOp.pointedType} $firstOp, align ${firstOp.type.align}")
|
||||||
}
|
}
|
||||||
"%=" -> {
|
"%=" -> {
|
||||||
val resultOp = codeBuilder.storeExpression(firstOp, firstNativeOp.type!!.operatorMod(firstNativeOp, secondNativeOp))
|
val resultOp = codeBuilder.storeExpression(firstOp, firstNativeOp.type.operatorMod(firstNativeOp, secondNativeOp))
|
||||||
return LLVMExpression(resultOp.type, "load ${firstOp.getType()} $firstOp, align ${firstOp.type!!.align}")
|
return LLVMExpression(resultOp.type, "load ${firstOp.pointedType} $firstOp, align ${firstOp.type.align}")
|
||||||
}
|
}
|
||||||
".." -> {
|
".." -> {
|
||||||
val descriptor = state.classes["kotlin.ranges.IntRange"]
|
val descriptor = state.classes["kotlin.ranges.IntRange"]
|
||||||
val arguments = listOf(firstOp, secondNativeOp)
|
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)
|
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})")
|
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 secondNativeOp = codeBuilder.receiveNativeValue(secondOp)
|
||||||
|
|
||||||
val llvmExpression = when (operator) {
|
val llvmExpression = when (operator) {
|
||||||
KtTokens.PLUS -> firstOp.type!!.operatorPlus(firstNativeOp, secondNativeOp)
|
KtTokens.PLUS -> firstOp.type.operatorPlus(firstNativeOp, secondNativeOp)
|
||||||
KtTokens.MINUS -> firstOp.type!!.operatorMinus(firstNativeOp, secondNativeOp)
|
KtTokens.MINUS -> firstOp.type.operatorMinus(firstNativeOp, secondNativeOp)
|
||||||
KtTokens.MUL -> firstOp.type!!.operatorTimes(firstNativeOp, secondNativeOp)
|
KtTokens.MUL -> firstOp.type.operatorTimes(firstNativeOp, secondNativeOp)
|
||||||
KtTokens.DIV -> firstOp.type!!.operatorDiv(firstNativeOp, secondNativeOp)
|
KtTokens.DIV -> firstOp.type.operatorDiv(firstNativeOp, secondNativeOp)
|
||||||
KtTokens.LT -> firstOp.type!!.operatorLt(firstNativeOp, secondNativeOp)
|
KtTokens.LT -> firstOp.type.operatorLt(firstNativeOp, secondNativeOp)
|
||||||
KtTokens.GT -> firstOp.type!!.operatorGt(firstNativeOp, secondNativeOp)
|
KtTokens.GT -> firstOp.type.operatorGt(firstNativeOp, secondNativeOp)
|
||||||
KtTokens.LTEQ -> firstOp.type!!.operatorLeq(firstNativeOp, secondNativeOp)
|
KtTokens.LTEQ -> firstOp.type.operatorLeq(firstNativeOp, secondNativeOp)
|
||||||
KtTokens.GTEQ -> firstOp.type!!.operatorGeq(firstNativeOp, secondNativeOp)
|
KtTokens.GTEQ -> firstOp.type.operatorGeq(firstNativeOp, secondNativeOp)
|
||||||
KtTokens.EQEQ ->
|
KtTokens.EQEQ ->
|
||||||
if (LLVMType.isReferredType(firstOp.type) && LLVMType.isReferredType(secondOp.type)) {
|
if (LLVMType.isReferredType(firstOp.type) && LLVMType.isReferredType(secondOp.type)) {
|
||||||
val firstPointedArgument = codeBuilder.receivePointedArgument(firstOp, 1)
|
val firstPointedArgument = codeBuilder.receivePointedArgument(firstOp, 1)
|
||||||
val secondPointedArgument = codeBuilder.receivePointedArgument(secondOp, 1)
|
val secondPointedArgument = codeBuilder.receivePointedArgument(secondOp, 1)
|
||||||
firstOp.type!!.operatorEq(firstPointedArgument, secondPointedArgument)
|
firstOp.type.operatorEq(firstPointedArgument, secondPointedArgument)
|
||||||
} else
|
} else
|
||||||
firstOp.type!!.operatorEq(firstNativeOp, secondNativeOp)
|
firstOp.type.operatorEq(firstNativeOp, secondNativeOp)
|
||||||
KtTokens.EQEQEQ -> {
|
KtTokens.EQEQEQ -> {
|
||||||
val firstPointedArgument = codeBuilder.receivePointedArgument(firstOp, 1)
|
val firstPointedArgument = codeBuilder.receivePointedArgument(firstOp, 1)
|
||||||
val secondPointedArgument = codeBuilder.receivePointedArgument(secondOp, 1)
|
val secondPointedArgument = codeBuilder.receivePointedArgument(secondOp, 1)
|
||||||
firstOp.type!!.operatorEq(firstPointedArgument, secondPointedArgument)
|
firstOp.type.operatorEq(firstPointedArgument, secondPointedArgument)
|
||||||
}
|
}
|
||||||
KtTokens.EXCLEQ -> {
|
KtTokens.EXCLEQ -> {
|
||||||
if (LLVMType.isReferredType(firstOp.type) && LLVMType.isReferredType(secondOp.type)) {
|
if (LLVMType.isReferredType(firstOp.type) && LLVMType.isReferredType(secondOp.type)) {
|
||||||
val firstPointedArgument = codeBuilder.receivePointedArgument(firstOp, 1)
|
val firstPointedArgument = codeBuilder.receivePointedArgument(firstOp, 1)
|
||||||
val secondPointedArgument = codeBuilder.receivePointedArgument(secondOp, 1)
|
val secondPointedArgument = codeBuilder.receivePointedArgument(secondOp, 1)
|
||||||
firstOp.type!!.operatorNeq(firstPointedArgument, secondPointedArgument)
|
firstOp.type.operatorNeq(firstPointedArgument, secondPointedArgument)
|
||||||
} else
|
} else
|
||||||
firstOp.type!!.operatorNeq(firstNativeOp, secondNativeOp)
|
firstOp.type.operatorNeq(firstNativeOp, secondNativeOp)
|
||||||
}
|
}
|
||||||
KtTokens.EXCLEQEQEQ -> {
|
KtTokens.EXCLEQEQEQ -> {
|
||||||
val firstPointedArgument = codeBuilder.receivePointedArgument(firstOp, 1)
|
val firstPointedArgument = codeBuilder.receivePointedArgument(firstOp, 1)
|
||||||
val secondPointedArgument = codeBuilder.receivePointedArgument(secondOp, 1)
|
val secondPointedArgument = codeBuilder.receivePointedArgument(secondOp, 1)
|
||||||
firstOp.type!!.operatorNeq(firstPointedArgument, secondPointedArgument)
|
firstOp.type.operatorNeq(firstPointedArgument, secondPointedArgument)
|
||||||
}
|
}
|
||||||
KtTokens.EQ -> {
|
KtTokens.EQ -> {
|
||||||
if (secondOp.type is LLVMNullType) {
|
if (secondOp.type is LLVMNullType) {
|
||||||
@@ -801,8 +801,8 @@ abstract class BlockCodegen(val state: TranslationState, val variableManager: Va
|
|||||||
|
|
||||||
val result = firstOp as LLVMVariable
|
val result = firstOp as LLVMVariable
|
||||||
val sourceArgument: LLVMSingleValue
|
val sourceArgument: LLVMSingleValue
|
||||||
if ((firstOp.pointer == 2) && secondOp.type!!.isPrimitive && (secondOp.pointer == 0)) {
|
if ((firstOp.pointer == 2) && secondOp.type.isPrimitive && (secondOp.pointer == 0)) {
|
||||||
sourceArgument = codeBuilder.getNewVariable(secondOp.type!!, 1)
|
sourceArgument = codeBuilder.getNewVariable(secondOp.type, 1)
|
||||||
codeBuilder.allocStaticVar(sourceArgument, asValue = true)
|
codeBuilder.allocStaticVar(sourceArgument, asValue = true)
|
||||||
codeBuilder.storeVariable(sourceArgument, secondOp)
|
codeBuilder.storeVariable(sourceArgument, secondOp)
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -137,12 +137,12 @@ class FunctionCodegen(state: TranslationState,
|
|||||||
|
|
||||||
private fun generateLoadArguments() {
|
private fun generateLoadArguments() {
|
||||||
args.forEach(fun(it: LLVMVariable) {
|
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)
|
variableManager.addVariable(it.label, LLVMVariable(it.label, it.type, it.label, LLVMRegisterScope(), pointer = 1), topLevel)
|
||||||
return
|
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 loadVariable = LLVMVariable(it.label, it.type, it.label, LLVMRegisterScope(), pointer = it.pointer)
|
||||||
val allocVar = codeBuilder.loadArgument(loadVariable)
|
val allocVar = codeBuilder.loadArgument(loadVariable)
|
||||||
variableManager.addVariable(it.label, allocVar, topLevel)
|
variableManager.addVariable(it.label, allocVar, topLevel)
|
||||||
|
|||||||
@@ -243,7 +243,7 @@ abstract class StructCodegen(val state: TranslationState,
|
|||||||
val result = LLVMInstanceOfStandardType(fieldName, ktType, LLVMRegisterScope(), state = state)
|
val result = LLVMInstanceOfStandardType(fieldName, ktType, LLVMRegisterScope(), state = state)
|
||||||
|
|
||||||
if (result.type is LLVMReferenceType) {
|
if (result.type is LLVMReferenceType) {
|
||||||
val type = result.type as LLVMReferenceType
|
val type = result.type
|
||||||
type.prefix = "class"
|
type.prefix = "class"
|
||||||
type.byRef = true
|
type.byRef = true
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -93,8 +93,8 @@ class LLVMBuilder(val arm: Boolean = false) {
|
|||||||
result = loadVariable(result as LLVMVariable)
|
result = loadVariable(result as LLVMVariable)
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((value.type is LLVMStringType) && (!(value.type as LLVMStringType).isLoaded)) {
|
if ((value.type is LLVMStringType) && !(value.type.isLoaded)) {
|
||||||
val newVariable = getNewVariable(value.type!!, pointer = result.pointer + 1)
|
val newVariable = getNewVariable(value.type, pointer = result.pointer + 1)
|
||||||
allocStackVar(newVariable, asValue = true)
|
allocStackVar(newVariable, asValue = true)
|
||||||
copyVariable(result as LLVMVariable, newVariable)
|
copyVariable(result as LLVMVariable, newVariable)
|
||||||
result = loadVariable(newVariable)
|
result = loadVariable(newVariable)
|
||||||
@@ -104,7 +104,7 @@ class LLVMBuilder(val arm: Boolean = false) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun downLoadArgument(value: LLVMSingleValue, pointer: Int): LLVMSingleValue =
|
fun downLoadArgument(value: LLVMSingleValue, pointer: Int): LLVMSingleValue =
|
||||||
loadOneArgumentIfRequired(value, LLVMVariable("", value.type!!, pointer = pointer))
|
loadOneArgumentIfRequired(value, LLVMVariable("", value.type, pointer = pointer))
|
||||||
|
|
||||||
fun clean() {
|
fun clean() {
|
||||||
localCode = StringBuilder()
|
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")
|
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
|
var resultVariable = variable
|
||||||
if (variable.type != targetType) {
|
if (variable.type != tarpointedType) {
|
||||||
val convertedExpression = targetType.convertFrom(variable)
|
val convertedExpression = tarpointedType.convertFrom(variable)
|
||||||
resultVariable = getNewVariable(convertedExpression.variableType)
|
resultVariable = getNewVariable(convertedExpression.variableType)
|
||||||
addAssignment(resultVariable, convertedExpression)
|
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) {
|
fun addGlobalInitialize(target: LLVMVariable, fields: ArrayList<LLVMVariable>, initializers: Map<LLVMVariable, String>, classType: LLVMType) {
|
||||||
val code = "$target = internal global $classType { ${
|
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}"
|
} }, align ${classType.align}"
|
||||||
globalCode.appendln(code)
|
globalCode.appendln(code)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun storeString(target: LLVMVariable, source: LLVMVariable, offset: Int) {
|
fun storeString(target: LLVMVariable, source: LLVMVariable, offset: Int) {
|
||||||
val code = "store ${target.type} getelementptr inbounds (" +
|
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
|
(target.type as LLVMStringType).isLoaded = true
|
||||||
localCode.appendln(code)
|
localCode.appendln(code)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun loadClassField(target: LLVMVariable, source: LLVMVariable, offset: Int) =
|
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?) {
|
fun markWithLabel(label: LLVMLabel?) {
|
||||||
if (label != null)
|
if (label != null)
|
||||||
@@ -167,10 +167,10 @@ class LLVMBuilder(val arm: Boolean = false) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun storeVariable(target: LLVMSingleValue, source: LLVMSingleValue) {
|
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)
|
storeString(target as LLVMVariable, source as LLVMVariable, 0)
|
||||||
} else {
|
} 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) =
|
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 {
|
fun nullCheck(variable: LLVMVariable): LLVMVariable {
|
||||||
val result = getNewVariable(LLVMBooleanType(), pointer = 0)
|
val result = getNewVariable(LLVMBooleanType(), pointer = 0)
|
||||||
val loaded = loadVariable(variable)
|
val loaded = loadVariable(variable)
|
||||||
|
|
||||||
addLLVMCodeToLocalPlace("$result = icmp eq ${loaded.getType()} null, $loaded")
|
addLLVMCodeToLocalPlace("$result = icmp eq ${loaded.pointedType} null, $loaded")
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -204,13 +204,13 @@ class LLVMBuilder(val arm: Boolean = false) {
|
|||||||
var from = source
|
var from = source
|
||||||
if (source.pointer > 0) {
|
if (source.pointer > 0) {
|
||||||
from = getNewVariable(source.type, source.pointer)
|
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) {
|
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)
|
else -> copyVariableValue(to, from)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -222,12 +222,12 @@ class LLVMBuilder(val arm: Boolean = false) {
|
|||||||
|
|
||||||
fun loadVariable(source: LLVMVariable): LLVMVariable {
|
fun loadVariable(source: LLVMVariable): LLVMVariable {
|
||||||
val target = getNewVariable(source.type, pointer = source.pointer - 1)
|
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
|
return target
|
||||||
}
|
}
|
||||||
|
|
||||||
fun allocStackVar(target: LLVMVariable, asValue: Boolean = false, pointer: Boolean = false) {
|
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}")
|
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
|
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("$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) {
|
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) {
|
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) =
|
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>)
|
fun makeStructInitializer(args: List<LLVMVariable>, values: List<String>)
|
||||||
@@ -258,12 +258,12 @@ class LLVMBuilder(val arm: Boolean = false) {
|
|||||||
fun loadAndGetVariable(source: LLVMVariable): LLVMVariable {
|
fun loadAndGetVariable(source: LLVMVariable): LLVMVariable {
|
||||||
assert(source.pointer > 0)
|
assert(source.pointer > 0)
|
||||||
val target = getNewVariable(source.type, source.pointer - 1, source.kotlinName)
|
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
|
return target
|
||||||
}
|
}
|
||||||
|
|
||||||
fun addCondition(condition: LLVMSingleValue, thenLabel: LLVMLabel, elseLabel: LLVMLabel) =
|
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) =
|
fun addUnconditionalJump(label: LLVMLabel) =
|
||||||
@@ -271,12 +271,12 @@ class LLVMBuilder(val arm: Boolean = false) {
|
|||||||
|
|
||||||
|
|
||||||
fun createClass(name: String, fields: List<LLVMVariable>) =
|
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 {
|
fun bitcast(src: LLVMVariable, llvmType: LLVMVariable): LLVMVariable {
|
||||||
val empty = getNewVariable(llvmType.type, pointer = llvmType.pointer)
|
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
|
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) {
|
class LLVMCall(val returnType: LLVMType, val name: String, val arguments: Collection<LLVMSingleValue>) : LLVMSingleValue(returnType) {
|
||||||
|
|
||||||
override fun toString(): String =
|
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
|
import org.kotlinnative.translator.llvm.types.LLVMType
|
||||||
|
|
||||||
open class LLVMConstant(value: String,
|
open class LLVMConstant(value: String,
|
||||||
type: LLVMType? = null,
|
type: LLVMType,
|
||||||
pointer: Int = 0) : LLVMSingleValue(type, pointer) {
|
pointer: Int = 0) : LLVMSingleValue(type, pointer) {
|
||||||
|
|
||||||
val value: String
|
val value: String
|
||||||
|
|
||||||
init {
|
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
|
override fun toString(): String = value
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1,10 +1,10 @@
|
|||||||
package org.kotlinnative.translator.llvm
|
package org.kotlinnative.translator.llvm
|
||||||
|
|
||||||
import org.kotlinnative.translator.exceptions.UnimplementedException
|
|
||||||
import org.kotlinnative.translator.llvm.types.LLVMType
|
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
|
import org.kotlinnative.translator.llvm.types.LLVMType
|
||||||
|
|
||||||
open class LLVMVariable(val label: String,
|
open class LLVMVariable(val label: String,
|
||||||
override val type: LLVMType,
|
type: LLVMType,
|
||||||
var kotlinName: String? = null,
|
var kotlinName: String? = null,
|
||||||
val scope: LLVMScope = LLVMRegisterScope(),
|
val scope: LLVMScope = LLVMRegisterScope(),
|
||||||
pointer: Int = 0) : LLVMSingleValue(type, pointer) {
|
pointer: Int = 0) : LLVMSingleValue(type, pointer) {
|
||||||
|
|
||||||
override fun getType(): String = type.toString() + "*".repeat(pointer)
|
|
||||||
|
|
||||||
override fun toString(): String = "$scope$label"
|
override fun toString(): String = "$scope$label"
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1,7 +1,6 @@
|
|||||||
package org.kotlinnative.translator.llvm
|
package org.kotlinnative.translator.llvm
|
||||||
|
|
||||||
import org.jetbrains.kotlin.builtins.isFunctionTypeOrSubtype
|
import org.jetbrains.kotlin.builtins.isFunctionTypeOrSubtype
|
||||||
import org.jetbrains.kotlin.cfg.pseudocode.getSubtypesPredicate
|
|
||||||
import org.jetbrains.kotlin.js.descriptorUtils.nameIfStandardType
|
import org.jetbrains.kotlin.js.descriptorUtils.nameIfStandardType
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
|
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) =
|
fun LLVMFunctionDescriptor(name: String, argTypes: List<LLVMVariable>?, returnType: LLVMType, declare: Boolean = false) =
|
||||||
"${if (declare) "declare" else "define weak"} $returnType @$name(${
|
"${if (declare) "declare" else "define weak"} $returnType @$name(${
|
||||||
argTypes?.mapIndexed { i: Int, s: LLVMVariable ->
|
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"
|
}?.joinToString()}) #0"
|
||||||
|
|
||||||
fun LLVMInstanceOfStandardType(name: String, type: KotlinType, scope: LLVMScope = LLVMRegisterScope(), state: TranslationState): LLVMVariable {
|
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
|
return if (pos < 0) this.length else pos
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fun FqName.convertToNativeName(): String =
|
fun FqName.convertToNativeName(): String =
|
||||||
this.asString().replace(".<init>", "")
|
this.asString().replace(".<init>", "")
|
||||||
+1
-1
@@ -26,7 +26,7 @@ class LLVMFunctionType(type: KotlinType, state: TranslationState) : LLVMType() {
|
|||||||
fun mangleArgs() = LLVMType.mangleFunctionArguments(arguments)
|
fun mangleArgs() = LLVMType.mangleFunctionArguments(arguments)
|
||||||
|
|
||||||
override fun toString() =
|
override fun toString() =
|
||||||
"${returnType.type} (${arguments.map { it.getType() }.joinToString()})"
|
"${returnType.type} (${arguments.map { it.pointedType }.joinToString()})"
|
||||||
|
|
||||||
override fun equals(other: Any?) =
|
override fun equals(other: Any?) =
|
||||||
(other is LLVMFunctionType) && (mangle == other.mangle)
|
(other is LLVMFunctionType) && (mangle == other.mangle)
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ class LLVMIntType() : LLVMType() {
|
|||||||
override val isPrimitive = true
|
override val isPrimitive = true
|
||||||
|
|
||||||
override fun convertFrom(source: LLVMSingleValue) =
|
override fun convertFrom(source: LLVMSingleValue) =
|
||||||
when (source.type!!) {
|
when (source.type) {
|
||||||
is LLVMBooleanType,
|
is LLVMBooleanType,
|
||||||
is LLVMByteType,
|
is LLVMByteType,
|
||||||
is LLVMCharType,
|
is LLVMCharType,
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ class LLVMLongType() : LLVMType() {
|
|||||||
override val isPrimitive = true
|
override val isPrimitive = true
|
||||||
|
|
||||||
override fun convertFrom(source: LLVMSingleValue) =
|
override fun convertFrom(source: LLVMSingleValue) =
|
||||||
when (source.type!!) {
|
when (source.type) {
|
||||||
is LLVMBooleanType,
|
is LLVMBooleanType,
|
||||||
is LLVMByteType,
|
is LLVMByteType,
|
||||||
is LLVMCharType,
|
is LLVMCharType,
|
||||||
|
|||||||
+3
-3
@@ -4,7 +4,7 @@ import org.kotlinnative.translator.TranslationState
|
|||||||
import org.kotlinnative.translator.llvm.LLVMExpression
|
import org.kotlinnative.translator.llvm.LLVMExpression
|
||||||
import org.kotlinnative.translator.llvm.LLVMSingleValue
|
import org.kotlinnative.translator.llvm.LLVMSingleValue
|
||||||
import org.kotlinnative.translator.llvm.addAfterIfNotEmpty
|
import org.kotlinnative.translator.llvm.addAfterIfNotEmpty
|
||||||
import java.util.*
|
|
||||||
|
|
||||||
class LLVMReferenceType(val type: String,
|
class LLVMReferenceType(val type: String,
|
||||||
var prefix: String = "",
|
var prefix: String = "",
|
||||||
@@ -19,10 +19,10 @@ class LLVMReferenceType(val type: String,
|
|||||||
override fun toString() = "%$typename"
|
override fun toString() = "%$typename"
|
||||||
|
|
||||||
override fun operatorEq(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) =
|
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) =
|
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?) =
|
override fun equals(other: Any?) =
|
||||||
(other is LLVMReferenceType) and (typename.equals((other as LLVMReferenceType).typename))
|
(other is LLVMReferenceType) and (typename.equals((other as LLVMReferenceType).typename))
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ abstract class LLVMType() : Cloneable {
|
|||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
fun mangleFunctionArguments(names: List<LLVMSingleValue>) =
|
fun mangleFunctionArguments(names: List<LLVMSingleValue>) =
|
||||||
mangleFunctionTypes(names.map { it.type!! })
|
mangleFunctionTypes(names.map { it.type })
|
||||||
|
|
||||||
fun mangleFunctionTypes(names: List<LLVMType>) =
|
fun mangleFunctionTypes(names: List<LLVMType>) =
|
||||||
if (names.size > 0) "_${names.joinToString(separator = "_", transform = { it.mangle })}" else ""
|
if (names.size > 0) "_${names.joinToString(separator = "_", transform = { it.mangle })}" else ""
|
||||||
|
|||||||
Reference in New Issue
Block a user