translator: add type detection and initializing on class variables
This commit is contained in:
@@ -78,7 +78,7 @@ abstract class BlockCodegen(open val state: TranslationState, open val variableM
|
||||
executeWhileBlock(condition.firstChild as KtBinaryExpression, bodyExpression.firstChild, scopeDepth, checkConditionBeforeExecute = false)
|
||||
}
|
||||
|
||||
private fun evaluateExpression(expr: PsiElement?, scopeDepth: Int): LLVMSingleValue? {
|
||||
fun evaluateExpression(expr: PsiElement?, scopeDepth: Int): LLVMSingleValue? {
|
||||
return when (expr) {
|
||||
is KtBinaryExpression -> evaluateBinaryExpression(expr, scopeDepth)
|
||||
is KtPostfixExpression -> evaluatePostfixExpression(expr, scopeDepth)
|
||||
@@ -191,6 +191,7 @@ abstract class BlockCodegen(open val state: TranslationState, open val variableM
|
||||
return evaluateClassScopedDotExpression(clazz, selectorExpr, scopeDepth)
|
||||
}
|
||||
|
||||
|
||||
private fun evaluateExtensionExpression(receiver: KtExpression, selector: KtCallExpression, scopeDepth: Int): LLVMSingleValue? {
|
||||
val receiverType = state.bindingContext.get(BindingContext.EXPRESSION_TYPE_INFO, receiver)
|
||||
val standardType = LLVMMapStandardType(receiverType!!.type!!)
|
||||
@@ -229,7 +230,7 @@ abstract class BlockCodegen(open val state: TranslationState, open val variableM
|
||||
return result
|
||||
}
|
||||
|
||||
private fun evaluateMemberMethodOrField(receiver: LLVMVariable, selectorName: String, scopeDepth: Int, call: PsiElement): LLVMSingleValue? {
|
||||
fun evaluateMemberMethodOrField(receiver: LLVMVariable, selectorName: String, scopeDepth: Int, call: PsiElement?): LLVMSingleValue? {
|
||||
val type = receiver.type as LLVMReferenceType
|
||||
val clazz = resolveClassOrObjectLocation(type)
|
||||
val field = clazz.fieldsIndex[selectorName]
|
||||
@@ -240,7 +241,7 @@ abstract class BlockCodegen(open val state: TranslationState, open val variableM
|
||||
return result
|
||||
}
|
||||
|
||||
val names = parseArgList(call as KtCallExpression, scopeDepth)
|
||||
val names = parseArgList(call!! as KtCallExpression, scopeDepth)
|
||||
val typePath = type.location.joinToString(".")
|
||||
val types = if (names.size > 0) "_${names.joinToString(separator = "_", transform = { it.type!!.mangle() })}" else ""
|
||||
val methodName = "${if (typePath.length > 0) "$typePath." else ""}${clazz.structName}.${selectorName.substringBefore('(')}$types"
|
||||
@@ -486,7 +487,7 @@ abstract class BlockCodegen(open val state: TranslationState, open val variableM
|
||||
}
|
||||
}
|
||||
|
||||
private fun executeBinaryExpression(operator: IElementType, referenceName: KtSimpleNameExpression?, left: LLVMSingleValue, right: LLVMSingleValue)
|
||||
fun executeBinaryExpression(operator: IElementType, referenceName: KtSimpleNameExpression?, left: LLVMSingleValue, right: LLVMSingleValue)
|
||||
= addPrimitiveBinaryOperation(operator, referenceName, left, right)
|
||||
|
||||
private fun evaluateElvisOperator(expr: KtBinaryExpression, scopeDepth: Int): LLVMVariable {
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
package org.kotlinnative.translator
|
||||
|
||||
import com.intellij.psi.PsiElement
|
||||
import jdk.nashorn.internal.ir.Block
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
@@ -28,6 +30,7 @@ abstract class StructCodegen(open val state: TranslationState,
|
||||
val enumFields = HashMap<String, LLVMVariable>()
|
||||
|
||||
val constructorFields = ArrayList<LLVMVariable>()
|
||||
val initializedFields = HashMap<LLVMVariable, KtExpression>()
|
||||
|
||||
abstract val type: LLVMReferenceType
|
||||
abstract var size: Int
|
||||
@@ -64,11 +67,15 @@ abstract class StructCodegen(open val state: TranslationState,
|
||||
for (declaration in declarations) {
|
||||
when (declaration) {
|
||||
is KtProperty -> {
|
||||
val ktType = state.bindingContext.get(BindingContext.TYPE, declaration.typeReference)!!
|
||||
val ktType = state.bindingContext.get(BindingContext.TYPE, declaration.typeReference)
|
||||
?: state.bindingContext.get(BindingContext.VARIABLE, declaration)!!.type
|
||||
val field = resolveType(declaration, ktType)
|
||||
field.offset = offset
|
||||
offset++
|
||||
|
||||
if ((declaration.initializer != null) && !(this is ObjectCodegen)){
|
||||
initializedFields.put(field, declaration.initializer!!)
|
||||
}
|
||||
fields.add(field)
|
||||
fieldsIndex[field.label] = field
|
||||
size += field.type.size
|
||||
@@ -133,7 +140,6 @@ abstract class StructCodegen(open val state: TranslationState,
|
||||
}
|
||||
|
||||
private fun generateLoadArguments(thisField: LLVMVariable) {
|
||||
|
||||
val thisVariable = LLVMVariable(thisField.label, thisField.type, thisField.label, LLVMRegisterScope(), pointer = 0)
|
||||
codeBuilder.loadArgument(thisVariable, false)
|
||||
|
||||
@@ -163,6 +169,16 @@ abstract class StructCodegen(open val state: TranslationState,
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
val blockCodegen = object : BlockCodegen(state, variableManager, codeBuilder) {}
|
||||
val receiverThis = LLVMVariable("classvariable.this.addr", type, scope = LLVMRegisterScope(), pointer = 1)
|
||||
for ((variable, initializer) in initializedFields) {
|
||||
val left = blockCodegen.evaluateMemberMethodOrField(receiverThis, variable.label, blockCodegen.topLevel, call = null)!!
|
||||
val right = blockCodegen.evaluateExpression(initializer, scopeDepth = blockCodegen.topLevel)!!
|
||||
|
||||
blockCodegen.executeBinaryExpression(KtTokens.EQ, referenceName = null, left = left, right = right)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private fun generateReturn() {
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
/*package org.kotlinnative.translator.llvm.types
|
||||
|
||||
class LLVMStringType(override val length: Int) : LLVMArray, LLVMType() {
|
||||
|
||||
override var size: Int = 1
|
||||
override val align = 8
|
||||
override val defaultValue = ""
|
||||
|
||||
override fun mangle() = "String"
|
||||
|
||||
override fun basicType() = LLVMCharType()
|
||||
override fun toString(): String = "i8*"
|
||||
override fun fullType() = "[${length + 1} x i8]"
|
||||
}
|
||||
*/
|
||||
@@ -0,0 +1 @@
|
||||
initialized_class_fields_1() == 524
|
||||
@@ -0,0 +1,8 @@
|
||||
class initialized_class_fields_1_class {
|
||||
var pos: Int = 524
|
||||
}
|
||||
|
||||
fun initialized_class_fields_1(): Int {
|
||||
val instance = initialized_class_fields_1_class()
|
||||
return instance.pos
|
||||
}
|
||||
Reference in New Issue
Block a user