translator: rewrite assignment for primitive nullable types
This commit is contained in:
@@ -849,8 +849,16 @@ abstract class BlockCodegen(val state: TranslationState, val variableManager: Va
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
val result = firstOp as LLVMVariable
|
val result = firstOp as LLVMVariable
|
||||||
val sourceArgument = if (result.pointer == secondOp.pointer + 1) secondOp else secondNativeOp
|
val sourceArgument: LLVMSingleValue
|
||||||
|
if (secondOp.type!!.isPrimitive() && (secondOp.pointer == 0) && (firstOp.pointer == 2)) {
|
||||||
|
sourceArgument = codeBuilder.getNewVariable(secondOp.type!!, 1)
|
||||||
|
codeBuilder.allocStaticVar(sourceArgument, true)
|
||||||
|
codeBuilder.storeVariable(sourceArgument, secondOp)
|
||||||
|
} else {
|
||||||
|
sourceArgument = if (result.pointer == secondOp.pointer + 1) secondOp else secondNativeOp
|
||||||
|
}
|
||||||
codeBuilder.storeVariable(result, sourceArgument)
|
codeBuilder.storeVariable(result, sourceArgument)
|
||||||
codeBuilder.addComment("end variable assignment")
|
codeBuilder.addComment("end variable assignment")
|
||||||
return result
|
return result
|
||||||
@@ -1036,26 +1044,27 @@ abstract class BlockCodegen(val state: TranslationState, val variableManager: Va
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun evaluateValExpression(element: KtProperty, scopeDepth: Int): LLVMVariable? {
|
private fun evaluateValExpression(element: KtProperty, scopeDepth: Int): LLVMVariable? {
|
||||||
|
|
||||||
val variable = state.bindingContext.get(BindingContext.VARIABLE, element)!!
|
val variable = state.bindingContext.get(BindingContext.VARIABLE, element)!!
|
||||||
val identifier = variable.name.toString()
|
val identifier = variable.name.toString()
|
||||||
|
|
||||||
val assignExpression = evaluateExpression(element.delegateExpressionOrInitializer, scopeDepth)
|
val assignExpression = evaluateExpression(element.delegateExpressionOrInitializer, scopeDepth)
|
||||||
val expectedExpressionType = LLVMMapStandardType(variable.type, state)
|
val expectedExpressionType = LLVMInstanceOfStandardType("", variable.type, state = state)
|
||||||
val assignExpressionType = assignExpression?.type
|
val assignExpressionType = assignExpression?.type
|
||||||
|
|
||||||
val isPrimitive = LLVMMapStandardType(variable.type, state) !is LLVMReferred
|
val primitivePointer = LLVMMapStandardType(variable.type, state) !is LLVMReferred
|
||||||
when (assignExpression) {
|
when (assignExpression) {
|
||||||
null,
|
null,
|
||||||
is LLVMVariable -> {
|
is LLVMVariable -> {
|
||||||
val allocVar = variableManager.receiveVariable(identifier, expectedExpressionType, LLVMRegisterScope(), pointer =
|
val allocVar = variableManager.receiveVariable(identifier, expectedExpressionType.type, LLVMRegisterScope(), pointer =
|
||||||
if (isPrimitive) 0 else 1)
|
expectedExpressionType.pointer)
|
||||||
codeBuilder.allocStackVar(allocVar)
|
codeBuilder.allocStackVar(allocVar)
|
||||||
allocVar.pointer++
|
allocVar.pointer++
|
||||||
allocVar.kotlinName = identifier
|
allocVar.kotlinName = identifier
|
||||||
|
|
||||||
variableManager.addVariable(identifier, allocVar, scopeDepth)
|
variableManager.addVariable(identifier, allocVar, scopeDepth)
|
||||||
if (assignExpression != null) {
|
if (assignExpression != null) {
|
||||||
if ((isPrimitive) && (assignExpression.type is LLVMReferenceType)) {
|
if ((primitivePointer) && (assignExpression.type is LLVMReferenceType)) {
|
||||||
throw UnexpectedException(element.text)
|
throw UnexpectedException(element.text)
|
||||||
}
|
}
|
||||||
addPrimitiveBinaryOperation(KtTokens.EQ, null, allocVar, assignExpression)
|
addPrimitiveBinaryOperation(KtTokens.EQ, null, allocVar, assignExpression)
|
||||||
|
|||||||
@@ -76,8 +76,9 @@ class LLVMBuilder(val arm: Boolean = false) {
|
|||||||
var result = value
|
var result = value
|
||||||
|
|
||||||
while (argument.pointer < result.pointer) {
|
while (argument.pointer < result.pointer) {
|
||||||
result = getNewVariable(argument.type, pointer = result.pointer - 1)
|
val currentArgument = getNewVariable(result.type!!, pointer = result.pointer - 1)
|
||||||
loadVariable(result, value as LLVMVariable)
|
loadVariable(currentArgument, result as LLVMVariable)
|
||||||
|
result = currentArgument
|
||||||
}
|
}
|
||||||
|
|
||||||
when (value.type) {
|
when (value.type) {
|
||||||
|
|||||||
@@ -15,26 +15,30 @@ fun LLVMFunctionDescriptor(name: String, argTypes: List<LLVMVariable>?, returnTy
|
|||||||
"${s.getType()} ${if (s.type is LLVMReferenceType && !(s.type as LLVMReferenceType).byRef) "byval" else ""} %${s.label}"
|
"${s.getType()} ${if (s.type is LLVMReferenceType && !(s.type as LLVMReferenceType).byRef) "byval" else ""} %${s.label}"
|
||||||
}?.joinToString()}) #0"
|
}?.joinToString()}) #0"
|
||||||
|
|
||||||
fun LLVMInstanceOfStandardType(name: String, type: KotlinType, scope: LLVMScope = LLVMRegisterScope(), state: TranslationState): LLVMVariable = when {
|
fun LLVMInstanceOfStandardType(name: String, type: KotlinType, scope: LLVMScope = LLVMRegisterScope(), state: TranslationState): LLVMVariable {
|
||||||
type.isFunctionTypeOrSubtype -> LLVMVariable(name, LLVMFunctionType(type, state), name, scope, pointer = 1)
|
val typeName = type.toString().dropLastWhile { it == '?' }
|
||||||
type.toString() == "Boolean" -> LLVMVariable(name, LLVMBooleanType(), name, scope)
|
val pointerMark = if (type.toString().last() == '?') 1 else 0
|
||||||
type.toString() == "Byte" -> LLVMVariable(name, LLVMByteType(), name, scope)
|
return when {
|
||||||
type.toString() == "Char" -> LLVMVariable(name, LLVMCharType(), name, scope)
|
type.isFunctionTypeOrSubtype -> LLVMVariable(name, LLVMFunctionType(type, state), name, scope, pointer = 1)
|
||||||
type.toString() == "Short" -> LLVMVariable(name, LLVMShortType(), name, scope)
|
typeName == "Boolean" -> LLVMVariable(name, LLVMBooleanType(), name, scope, pointerMark)
|
||||||
type.toString() == "Int" -> LLVMVariable(name, LLVMIntType(), name, scope)
|
typeName == "Byte" -> LLVMVariable(name, LLVMByteType(), name, scope, pointerMark)
|
||||||
type.toString() == "Long" -> LLVMVariable(name, LLVMLongType(), name, scope)
|
typeName == "Char" -> LLVMVariable(name, LLVMCharType(), name, scope, pointerMark)
|
||||||
type.toString() == "Float" -> LLVMVariable(name, LLVMFloatType(), name, scope)
|
typeName == "Short" -> LLVMVariable(name, LLVMShortType(), name, scope, pointerMark)
|
||||||
type.toString() == "Double" -> LLVMVariable(name, LLVMDoubleType(), name, scope)
|
typeName == "Int" -> LLVMVariable(name, LLVMIntType(), name, scope, pointerMark)
|
||||||
type.toString() == "String" -> LLVMVariable(name, LLVMStringType(0), name, scope)
|
typeName == "Long" -> LLVMVariable(name, LLVMLongType(), name, scope, pointerMark)
|
||||||
type.nameIfStandardType.toString() == "Nothing" -> LLVMVariable(name, LLVMNullType(), name, scope)
|
typeName == "Float" -> LLVMVariable(name, LLVMFloatType(), name, scope, pointerMark)
|
||||||
type.isUnit() -> LLVMVariable("", LLVMVoidType(), name, scope)
|
typeName == "Double" -> LLVMVariable(name, LLVMDoubleType(), name, scope, pointerMark)
|
||||||
type.isMarkedNullable -> LLVMVariable(name, LLVMReferenceType(type.toString().dropLast(1), prefix = "class"), name, scope, pointer = 1)
|
typeName == "String" -> LLVMVariable(name, LLVMStringType(0), name, scope, pointerMark)
|
||||||
else -> {
|
type.nameIfStandardType.toString() == "Nothing" -> LLVMVariable(name, LLVMNullType(), name, scope)
|
||||||
val refType = state.classes[type.toString()]?.type ?: LLVMReferenceType(type.toString(), align = state.pointerAlign, prefix = "class")
|
type.isUnit() -> LLVMVariable("", LLVMVoidType(), name, scope)
|
||||||
|
type.isMarkedNullable -> LLVMVariable(name, LLVMReferenceType(typeName, prefix = "class"), name, scope, pointer = pointerMark)
|
||||||
|
else -> {
|
||||||
|
val refType = state.classes[type.toString()]?.type ?: LLVMReferenceType(typeName, align = state.pointerAlign, prefix = "class")
|
||||||
|
|
||||||
val result = LLVMVariable(name, refType, name, scope, pointer = 1)
|
val result = LLVMVariable(name, refType, name, scope, pointer = 1)
|
||||||
refType.location.addAll(type.getSubtypesPredicate().toString().split(".").dropLast(1))
|
refType.location.addAll(type.getSubtypesPredicate().toString().split(".").dropLast(1))
|
||||||
result
|
result
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user