From a8d2798e588765030340a511ddb3d9004bc1fce0 Mon Sep 17 00:00:00 2001 From: e5l Date: Wed, 20 Jul 2016 10:54:18 +0300 Subject: [PATCH] translator: nullable tests, fix null reassignment, fix reference assignment --- car_llvmkot/kotlib/kotlin_main.ll | 39 ++++++++++++------- .../kotlinnative/translator/BlockCodegen.kt | 11 +++++- .../translator/VariableManager.kt | 2 +- .../translator/llvm/LLVMBuilder.kt | 2 +- .../translator/llvm/generators.kt | 14 +++---- .../tests/input/class_init_section_1.txt | 2 +- .../kotlin/tests/input/class_methods_1.txt | 2 +- .../test/kotlin/tests/input/do_while_1.txt | 2 +- .../test/kotlin/tests/input/nullable_1.txt | 4 +- .../src/test/kotlin/tests/input/object_1.txt | 2 +- .../test/kotlin/tests/input/reassigment_0.txt | 2 +- .../test/kotlin/tests/input/reassigment_1.txt | 2 +- .../kotlin/tests/input/simply_class_1.txt | 2 +- .../test/kotlin/tests/kotlin/nullable_1.kt | 12 +++--- 14 files changed, 58 insertions(+), 40 deletions(-) diff --git a/car_llvmkot/kotlib/kotlin_main.ll b/car_llvmkot/kotlib/kotlin_main.ll index 80efca64166..6cf6b53a217 100644 --- a/car_llvmkot/kotlib/kotlin_main.ll +++ b/car_llvmkot/kotlib/kotlin_main.ll @@ -1,29 +1,40 @@ declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture readonly, i64, i32, i1) declare i8* @malloc(i32) -%class.MyClass = type { i32 } -define void @MyClass(%class.MyClass* %classvariable.this, i32 %i) +%class.MyAwesomeClass = type { i32 } +define void @MyAwesomeClass(%class.MyAwesomeClass* %classvariable.this, i32 %i) { -%classvariable.this.addr = alloca %class.MyClass, align 4 +%classvariable.this.addr = alloca %class.MyAwesomeClass, align 4 %i.addr = alloca i32, align 4 store i32 %i, i32* %i.addr, align 4 %var1 = load i32* %i.addr, align 4 -%var2 = getelementptr inbounds %class.MyClass* %classvariable.this.addr, i32 0, i32 0 +%var2 = getelementptr inbounds %class.MyAwesomeClass* %classvariable.this.addr, i32 0, i32 0 store i32 %var1, i32* %var2, align 4 -%var3 = bitcast %class.MyClass* %classvariable.this to i8* -%var4 = bitcast %class.MyClass* %classvariable.this.addr to i8* +%var3 = bitcast %class.MyAwesomeClass* %classvariable.this to i8* +%var4 = bitcast %class.MyAwesomeClass* %classvariable.this.addr to i8* call void @llvm.memcpy.p0i8.p0i8.i64(i8* %var3, i8* %var4, i64 4, i32 4, i1 false) ret void } +define i32 @nullable_test(i32 %i) +{ +%i.addr = alloca i32, align 4 +store i32 %i, i32* %i.addr, align 4 +%var6 = call i8* @malloc(i32 4) +%var5 = bitcast i8* %var6 to %class.MyAwesomeClass* +call void @MyAwesomeClass(%class.MyAwesomeClass* %var5, i32 1) +%var8 = call i8* @malloc(i32 4) +%var7 = bitcast i8* %var8 to %class.MyAwesomeClass* +call void @MyAwesomeClass(%class.MyAwesomeClass* %var7, i32 2) +%var9 = load %class.MyAwesomeClass* %var5, align 4 +%var10 = load %class.MyAwesomeClass* %var7, align 4 +%var11 = getelementptr inbounds %class.MyAwesomeClass* %var7, i32 0, i32 0 +%var12 = load i32* %var11, align 4 +ret i32 %var12 +} define void @main() { -%a = alloca %class.MyClass*, align 4 -store %class.MyClass* null, %class.MyClass** %a, align 4 -%var5 = load %class.MyClass** %a, align 4 -%var7 = call i8* @malloc(i32 4) -%var6 = bitcast i8* %var7 to %class.MyClass* -call void @MyClass(%class.MyClass* %var6, i32 2) -%var8 = load %class.MyClass* %var5, align 4 -%var9 = load %class.MyClass* %var6, align 4 +%var13 = call i32 @nullable_test(i32 0) +%var14 = alloca i32, align 4 +store i32 %var13, i32* %var14, align 4 ret void } diff --git a/translator/src/main/kotlin/org/kotlinnative/translator/BlockCodegen.kt b/translator/src/main/kotlin/org/kotlinnative/translator/BlockCodegen.kt index b2333b65d9a..529c26061a2 100644 --- a/translator/src/main/kotlin/org/kotlinnative/translator/BlockCodegen.kt +++ b/translator/src/main/kotlin/org/kotlinnative/translator/BlockCodegen.kt @@ -231,7 +231,13 @@ abstract class BlockCodegen(open val state: TranslationState, open val variableM val right = evaluateExpression(expr.lastChild, scopeDepth) ?: throw UnsupportedOperationException("Wrong binary exception") val operator = expr.operationToken - return codeBuilder.addPrimitiveBinaryOperation(operator, expr.operationReference, left, right) + val result = codeBuilder.addPrimitiveBinaryOperation(operator, expr.operationReference, left, right) + + if (left.type is LLVMReferenceType && left.pointer > 0 && right.pointer > 0) { + variableManager.addVariable((left as LLVMVariable).kotlinName!!, result, scopeDepth) + } + + return result } private fun evaluateConstantExpression(expr: KtConstantExpression): LLVMConstant { @@ -359,9 +365,12 @@ abstract class BlockCodegen(open val state: TranslationState, open val variableM val allocVar = variableManager.receiveVariable(identifier, assignExpression.type, LLVMRegisterScope(), pointer = 0) codeBuilder.allocStackVar(allocVar) allocVar.pointer++ + allocVar.kotlinName = identifier + variableManager.addVariable(identifier, allocVar, scopeDepth) copyVariable(assignExpression, allocVar) } else { + assignExpression.kotlinName = identifier variableManager.addVariable(identifier, assignExpression, scopeDepth) } } diff --git a/translator/src/main/kotlin/org/kotlinnative/translator/VariableManager.kt b/translator/src/main/kotlin/org/kotlinnative/translator/VariableManager.kt index d0cddefd095..bce75e8fe11 100644 --- a/translator/src/main/kotlin/org/kotlinnative/translator/VariableManager.kt +++ b/translator/src/main/kotlin/org/kotlinnative/translator/VariableManager.kt @@ -15,7 +15,7 @@ class VariableManager(val globalVariableCollection: HashMap if (!stack.empty() && stack.peek().second >= level) stack.pop() else Unit } + fileVariableCollectionTree.forEach { s, stack -> while (!stack.empty() && stack.peek().second >= level) stack.pop() } } fun addVariable(name: String, variable: LLVMVariable, level: Int) { 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 3eecff070f5..8883aa0b249 100644 --- a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/LLVMBuilder.kt +++ b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/LLVMBuilder.kt @@ -93,7 +93,7 @@ class LLVMBuilder(val arm: Boolean) { return result } - if (firstOp.pointer > 1 && secondOp.pointer > 0) { + if (firstOp.type is LLVMReferenceType && firstOp.pointer > 0 && secondOp.pointer > 0) { return secondOp as LLVMVariable } 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 6efabf0d40d..deedb3439f2 100644 --- a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/generators.kt +++ b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/generators.kt @@ -13,13 +13,13 @@ fun LLVMFunctionDescriptor(name: String, argTypes: List?, returnTy }?.joinToString()}) ${if (arm) "#0" else ""}" 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) - type.toString() == "Byte" -> LLVMVariable(name, LLVMByteType(), type.toString(), scope) - type.toString() == "Char" -> LLVMVariable(name, LLVMCharType(), type.toString(), scope) - type.toString() == "Boolean" -> LLVMVariable(name, LLVMBooleanType(), type.toString(), scope) - type.isUnit() -> LLVMVariable("", LLVMVoidType(), "", scope) + type.isFunctionTypeOrSubtype -> LLVMVariable(name, LLVMFunctionType(type), name, scope, pointer = 1) + type.toString() == "Int" -> LLVMVariable(name, LLVMIntType(), name, scope) + type.toString() == "Double" -> LLVMVariable(name, LLVMDoubleType(), name, scope) + type.toString() == "Byte" -> LLVMVariable(name, LLVMByteType(), name, scope) + type.toString() == "Char" -> LLVMVariable(name, LLVMCharType(), name, scope) + type.toString() == "Boolean" -> LLVMVariable(name, LLVMBooleanType(), name, scope) + type.isUnit() -> LLVMVariable("", LLVMVoidType(), name, scope) type.isMarkedNullable -> LLVMVariable(name, LLVMReferenceType("${type.toString().dropLast(1)}"), name, scope, pointer = 1) else -> LLVMVariable(name, LLVMReferenceType("$type"), name, scope, pointer = 1) } diff --git a/translator/src/test/kotlin/tests/input/class_init_section_1.txt b/translator/src/test/kotlin/tests/input/class_init_section_1.txt index df0e702a438..5d4017df746 100644 --- a/translator/src/test/kotlin/tests/input/class_init_section_1.txt +++ b/translator/src/test/kotlin/tests/input/class_init_section_1.txt @@ -1 +1 @@ -class_init_section(523) == 12868 \ No newline at end of file +class_init_section(523) == 12868 diff --git a/translator/src/test/kotlin/tests/input/class_methods_1.txt b/translator/src/test/kotlin/tests/input/class_methods_1.txt index 2a1153ba1de..3abc33f92e2 100644 --- a/translator/src/test/kotlin/tests/input/class_methods_1.txt +++ b/translator/src/test/kotlin/tests/input/class_methods_1.txt @@ -1 +1 @@ -class_methods_1(55) == 60 \ No newline at end of file +class_methods_1(55) == 60 diff --git a/translator/src/test/kotlin/tests/input/do_while_1.txt b/translator/src/test/kotlin/tests/input/do_while_1.txt index 8ed138d0b7c..fbbf42402a4 100644 --- a/translator/src/test/kotlin/tests/input/do_while_1.txt +++ b/translator/src/test/kotlin/tests/input/do_while_1.txt @@ -1,2 +1,2 @@ do_while_test_1(5) == 6 -do_while_test_1(57) == 68 \ No newline at end of file +do_while_test_1(57) == 68 diff --git a/translator/src/test/kotlin/tests/input/nullable_1.txt b/translator/src/test/kotlin/tests/input/nullable_1.txt index 02c3e96bd33..c4a4483512d 100644 --- a/translator/src/test/kotlin/tests/input/nullable_1.txt +++ b/translator/src/test/kotlin/tests/input/nullable_1.txt @@ -1,2 +1,2 @@ -nullable_test(1) == 2 -nullable_test_2(1) == 1 +nullable_test(1) == 1 +nullable_test_2(4) == 5 diff --git a/translator/src/test/kotlin/tests/input/object_1.txt b/translator/src/test/kotlin/tests/input/object_1.txt index fdc224811d9..33cda73f7b5 100644 --- a/translator/src/test/kotlin/tests/input/object_1.txt +++ b/translator/src/test/kotlin/tests/input/object_1.txt @@ -1 +1 @@ -Singleton.create(5) == 40 \ No newline at end of file +Singleton.create(5) == 40 diff --git a/translator/src/test/kotlin/tests/input/reassigment_0.txt b/translator/src/test/kotlin/tests/input/reassigment_0.txt index 1f23a87f28c..af7ac66fa71 100644 --- a/translator/src/test/kotlin/tests/input/reassigment_0.txt +++ b/translator/src/test/kotlin/tests/input/reassigment_0.txt @@ -1 +1 @@ -reassigment_0(5) == 6 \ No newline at end of file +reassigment_0(5) == 6 diff --git a/translator/src/test/kotlin/tests/input/reassigment_1.txt b/translator/src/test/kotlin/tests/input/reassigment_1.txt index 52daf32b1a9..ec3618dbf86 100644 --- a/translator/src/test/kotlin/tests/input/reassigment_1.txt +++ b/translator/src/test/kotlin/tests/input/reassigment_1.txt @@ -1 +1 @@ -reassigment_1(5) == 7 \ No newline at end of file +reassigment_1(5) == 7 diff --git a/translator/src/test/kotlin/tests/input/simply_class_1.txt b/translator/src/test/kotlin/tests/input/simply_class_1.txt index 11d04a1a9a7..ca173b143f4 100644 --- a/translator/src/test/kotlin/tests/input/simply_class_1.txt +++ b/translator/src/test/kotlin/tests/input/simply_class_1.txt @@ -1 +1 @@ -simply_class_1(6789) == 6794 \ No newline at end of file +simply_class_1(6789) == 6794 diff --git a/translator/src/test/kotlin/tests/kotlin/nullable_1.kt b/translator/src/test/kotlin/tests/kotlin/nullable_1.kt index 0a8d3fb2b71..2ec1b26bbb2 100644 --- a/translator/src/test/kotlin/tests/kotlin/nullable_1.kt +++ b/translator/src/test/kotlin/tests/kotlin/nullable_1.kt @@ -4,15 +4,13 @@ class MyAwesomeClass(var i: Int) fun nullable_test(i: Int): Int { var x: MyAwesomeClass? = null x = MyAwesomeClass(i) -// x = MyAwesomeClass(i + 1) - - return i + 1 + return x.i } fun nullable_test_2(i: Int): Int { -// var x: MyAwesomeClass? = MyAwesomeClass(i) -// x = null -// x = MyAwesomeClass(i) + var x: MyAwesomeClass? = MyAwesomeClass(i) + x = null + x = MyAwesomeClass(i) - return i + return x.i + 1 } \ No newline at end of file