Allow entry points without args: Array<String> (#2049)
This commit is contained in:
committed by
Nikolay Igotti
parent
b6a01a86f1
commit
30f5eb0bfa
+13
-6
@@ -36,16 +36,21 @@ internal fun findMainEntryPoint(context: Context): FunctionDescriptor? {
|
|||||||
|
|
||||||
val packageScope = context.builtIns.builtInsModule.getPackage(packageName).memberScope
|
val packageScope = context.builtIns.builtInsModule.getPackage(packageName).memberScope
|
||||||
|
|
||||||
val main = packageScope.getContributedFunctions(entryName,
|
val candidates = packageScope.getContributedFunctions(entryName,
|
||||||
NoLookupLocation.FROM_BACKEND).singleOrNull {
|
NoLookupLocation.FROM_BACKEND).filter {
|
||||||
it.returnType?.isUnit() == true &&
|
it.returnType?.isUnit() == true &&
|
||||||
it.hasSingleArrayOfStringParameter &&
|
|
||||||
it.typeParameters.isEmpty() &&
|
it.typeParameters.isEmpty() &&
|
||||||
it.visibility.isPublicAPI
|
it.visibility.isPublicAPI
|
||||||
}
|
}
|
||||||
if (main == null) {
|
|
||||||
context.reportCompilationError("Could not find '$entryName' in '$packageName' package.")
|
val main =
|
||||||
}
|
candidates.singleOrNull { it.hasSingleArrayOfStringParameter } ?:
|
||||||
|
candidates.singleOrNull { it.hasNoParameters } ?:
|
||||||
|
run {
|
||||||
|
context.reportCompilationError("Could not find '$entryName' in '$packageName' package.")
|
||||||
|
null
|
||||||
|
}
|
||||||
|
|
||||||
return main
|
return main
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -73,3 +78,5 @@ private val KotlinType.isArrayOfString: Boolean
|
|||||||
private val FunctionDescriptor.hasSingleArrayOfStringParameter: Boolean
|
private val FunctionDescriptor.hasSingleArrayOfStringParameter: Boolean
|
||||||
get() = valueParameters.singleOrNull()?.type?.isArrayOfString ?: false
|
get() = valueParameters.singleOrNull()?.type?.isArrayOfString ?: false
|
||||||
|
|
||||||
|
private val FunctionDescriptor.hasNoParameters: Boolean
|
||||||
|
get() = valueParameters.isEmpty()
|
||||||
|
|||||||
+10
-5
@@ -2618,9 +2618,9 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map<IrE
|
|||||||
//-------------------------------------------------------------------------//
|
//-------------------------------------------------------------------------//
|
||||||
|
|
||||||
private fun entryPointSelector(entryPoint: LLVMValueRef,
|
private fun entryPointSelector(entryPoint: LLVMValueRef,
|
||||||
entryPointType: LLVMTypeRef, selectorName: String): LLVMValueRef {
|
entryPointType: LLVMTypeRef, selectorName: String, argCount: Int): LLVMValueRef {
|
||||||
|
|
||||||
assert(LLVMCountParams(entryPoint) == 1)
|
assert(LLVMCountParams(entryPoint) <= 1)
|
||||||
|
|
||||||
val selector = LLVMAddFunction(context.llvmModule, selectorName, entryPointType)!!
|
val selector = LLVMAddFunction(context.llvmModule, selectorName, entryPointType)!!
|
||||||
generateFunction(codegen, selector) {
|
generateFunction(codegen, selector) {
|
||||||
@@ -2629,8 +2629,11 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map<IrE
|
|||||||
// scheme for arguments guarantees, that reference is being held in C++
|
// scheme for arguments guarantees, that reference is being held in C++
|
||||||
// launcher, so we could optimize out creating slot for 'parameter' in
|
// launcher, so we could optimize out creating slot for 'parameter' in
|
||||||
// this function.
|
// this function.
|
||||||
val parameter = LLVMGetParam(selector, 0)!!
|
val parameters = if (argCount == 1)
|
||||||
call(entryPoint, listOf(parameter), Lifetime.IRRELEVANT, ExceptionHandler.Caller)
|
listOf(LLVMGetParam(selector, 0)!!)
|
||||||
|
else
|
||||||
|
emptyList()
|
||||||
|
call(entryPoint, parameters, Lifetime.IRRELEVANT, ExceptionHandler.Caller)
|
||||||
ret(null)
|
ret(null)
|
||||||
}
|
}
|
||||||
return selector
|
return selector
|
||||||
@@ -2644,8 +2647,10 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map<IrE
|
|||||||
val entryPoint = codegen.llvmFunction(descriptor)
|
val entryPoint = codegen.llvmFunction(descriptor)
|
||||||
val selectorName = "EntryPointSelector"
|
val selectorName = "EntryPointSelector"
|
||||||
val entryPointType = getFunctionType(entryPoint)
|
val entryPointType = getFunctionType(entryPoint)
|
||||||
|
val argCount = descriptor.valueParameters.size
|
||||||
|
assert(argCount <= 1)
|
||||||
|
|
||||||
val selector = entryPointSelector(entryPoint, entryPointType, selectorName)
|
val selector = entryPointSelector(entryPoint, entryPointType, selectorName, argCount)
|
||||||
|
|
||||||
LLVMSetLinkage(selector, LLVMLinkage.LLVMExternalLinkage)
|
LLVMSetLinkage(selector, LLVMLinkage.LLVMExternalLinkage)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -546,6 +546,17 @@ task entry2(type: LinkKonanTest) {
|
|||||||
flags = ["-entry", "foo"]
|
flags = ["-entry", "foo"]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
task entry3(type: RunStandaloneKonanTest) {
|
||||||
|
goldValue = "Hello, without args.\n"
|
||||||
|
source = "runtime/basic/entry1.kt"
|
||||||
|
flags = ["-entry", "bar"]
|
||||||
|
}
|
||||||
|
|
||||||
|
task entry4(type: RunStandaloneKonanTest) {
|
||||||
|
goldValue = "This is main without args\n"
|
||||||
|
source = "runtime/basic/entry4.kt"
|
||||||
|
}
|
||||||
|
|
||||||
task readline0(type: RunStandaloneKonanTest) {
|
task readline0(type: RunStandaloneKonanTest) {
|
||||||
goldValue = "41"
|
goldValue = "41"
|
||||||
testData = "41\r\n"
|
testData = "41\r\n"
|
||||||
|
|||||||
@@ -11,6 +11,10 @@ fun foo(args: Array<String>) {
|
|||||||
println("Hello.")
|
println("Hello.")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun bar() {
|
||||||
|
println("Hello, without args.")
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
fun main(args: Array<String>) {
|
fun main(args: Array<String>) {
|
||||||
fail()
|
fail()
|
||||||
|
|||||||
@@ -0,0 +1,3 @@
|
|||||||
|
fun main() {
|
||||||
|
println("This is main without args")
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user