translator: add ability specify entry point, optimize external function detector

This commit is contained in:
Alexey Stepanov
2016-08-29 13:50:01 +03:00
parent ffbb69e051
commit 4ab79533b1
6 changed files with 23 additions and 42 deletions
@@ -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
)
}
}
+1 -1
View File
@@ -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? {