translator: reference type move without copy, tests
This commit is contained in:
@@ -1,14 +1,29 @@
|
|||||||
declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture readonly, i64, i32, i1)
|
declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture readonly, i64, i32, i1)
|
||||||
declare i8* @malloc_static(i32)
|
declare i8* @malloc(i32)
|
||||||
attributes #0 = { nounwind "stack-protector-buffer-size"="8" "target-cpu"="cortex-m3" "target-features"="+hwdiv,+strict-align" }
|
%class.MyClass = type { i32 }
|
||||||
define i32 @reassigment_1(i32 %x) #0
|
define void @MyClass(%class.MyClass* %classvariable.this, i32 %i)
|
||||||
{
|
{
|
||||||
%x.addr = alloca i32, align 4
|
%classvariable.this.addr = alloca %class.MyClass, align 4
|
||||||
store i32 %x, i32* %x.addr, align 4
|
%i.addr = alloca i32, align 4
|
||||||
%var1 = load i32* %x.addr, align 4
|
store i32 %i, i32* %i.addr, align 4
|
||||||
%var2 = add nsw i32 %var1, 1
|
%var1 = load i32* %i.addr, align 4
|
||||||
%var3 = add nsw i32 %var2, 1
|
%var2 = getelementptr inbounds %class.MyClass* %classvariable.this.addr, i32 0, i32 0
|
||||||
store i32 %var3, i32 %var2, align 4
|
store i32 %var1, i32* %var2, align 4
|
||||||
ret i32 %var2
|
%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 structName: String
|
||||||
override val type: LLVMType = LLVMReferenceType(clazz.name.toString(), "class", byRef = true)
|
override val type: LLVMType = LLVMReferenceType(clazz.name.toString(), "class", byRef = true)
|
||||||
|
|
||||||
|
|
||||||
init {
|
init {
|
||||||
structName = clazz.name.toString()
|
structName = clazz.name.toString()
|
||||||
val descriptor = state.bindingContext.get(BindingContext.CLASS, clazz) ?: throw TranslationException()
|
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() {
|
fun generate() {
|
||||||
generate(objectDeclaration.declarations)
|
generate(objectDeclaration.declarations)
|
||||||
val classInstance = LLVMVariable("object.instance.${structName}", type, objectDeclaration.name, LLVMVariableScope())
|
val classInstance = LLVMVariable("object.instance.$structName", type, objectDeclaration.name, LLVMVariableScope())
|
||||||
codeBuilder.addGlobalIntialize(classInstance, type);
|
codeBuilder.addGlobalIntialize(classInstance, type)
|
||||||
variableManager.addGlobalVariable(structName, classInstance)
|
variableManager.addGlobalVariable(structName, classInstance)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,10 +3,7 @@ package org.kotlinnative.translator.llvm
|
|||||||
import com.intellij.psi.tree.IElementType
|
import com.intellij.psi.tree.IElementType
|
||||||
import org.jetbrains.kotlin.lexer.KtTokens
|
import org.jetbrains.kotlin.lexer.KtTokens
|
||||||
import org.jetbrains.kotlin.psi.KtSimpleNameExpression
|
import org.jetbrains.kotlin.psi.KtSimpleNameExpression
|
||||||
import org.kotlinnative.translator.llvm.types.LLVMCharType
|
import org.kotlinnative.translator.llvm.types.*
|
||||||
import org.kotlinnative.translator.llvm.types.LLVMIntType
|
|
||||||
import org.kotlinnative.translator.llvm.types.LLVMStringType
|
|
||||||
import org.kotlinnative.translator.llvm.types.LLVMType
|
|
||||||
|
|
||||||
class LLVMBuilder(val arm: Boolean) {
|
class LLVMBuilder(val arm: Boolean) {
|
||||||
private val POINTER_SIZE = 4
|
private val POINTER_SIZE = 4
|
||||||
@@ -87,6 +84,19 @@ class LLVMBuilder(val arm: Boolean) {
|
|||||||
KtTokens.EQEQ -> firstOp.type!!.operatorEq(firstNativeOp, secondNativeOp)
|
KtTokens.EQEQ -> firstOp.type!!.operatorEq(firstNativeOp, secondNativeOp)
|
||||||
KtTokens.EXCLEQ -> firstOp.type!!.operatorNeq(firstNativeOp, secondNativeOp)
|
KtTokens.EXCLEQ -> firstOp.type!!.operatorNeq(firstNativeOp, secondNativeOp)
|
||||||
KtTokens.EQ -> {
|
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
|
val result = firstOp as LLVMVariable
|
||||||
storeVariable(result, secondNativeOp)
|
storeVariable(result, secondNativeOp)
|
||||||
return result
|
return result
|
||||||
|
|||||||
@@ -1,8 +1,5 @@
|
|||||||
package org.kotlinnative.translator.llvm.types
|
package org.kotlinnative.translator.llvm.types
|
||||||
|
|
||||||
import org.kotlinnative.translator.llvm.LLVMExpression
|
|
||||||
import org.kotlinnative.translator.llvm.LLVMSingleValue
|
|
||||||
|
|
||||||
|
|
||||||
class LLVMEnumItemType() : LLVMType() {
|
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
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user