translator: escape initBuilder in LLVMBuilder, fix fucntions named arguments

This commit is contained in:
Alexey Stepanov
2016-09-01 09:50:28 +03:00
parent bf170beffa
commit 0c0657f1af
7 changed files with 86 additions and 109 deletions
@@ -1,7 +1,6 @@
package org.kotlinnative.translator
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiWhiteSpace
import com.intellij.psi.impl.source.tree.LeafPsiElement
import com.intellij.psi.tree.IElementType
import org.jetbrains.kotlin.descriptors.impl.PropertyDescriptorImpl
@@ -41,7 +40,7 @@ abstract class BlockCodegen(val state: TranslationState, val variableManager: Va
if (result.type is LLVMReferenceType) {
generateReferenceReturn(result)
} else {
result = codeBuilder.receivePointedArgument(result, 0)
result = codeBuilder.receivePointedArgument(result, requirePointer = 0)
codeBuilder.addReturnOperator(result)
}
}
@@ -74,8 +73,7 @@ abstract class BlockCodegen(val state: TranslationState, val variableManager: Va
is KtThisExpression -> evaluateThisExpression()
is KtSafeQualifiedExpression -> evaluateSafeAccessExpression(expr, scopeDepth)
is KtParenthesizedExpression -> evaluateExpression(expr.expression, scopeDepth)
null,
is PsiWhiteSpace -> null
null -> null
is PsiElement -> evaluatePsiElement(expr, scopeDepth)
else -> throw UnsupportedOperationException()
}
@@ -114,27 +112,27 @@ abstract class BlockCodegen(val state: TranslationState, val variableManager: Va
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)
val firstPointedArgument = codeBuilder.receivePointedArgument(firstOp, requirePointer = 1)
val secondPointedArgument = codeBuilder.receivePointedArgument(secondOp, requirePointer = 1)
firstOp.type.operatorEq(firstPointedArgument, secondPointedArgument)
} else
firstOp.type.operatorEq(firstNativeOp, secondNativeOp)
KtTokens.EQEQEQ -> {
val firstPointedArgument = codeBuilder.receivePointedArgument(firstOp, 1)
val secondPointedArgument = codeBuilder.receivePointedArgument(secondOp, 1)
val firstPointedArgument = codeBuilder.receivePointedArgument(firstOp, requirePointer = 1)
val secondPointedArgument = codeBuilder.receivePointedArgument(secondOp, requirePointer = 1)
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)
val firstPointedArgument = codeBuilder.receivePointedArgument(firstOp, requirePointer = 1)
val secondPointedArgument = codeBuilder.receivePointedArgument(secondOp, requirePointer = 1)
firstOp.type.operatorNeq(firstPointedArgument, secondPointedArgument)
} else
firstOp.type.operatorNeq(firstNativeOp, secondNativeOp)
}
KtTokens.EXCLEQEQEQ -> {
val firstPointedArgument = codeBuilder.receivePointedArgument(firstOp, 1)
val secondPointedArgument = codeBuilder.receivePointedArgument(secondOp, 1)
val firstPointedArgument = codeBuilder.receivePointedArgument(firstOp, requirePointer = 1)
val secondPointedArgument = codeBuilder.receivePointedArgument(secondOp, requirePointer = 1)
firstOp.type.operatorNeq(firstPointedArgument, secondPointedArgument)
}
KtTokens.EQ -> {
@@ -146,7 +144,7 @@ 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)
sourceArgument = codeBuilder.getNewVariable(secondOp.type, pointer = 1)
codeBuilder.allocStaticVar(sourceArgument, asValue = true)
codeBuilder.storeVariable(sourceArgument, secondOp)
} else {
@@ -158,7 +156,7 @@ abstract class BlockCodegen(val state: TranslationState, val variableManager: Va
}
else -> addPrimitiveReferenceOperationByName(referenceName!!.getReferencedName(), firstOp, secondNativeOp)
}
return codeBuilder.storeExpression(llvmExpression)
return codeBuilder.saveExpression(llvmExpression)
}
private fun expressionWalker(expr: PsiElement?, breakLabel: LLVMLabel?, scopeDepth: Int) {
@@ -223,7 +221,7 @@ abstract class BlockCodegen(val state: TranslationState, val variableManager: Va
val notNullLabel = codeBuilder.getNewLabel(prefix = "safe.access")
val endLabel = codeBuilder.getNewLabel(prefix = "safe.access")
val conditionResult = codeBuilder.storeExpression(condition)
val conditionResult = codeBuilder.saveExpression(condition)
codeBuilder.addCondition(conditionResult, nullLabel, notNullLabel)
codeBuilder.markWithLabel(nullLabel)
@@ -323,7 +321,7 @@ abstract class BlockCodegen(val state: TranslationState, val variableManager: Va
?: throw UnexpectedException(constructedFunctionName)
val receiverExpression = receiverExpressionArgument ?: evaluateExpression(receiver, scopeDepth + 1)!!
val args = mutableListOf(codeBuilder.receivePointedArgument(receiverExpression, if (receiverType is LLVMReferenceType) 1 else 0))
val args = mutableListOf(codeBuilder.receivePointedArgument(receiverExpression, requirePointer = if (receiverType is LLVMReferenceType) 1 else 0))
args.addAll(codeBuilder.loadArgsIfRequired(names, extensionCodegen.args))
return evaluateFunctionCallExpression(LLVMVariable(extensionCodegen.fullName, extensionCodegen.returnType!!.type, scope = LLVMVariableScope()), args)
}
@@ -400,7 +398,7 @@ abstract class BlockCodegen(val state: TranslationState, val variableManager: Va
val arrayActionType = if (callMaker.callType == Call.CallType.ARRAY_SET_METHOD) "set" else "get"
val explicitReceiver = callMaker.explicitReceiver as ExpressionReceiver
val receiver = evaluateExpression(explicitReceiver.expression, scope)!! as LLVMVariable
val pureReceiver = codeBuilder.receivePointedArgument(receiver, 1)
val pureReceiver = codeBuilder.receivePointedArgument(receiver, requirePointer = 1)
val targetClassName = (receiver.type as LLVMReferenceType).type
@@ -409,7 +407,7 @@ abstract class BlockCodegen(val state: TranslationState, val variableManager: Va
val clazz = resolveClassOrObjectLocation(receiver.type) ?: throw UnexpectedException(receiver.type.toString())
val method = clazz.methods[methodName] ?: throw UnexpectedException(expr.text)
val returnType = clazz.methods[methodName]!!.returnType!!.type
val returnType = method.returnType!!.type
val loadedArgs = codeBuilder.loadArgsIfRequired(names, method.args)
val callArgs = mutableListOf(pureReceiver)
@@ -424,9 +422,9 @@ abstract class BlockCodegen(val state: TranslationState, val variableManager: Va
val arrayIndex = evaluateConstantExpression(expr.indexExpressions.first() as KtConstantExpression)
val arrayReceivedVariable = codeBuilder.loadAndGetVariable(arrayNameVariable)
val arrayElementType = (arrayNameVariable.type as LLVMArray).arrayElementType
val indexVariable = codeBuilder.getNewVariable(arrayElementType, pointer = 1)
codeBuilder.loadVariableOffset(indexVariable, arrayReceivedVariable, arrayIndex)
indexVariable
val arrayElement = codeBuilder.getNewVariable(arrayElementType, pointer = 1)
codeBuilder.loadVariableOffset(arrayElement, arrayReceivedVariable, arrayIndex)
arrayElement
}
}
}
@@ -561,8 +559,7 @@ abstract class BlockCodegen(val state: TranslationState, val variableManager: Va
}
}
else -> {
val result = codeBuilder.getNewVariable(returnType)
codeBuilder.addAssignment(result, LLVMCall(returnType, function.toString(), names))
val result = codeBuilder.saveExpression(LLVMCall(returnType, function.toString(), names))
val resultPtr = codeBuilder.getNewVariable(returnType, pointer = 1)
codeBuilder.allocStackVar(resultPtr, pointer = true)
@@ -657,9 +654,8 @@ abstract class BlockCodegen(val state: TranslationState, val variableManager: Va
else -> throw IllegalAccessError()
}
val resultOp = codeBuilder.storeExpression(llvmExpression)
val resultOp = codeBuilder.saveExpression(llvmExpression)
codeBuilder.storeVariable(firstOp, resultOp)
oldValue
}
KtTokens.EXCLEXCL -> {
@@ -673,7 +669,7 @@ abstract class BlockCodegen(val state: TranslationState, val variableManager: Va
codeBuilder.addUnconditionalJump(notNullLabel)
codeBuilder.markWithLabel(notNullLabel)
if (firstOp.type.isPrimitive) {
result = codeBuilder.receivePointedArgument(firstOp, 0) as LLVMVariable
result = codeBuilder.receivePointedArgument(firstOp, requirePointer = 0) as LLVMVariable
}
result
}
@@ -681,20 +677,18 @@ abstract class BlockCodegen(val state: TranslationState, val variableManager: Va
}
private fun addPrimitivePrefixOperation(operator: IElementType?, firstOp: LLVMSingleValue): LLVMSingleValue? {
when (operator) {
KtTokens.MINUS,
KtTokens.PLUS -> {
return addPrimitiveBinaryOperation(operator!!, LLVMConstant("0", firstOp.type), firstOp)
private fun addPrimitivePrefixOperation(operator: IElementType?, firstOp: LLVMSingleValue): LLVMSingleValue? =
when (operator) {
KtTokens.MINUS,
KtTokens.PLUS -> addPrimitiveBinaryOperation(operator!!, LLVMConstant("0", firstOp.type), firstOp)
KtTokens.EXCL -> {
val firstNativeOp = codeBuilder.receiveNativeValue(firstOp)
val llvmExpression = addPrimitiveReferenceOperationByName("xor", LLVMConstant("true", LLVMBooleanType()), firstNativeOp)
codeBuilder.saveExpression(llvmExpression)
}
else -> throw UnsupportedOperationException()
}
KtTokens.EXCL -> {
val firstNativeOp = codeBuilder.receiveNativeValue(firstOp)
val llvmExpression = addPrimitiveReferenceOperationByName("xor", LLVMConstant("true", LLVMBooleanType()), firstNativeOp)
return codeBuilder.storeExpression(llvmExpression)
}
else -> throw UnsupportedOperationException()
}
}
private fun evaluateElvisOperator(expr: KtBinaryExpression, scopeDepth: Int): LLVMVariable {
val left = evaluateExpression(expr.left, scopeDepth)
@@ -703,7 +697,7 @@ abstract class BlockCodegen(val state: TranslationState, val variableManager: Va
val condition = lptr.type.operatorEq(lptr, LLVMVariable("", LLVMNullType()))
val conditionResult = codeBuilder.storeExpression(condition)
val conditionResult = codeBuilder.saveExpression(condition)
val notNull = codeBuilder.getNewLabel(prefix = "elvis")
val endLabel = codeBuilder.getNewLabel(prefix = "elvis")
@@ -737,22 +731,22 @@ abstract class BlockCodegen(val state: TranslationState, val variableManager: Va
"shr" -> firstNativeOp.type.operatorShr(firstNativeOp, codeBuilder.convertVariableToType(secondNativeOp, firstNativeOp.type))
"ushr" -> firstNativeOp.type.operatorUshr(firstNativeOp, codeBuilder.convertVariableToType(secondNativeOp, firstNativeOp.type))
"+=" -> {
val resultOp = codeBuilder.storeExpression(firstNativeOp.type.operatorPlus(firstNativeOp, secondNativeOp))
val resultOp = codeBuilder.saveExpression(firstNativeOp.type.operatorPlus(firstNativeOp, secondNativeOp))
codeBuilder.storeVariable(firstOp, resultOp)
return LLVMExpression(resultOp.type, "load ${firstOp.pointedType} $firstOp, align ${firstOp.type.align}")
}
"-=" -> {
val resultOp = codeBuilder.storeExpression(firstNativeOp.type.operatorMinus(firstNativeOp, secondNativeOp))
val resultOp = codeBuilder.saveExpression(firstNativeOp.type.operatorMinus(firstNativeOp, secondNativeOp))
codeBuilder.storeVariable(firstOp, resultOp)
return LLVMExpression(resultOp.type, "load ${firstOp.pointedType} $firstOp, align ${firstOp.type.align}")
}
"*=" -> {
val resultOp = codeBuilder.storeExpression(firstNativeOp.type.operatorTimes(firstNativeOp, secondNativeOp))
val resultOp = codeBuilder.saveExpression(firstNativeOp.type.operatorTimes(firstNativeOp, secondNativeOp))
codeBuilder.storeVariable(firstOp, resultOp)
return LLVMExpression(resultOp.type, "load ${firstOp.pointedType} $firstOp, align ${firstOp.type.align}")
}
"%=" -> {
val resultOp = codeBuilder.storeExpression(firstNativeOp.type.operatorMod(firstNativeOp, secondNativeOp))
val resultOp = codeBuilder.saveExpression(firstNativeOp.type.operatorMod(firstNativeOp, secondNativeOp))
codeBuilder.storeVariable(firstOp, resultOp)
return LLVMExpression(resultOp.type, "load ${firstOp.pointedType} $firstOp, align ${firstOp.type.align}")
}
@@ -774,13 +768,13 @@ abstract class BlockCodegen(val state: TranslationState, val variableManager: Va
return LLVMConstant(expressionValue?.toString().orEmpty(), type, pointer = 0)
}
private fun evaluatePsiElement(element: PsiElement, scopeDepth: Int): LLVMSingleValue? {
return when (element) {
is LeafPsiElement -> evaluateLeafPsiElement(element, scopeDepth)
is KtConstantExpression -> evaluateConstantExpression(element)
else -> null
}
}
private fun evaluatePsiElement(element: PsiElement, scopeDepth: Int): LLVMSingleValue? =
when (element) {
is LeafPsiElement -> evaluateLeafPsiElement(element, scopeDepth)
is KtConstantExpression -> evaluateConstantExpression(element)
else -> null
}
private fun evaluateLeafPsiElement(element: LeafPsiElement, scopeDepth: Int): LLVMVariable? {
return when (element.elementType) {
@@ -807,11 +801,11 @@ abstract class BlockCodegen(val state: TranslationState, val variableManager: Va
val nextDescriptor = iteratorDescriptor!!.methods["$returnTypeName.next"] ?: throw UnexpectedException("$returnTypeName.nextInt")
val conditionIterator = evaluateFunctionCallExpression(LLVMVariable("$rangeTypeName.iterator", returnType, scope = LLVMVariableScope()), listOf(range))!!
val iteratorThisArgument = codeBuilder.receivePointedArgument(conditionIterator, 1)
val iteratorThisArgument = codeBuilder.receivePointedArgument(conditionIterator, requirePointer = 1)
codeBuilder.addUnconditionalJump(conditionLabel)
codeBuilder.markWithLabel(conditionLabel)
var conditionResult = evaluateFunctionCallExpression(LLVMVariable("$returnTypeName.hasNext", LLVMBooleanType(), scope = LLVMVariableScope()), listOf(iteratorThisArgument))!!
conditionResult = codeBuilder.receivePointedArgument(conditionResult, 0)
conditionResult = codeBuilder.receivePointedArgument(conditionResult, requirePointer = 0)
codeBuilder.addCondition(conditionResult, bodyLabel, exitLabel)
codeBuilder.addUnconditionalJump(bodyLabel)
@@ -855,7 +849,7 @@ abstract class BlockCodegen(val state: TranslationState, val variableManager: Va
var successExpression = evaluateExpression(item.expression, scopeDepth + 1)
if (successExpression != null && !LLVMType.nullOrVoidType(resultVariable.type)) {
successExpression = codeBuilder.receivePointedArgument(successExpression, 0)
successExpression = codeBuilder.receivePointedArgument(successExpression, requirePointer = 0)
codeBuilder.storeVariable(resultVariable, successExpression)
}
@@ -905,7 +899,7 @@ abstract class BlockCodegen(val state: TranslationState, val variableManager: Va
codeBuilder.addUnconditionalJump(if (checkConditionBeforeExecute) conditionLabel else bodyLabel)
codeBuilder.markWithLabel(conditionLabel)
var conditionResult = evaluateExpression(condition, scopeDepth + 1)!!
conditionResult = codeBuilder.receivePointedArgument(conditionResult, 0)
conditionResult = codeBuilder.receivePointedArgument(conditionResult, requirePointer = 0)
codeBuilder.addCondition(conditionResult, bodyLabel, exitLabel)
evaluateCodeBlock(bodyExpression, bodyLabel, conditionLabel, exitLabel, scopeDepth + 1)
@@ -916,7 +910,7 @@ abstract class BlockCodegen(val state: TranslationState, val variableManager: Va
private fun evaluateIfOperator(element: KtIfExpression, scopeDepth: Int, isExpression: Boolean = true): LLVMVariable? {
val conditionResult = evaluateExpression(element.condition, scopeDepth)!!
val conditionNativeResult = codeBuilder.receivePointedArgument(conditionResult, 0)
val conditionNativeResult = codeBuilder.receivePointedArgument(conditionResult, requirePointer = 0)
return if (isExpression)
executeIfExpression(conditionNativeResult, element.then!!, element.`else`, element, scopeDepth + 1)
@@ -56,15 +56,13 @@ class FunctionCodegen(state: TranslationState,
state.extensionFunctions.put(translatorType.toString(), extensionFunctionsOfThisType)
}
defaultValues = mutableListOf()
for (index in descriptor.valueParameters.indices) {
val parameterDescriptor = descriptor.valueParameters[index]
defaultValues = descriptor.valueParameters.indices.map {
val parameterDescriptor = descriptor.valueParameters[it]
if (parameterDescriptor.declaresDefaultValue()) {
val initializer = (parameterDescriptor.source as KotlinSourceElement).psi
val defaultValue = (initializer as KtParameter).defaultValue
defaultValues.add(defaultValue!!)
val initializer = (parameterDescriptor.source as KotlinSourceElement).psi as KtParameter
initializer.defaultValue
} else {
defaultValues.add(null)
null
}
}
}
@@ -105,7 +103,7 @@ class FunctionCodegen(state: TranslationState,
else -> LLVMVariable("type", translatorType, pointer = 0)
}
variableManager.addVariable("this", classVal, 0)
variableManager.addVariable("this", classVal, level = 0)
actualArgs.add(classVal)
}
@@ -17,10 +17,9 @@ class ObjectCodegen(state: TranslationState,
override var size: Int = 0
override val structName: String = objectDeclaration.fqName?.asString()!!
override val type: LLVMReferenceType
override val type = LLVMReferenceType(structName, "class")
init {
type = LLVMReferenceType(structName, "class", align = TranslationState.POINTER_ALIGN, size = TranslationState.POINTER_SIZE, byRef = true)
primaryConstructorIndex = LLVMType.mangleFunctionArguments(emptyList())
constructorFields.put(primaryConstructorIndex!!, arrayListOf())
}
@@ -28,7 +27,6 @@ class ObjectCodegen(state: TranslationState,
override fun prepareForGenerate() {
generateInnerFields(objectDeclaration.declarations)
type.size = calculateTypeSize()
type.align = TranslationState.POINTER_ALIGN
super.prepareForGenerate()
@@ -6,7 +6,6 @@ class ProjectTranslator(val files: List<KtFile>, val state: TranslationState) {
private var codeBuilder = state.codeBuilder
fun generateCode(): String {
codeBuilder.clean()
with(files) {
map { addClassDeclarations(it) }
map { addObjectDeclarations(it) }
@@ -63,7 +63,7 @@ abstract class StructCodegen(val state: TranslationState,
classOrObject.getSecondaryConstructors().map { generateSecondaryConstructor(it) }
val classVal = LLVMVariable("classvariable.this", type, pointer = if (type.isPrimitive) 0 else 1)
variableManager.addVariable("this", classVal, 0)
variableManager.addVariable("this", classVal, level = 0)
methods.values.map { it.generate(classVal) }
}
@@ -121,7 +121,7 @@ abstract class StructCodegen(val state: TranslationState,
val descriptor = state.bindingContext.get(BindingContext.CONSTRUCTOR, secondaryConstructor)
val classVal = LLVMVariable("classvariable.this", type, pointer = 1)
variableManager.addVariable("this", classVal, 0)
variableManager.addVariable("this", classVal, level = 0)
val secondaryConstructorArguments = descriptor!!.valueParameters.map {
LLVMInstanceOfStandardType(it.fqNameSafe.convertToNativeName(), it.type, state = state)
@@ -135,21 +135,21 @@ abstract class StructCodegen(val state: TranslationState,
codeBuilder.addStartExpression()
secondaryConstructorArguments.map { variableManager.addVariable(it.label, it, 2) }
secondaryConstructorArguments.map { variableManager.addVariable(it.label, it, level = 2) }
val blockCodegen = object : BlockCodegen(state, variableManager, codeBuilder) {}
val mainConstructorThis = blockCodegen.evaluateConstructorDelegationReferenceExpression(thisCall!!, this, secondaryConstructorArguments, 1) as LLVMVariable
variableManager.addVariable("this", mainConstructorThis, 0)
variableManager.addVariable("this", mainConstructorThis, level = 0)
blockCodegen.evaluateCodeBlock(secondaryConstructor.bodyExpression, scopeDepth = 1)
generateReturn(codeBuilder.receivePointedArgument(variableManager["this"]!!, 1) as LLVMVariable)
generateReturn(codeBuilder.receivePointedArgument(variableManager["this"]!!, requirePointer = 1) as LLVMVariable)
codeBuilder.addAnyReturn(LLVMVoidType())
codeBuilder.addEndExpression()
}
private fun generatePrimaryConstructor() {
val classVal = LLVMVariable("classvariable.this", type, pointer = 1)
variableManager.addVariable("this", classVal, 0)
variableManager.addVariable("this", classVal, level = 0)
val argFields = mutableListOf(classVal)
argFields.addAll(constructorFields[primaryConstructorIndex]!!)
@@ -194,7 +194,7 @@ abstract class StructCodegen(val state: TranslationState,
val blockCodegen = object : BlockCodegen(state, variableManager, codeBuilder) {}
val receiverThis = LLVMVariable("classvariable.this.addr", type, scope = LLVMRegisterScope(), pointer = 1)
variableManager.addVariable("this", receiverThis, 2)
variableManager.addVariable("this", receiverThis, level = 2)
for ((variable, initializer) in initializedFields) {
val left = blockCodegen.evaluateMemberMethodOrField(receiverThis, variable.label, blockCodegen.topLevelScopeDepth, call = null)!!
@@ -5,17 +5,30 @@ import org.kotlinnative.translator.llvm.types.*
import java.rmi.UnexpectedException
import java.util.*
class LLVMBuilder(val arm: Boolean = false) {
class LLVMBuilder(arm: Boolean = false) {
private var localCode: StringBuilder = StringBuilder()
private var globalCode: StringBuilder = StringBuilder()
private var variableCount = 0
private var labelCount = 0
var exceptions: Map<String, LLVMVariable> = mapOf()
private val exceptions = mapOf(
Pair("KotlinNullPointerException", initializeExceptionString("Exception in thread main kotlin.KotlinNullPointerException")))
init {
initBuilder()
val declares = arrayOf(
"declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture readonly, i64, i32, i1)",
"declare i8* @malloc_heap(i32)",
"declare i32 @printf(i8*, ...)",
"declare void @abort()",
"%class.Nothing = type { }")
declares.forEach { addLLVMCodeToGlobalPlace(it) }
if (arm) {
val functionAttributes = """attributes #0 = { nounwind "stack-protector-buffer-size"="8" "target-cpu"="cortex-m3" "target-features"="+hwdiv,+strict-align" }"""
addLLVMCodeToGlobalPlace(functionAttributes)
}
}
fun addLLVMCodeToLocalPlace(code: String) =
@@ -95,17 +108,11 @@ class LLVMBuilder(val arm: Boolean = false) {
return empty
}
fun clean() {
localCode = StringBuilder()
globalCode = StringBuilder()
initBuilder()
}
fun convertVariableToType(variable: LLVMSingleValue, targetType: LLVMType): LLVMSingleValue {
var resultVariable = variable
if (variable.type != targetType) {
val convertedExpression = targetType.convertFrom(variable)
resultVariable = storeExpression(convertedExpression)
resultVariable = saveExpression(convertedExpression)
}
return resultVariable
}
@@ -189,10 +196,10 @@ class LLVMBuilder(val arm: Boolean = false) {
else -> throw UnexpectedException("Unknown inheritor of LLVMSingleValue")
}
fun receivePointedArgument(value: LLVMSingleValue, pointer: Int): LLVMSingleValue {
fun receivePointedArgument(value: LLVMSingleValue, requirePointer: Int): LLVMSingleValue {
var result = value
while (result.pointer > pointer) {
while (result.pointer > requirePointer) {
result = receiveNativeValue(result)
}
@@ -221,8 +228,8 @@ class LLVMBuilder(val arm: Boolean = false) {
}
}
fun storeExpression(expression: LLVMExpression): LLVMVariable {
val resultOp = getNewVariable(expression.variableType, pointer = expression.pointer)
fun saveExpression(expression: LLVMSingleValue): LLVMVariable {
val resultOp = getNewVariable(expression.type, pointer = expression.pointer)
addAssignment(resultOp, expression)
return resultOp
}
@@ -241,25 +248,6 @@ class LLVMBuilder(val arm: Boolean = false) {
addLLVMCodeToLocalPlace("store ${target.type} $from, ${target.pointedType} $target, align ${from.type.align}")
}
private fun initBuilder() {
val declares = arrayOf(
"declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture readonly, i64, i32, i1)",
"declare i8* @malloc_heap(i32)",
"declare i32 @printf(i8*, ...)",
"%class.Nothing = type { }",
"declare void @abort()")
declares.forEach { addLLVMCodeToGlobalPlace(it) }
exceptions = mapOf(
Pair("KotlinNullPointerException", initializeExceptionString("Exception in thread main kotlin.KotlinNullPointerException")))
if (arm) {
val functionAttributes = """attributes #0 = { nounwind "stack-protector-buffer-size"="8" "target-cpu"="cortex-m3" "target-features"="+hwdiv,+strict-align" }"""
addLLVMCodeToGlobalPlace(functionAttributes)
}
}
private fun initializeExceptionString(string: String): LLVMVariable {
val result = getNewVariable(LLVMStringType(string.length), pointer = 0, scope = LLVMVariableScope(), prefix = "exceptions.str.")
addStringConstant(result, string)
@@ -2,7 +2,7 @@ package org.kotlinnative.translator.llvm
import org.kotlinnative.translator.llvm.types.LLVMType
class LLVMExpression(val variableType: LLVMType, val llvmCode: String, val pointer: Int = 0) : LLVMNode() {
class LLVMExpression(type: LLVMType, val llvmCode: String, pointer: Int = 0) : LLVMSingleValue(type, pointer) {
override fun toString() = llvmCode