translator: reference type move without copy, tests

This commit is contained in:
e5l
2016-07-19 17:14:19 +03:00
parent 22890b0cea
commit 7d4e608072
7 changed files with 61 additions and 20 deletions
+25 -10
View File
@@ -1,14 +1,29 @@
declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture readonly, i64, i32, i1)
declare i8* @malloc_static(i32)
attributes #0 = { nounwind "stack-protector-buffer-size"="8" "target-cpu"="cortex-m3" "target-features"="+hwdiv,+strict-align" }
define i32 @reassigment_1(i32 %x) #0
declare i8* @malloc(i32)
%class.MyClass = type { i32 }
define void @MyClass(%class.MyClass* %classvariable.this, i32 %i)
{
%x.addr = alloca i32, align 4
store i32 %x, i32* %x.addr, align 4
%var1 = load i32* %x.addr, align 4
%var2 = add nsw i32 %var1, 1
%var3 = add nsw i32 %var2, 1
store i32 %var3, i32 %var2, align 4
ret i32 %var2
%classvariable.this.addr = alloca %class.MyClass, 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
store i32 %var1, i32* %var2, align 4
%var3 = bitcast %class.MyClass* %classvariable.this to i8*
%var4 = bitcast %class.MyClass* %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 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
ret void
}
@@ -21,7 +21,6 @@ class ClassCodegen(override val state: TranslationState, override val variableMa
override val structName: String
override val type: LLVMType = LLVMReferenceType(clazz.name.toString(), "class", byRef = true)
init {
structName = clazz.name.toString()
val descriptor = state.bindingContext.get(BindingContext.CLASS, clazz) ?: throw TranslationException()
@@ -22,8 +22,8 @@ class ObjectCodegen(override val state: TranslationState, override val variableM
fun generate() {
generate(objectDeclaration.declarations)
val classInstance = LLVMVariable("object.instance.${structName}", type, objectDeclaration.name, LLVMVariableScope())
codeBuilder.addGlobalIntialize(classInstance, type);
val classInstance = LLVMVariable("object.instance.$structName", type, objectDeclaration.name, LLVMVariableScope())
codeBuilder.addGlobalIntialize(classInstance, type)
variableManager.addGlobalVariable(structName, classInstance)
}
}
@@ -3,10 +3,7 @@ package org.kotlinnative.translator.llvm
import com.intellij.psi.tree.IElementType
import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.psi.KtSimpleNameExpression
import org.kotlinnative.translator.llvm.types.LLVMCharType
import org.kotlinnative.translator.llvm.types.LLVMIntType
import org.kotlinnative.translator.llvm.types.LLVMStringType
import org.kotlinnative.translator.llvm.types.LLVMType
import org.kotlinnative.translator.llvm.types.*
class LLVMBuilder(val arm: Boolean) {
private val POINTER_SIZE = 4
@@ -87,6 +84,19 @@ class LLVMBuilder(val arm: Boolean) {
KtTokens.EQEQ -> firstOp.type!!.operatorEq(firstNativeOp, secondNativeOp)
KtTokens.EXCLEQ -> firstOp.type!!.operatorNeq(firstNativeOp, secondNativeOp)
KtTokens.EQ -> {
if (secondOp.type is LLVMNullType) {
val result = getNewVariable(firstOp.type!!, firstOp.pointer)
allocStackVar(result)
result.pointer++
storeNull(result)
return result
}
if (firstOp.pointer > 0 && secondOp.pointer > 0) {
return secondOp as LLVMVariable
}
val result = firstOp as LLVMVariable
storeVariable(result, secondNativeOp)
return result
@@ -1,8 +1,5 @@
package org.kotlinnative.translator.llvm.types
import org.kotlinnative.translator.llvm.LLVMExpression
import org.kotlinnative.translator.llvm.LLVMSingleValue
class LLVMEnumItemType() : LLVMType() {
@@ -0,0 +1,2 @@
nullable_test(1) == 2
nullable_test_2(1) == 1
@@ -0,0 +1,18 @@
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
}
fun nullable_test_2(i: Int): Int {
// var x: MyAwesomeClass? = MyAwesomeClass(i)
// x = null
// x = MyAwesomeClass(i)
return i
}