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