translator: fix String variables - load and transfer

This commit is contained in:
Alexey Stepanov
2016-08-16 14:09:06 +03:00
parent 3358a9caaa
commit e35b6897a8
4 changed files with 18 additions and 4 deletions
+1
View File
@@ -10,6 +10,7 @@
</content> </content>
<orderEntry type="inheritedJdk" /> <orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" /> <orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="module" module-name="translator_main" />
<orderEntry type="library" name="Gradle: org.jetbrains.kotlin:kotlin-stdlib:1.0.1" level="project" /> <orderEntry type="library" name="Gradle: org.jetbrains.kotlin:kotlin-stdlib:1.0.1" level="project" />
<orderEntry type="library" name="Gradle: org.jetbrains.kotlin:kotlin-compiler:1.0.3" level="project" /> <orderEntry type="library" name="Gradle: org.jetbrains.kotlin:kotlin-compiler:1.0.3" level="project" />
<orderEntry type="library" name="Gradle: com.github.jshmrsn:karg:a636b3e" level="project" /> <orderEntry type="library" name="Gradle: com.github.jshmrsn:karg:a636b3e" level="project" />
@@ -118,7 +118,7 @@ abstract class BlockCodegen(val state: TranslationState, val variableManager: Va
val receiveValue = state.bindingContext.get(BindingContext.COMPILE_TIME_VALUE, expr) val receiveValue = state.bindingContext.get(BindingContext.COMPILE_TIME_VALUE, expr)
val type = (receiveValue as TypedCompileTimeConstant).type val type = (receiveValue as TypedCompileTimeConstant).type
val value = receiveValue.getValue(type) ?: return null val value = receiveValue.getValue(type) ?: return null
val variable = variableManager.receiveVariable(".str", LLVMStringType(value.toString().length), LLVMVariableScope(), pointer = 0) val variable = variableManager.receiveVariable(".str", LLVMStringType(value.toString().length, isLoaded = false), LLVMVariableScope(), pointer = 0)
codeBuilder.addStringConstant(variable, value.toString()) codeBuilder.addStringConstant(variable, value.toString())
return variable return variable
@@ -512,6 +512,17 @@ abstract class BlockCodegen(val state: TranslationState, val variableManager: Va
codeBuilder.loadVariable(result, value as LLVMVariable) codeBuilder.loadVariable(result, value as LLVMVariable)
} }
when (value.type) {
is LLVMStringType -> if (!(value.type as LLVMStringType).isLoaded) {
val newVariable = codeBuilder.getNewVariable(value.type!!, pointer = result.pointer + 1)
codeBuilder.allocStackPointedVarAsValue(newVariable)
codeBuilder.copyVariable(result as LLVMVariable, newVariable)
result = codeBuilder.getNewVariable(argument.type, pointer = newVariable.pointer - 1)
codeBuilder.loadVariable(result, newVariable as LLVMVariable)
}
}
return result return result
} }
@@ -93,6 +93,7 @@ class LLVMBuilder(val arm: Boolean = false) {
val stringType = source.type as LLVMStringType val stringType = source.type as LLVMStringType
val code = "store ${target.type} getelementptr inbounds (" + val code = "store ${target.type} getelementptr inbounds (" +
"${stringType.fullType()}* $source, i32 0, i32 $offset), ${target.getType()} $target, align ${stringType.align}" "${stringType.fullType()}* $source, i32 0, i32 $offset), ${target.getType()} $target, align ${stringType.align}"
(target.type as LLVMStringType).isLoaded = true
localCode.appendln(code) localCode.appendln(code)
} }
@@ -139,7 +140,7 @@ class LLVMBuilder(val arm: Boolean = false) {
} }
fun copyVariable(from: LLVMVariable, to: LLVMVariable) = when (from.type) { fun copyVariable(from: LLVMVariable, to: LLVMVariable) = when (from.type) {
is LLVMStringType -> storeString(to, from, 0) is LLVMStringType -> if ((from.type as LLVMStringType).isLoaded) copyVariableValue(to, from) else storeString(to, from, 0)
else -> copyVariableValue(to, from) else -> copyVariableValue(to, from)
} }
@@ -1,6 +1,6 @@
package org.kotlinnative.translator.llvm.types package org.kotlinnative.translator.llvm.types
class LLVMStringType(override val length: Int) : LLVMArray, LLVMType() { class LLVMStringType(override val length: Int, var isLoaded: Boolean = true) : LLVMArray, LLVMType() {
override var size: Int = 1 override var size: Int = 1
override val align = 8 override val align = 8
@@ -14,11 +14,12 @@ class LLVMStringType(override val length: Int) : LLVMArray, LLVMType() {
else -> false else -> false
} }
override fun basicType() = LLVMCharType() override fun basicType() = LLVMCharType()
override val typename = "i8*" override val typename = "i8*"
override fun fullType() = "[${length + 1} x i8]" override fun fullType() = "[${length + 1} x i8]"
override fun hashCode(): Int { override fun hashCode(): Int {
return length * 31 + return length * 31 + if (isLoaded) 1 else 0 +
mangle().hashCode() mangle().hashCode()
} }
} }