From 4ab79533b1952b8d725a0c71d5d65b64d6a35bcc Mon Sep 17 00:00:00 2001 From: Alexey Stepanov Date: Mon, 29 Aug 2016 13:50:01 +0300 Subject: [PATCH] translator: add ability specify entry point, optimize external function detector --- .../src/main/kotlin/DefaultArguments.kt | 10 ++++++- translator/src/main/kotlin/main.kt | 2 +- .../translator/FunctionCodegen.kt | 27 ++++--------------- .../translator/ProjectTranslator.kt | 4 +-- .../kotlinnative/translator/StructCodegen.kt | 15 +++-------- .../translator/TranslationState.kt | 7 +++-- 6 files changed, 23 insertions(+), 42 deletions(-) diff --git a/translator/src/main/kotlin/DefaultArguments.kt b/translator/src/main/kotlin/DefaultArguments.kt index 0422f4947e6..de4f61bc078 100644 --- a/translator/src/main/kotlin/DefaultArguments.kt +++ b/translator/src/main/kotlin/DefaultArguments.kt @@ -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 ) -} + +} \ No newline at end of file diff --git a/translator/src/main/kotlin/main.kt b/translator/src/main/kotlin/main.kt index 4f442700ed0..72d357a13e4 100644 --- a/translator/src/main/kotlin/main.kt +++ b/translator/src/main/kotlin/main.kt @@ -20,7 +20,7 @@ fun main(args: Array) { 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() diff --git a/translator/src/main/kotlin/org/kotlinnative/translator/FunctionCodegen.kt b/translator/src/main/kotlin/org/kotlinnative/translator/FunctionCodegen.kt index b96a09aa614..bf83497d51e 100644 --- a/translator/src/main/kotlin/org/kotlinnative/translator/FunctionCodegen.kt +++ b/translator/src/main/kotlin/org/kotlinnative/translator/FunctionCodegen.kt @@ -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 - } } \ No newline at end of file diff --git a/translator/src/main/kotlin/org/kotlinnative/translator/ProjectTranslator.kt b/translator/src/main/kotlin/org/kotlinnative/translator/ProjectTranslator.kt index 0823191fb57..b442d8d48d3 100644 --- a/translator/src/main/kotlin/org/kotlinnative/translator/ProjectTranslator.kt +++ b/translator/src/main/kotlin/org/kotlinnative/translator/ProjectTranslator.kt @@ -63,8 +63,8 @@ class ProjectTranslator(val files: List, 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) } } diff --git a/translator/src/main/kotlin/org/kotlinnative/translator/StructCodegen.kt b/translator/src/main/kotlin/org/kotlinnative/translator/StructCodegen.kt index 679bb0d40a2..d3412fbbcda 100644 --- a/translator/src/main/kotlin/org/kotlinnative/translator/StructCodegen.kt +++ b/translator/src/main/kotlin/org/kotlinnative/translator/StructCodegen.kt @@ -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) { diff --git a/translator/src/main/kotlin/org/kotlinnative/translator/TranslationState.kt b/translator/src/main/kotlin/org/kotlinnative/translator/TranslationState.kt index f77541233a8..ecb5e117dc9 100644 --- a/translator/src/main/kotlin/org/kotlinnative/translator/TranslationState.kt +++ b/translator/src/main/kotlin/org/kotlinnative/translator/TranslationState.kt @@ -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() var properties = HashMap() val codeBuilder = LLVMBuilder(arm) - val mainFunctions = ArrayList() val extensionFunctions = HashMap>() } -fun parseAndAnalyze(sources: List, disposer: Disposable, arm: Boolean = false): TranslationState { +fun parseAndAnalyze(sources: List, disposer: Disposable, mainFunction: String, arm: Boolean = false): TranslationState { val configuration = CompilerConfiguration() val messageCollector = object : MessageCollector { @@ -72,7 +71,7 @@ fun parseAndAnalyze(sources: List, 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? {