translator: add skeleton for user type select, rename LLVMScope
This commit is contained in:
@@ -78,17 +78,17 @@ class ClassCodegen(val state: TranslationState, val clazz: KtClass, val codeBuil
|
|||||||
generateLoadArguments(thisField)
|
generateLoadArguments(thisField)
|
||||||
generateAssignments()
|
generateAssignments()
|
||||||
generateReturn()
|
generateReturn()
|
||||||
codeBuilder.addVoidReturn()
|
codeBuilder.addAnyReturn(LLVMVoidType())
|
||||||
codeBuilder.addEndExpression()
|
codeBuilder.addEndExpression()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun generateLoadArguments(thisField: LLVMVariable) {
|
private fun generateLoadArguments(thisField: LLVMVariable) {
|
||||||
|
|
||||||
val thisVariable = LLVMVariable(thisField.label, thisField.type, thisField.label, LLVMLocalScope(), pointer = 1)
|
val thisVariable = LLVMVariable(thisField.label, thisField.type, thisField.label, LLVMRegisterScope(), pointer = 1)
|
||||||
codeBuilder.loadArgument(thisVariable, false)
|
codeBuilder.loadArgument(thisVariable, false)
|
||||||
|
|
||||||
fields.forEach {
|
fields.forEach {
|
||||||
val loadVariable = LLVMVariable(it.label, it.type, it.label, LLVMLocalScope())
|
val loadVariable = LLVMVariable(it.label, it.type, it.label, LLVMRegisterScope())
|
||||||
codeBuilder.loadArgument(loadVariable)
|
codeBuilder.loadArgument(loadVariable)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -96,16 +96,16 @@ class ClassCodegen(val state: TranslationState, val clazz: KtClass, val codeBuil
|
|||||||
private fun generateAssignments() {
|
private fun generateAssignments() {
|
||||||
fields.forEach {
|
fields.forEach {
|
||||||
val argument = codeBuilder.getNewVariable(it.type)
|
val argument = codeBuilder.getNewVariable(it.type)
|
||||||
codeBuilder.loadVariable(argument, LLVMVariable("${it.label}.addr", it.type, scope = LLVMLocalScope(), pointer = 1))
|
codeBuilder.loadVariable(argument, LLVMVariable("${it.label}.addr", it.type, scope = LLVMRegisterScope(), pointer = 1))
|
||||||
val classField = codeBuilder.getNewVariable(it.type, pointer = 1)
|
val classField = codeBuilder.getNewVariable(it.type, pointer = 1)
|
||||||
codeBuilder.loadClassField(classField, LLVMVariable("instance.addr", type, scope = LLVMLocalScope(), pointer = 1), (it as LLVMClassVariable).offset)
|
codeBuilder.loadClassField(classField, LLVMVariable("instance.addr", type, scope = LLVMRegisterScope(), pointer = 1), (it as LLVMClassVariable).offset)
|
||||||
codeBuilder.storeVariable(classField, argument)
|
codeBuilder.storeVariable(classField, argument)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun generateReturn() {
|
private fun generateReturn() {
|
||||||
val dst = LLVMVariable("instance", type, scope = LLVMLocalScope(), pointer = 1)
|
val dst = LLVMVariable("instance", type, scope = LLVMRegisterScope(), pointer = 1)
|
||||||
val src = LLVMVariable("instance.addr", type, scope = LLVMLocalScope(), pointer = 1)
|
val src = LLVMVariable("instance.addr", type, scope = LLVMRegisterScope(), pointer = 1)
|
||||||
|
|
||||||
val castedDst = codeBuilder.bitcast(dst, LLVMCharType())
|
val castedDst = codeBuilder.bitcast(dst, LLVMCharType())
|
||||||
val castedSrc = codeBuilder.bitcast(src, LLVMCharType())
|
val castedSrc = codeBuilder.bitcast(src, LLVMCharType())
|
||||||
|
|||||||
@@ -98,16 +98,16 @@ class FunctionCodegen(val state: TranslationState, val function: KtNamedFunction
|
|||||||
private fun generateLoadArguments() {
|
private fun generateLoadArguments() {
|
||||||
args.forEach(fun(it: LLVMVariable) {
|
args.forEach(fun(it: LLVMVariable) {
|
||||||
if (it.type is LLVMFunctionType) {
|
if (it.type is LLVMFunctionType) {
|
||||||
variableManager.addVariable(it.label, LLVMVariable(it.label, it.type, it.label, LLVMLocalScope(), pointer = 1), topLevel)
|
variableManager.addVariable(it.label, LLVMVariable(it.label, it.type, it.label, LLVMRegisterScope(), pointer = 1), topLevel)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if (it.type !is LLVMReferenceType || (it.type as LLVMReferenceType).isReturn) {
|
if (it.type !is LLVMReferenceType || (it.type as LLVMReferenceType).isReturn) {
|
||||||
val loadVariable = LLVMVariable("${it.label}", it.type, it.label, LLVMLocalScope(), pointer = 0)
|
val loadVariable = LLVMVariable("${it.label}", it.type, it.label, LLVMRegisterScope(), pointer = 0)
|
||||||
val allocVar = codeBuilder.loadArgument(loadVariable)
|
val allocVar = codeBuilder.loadArgument(loadVariable)
|
||||||
variableManager.addVariable(it.label, allocVar, topLevel)
|
variableManager.addVariable(it.label, allocVar, topLevel)
|
||||||
} else {
|
} else {
|
||||||
variableManager.addVariable(it.label, LLVMVariable(it.label, it.type, it.label, LLVMLocalScope(), pointer = 0), topLevel)
|
variableManager.addVariable(it.label, LLVMVariable(it.label, it.type, it.label, LLVMRegisterScope(), pointer = 0), topLevel)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -157,7 +157,7 @@ class FunctionCodegen(val state: TranslationState, val function: KtNamedFunction
|
|||||||
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), LLVMGlobalScope(), pointer = 0)
|
val variable = variableManager.receiveVariable(".str", LLVMStringType(value.toString().length), LLVMVariableScope(), pointer = 0)
|
||||||
|
|
||||||
codeBuilder.addStringConstant(variable, value.toString())
|
codeBuilder.addStringConstant(variable, value.toString())
|
||||||
return variable
|
return variable
|
||||||
@@ -165,7 +165,7 @@ class FunctionCodegen(val state: TranslationState, val function: KtNamedFunction
|
|||||||
|
|
||||||
private fun evaluateCallableReferenceExpression(expr: KtCallableReferenceExpression): LLVMSingleValue? {
|
private fun evaluateCallableReferenceExpression(expr: KtCallableReferenceExpression): LLVMSingleValue? {
|
||||||
val kotlinType = state.bindingContext.get(BindingContext.EXPRESSION_TYPE_INFO, expr)!!.type!!
|
val kotlinType = state.bindingContext.get(BindingContext.EXPRESSION_TYPE_INFO, expr)!!.type!!
|
||||||
return LLVMMapStandardType(expr.text.substring(2), kotlinType, LLVMGlobalScope())
|
return LLVMMapStandardType(expr.text.substring(2), kotlinType, LLVMVariableScope())
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun evaluateDotExpression(expr: KtDotQualifiedExpression): LLVMSingleValue? {
|
private fun evaluateDotExpression(expr: KtDotQualifiedExpression): LLVMSingleValue? {
|
||||||
@@ -203,7 +203,7 @@ class FunctionCodegen(val state: TranslationState, val function: KtNamedFunction
|
|||||||
|
|
||||||
if (state.functions.containsKey(function)) {
|
if (state.functions.containsKey(function)) {
|
||||||
val descriptor = state.functions[function] ?: return null
|
val descriptor = state.functions[function] ?: return null
|
||||||
return evaluateFunctionCallExpression(LLVMVariable(function, descriptor.returnType.type, scope = LLVMGlobalScope()), names, descriptor.args)
|
return evaluateFunctionCallExpression(LLVMVariable(function, descriptor.returnType.type, scope = LLVMVariableScope()), names, descriptor.args)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state.classes.containsKey(function)) {
|
if (state.classes.containsKey(function)) {
|
||||||
@@ -214,7 +214,7 @@ class FunctionCodegen(val state: TranslationState, val function: KtNamedFunction
|
|||||||
val localFunction = variableManager.getLLVMvalue(function)
|
val localFunction = variableManager.getLLVMvalue(function)
|
||||||
if (localFunction != null) {
|
if (localFunction != null) {
|
||||||
val type = localFunction.type as LLVMFunctionType
|
val type = localFunction.type as LLVMFunctionType
|
||||||
return evaluateFunctionCallExpression(LLVMVariable(function, type.returnType.type, scope = LLVMLocalScope()), names, type.arguments)
|
return evaluateFunctionCallExpression(LLVMVariable(function, type.returnType.type, scope = LLVMRegisterScope()), names, type.arguments)
|
||||||
}
|
}
|
||||||
|
|
||||||
return null
|
return null
|
||||||
@@ -320,11 +320,22 @@ class FunctionCodegen(val state: TranslationState, val function: KtNamedFunction
|
|||||||
return when (element) {
|
return when (element) {
|
||||||
is LeafPsiElement -> evaluateLeafPsiElement(element, scopeDepth)
|
is LeafPsiElement -> evaluateLeafPsiElement(element, scopeDepth)
|
||||||
is KtConstantExpression -> evaluateConstantExpression(element)
|
is KtConstantExpression -> evaluateConstantExpression(element)
|
||||||
|
is KtTypeReference -> evaluateTypeReference(element)
|
||||||
KtTokens.INTEGER_LITERAL -> null
|
KtTokens.INTEGER_LITERAL -> null
|
||||||
else -> null
|
else -> null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun evaluateTypeReference(element: KtTypeReference): LLVMSingleValue? {
|
||||||
|
val type = element.typeElement as KtUserType
|
||||||
|
val operator = element.getNextSiblingIgnoringWhitespaceAndComments()
|
||||||
|
val value = operator?.getNextSiblingIgnoringWhitespaceAndComments() as KtConstantExpression
|
||||||
|
|
||||||
|
return when (operator) {
|
||||||
|
else -> throw UnsupportedOperationException()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun evaluateLeafPsiElement(element: LeafPsiElement, scopeDepth: Int): LLVMVariable? {
|
private fun evaluateLeafPsiElement(element: LeafPsiElement, scopeDepth: Int): LLVMVariable? {
|
||||||
return when (element.elementType) {
|
return when (element.elementType) {
|
||||||
KtTokens.RETURN_KEYWORD -> evaluateReturnInstruction(element, scopeDepth)
|
KtTokens.RETURN_KEYWORD -> evaluateReturnInstruction(element, scopeDepth)
|
||||||
@@ -426,13 +437,13 @@ class FunctionCodegen(val state: TranslationState, val function: KtNamedFunction
|
|||||||
|
|
||||||
when (assignExpression) {
|
when (assignExpression) {
|
||||||
is LLVMVariable -> {
|
is LLVMVariable -> {
|
||||||
val allocVar = variableManager.receiveVariable(identifier!!.text, assignExpression.type, LLVMLocalScope(), pointer = 1)
|
val allocVar = variableManager.receiveVariable(identifier!!.text, assignExpression.type, LLVMRegisterScope(), pointer = 1)
|
||||||
codeBuilder.allocVar(allocVar)
|
codeBuilder.allocVar(allocVar)
|
||||||
variableManager.addVariable(identifier.text, allocVar, scopeDepth)
|
variableManager.addVariable(identifier.text, allocVar, scopeDepth)
|
||||||
copyVariable(assignExpression, allocVar)
|
copyVariable(assignExpression, allocVar)
|
||||||
}
|
}
|
||||||
is LLVMConstant -> {
|
is LLVMConstant -> {
|
||||||
val newVar = variableManager.receiveVariable(identifier!!.text, assignExpression.type!!, LLVMLocalScope(), pointer = 1)
|
val newVar = variableManager.receiveVariable(identifier!!.text, assignExpression.type!!, LLVMRegisterScope(), pointer = 1)
|
||||||
|
|
||||||
codeBuilder.addConstant(newVar, assignExpression)
|
codeBuilder.addConstant(newVar, assignExpression)
|
||||||
variableManager.addVariable(identifier.text, newVar, scopeDepth)
|
variableManager.addVariable(identifier.text, newVar, scopeDepth)
|
||||||
@@ -454,7 +465,7 @@ class FunctionCodegen(val state: TranslationState, val function: KtNamedFunction
|
|||||||
val dst = codeBuilder.bitcast(returnType, LLVMCharType())
|
val dst = codeBuilder.bitcast(returnType, LLVMCharType())
|
||||||
val size = state.classes[(retVar.type as LLVMReferenceType).type]!!.size
|
val size = state.classes[(retVar.type as LLVMReferenceType).type]!!.size
|
||||||
codeBuilder.memcpy(dst, src, size)
|
codeBuilder.memcpy(dst, src, size)
|
||||||
codeBuilder.addVoidReturn()
|
codeBuilder.addAnyReturn(LLVMVoidType())
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
val retNativeValue = codeBuilder.receiveNativeValue(retVar)
|
val retNativeValue = codeBuilder.receiveNativeValue(retVar)
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import org.jetbrains.kotlin.js.descriptorUtils.nameIfStandardType
|
|||||||
import org.jetbrains.kotlin.psi.KtProperty
|
import org.jetbrains.kotlin.psi.KtProperty
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
import org.kotlinnative.translator.llvm.LLVMBuilder
|
import org.kotlinnative.translator.llvm.LLVMBuilder
|
||||||
import org.kotlinnative.translator.llvm.LLVMGlobalScope
|
import org.kotlinnative.translator.llvm.LLVMVariableScope
|
||||||
import org.kotlinnative.translator.llvm.LLVMMapStandardType
|
import org.kotlinnative.translator.llvm.LLVMMapStandardType
|
||||||
import org.kotlinnative.translator.llvm.LLVMVariable
|
import org.kotlinnative.translator.llvm.LLVMVariable
|
||||||
|
|
||||||
@@ -19,7 +19,7 @@ class PropertyCodegen(val state: TranslationState, val property: KtProperty, val
|
|||||||
val value = varInfo.value
|
val value = varInfo.value
|
||||||
if (kotlinType.nameIfStandardType != null) {
|
if (kotlinType.nameIfStandardType != null) {
|
||||||
val variableType = LLVMMapStandardType(property.name ?: return, kotlinType).type
|
val variableType = LLVMMapStandardType(property.name ?: return, kotlinType).type
|
||||||
val variable = LLVMVariable(property.name.toString(), variableType, property.name.toString(), LLVMGlobalScope(), pointer = 1)
|
val variable = LLVMVariable(property.name.toString(), variableType, property.name.toString(), LLVMVariableScope(), pointer = 1)
|
||||||
variableManager.addGlobalVariable(property.name.toString(), variable)
|
variableManager.addGlobalVariable(property.name.toString(), variable)
|
||||||
codeBuilder.declareGlobalVariable(variable, variableType.parseArg(value.toString()))
|
codeBuilder.declareGlobalVariable(variable, variableType.parseArg(value.toString()))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,10 +28,10 @@ class LLVMBuilder(val arm: Boolean) {
|
|||||||
|
|
||||||
fun getNewVariable(type: LLVMType, pointer: Int = 0, kotlinName: String? = null): LLVMVariable {
|
fun getNewVariable(type: LLVMType, pointer: Int = 0, kotlinName: String? = null): LLVMVariable {
|
||||||
variableCount++
|
variableCount++
|
||||||
return LLVMVariable("var$variableCount", type, kotlinName, LLVMLocalScope(), pointer)
|
return LLVMVariable("var$variableCount", type, kotlinName, LLVMRegisterScope(), pointer)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getNewLabel(scope: LLVMScope = LLVMLocalScope(), prefix: String): LLVMLabel {
|
fun getNewLabel(scope: LLVMScope = LLVMRegisterScope(), prefix: String): LLVMLabel {
|
||||||
labelCount++
|
labelCount++
|
||||||
return LLVMLabel("label.$prefix.$labelCount", scope)
|
return LLVMLabel("label.$prefix.$labelCount", scope)
|
||||||
}
|
}
|
||||||
@@ -93,11 +93,7 @@ class LLVMBuilder(val arm: Boolean) {
|
|||||||
llvmLocalCode.appendln("ret ${llvmVariable.type} $llvmVariable")
|
llvmLocalCode.appendln("ret ${llvmVariable.type} $llvmVariable")
|
||||||
}
|
}
|
||||||
|
|
||||||
fun addVoidReturn() {
|
fun addAnyReturn(type: LLVMType, value: String = type.defaultValue) {
|
||||||
llvmLocalCode.appendln("ret void")
|
|
||||||
}
|
|
||||||
|
|
||||||
fun addAnyReturn(type: LLVMType, value: String = type.defaultValue){
|
|
||||||
llvmLocalCode.appendln("ret $type $value")
|
llvmLocalCode.appendln("ret $type $value")
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -144,7 +140,7 @@ class LLVMBuilder(val arm: Boolean) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun loadArgument(llvmVariable: LLVMVariable, store: Boolean = true): LLVMVariable {
|
fun loadArgument(llvmVariable: LLVMVariable, store: Boolean = true): LLVMVariable {
|
||||||
val allocVar = LLVMVariable("${llvmVariable.label}.addr", llvmVariable.type, llvmVariable.kotlinName, LLVMLocalScope(), pointer = 1)
|
val allocVar = LLVMVariable("${llvmVariable.label}.addr", llvmVariable.type, llvmVariable.kotlinName, LLVMRegisterScope(), pointer = 1)
|
||||||
addVariableByRef(allocVar, llvmVariable, store)
|
addVariableByRef(allocVar, llvmVariable, store)
|
||||||
return allocVar
|
return allocVar
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,11 +2,11 @@ package org.kotlinnative.translator.llvm
|
|||||||
|
|
||||||
open class LLVMScope
|
open class LLVMScope
|
||||||
|
|
||||||
class LLVMGlobalScope : LLVMScope() {
|
class LLVMVariableScope : LLVMScope() {
|
||||||
override fun toString() = "@"
|
override fun toString() = "@"
|
||||||
}
|
}
|
||||||
|
|
||||||
class LLVMLocalScope : LLVMScope() {
|
class LLVMRegisterScope : LLVMScope() {
|
||||||
override fun toString() = "%"
|
override fun toString() = "%"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ package org.kotlinnative.translator.llvm
|
|||||||
|
|
||||||
import org.kotlinnative.translator.llvm.types.LLVMType
|
import org.kotlinnative.translator.llvm.types.LLVMType
|
||||||
|
|
||||||
open class LLVMVariable(val label: String, override val type: LLVMType, var kotlinName: String? = null, val scope: LLVMScope = LLVMLocalScope(), override var pointer: Int = 0) : LLVMSingleValue() {
|
open class LLVMVariable(val label: String, override val type: LLVMType, var kotlinName: String? = null, val scope: LLVMScope = LLVMRegisterScope(), override var pointer: Int = 0) : LLVMSingleValue() {
|
||||||
|
|
||||||
override fun getType(): String = type.toString() + "*".repeat(pointer)
|
override fun getType(): String = type.toString() + "*".repeat(pointer)
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ fun LLVMFunctionDescriptor(name: String, argTypes: List<LLVMVariable>?, returnTy
|
|||||||
"${s.getType()} ${if (s.type is LLVMReferenceType && !(s.type as LLVMReferenceType).isReturn) "byval" else ""} %${s.label}"
|
"${s.getType()} ${if (s.type is LLVMReferenceType && !(s.type as LLVMReferenceType).isReturn) "byval" else ""} %${s.label}"
|
||||||
}?.joinToString()}) ${if (arm) "#0" else ""}"
|
}?.joinToString()}) ${if (arm) "#0" else ""}"
|
||||||
|
|
||||||
fun LLVMMapStandardType(name: String, type: KotlinType, scope: LLVMScope = LLVMLocalScope()): LLVMVariable = when {
|
fun LLVMMapStandardType(name: String, type: KotlinType, scope: LLVMScope = LLVMRegisterScope()): LLVMVariable = when {
|
||||||
type.isFunctionTypeOrSubtype -> LLVMVariable(name, LLVMFunctionType(type), type.toString(), scope, pointer = 1)
|
type.isFunctionTypeOrSubtype -> LLVMVariable(name, LLVMFunctionType(type), type.toString(), scope, pointer = 1)
|
||||||
type.toString() == "Int" -> LLVMVariable(name, LLVMIntType(), type.toString(), scope)
|
type.toString() == "Int" -> LLVMVariable(name, LLVMIntType(), type.toString(), scope)
|
||||||
type.toString() == "Double" -> LLVMVariable(name, LLVMDoubleType(), type.toString(), scope)
|
type.toString() == "Double" -> LLVMVariable(name, LLVMDoubleType(), type.toString(), scope)
|
||||||
|
|||||||
Reference in New Issue
Block a user