Use FunctionImplN instead of FunctionN in codegen

Superclass of closures should now be FunctionImplN instead of FunctionN. Since
these -Impl classes are needed only in JVM, the corresponding descriptors and
types are created in the back-end only.
This commit is contained in:
Alexander Udalov
2013-03-21 20:39:01 +04:00
parent 6f6cb03549
commit 974df0ed8e
7 changed files with 58 additions and 14 deletions
@@ -126,10 +126,10 @@ public class CodegenUtil {
public static JvmClassName getInternalClassName(FunctionDescriptor descriptor) {
int paramCount = descriptor.getValueParameters().size();
if (descriptor.getReceiverParameter() != null) {
return JvmClassName.byInternalName("jet/ExtensionFunction" + paramCount);
return JvmClassName.byInternalName("jet/ExtensionFunctionImpl" + paramCount);
}
else {
return JvmClassName.byInternalName("jet/Function" + paramCount);
return JvmClassName.byInternalName("jet/FunctionImpl" + paramCount);
}
}
@@ -3122,7 +3122,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
v.dup2();
v.load(indexIndex, Type.INT_TYPE);
v.invokestatic("java/lang/Integer", "valueOf", "(I)Ljava/lang/Integer;");
v.invokevirtual("jet/Function1", "invoke", "(Ljava/lang/Object;)Ljava/lang/Object;");
v.invokeinterface("jet/Function1", "invoke", "(Ljava/lang/Object;)Ljava/lang/Object;");
v.load(indexIndex, Type.INT_TYPE);
v.iinc(indexIndex, 1);
v.swap();
@@ -22,6 +22,7 @@ import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
import org.jetbrains.jet.lang.descriptors.impl.ClassDescriptorImpl;
import org.jetbrains.jet.lang.descriptors.impl.MutableClassDescriptor;
import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.BindingTrace;
@@ -33,11 +34,10 @@ import org.jetbrains.jet.lang.resolve.java.PackageClassUtils;
import org.jetbrains.jet.lang.resolve.name.FqName;
import org.jetbrains.jet.lang.resolve.name.Name;
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.*;
import static org.jetbrains.jet.codegen.CodegenUtil.peekFromStack;
import static org.jetbrains.jet.codegen.binding.CodegenBinding.*;
@@ -56,6 +56,42 @@ class CodegenAnnotatingVisitor extends JetVisitorVoid {
this.bindingContext = bindingTrace.getBindingContext();
}
private static final List<ClassDescriptor> FUNCTIONS;
private static final List<ClassDescriptor> EXTENSION_FUNCTIONS;
static {
int n = KotlinBuiltIns.FUNCTION_TRAIT_COUNT;
FUNCTIONS = new ArrayList<ClassDescriptor>(n);
EXTENSION_FUNCTIONS = new ArrayList<ClassDescriptor>(n);
KotlinBuiltIns builtIns = KotlinBuiltIns.getInstance();
for (int i = 0; i < n; i++) {
Name functionImpl = Name.identifier("FunctionImpl" + i);
FUNCTIONS.add(createFunctionImplDescriptor(functionImpl, builtIns.getFunction(i)));
Name extensionFunctionImpl = Name.identifier("ExtensionFunctionImpl" + i);
EXTENSION_FUNCTIONS.add(createFunctionImplDescriptor(extensionFunctionImpl, builtIns.getExtensionFunction(i)));
}
}
private static ClassDescriptor createFunctionImplDescriptor(Name name, ClassDescriptor functionInterface) {
JetScope builtInsScope = KotlinBuiltIns.getInstance().getBuiltInsScope();
MutableClassDescriptor functionImpl = new MutableClassDescriptor(
builtInsScope.getContainingDeclaration(),
builtInsScope,
ClassKind.CLASS,
false,
name
);
functionImpl.setModality(Modality.FINAL);
functionImpl.setVisibility(Visibilities.PUBLIC);
functionImpl.setTypeParameterDescriptors(functionInterface.getDefaultType().getConstructor().getParameters());
functionImpl.createTypeConstructor();
return functionImpl;
}
@Override
public void visitCallExpression(JetCallExpression expression) {
super.visitCallExpression(expression);
@@ -92,9 +128,8 @@ class CodegenAnnotatingVisitor extends JetVisitorVoid {
((ClassDescriptorImpl)classDescriptor).initialize(
false,
Collections.<TypeParameterDescriptor>emptyList(),
Collections.singleton((funDescriptor.getReceiverParameter() != null
? KotlinBuiltIns.getInstance().getExtensionFunction(arity)
: KotlinBuiltIns.getInstance().getFunction(arity)).getDefaultType()), JetScope.EMPTY,
Collections.singleton(getSuperTypeForClosure(funDescriptor, arity)),
JetScope.EMPTY,
Collections.<ConstructorDescriptor>emptySet(),
null,
false);
@@ -104,6 +139,15 @@ class CodegenAnnotatingVisitor extends JetVisitorVoid {
return classDescriptor;
}
private JetType getSuperTypeForClosure(FunctionDescriptor funDescriptor, int arity) {
if (funDescriptor.getReceiverParameter() != null) {
return EXTENSION_FUNCTIONS.get(arity).getDefaultType();
}
else {
return FUNCTIONS.get(arity).getDefaultType();
}
}
private String inventAnonymousClassName(JetElement declaration) {
String top = peekFromStack(nameStack);
Integer cnt = anonymousSubclassesCount.get(top);
@@ -80,7 +80,7 @@ public class KotlinBuiltIns {
BUILT_INS_DIR + "/Unit.jet"
);
private static final int FUNCTION_TRAIT_COUNT = 23;
public static final int FUNCTION_TRAIT_COUNT = 23;
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -1,9 +1,9 @@
class Works() : jet.Function0<Object>() {
class Works() : jet.Function0<Object> {
public override fun invoke():Object {
return "Works" as Object
}
}
class Broken() : jet.Function0<String>() {
class Broken() : jet.Function0<String> {
public override fun invoke():String {
return "Broken"
}
@@ -7,7 +7,7 @@ val getter: String
fun f() = { "OK" }()
val obj = object : Function0<String>() {
val obj = object : Function0<String> {
override fun invoke() = "OK"
}
@@ -5,7 +5,7 @@ val getter: String
fun f() = { "OK" }()
val obj = object : Function0<String>() {
val obj = object : Function0<String> {
override fun invoke() = "OK"
}