diff --git a/translator/src/main/kotlin/org/kotlinnative/translator/ClassCodegen.kt b/translator/src/main/kotlin/org/kotlinnative/translator/ClassCodegen.kt index 54c2a713392..8a606bf114a 100644 --- a/translator/src/main/kotlin/org/kotlinnative/translator/ClassCodegen.kt +++ b/translator/src/main/kotlin/org/kotlinnative/translator/ClassCodegen.kt @@ -78,17 +78,17 @@ class ClassCodegen(val state: TranslationState, val clazz: KtClass, val codeBuil generateLoadArguments(thisField) generateAssignments() generateReturn() - codeBuilder.addVoidReturn() + codeBuilder.addAnyReturn(LLVMVoidType()) codeBuilder.addEndExpression() } private fun generateLoadArguments(thisField: LLVMVariable) { - val thisVariable = LLVMVariable(thisField.label, thisField.type, thisField.label, LLVMLocalScope(), pointer = 1) + val thisVariable = LLVMVariable(thisField.label, thisField.type, thisField.label, LLVMRegisterScope(), pointer = 1) codeBuilder.loadArgument(thisVariable, false) fields.forEach { - val loadVariable = LLVMVariable(it.label, it.type, it.label, LLVMLocalScope()) + val loadVariable = LLVMVariable(it.label, it.type, it.label, LLVMRegisterScope()) codeBuilder.loadArgument(loadVariable) } } @@ -96,16 +96,16 @@ class ClassCodegen(val state: TranslationState, val clazz: KtClass, val codeBuil private fun generateAssignments() { fields.forEach { val argument = codeBuilder.getNewVariable(it.type) - codeBuilder.loadVariable(argument, LLVMVariable("${it.label}.addr", it.type, scope = LLVMLocalScope(), pointer = 1)) + codeBuilder.loadVariable(argument, LLVMVariable("${it.label}.addr", it.type, scope = LLVMRegisterScope(), pointer = 1)) val classField = codeBuilder.getNewVariable(it.type, pointer = 1) - codeBuilder.loadClassField(classField, LLVMVariable("instance.addr", type, scope = LLVMLocalScope(), pointer = 1), (it as LLVMClassVariable).offset) + codeBuilder.loadClassField(classField, LLVMVariable("instance.addr", type, scope = LLVMRegisterScope(), pointer = 1), (it as LLVMClassVariable).offset) codeBuilder.storeVariable(classField, argument) } } private fun generateReturn() { - val dst = LLVMVariable("instance", type, scope = LLVMLocalScope(), pointer = 1) - val src = LLVMVariable("instance.addr", type, scope = LLVMLocalScope(), pointer = 1) + val dst = LLVMVariable("instance", type, scope = LLVMRegisterScope(), pointer = 1) + val src = LLVMVariable("instance.addr", type, scope = LLVMRegisterScope(), pointer = 1) val castedDst = codeBuilder.bitcast(dst, LLVMCharType()) val castedSrc = codeBuilder.bitcast(src, LLVMCharType()) diff --git a/translator/src/main/kotlin/org/kotlinnative/translator/FunctionCodegen.kt b/translator/src/main/kotlin/org/kotlinnative/translator/FunctionCodegen.kt index 23917151b80..1435bfe1f0e 100644 --- a/translator/src/main/kotlin/org/kotlinnative/translator/FunctionCodegen.kt +++ b/translator/src/main/kotlin/org/kotlinnative/translator/FunctionCodegen.kt @@ -98,16 +98,16 @@ class FunctionCodegen(val state: TranslationState, val function: KtNamedFunction private fun generateLoadArguments() { args.forEach(fun(it: LLVMVariable) { if (it.type is LLVMFunctionType) { - variableManager.addVariable(it.label, LLVMVariable(it.label, it.type, it.label, LLVMLocalScope(), pointer = 1), topLevel) + 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).isReturn) { - val loadVariable = LLVMVariable("${it.label}", it.type, it.label, LLVMLocalScope(), pointer = 0) + val loadVariable = LLVMVariable("${it.label}", it.type, it.label, LLVMRegisterScope(), pointer = 0) val allocVar = codeBuilder.loadArgument(loadVariable) variableManager.addVariable(it.label, allocVar, topLevel) } else { - variableManager.addVariable(it.label, LLVMVariable(it.label, it.type, it.label, LLVMLocalScope(), pointer = 0), topLevel) + variableManager.addVariable(it.label, LLVMVariable(it.label, it.type, it.label, LLVMRegisterScope(), pointer = 0), topLevel) } }) } @@ -157,7 +157,7 @@ class FunctionCodegen(val state: TranslationState, val function: KtNamedFunction val receiveValue = state.bindingContext.get(BindingContext.COMPILE_TIME_VALUE, expr) val type = (receiveValue as TypedCompileTimeConstant).type val value = receiveValue.getValue(type) ?: return null - val variable = variableManager.receiveVariable(".str", LLVMStringType(value.toString().length), LLVMGlobalScope(), pointer = 0) + val variable = variableManager.receiveVariable(".str", LLVMStringType(value.toString().length), LLVMVariableScope(), pointer = 0) codeBuilder.addStringConstant(variable, value.toString()) return variable @@ -165,7 +165,7 @@ class FunctionCodegen(val state: TranslationState, val function: KtNamedFunction private fun evaluateCallableReferenceExpression(expr: KtCallableReferenceExpression): LLVMSingleValue? { val kotlinType = state.bindingContext.get(BindingContext.EXPRESSION_TYPE_INFO, expr)!!.type!! - return LLVMMapStandardType(expr.text.substring(2), kotlinType, LLVMGlobalScope()) + return LLVMMapStandardType(expr.text.substring(2), kotlinType, LLVMVariableScope()) } private fun evaluateDotExpression(expr: KtDotQualifiedExpression): LLVMSingleValue? { @@ -203,7 +203,7 @@ class FunctionCodegen(val state: TranslationState, val function: KtNamedFunction if (state.functions.containsKey(function)) { val descriptor = state.functions[function] ?: return null - return evaluateFunctionCallExpression(LLVMVariable(function, descriptor.returnType.type, scope = LLVMGlobalScope()), names, descriptor.args) + return evaluateFunctionCallExpression(LLVMVariable(function, descriptor.returnType.type, scope = LLVMVariableScope()), names, descriptor.args) } if (state.classes.containsKey(function)) { @@ -214,7 +214,7 @@ class FunctionCodegen(val state: TranslationState, val function: KtNamedFunction val localFunction = variableManager.getLLVMvalue(function) if (localFunction != null) { val type = localFunction.type as LLVMFunctionType - return evaluateFunctionCallExpression(LLVMVariable(function, type.returnType.type, scope = LLVMLocalScope()), names, type.arguments) + return evaluateFunctionCallExpression(LLVMVariable(function, type.returnType.type, scope = LLVMRegisterScope()), names, type.arguments) } return null @@ -320,11 +320,22 @@ class FunctionCodegen(val state: TranslationState, val function: KtNamedFunction return when (element) { is LeafPsiElement -> evaluateLeafPsiElement(element, scopeDepth) is KtConstantExpression -> evaluateConstantExpression(element) + is KtTypeReference -> evaluateTypeReference(element) KtTokens.INTEGER_LITERAL -> null else -> null } } + private fun evaluateTypeReference(element: KtTypeReference): LLVMSingleValue? { + val type = element.typeElement as KtUserType + val operator = element.getNextSiblingIgnoringWhitespaceAndComments() + val value = operator?.getNextSiblingIgnoringWhitespaceAndComments() as KtConstantExpression + + return when (operator) { + else -> throw UnsupportedOperationException() + } + } + private fun evaluateLeafPsiElement(element: LeafPsiElement, scopeDepth: Int): LLVMVariable? { return when (element.elementType) { KtTokens.RETURN_KEYWORD -> evaluateReturnInstruction(element, scopeDepth) @@ -426,13 +437,13 @@ class FunctionCodegen(val state: TranslationState, val function: KtNamedFunction when (assignExpression) { is LLVMVariable -> { - val allocVar = variableManager.receiveVariable(identifier!!.text, assignExpression.type, LLVMLocalScope(), pointer = 1) + val allocVar = variableManager.receiveVariable(identifier!!.text, assignExpression.type, LLVMRegisterScope(), pointer = 1) codeBuilder.allocVar(allocVar) variableManager.addVariable(identifier.text, allocVar, scopeDepth) copyVariable(assignExpression, allocVar) } is LLVMConstant -> { - val newVar = variableManager.receiveVariable(identifier!!.text, assignExpression.type!!, LLVMLocalScope(), pointer = 1) + val newVar = variableManager.receiveVariable(identifier!!.text, assignExpression.type!!, LLVMRegisterScope(), pointer = 1) codeBuilder.addConstant(newVar, assignExpression) variableManager.addVariable(identifier.text, newVar, scopeDepth) @@ -454,7 +465,7 @@ class FunctionCodegen(val state: TranslationState, val function: KtNamedFunction val dst = codeBuilder.bitcast(returnType, LLVMCharType()) val size = state.classes[(retVar.type as LLVMReferenceType).type]!!.size codeBuilder.memcpy(dst, src, size) - codeBuilder.addVoidReturn() + codeBuilder.addAnyReturn(LLVMVoidType()) } else -> { val retNativeValue = codeBuilder.receiveNativeValue(retVar) diff --git a/translator/src/main/kotlin/org/kotlinnative/translator/PropertyCodegen.kt b/translator/src/main/kotlin/org/kotlinnative/translator/PropertyCodegen.kt index 09b17b5155c..f72effb09d9 100644 --- a/translator/src/main/kotlin/org/kotlinnative/translator/PropertyCodegen.kt +++ b/translator/src/main/kotlin/org/kotlinnative/translator/PropertyCodegen.kt @@ -4,7 +4,7 @@ import org.jetbrains.kotlin.js.descriptorUtils.nameIfStandardType import org.jetbrains.kotlin.psi.KtProperty import org.jetbrains.kotlin.resolve.BindingContext import org.kotlinnative.translator.llvm.LLVMBuilder -import org.kotlinnative.translator.llvm.LLVMGlobalScope +import org.kotlinnative.translator.llvm.LLVMVariableScope import org.kotlinnative.translator.llvm.LLVMMapStandardType import org.kotlinnative.translator.llvm.LLVMVariable @@ -19,7 +19,7 @@ class PropertyCodegen(val state: TranslationState, val property: KtProperty, val val value = varInfo.value if (kotlinType.nameIfStandardType != null) { val variableType = LLVMMapStandardType(property.name ?: return, kotlinType).type - val variable = LLVMVariable(property.name.toString(), variableType, property.name.toString(), LLVMGlobalScope(), pointer = 1) + val variable = LLVMVariable(property.name.toString(), variableType, property.name.toString(), LLVMVariableScope(), pointer = 1) variableManager.addGlobalVariable(property.name.toString(), variable) codeBuilder.declareGlobalVariable(variable, variableType.parseArg(value.toString())) } diff --git a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/LLVMBuilder.kt b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/LLVMBuilder.kt index 0be23dbc55b..226bddb55fc 100644 --- a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/LLVMBuilder.kt +++ b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/LLVMBuilder.kt @@ -28,10 +28,10 @@ class LLVMBuilder(val arm: Boolean) { fun getNewVariable(type: LLVMType, pointer: Int = 0, kotlinName: String? = null): LLVMVariable { variableCount++ - return LLVMVariable("var$variableCount", type, kotlinName, LLVMLocalScope(), pointer) + return LLVMVariable("var$variableCount", type, kotlinName, LLVMRegisterScope(), pointer) } - fun getNewLabel(scope: LLVMScope = LLVMLocalScope(), prefix: String): LLVMLabel { + fun getNewLabel(scope: LLVMScope = LLVMRegisterScope(), prefix: String): LLVMLabel { labelCount++ return LLVMLabel("label.$prefix.$labelCount", scope) } @@ -93,11 +93,7 @@ class LLVMBuilder(val arm: Boolean) { llvmLocalCode.appendln("ret ${llvmVariable.type} $llvmVariable") } - fun addVoidReturn() { - llvmLocalCode.appendln("ret void") - } - - fun addAnyReturn(type: LLVMType, value: String = type.defaultValue){ + fun addAnyReturn(type: LLVMType, value: String = type.defaultValue) { llvmLocalCode.appendln("ret $type $value") } @@ -144,7 +140,7 @@ class LLVMBuilder(val arm: Boolean) { } fun loadArgument(llvmVariable: LLVMVariable, store: Boolean = true): LLVMVariable { - val allocVar = LLVMVariable("${llvmVariable.label}.addr", llvmVariable.type, llvmVariable.kotlinName, LLVMLocalScope(), pointer = 1) + val allocVar = LLVMVariable("${llvmVariable.label}.addr", llvmVariable.type, llvmVariable.kotlinName, LLVMRegisterScope(), pointer = 1) addVariableByRef(allocVar, llvmVariable, store) return allocVar } diff --git a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/LLVMScope.kt b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/LLVMScope.kt index 0d6e88a3e19..cdda752fe3e 100644 --- a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/LLVMScope.kt +++ b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/LLVMScope.kt @@ -2,11 +2,11 @@ package org.kotlinnative.translator.llvm open class LLVMScope -class LLVMGlobalScope : LLVMScope() { +class LLVMVariableScope : LLVMScope() { override fun toString() = "@" } -class LLVMLocalScope : LLVMScope() { +class LLVMRegisterScope : LLVMScope() { override fun toString() = "%" } diff --git a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/LLVMVariable.kt b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/LLVMVariable.kt index a18c45cb69d..82c612680e0 100644 --- a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/LLVMVariable.kt +++ b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/LLVMVariable.kt @@ -2,7 +2,7 @@ package org.kotlinnative.translator.llvm import org.kotlinnative.translator.llvm.types.LLVMType -open class LLVMVariable(val label: String, override val type: LLVMType, var kotlinName: String? = null, val scope: LLVMScope = LLVMLocalScope(), override var pointer: Int = 0) : LLVMSingleValue() { +open class LLVMVariable(val label: String, override val type: LLVMType, var kotlinName: String? = null, val scope: LLVMScope = LLVMRegisterScope(), override var pointer: Int = 0) : LLVMSingleValue() { override fun getType(): String = type.toString() + "*".repeat(pointer) diff --git a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/generators.kt b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/generators.kt index 19dbbddbbab..768276e4787 100644 --- a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/generators.kt +++ b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/generators.kt @@ -12,7 +12,7 @@ fun LLVMFunctionDescriptor(name: String, argTypes: List?, returnTy "${s.getType()} ${if (s.type is LLVMReferenceType && !(s.type as LLVMReferenceType).isReturn) "byval" else ""} %${s.label}" }?.joinToString()}) ${if (arm) "#0" else ""}" -fun LLVMMapStandardType(name: String, type: KotlinType, scope: LLVMScope = LLVMLocalScope()): LLVMVariable = when { +fun LLVMMapStandardType(name: String, type: KotlinType, scope: LLVMScope = LLVMRegisterScope()): LLVMVariable = when { type.isFunctionTypeOrSubtype -> LLVMVariable(name, LLVMFunctionType(type), type.toString(), scope, pointer = 1) type.toString() == "Int" -> LLVMVariable(name, LLVMIntType(), type.toString(), scope) type.toString() == "Double" -> LLVMVariable(name, LLVMDoubleType(), type.toString(), scope)