Default args support

This commit is contained in:
Michael Bogdanov
2016-09-23 15:01:06 +03:00
committed by Dmitry Petrov
parent bf822daa3b
commit 58ba5ed37b
2 changed files with 38 additions and 10 deletions
@@ -18,6 +18,7 @@ package org.jetbrains.kotlin.codegen
import org.jetbrains.kotlin.resolve.jvm.AsmTypes
import org.jetbrains.org.objectweb.asm.Type
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
import java.util.*
class DefaultCallArgs(val size: Int) {
@@ -63,4 +64,17 @@ class DefaultCallArgs(val size: Int) {
}
return toInts.isNotEmpty()
}
fun generateOnStackIfNeeded(iv: InstructionAdapter, isConstructor: Boolean): Boolean {
val toInts = toInts()
if (!toInts.isEmpty()) {
for (mask in toInts) {
iv.iconst(mask)
}
val parameterType = if (isConstructor) AsmTypes.DEFAULT_CONSTRUCTOR_MARKER else AsmTypes.OBJECT_TYPE
iv.aconst(null)
}
return toInts.isNotEmpty()
}
}
@@ -20,8 +20,7 @@ import org.jetbrains.kotlin.backend.jvm.intrinsics.IrIntrinsicFunction
import org.jetbrains.kotlin.backend.jvm.intrinsics.IrIntrinsicMethods
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.codegen.*
import org.jetbrains.kotlin.codegen.AsmUtil.boxType
import org.jetbrains.kotlin.codegen.AsmUtil.correctElementType
import org.jetbrains.kotlin.codegen.AsmUtil.*
import org.jetbrains.kotlin.codegen.StackValue.*
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.ir.IrElement
@@ -158,19 +157,33 @@ class ExpressionCodegen(
receiver?.apply {
gen(receiver, callable.owner, data)
}
val args = (listOf(expression.extensionReceiver) +
val args = (listOf(expression.extensionReceiver).filterNotNull() +
expression.descriptor.valueParameters.mapIndexed { i, valueParameterDescriptor ->
expression.getValueArgument(i)
}).filterNotNull()
expression.getValueArgument(i) ?: DefaultArg(i)
})
val defaultMask = DefaultCallArgs(callable.valueParameterTypes.size)
args.forEachIndexed { i, expression ->
gen(expression, callable.parameterTypes[i], data)
when (expression) {
is IrExpression -> {
gen(expression, callable.parameterTypes[i], data)
}
is DefaultArg -> {
pushDefaultValueOnStack(callable.parameterTypes[i], mv)
defaultMask.mark(expression.index)
}
else -> TODO()
}
}
callable.genInvokeInstruction(mv)
if (!defaultMask.generateOnStackIfNeeded(mv, expression.descriptor is ConstructorDescriptor)) {
callable.genInvokeInstruction(mv)
} else {
(callable as CallableMethod).genInvokeDefaultInstruction(mv)
}
return StackValue.onStack(callable.returnType)
// if (expression.descriptor !is ConstructorDescriptor) {
// //coerce(callable.returnType, expression.asmType, mv)
// }
}
return expression.onStack
@@ -421,3 +434,4 @@ class ExpressionCodegen(
get() = typeMapper.mapType(this)
}
private class DefaultArg(val index: Int)