translator: add ability specify entry point, optimize external function detector
This commit is contained in:
@@ -21,9 +21,17 @@ class DefaultArguments(raw: RawArguments) : Arguments(raw, name = "default") {
|
||||
shortNames = listOf('o')
|
||||
)
|
||||
|
||||
val mainClass = optionalParameter(
|
||||
name = "main class",
|
||||
aliasNames = listOf("main"),
|
||||
default = "main",
|
||||
shortNames = listOf('M')
|
||||
)
|
||||
|
||||
val sources = positionalArguments(
|
||||
name = "sources",
|
||||
description = "source files",
|
||||
minCount = 1
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -20,7 +20,7 @@ fun main(args: Array<String>) {
|
||||
|
||||
analyzedFiles.addAll(arguments.sources)
|
||||
|
||||
val state = parseAndAnalyze(analyzedFiles, disposer, arguments.arm ?: false)
|
||||
val state = parseAndAnalyze(analyzedFiles, disposer, arguments.mainClass, arguments.arm ?: false)
|
||||
val files = state.environment.getSourceFiles()
|
||||
val code = ProjectTranslator(files, state).generateCode()
|
||||
|
||||
|
||||
@@ -44,23 +44,18 @@ class FunctionCodegen(state: TranslationState,
|
||||
if (returnType!!.type is LLVMReferenceType) {
|
||||
returnType!!.pointer = 2
|
||||
}
|
||||
external = isExternal()
|
||||
name = "${function.fqName}${if (args.size > 0 && !external) LLVMType.mangleFunctionArguments(args) else ""}"
|
||||
val pureName = name.substringAfterLast('.')
|
||||
if (pureName == "main") {
|
||||
state.mainFunctions.add(name)
|
||||
}
|
||||
external = descriptor.isExternal
|
||||
name = "${function.fqName}${if (!external) LLVMType.mangleFunctionArguments(args) else ""}"
|
||||
|
||||
if (isExtensionDeclaration) {
|
||||
name = "${function.name}${if (args.size > 0 && !external) LLVMType.mangleFunctionArguments(args) else ""}"
|
||||
val receiverType = descriptor.extensionReceiverParameter!!.type
|
||||
val translatorType = LLVMMapStandardType(receiverType, state)
|
||||
val packageName = (function.containingFile as KtFile).packageFqName.asString()
|
||||
functionNamePrefix += if (packageName.length > 0) "$packageName." else ""
|
||||
functionNamePrefix += translatorType.mangle() + "."
|
||||
functionNamePrefix = packageName.addAfterIfNotEmpty(".") + translatorType.mangle() + "."
|
||||
|
||||
val extensionFunctionsOfThisType = state.extensionFunctions.getOrDefault(translatorType.toString(), HashMap())
|
||||
extensionFunctionsOfThisType.put(functionNamePrefix + name, this)
|
||||
extensionFunctionsOfThisType.put(fullName, this)
|
||||
state.extensionFunctions.put(translatorType.toString(), extensionFunctionsOfThisType)
|
||||
}
|
||||
|
||||
@@ -150,7 +145,7 @@ class FunctionCodegen(state: TranslationState,
|
||||
}
|
||||
|
||||
if (it.type !is LLVMReferenceType || (it.type as LLVMReferenceType).byRef) {
|
||||
val loadVariable = LLVMVariable("${it.label}", it.type, it.label, LLVMRegisterScope(), pointer = it.pointer)
|
||||
val loadVariable = LLVMVariable(it.label, it.type, it.label, LLVMRegisterScope(), pointer = it.pointer)
|
||||
val allocVar = codeBuilder.loadArgument(loadVariable)
|
||||
variableManager.addVariable(it.label, allocVar, topLevel)
|
||||
} else {
|
||||
@@ -159,16 +154,4 @@ class FunctionCodegen(state: TranslationState,
|
||||
})
|
||||
}
|
||||
|
||||
private fun isExternal(): Boolean {
|
||||
var keyword = function.firstChild
|
||||
while (keyword != null) {
|
||||
if (keyword.text == "external") {
|
||||
return true
|
||||
}
|
||||
|
||||
keyword = keyword.getNextSiblingIgnoringWhitespaceAndComments()
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
}
|
||||
@@ -63,8 +63,8 @@ class ProjectTranslator(val files: List<KtFile>, val state: TranslationState) {
|
||||
functions.values.filter { !it.isExtensionDeclaration }.map { it.generate() }
|
||||
}
|
||||
|
||||
if (!state.mainFunctions.contains("main") && state.mainFunctions.isNotEmpty()) {
|
||||
codeBuilder.declareEntryPoint(state.mainFunctions.first())
|
||||
if (state.mainFunction != "main") {
|
||||
codeBuilder.declareEntryPoint(state.mainFunction)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -39,13 +39,9 @@ abstract class StructCodegen(val state: TranslationState,
|
||||
open fun prepareForGenerate() {
|
||||
generateStruct()
|
||||
|
||||
for (declaration in classOrObject.declarations) {
|
||||
when (declaration) {
|
||||
is KtNamedFunction -> {
|
||||
val function = FunctionCodegen(state, variableManager, declaration, codeBuilder, packageName, this)
|
||||
methods.put(function.name, function)
|
||||
}
|
||||
}
|
||||
for (declaration in classOrObject.declarations.filter { it is KtNamedFunction }) {
|
||||
val function = FunctionCodegen(state, variableManager, declaration as KtNamedFunction, codeBuilder, packageName, this)
|
||||
methods.put(function.name, function)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -222,20 +218,15 @@ abstract class StructCodegen(val state: TranslationState,
|
||||
|
||||
val blockCodegen = object : BlockCodegen(state, variableManager, codeBuilder) {}
|
||||
val receiverThis = LLVMVariable("classvariable.this.addr", type, scope = LLVMRegisterScope(), pointer = 1)
|
||||
codeBuilder.addComment("field initializers starts")
|
||||
variableManager.addVariable("this", receiverThis, 2)
|
||||
|
||||
for ((variable, initializer) in initializedFields) {
|
||||
val left = blockCodegen.evaluateMemberMethodOrField(receiverThis, variable.label, blockCodegen.topLevel, call = null)!!
|
||||
codeBuilder.addComment("left expression")
|
||||
val right = blockCodegen.evaluateExpression(initializer, scopeDepth = blockCodegen.topLevel)!!
|
||||
codeBuilder.addComment("right expression")
|
||||
blockCodegen.executeBinaryExpression(KtTokens.EQ, referenceName = null, left = left, right = right)
|
||||
codeBuilder.addComment("next initializer")
|
||||
}
|
||||
|
||||
variableManager.pullOneUpwardLevelVariable("this")
|
||||
codeBuilder.addComment("field initializers ends")
|
||||
}
|
||||
|
||||
private fun generateReturn(src: LLVMVariable) {
|
||||
|
||||
@@ -25,7 +25,7 @@ import org.kotlinnative.translator.llvm.LLVMBuilder
|
||||
import org.kotlinnative.translator.llvm.LLVMVariable
|
||||
import java.util.*
|
||||
|
||||
class TranslationState(val environment: KotlinCoreEnvironment, val bindingContext: BindingContext, arm: Boolean) {
|
||||
class TranslationState(val environment: KotlinCoreEnvironment, val bindingContext: BindingContext, val mainFunction: String, arm: Boolean) {
|
||||
companion object {
|
||||
var pointerAlign = 4
|
||||
var pointerSize = 4
|
||||
@@ -43,12 +43,11 @@ class TranslationState(val environment: KotlinCoreEnvironment, val bindingContex
|
||||
var objects = HashMap<String, ObjectCodegen>()
|
||||
var properties = HashMap<String, PropertyCodegen>()
|
||||
val codeBuilder = LLVMBuilder(arm)
|
||||
val mainFunctions = ArrayList<String>()
|
||||
val extensionFunctions = HashMap<String, HashMap<String, FunctionCodegen>>()
|
||||
|
||||
}
|
||||
|
||||
fun parseAndAnalyze(sources: List<String>, disposer: Disposable, arm: Boolean = false): TranslationState {
|
||||
fun parseAndAnalyze(sources: List<String>, disposer: Disposable, mainFunction: String, arm: Boolean = false): TranslationState {
|
||||
|
||||
val configuration = CompilerConfiguration()
|
||||
val messageCollector = object : MessageCollector {
|
||||
@@ -72,7 +71,7 @@ fun parseAndAnalyze(sources: List<String>, disposer: Disposable, arm: Boolean =
|
||||
val environment = KotlinCoreEnvironment.createForProduction(disposer, configuration, EnvironmentConfigFiles.JVM_CONFIG_FILES)
|
||||
val bindingContext = analyze(environment)?.bindingContext ?: throw TranslationException("Can't initialize binding context for project")
|
||||
|
||||
return TranslationState(environment, bindingContext, arm)
|
||||
return TranslationState(environment, bindingContext, mainFunction, arm)
|
||||
}
|
||||
|
||||
fun analyze(environment: KotlinCoreEnvironment): AnalysisResult? {
|
||||
|
||||
Reference in New Issue
Block a user