From 89e626c8f588dcac9decfcc303b1ce4c0d430031 Mon Sep 17 00:00:00 2001 From: e5l Date: Tue, 12 Jul 2016 14:07:25 +0300 Subject: [PATCH] translator: call fixes, constructors stub --- .../kotlinnative/translator/ClassCodegen.kt | 61 +++++++++++++------ .../kotlinnative/translator/FileTranslator.kt | 19 +++--- .../translator/FunctionCodegen.kt | 36 ++++++++--- .../translator/TranslationState.kt | 5 +- .../translator/llvm/LLVMVariable.kt | 3 +- .../translator/llvm/generators.kt | 9 ++- .../translator/llvm/types/LLVMCharType.kt | 2 +- .../translator/llvm/types/LLVMDoubleType.kt | 4 +- .../translator/llvm/types/LLVMIntType.kt | 4 +- .../llvm/types/LLVMReferenceType.kt | 16 +---- .../translator/llvm/types/LLVMShortType.kt | 5 +- .../translator/llvm/types/LLVMType.kt | 4 +- .../translator/llvm/types/LLVMVoidType.kt | 1 + .../kotlinnative/translator/utils/types.kt | 7 --- 14 files changed, 103 insertions(+), 73 deletions(-) delete mode 100644 translator/src/main/kotlin/org/kotlinnative/translator/utils/types.kt diff --git a/translator/src/main/kotlin/org/kotlinnative/translator/ClassCodegen.kt b/translator/src/main/kotlin/org/kotlinnative/translator/ClassCodegen.kt index 33c19ea6000..32a696c0865 100644 --- a/translator/src/main/kotlin/org/kotlinnative/translator/ClassCodegen.kt +++ b/translator/src/main/kotlin/org/kotlinnative/translator/ClassCodegen.kt @@ -10,48 +10,71 @@ import org.jetbrains.kotlin.resolve.annotations.argumentValue import org.kotlinnative.translator.exceptions.TranslationException import org.kotlinnative.translator.llvm.LLVMBuilder import org.kotlinnative.translator.llvm.LLVMClassVariable +import org.kotlinnative.translator.llvm.LLVMFunctionDescriptor import org.kotlinnative.translator.llvm.LLVMVariable import org.kotlinnative.translator.llvm.types.LLVMType +import org.kotlinnative.translator.llvm.types.LLVMVoidType import org.kotlinnative.translator.llvm.types.parseLLVMType import java.util.* class ClassCodegen(val state: TranslationState, val clazz: KtClass, val codeBuilder: LLVMBuilder) { - var native = false + val annotation: Boolean + val native: Boolean + val fields = ArrayList() + val size: Int - fun generate() { + init { val descriptor = state.bindingContext.get(BindingContext.CLASS, clazz) ?: throw TranslationException() + val parameterList = clazz.getPrimaryConstructorParameterList()!!.parameters - if (descriptor.kind == ClassKind.ANNOTATION_CLASS) { - return + var offset = 0 + var currentSize = 0 + annotation = descriptor.kind == ClassKind.ANNOTATION_CLASS + + if (!annotation) { + for (field in parameterList) { + val type = getNativeType(field) ?: parseLLVMType((field.typeReference?.typeElement as KtUserType).referencedName!!) + val field = LLVMClassVariable(field.name!!, type, offset) + fields.add(field) + + currentSize += type.size + offset++ + } } native = isNative(descriptor.annotations) - - generateBody() + size = currentSize } - private fun generateBody() { + fun generate() { + if (annotation) { + return + } + + generateStruct() + generateDefaultConstructor() + } + + private fun generateStruct() { val name = clazz.name!! - val fields = getFields() codeBuilder.createClass(name, fields) } - private fun getFields(): List { - val fields = ArrayList() - val parameterList = clazz.getPrimaryConstructorParameterList()!!.parameters - var offset = 0 + private fun generateDefaultConstructor() { + codeBuilder.addLLVMCode(LLVMFunctionDescriptor(clazz.name!!, fields, LLVMVoidType())) - for (field in parameterList) { - val type = getNativeType(field) ?: parseLLVMType((field.typeReference?.typeElement as KtUserType).referencedName!!) - val field = LLVMClassVariable(field.name!!, type, offset) - fields.add(field) + codeBuilder.addStartExpression() + generateLoadArguments() + codeBuilder.addEndExpression() + } - offset++ + private fun generateLoadArguments() { + fields.forEach { + val loadVariable = LLVMVariable("%${it.label}", it.type, it.label) + codeBuilder.loadVariable(loadVariable) } - - return fields } private fun getNativeType(field: KtParameter): LLVMType? { diff --git a/translator/src/main/kotlin/org/kotlinnative/translator/FileTranslator.kt b/translator/src/main/kotlin/org/kotlinnative/translator/FileTranslator.kt index 22801ebe1c8..52eb5f7f65c 100644 --- a/translator/src/main/kotlin/org/kotlinnative/translator/FileTranslator.kt +++ b/translator/src/main/kotlin/org/kotlinnative/translator/FileTranslator.kt @@ -4,7 +4,6 @@ import org.jetbrains.kotlin.psi.KtClass import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.psi.KtNamedFunction import org.kotlinnative.translator.llvm.LLVMBuilder -import org.kotlinnative.translator.utils.FunctionDescriptor class FileTranslator(val state: TranslationState, val file: KtFile) { @@ -21,18 +20,24 @@ class FileTranslator(val state: TranslationState, val file: KtFile) { when (declaration) { is KtNamedFunction -> { val function = FunctionCodegen(state, declaration, codeBuilder) - state.functions.put(function.name, FunctionDescriptor( - function.returnType, - function.args?.map { it.type }?.toList() ?: listOf() - )) + state.functions.put(function.name, function) - function.generate() } is KtClass -> { - ClassCodegen(state, declaration, codeBuilder).generate() + val codegen = ClassCodegen(state, declaration, codeBuilder) + state.classes.put(declaration.name!!, codegen) } } } + + for (clazz in state.classes.values) { + clazz.generate() + } + + for (function in state.functions.values) { + function.generate() + } + } } diff --git a/translator/src/main/kotlin/org/kotlinnative/translator/FunctionCodegen.kt b/translator/src/main/kotlin/org/kotlinnative/translator/FunctionCodegen.kt index 91b6e1c9d18..455e0a58127 100644 --- a/translator/src/main/kotlin/org/kotlinnative/translator/FunctionCodegen.kt +++ b/translator/src/main/kotlin/org/kotlinnative/translator/FunctionCodegen.kt @@ -11,7 +11,6 @@ import org.kotlinnative.translator.llvm.* import org.kotlinnative.translator.llvm.types.LLVMIntType import org.kotlinnative.translator.llvm.types.LLVMType import org.kotlinnative.translator.llvm.types.LLVMVoidType -import org.kotlinnative.translator.utils.FunctionArgument import java.util.* @@ -19,13 +18,13 @@ class FunctionCodegen(val state: TranslationState, val function: KtNamedFunction var name = function.fqName.toString() var returnType: LLVMType - var args: List? + var args: List? val variableManager = state.variableManager init { val descriptor = state.bindingContext.get(BindingContext.FUNCTION, function) args = descriptor?.valueParameters?.map { - FunctionArgument(LLVMMapStandardType(it.type.toString()), it.name.toString()) + LLVMVariable(it.name.toString(), LLVMMapStandardType(it.type.toString())) } returnType = LLVMMapStandardType(descriptor?.returnType.toString()) @@ -37,7 +36,7 @@ class FunctionCodegen(val state: TranslationState, val function: KtNamedFunction } codeBuilder.addStartExpression() - generateLoadArguments(function) + generateLoadArguments() expressionWalker(function.bodyExpression) if (returnType is LLVMVoidType) { @@ -64,11 +63,11 @@ class FunctionCodegen(val state: TranslationState, val function: KtNamedFunction return external } - private fun generateLoadArguments(function: KtNamedFunction) { + private fun generateLoadArguments() { args?.forEach { - val loadVariable = LLVMVariable("%${it.name}", it.type, it.name, true) + val loadVariable = LLVMVariable("%${it.label}", it.type, it.label, true) codeBuilder.loadVariable(loadVariable) - variableManager.addVariable(it.name, loadVariable, 2) + variableManager.addVariable(it.label, loadVariable, 2) } } @@ -107,14 +106,35 @@ class FunctionCodegen(val state: TranslationState, val function: KtNamedFunction } private fun evaluateCallExpression(expr: KtCallExpression): LLVMNode? { + val function = expr.firstChild.firstChild.text + + if (state.functions.containsKey(function)) { + return evaluteFunctionCallExpression(expr) + } + + if (state.classes.containsKey(function)) { + return evaluteConstructorCallExpression(expr) + } + + return null + } + + private fun evaluteConstructorCallExpression(expr: KtCallExpression): LLVMNode? { + return null + } + + private fun evaluteFunctionCallExpression(expr: KtCallExpression): LLVMNode? { val function = expr.firstChild.firstChild + val descriptor = state.functions[function.text] ?: return null val names = parseArgList(expr .firstChild .getNextSiblingIgnoringWhitespaceAndComments() ?.firstChild) - return LLVMCall(descriptor.returnType, "@${function.text}", descriptor.argTypes.mapIndexed { i: Int, type: LLVMType -> LLVMVariable(names[i], type) }) + return LLVMCall(descriptor.returnType, "@${function.text}", descriptor.args?.mapIndexed { + i: Int, variable: LLVMVariable -> LLVMVariable(names[i], variable.type) + } ?: listOf()) } private fun parseArgList(argumentList: PsiElement?): List { diff --git a/translator/src/main/kotlin/org/kotlinnative/translator/TranslationState.kt b/translator/src/main/kotlin/org/kotlinnative/translator/TranslationState.kt index 28eca133767..d1249ff98b7 100644 --- a/translator/src/main/kotlin/org/kotlinnative/translator/TranslationState.kt +++ b/translator/src/main/kotlin/org/kotlinnative/translator/TranslationState.kt @@ -18,7 +18,6 @@ import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.jvm.TopDownAnalyzerFacadeForJVM import org.jetbrains.kotlin.utils.PathUtil import org.kotlinnative.translator.exceptions.TranslationException -import org.kotlinnative.translator.utils.FunctionDescriptor import java.util.* @@ -26,7 +25,9 @@ class TranslationState(sources: List, disposer: Disposable) { val environment: KotlinCoreEnvironment val bindingContext: BindingContext - var functions = HashMap() + var functions = HashMap() + var classes = HashMap() + val variableManager = VariableManager() init { 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 1276f8edf7a..4e0fec41040 100644 --- a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/LLVMVariable.kt +++ b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/LLVMVariable.kt @@ -4,8 +4,7 @@ import org.kotlinnative.translator.llvm.types.LLVMType open class LLVMVariable(val label: String, val type: LLVMType? = null, var kotlinName: String? = null, var pointer: Boolean = false) : LLVMNode() { - override fun toString(): String = label - fun getType(): String = type.toString() + if (pointer) "*" else "" + override fun toString(): String = label } \ No newline at end of file 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 e3af6ca9de8..d408c76d6d8 100644 --- a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/generators.kt +++ b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/generators.kt @@ -1,14 +1,13 @@ package org.kotlinnative.translator.llvm import org.kotlinnative.translator.llvm.types.* -import org.kotlinnative.translator.utils.FunctionArgument -fun LLVMFunctionDescriptor(name: String, argTypes: List?, returnType: LLVMType, declare: Boolean = false) = +fun LLVMFunctionDescriptor(name: String, argTypes: List?, returnType: LLVMType, declare: Boolean = false) = "${if (declare) "declare" else "define"} $returnType @$name(${ - argTypes?.mapIndexed { i: Int, s: FunctionArgument -> - "${s.type} %${s.name}" - }?.joinToString() ?: ""})" + argTypes?.mapIndexed { i: Int, s: LLVMVariable -> + "${s.type} %${s.label}" + }?.joinToString() })" fun LLVMMapStandardType(type: String): LLVMType = when (type) { "Int" -> LLVMIntType() diff --git a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMCharType.kt b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMCharType.kt index d7f693fbca9..3a109c02d5c 100644 --- a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMCharType.kt +++ b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMCharType.kt @@ -3,7 +3,7 @@ package org.kotlinnative.translator.llvm.types class LLVMCharType() : LLVMType() { override fun toString(): String = "i8" - override val align = 1 + override val size: Byte = 1 } diff --git a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMDoubleType.kt b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMDoubleType.kt index 09008e62575..d5943bf85c9 100644 --- a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMDoubleType.kt +++ b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMDoubleType.kt @@ -18,7 +18,7 @@ class LLVMDoubleType() : LLVMType() { override fun operatorPlus(result: LLVMVariable, firstOp: LLVMVariable, secondOp: LLVMVariable): LLVMExpression = LLVMExpression(LLVMDoubleType(), "fadd double $firstOp, $secondOp") - override fun toString() = "double" - override val align = 8 + override val size: Byte = 8 + override fun toString() = "double" } \ No newline at end of file diff --git a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMIntType.kt b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMIntType.kt index 8861b15862f..34d3dbf49d5 100644 --- a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMIntType.kt +++ b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMIntType.kt @@ -18,8 +18,8 @@ class LLVMIntType() : LLVMType() { override fun operatorPlus(result: LLVMVariable, firstOp: LLVMVariable, secondOp: LLVMVariable): LLVMExpression = LLVMExpression(LLVMIntType(), "add nsw i32 $firstOp, $secondOp") - override fun toString() = "i32" - override val align = 4 + override val size: Byte = 4 + override fun toString() = "i32" } \ No newline at end of file diff --git a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMReferenceType.kt b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMReferenceType.kt index 0b4a94c3b8d..abdca17eb1b 100644 --- a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMReferenceType.kt +++ b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMReferenceType.kt @@ -1,22 +1,10 @@ package org.kotlinnative.translator.llvm.types -import org.kotlinnative.translator.llvm.LLVMExpression -import org.kotlinnative.translator.llvm.LLVMVariable - class LLVMReferenceType(val type: String) : LLVMType() { - override fun operatorTimes(result: LLVMVariable, firstOp: LLVMVariable, secondOp: LLVMVariable): LLVMExpression { - throw UnsupportedOperationException("not implemented") - } - override fun operatorMinus(result: LLVMVariable, firstOp: LLVMVariable, secondOp: LLVMVariable): LLVMExpression { - throw UnsupportedOperationException("not implemented") - } - - override fun operatorPlus(result: LLVMVariable, firstOp: LLVMVariable, secondOp: LLVMVariable): LLVMExpression { - throw UnsupportedOperationException("not implemented") - } + override val align = 4 + override val size: Byte = 4 override fun toString() = type - override val align = -1 } \ No newline at end of file diff --git a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMShortType.kt b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMShortType.kt index bb7249ee78a..b90f6d68e2d 100644 --- a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMShortType.kt +++ b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMShortType.kt @@ -2,7 +2,8 @@ package org.kotlinnative.translator.llvm.types class LLVMShortType() : LLVMType() { - override fun toString(): String = "i16" - + override val size: Byte = 2 override val align = 1 + + override fun toString(): String = "i16" } diff --git a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMType.kt b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMType.kt index 01beb25005e..84556d91af3 100644 --- a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMType.kt +++ b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMType.kt @@ -1,6 +1,5 @@ package org.kotlinnative.translator.llvm.types -import org.kotlinnative.translator.exceptions.TranslationException import org.kotlinnative.translator.exceptions.UnimplementedException import org.kotlinnative.translator.llvm.LLVMExpression import org.kotlinnative.translator.llvm.LLVMVariable @@ -12,6 +11,7 @@ abstract class LLVMType() { open fun operatorMinus(result: LLVMVariable, firstOp: LLVMVariable, secondOp: LLVMVariable): LLVMExpression = throw UnimplementedException() abstract val align: Int + abstract val size: Byte } fun parseLLVMType(type: String): LLVMType = when (type) { @@ -19,5 +19,5 @@ fun parseLLVMType(type: String): LLVMType = when (type) { "i16" -> LLVMShortType() "i8" -> LLVMCharType() "Unit" -> LLVMVoidType() - else -> throw TranslationException() + else -> LLVMReferenceType(type) } diff --git a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMVoidType.kt b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMVoidType.kt index 55612dbd882..92845eaa37d 100644 --- a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMVoidType.kt +++ b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMVoidType.kt @@ -5,5 +5,6 @@ class LLVMVoidType() : LLVMType() { override val align = 0 override fun toString(): String = "void" + override val size: Byte = 0 } diff --git a/translator/src/main/kotlin/org/kotlinnative/translator/utils/types.kt b/translator/src/main/kotlin/org/kotlinnative/translator/utils/types.kt deleted file mode 100644 index 3be04314af9..00000000000 --- a/translator/src/main/kotlin/org/kotlinnative/translator/utils/types.kt +++ /dev/null @@ -1,7 +0,0 @@ -package org.kotlinnative.translator.utils - -import org.kotlinnative.translator.llvm.types.LLVMType - -data class FunctionArgument(val type: LLVMType, val name: String) - -data class FunctionDescriptor(val returnType: LLVMType, val argTypes: List)