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)
|
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) {
|
return when (expr) {
|
||||||
is KtBinaryExpression -> evaluateBinaryExpression(expr, scopeDepth)
|
is KtBinaryExpression -> evaluateBinaryExpression(expr, scopeDepth)
|
||||||
is KtPostfixExpression -> evaluatePostfixExpression(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)
|
return evaluateClassScopedDotExpression(clazz, selectorExpr, scopeDepth)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private fun evaluateExtensionExpression(receiver: KtExpression, selector: KtCallExpression, scopeDepth: Int): LLVMSingleValue? {
|
private fun evaluateExtensionExpression(receiver: KtExpression, selector: KtCallExpression, scopeDepth: Int): LLVMSingleValue? {
|
||||||
val receiverType = state.bindingContext.get(BindingContext.EXPRESSION_TYPE_INFO, receiver)
|
val receiverType = state.bindingContext.get(BindingContext.EXPRESSION_TYPE_INFO, receiver)
|
||||||
val standardType = LLVMMapStandardType(receiverType!!.type!!)
|
val standardType = LLVMMapStandardType(receiverType!!.type!!)
|
||||||
@@ -229,7 +230,7 @@ abstract class BlockCodegen(open val state: TranslationState, open val variableM
|
|||||||
return result
|
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 type = receiver.type as LLVMReferenceType
|
||||||
val clazz = resolveClassOrObjectLocation(type)
|
val clazz = resolveClassOrObjectLocation(type)
|
||||||
val field = clazz.fieldsIndex[selectorName]
|
val field = clazz.fieldsIndex[selectorName]
|
||||||
@@ -240,7 +241,7 @@ abstract class BlockCodegen(open val state: TranslationState, open val variableM
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
val names = parseArgList(call as KtCallExpression, scopeDepth)
|
val names = parseArgList(call!! as KtCallExpression, scopeDepth)
|
||||||
val typePath = type.location.joinToString(".")
|
val typePath = type.location.joinToString(".")
|
||||||
val types = if (names.size > 0) "_${names.joinToString(separator = "_", transform = { it.type!!.mangle() })}" else ""
|
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"
|
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)
|
= addPrimitiveBinaryOperation(operator, referenceName, left, right)
|
||||||
|
|
||||||
private fun evaluateElvisOperator(expr: KtBinaryExpression, scopeDepth: Int): LLVMVariable {
|
private fun evaluateElvisOperator(expr: KtBinaryExpression, scopeDepth: Int): LLVMVariable {
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
package org.kotlinnative.translator
|
package org.kotlinnative.translator
|
||||||
|
|
||||||
import com.intellij.psi.PsiElement
|
import com.intellij.psi.PsiElement
|
||||||
|
import jdk.nashorn.internal.ir.Block
|
||||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||||
|
import org.jetbrains.kotlin.lexer.KtTokens
|
||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
@@ -28,6 +30,7 @@ abstract class StructCodegen(open val state: TranslationState,
|
|||||||
val enumFields = HashMap<String, LLVMVariable>()
|
val enumFields = HashMap<String, LLVMVariable>()
|
||||||
|
|
||||||
val constructorFields = ArrayList<LLVMVariable>()
|
val constructorFields = ArrayList<LLVMVariable>()
|
||||||
|
val initializedFields = HashMap<LLVMVariable, KtExpression>()
|
||||||
|
|
||||||
abstract val type: LLVMReferenceType
|
abstract val type: LLVMReferenceType
|
||||||
abstract var size: Int
|
abstract var size: Int
|
||||||
@@ -64,11 +67,15 @@ abstract class StructCodegen(open val state: TranslationState,
|
|||||||
for (declaration in declarations) {
|
for (declaration in declarations) {
|
||||||
when (declaration) {
|
when (declaration) {
|
||||||
is KtProperty -> {
|
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)
|
val field = resolveType(declaration, ktType)
|
||||||
field.offset = offset
|
field.offset = offset
|
||||||
offset++
|
offset++
|
||||||
|
|
||||||
|
if ((declaration.initializer != null) && !(this is ObjectCodegen)){
|
||||||
|
initializedFields.put(field, declaration.initializer!!)
|
||||||
|
}
|
||||||
fields.add(field)
|
fields.add(field)
|
||||||
fieldsIndex[field.label] = field
|
fieldsIndex[field.label] = field
|
||||||
size += field.type.size
|
size += field.type.size
|
||||||
@@ -133,7 +140,6 @@ abstract class StructCodegen(open val state: TranslationState,
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun generateLoadArguments(thisField: LLVMVariable) {
|
private fun generateLoadArguments(thisField: LLVMVariable) {
|
||||||
|
|
||||||
val thisVariable = LLVMVariable(thisField.label, thisField.type, thisField.label, LLVMRegisterScope(), pointer = 0)
|
val thisVariable = LLVMVariable(thisField.label, thisField.type, thisField.label, LLVMRegisterScope(), pointer = 0)
|
||||||
codeBuilder.loadArgument(thisVariable, false)
|
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() {
|
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