translator: escape initBuilder in LLVMBuilder, fix fucntions named arguments
This commit is contained in:
@@ -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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user