translator: nullable tests, fix null reassignment, fix reference assignment
This commit is contained in:
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ class VariableManager(val globalVariableCollection: HashMap<String, LLVMVariable
|
||||
}
|
||||
|
||||
fun pullUpwardsLevel(level: Int) {
|
||||
fileVariableCollectionTree.forEach { s, stack -> 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) {
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -13,13 +13,13 @@ fun LLVMFunctionDescriptor(name: String, argTypes: List<LLVMVariable>?, 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)
|
||||
}
|
||||
|
||||
@@ -1 +1 @@
|
||||
class_init_section(523) == 12868
|
||||
class_init_section(523) == 12868
|
||||
|
||||
@@ -1 +1 @@
|
||||
class_methods_1(55) == 60
|
||||
class_methods_1(55) == 60
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
do_while_test_1(5) == 6
|
||||
do_while_test_1(57) == 68
|
||||
do_while_test_1(57) == 68
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
nullable_test(1) == 2
|
||||
nullable_test_2(1) == 1
|
||||
nullable_test(1) == 1
|
||||
nullable_test_2(4) == 5
|
||||
|
||||
@@ -1 +1 @@
|
||||
Singleton.create(5) == 40
|
||||
Singleton.create(5) == 40
|
||||
|
||||
@@ -1 +1 @@
|
||||
reassigment_0(5) == 6
|
||||
reassigment_0(5) == 6
|
||||
|
||||
@@ -1 +1 @@
|
||||
reassigment_1(5) == 7
|
||||
reassigment_1(5) == 7
|
||||
|
||||
@@ -1 +1 @@
|
||||
simply_class_1(6789) == 6794
|
||||
simply_class_1(6789) == 6794
|
||||
|
||||
@@ -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
|
||||
}
|
||||
Reference in New Issue
Block a user