PlatformStaticGenerator reworked to use FunctionCodegen.generateMethod()

This commit is contained in:
Andrey Breslav
2014-12-11 19:16:05 +03:00
parent 6916c0f5cc
commit f9fea88749
9 changed files with 95 additions and 57 deletions
@@ -173,7 +173,7 @@ public class AsmUtil {
public static boolean isStaticMethod(OwnerKind kind, CallableMemberDescriptor functionDescriptor) {
return isStaticKind(kind) ||
JetTypeMapper.isAccessor(functionDescriptor) ||
AnnotationsPackage.isPlatformStaticInObject(functionDescriptor);
AnnotationsPackage.isPlatformStaticInObjectOrClass(functionDescriptor);
}
public static boolean isStaticKind(OwnerKind kind) {
@@ -2419,7 +2419,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
if (isSingleton) {
if (context.hasThisDescriptor() &&
context.getThisDescriptor().equals(calleeContainingClass) &&
!AnnotationsPackage.isPlatformStaticInObject(context.getContextDescriptor())) {
!AnnotationsPackage.isPlatformStaticInObjectOrClass(context.getContextDescriptor())) {
return StackValue.local(0, typeMapper.mapType(calleeContainingClass));
}
else {
@@ -17,12 +17,18 @@
package org.jetbrains.jet.codegen
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor
import org.jetbrains.org.objectweb.asm.Opcodes
import org.jetbrains.jet.codegen.state.GenerationState
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
import org.jetbrains.jet.lang.descriptors.ClassDescriptor
import org.jetbrains.jet.lang.resolve.java.diagnostics.JvmDeclarationOrigin
import org.jetbrains.jet.lang.resolve.java.diagnostics.Synthetic
import org.jetbrains.jet.lang.descriptors.CallableMemberDescriptor
import org.jetbrains.org.objectweb.asm.MethodVisitor
import org.jetbrains.jet.lang.resolve.java.jvmSignature.JvmMethodSignature
import org.jetbrains.jet.codegen.context.MethodContext
import org.jetbrains.jet.lang.psi.JetElement
import org.jetbrains.jet.backend.common.CodegenUtil
import org.jetbrains.jet.lang.descriptors.PropertyAccessorDescriptor
class PlatformStaticGenerator(
val descriptor: FunctionDescriptor,
@@ -31,39 +37,54 @@ class PlatformStaticGenerator(
) : Function2<ImplementationBodyCodegen, ClassBuilder, Unit> {
override fun invoke(codegen: ImplementationBodyCodegen, classBuilder: ClassBuilder) {
val typeMapper = state.getTypeMapper()
val asmMethod = typeMapper.mapSignature(descriptor).getAsmMethod()
val flags = Opcodes.ACC_STATIC or AsmUtil.getMethodAsmFlags(descriptor, OwnerKind.IMPLEMENTATION)
val methodVisitor = classBuilder.newMethod(
Synthetic(declarationOrigin.element, descriptor),
flags,
asmMethod.getName()!!,
asmMethod.getDescriptor()!!,
typeMapper.mapSignature(descriptor).getGenericsSignature(),
FunctionCodegen.getThrownExceptions(descriptor, typeMapper))
val memberDescriptor = if (descriptor is PropertyAccessorDescriptor) descriptor.getCorrespondingProperty() else descriptor
val copies = CodegenUtil.copyFunctions(
memberDescriptor,
memberDescriptor,
declarationOrigin.descriptor?.getContainingDeclaration()?.getContainingDeclaration(),
descriptor.getModality(),
descriptor.getVisibility(),
CallableMemberDescriptor.Kind.SYNTHESIZED,
false
)
val staticFunctionDescriptor = copies[descriptor]!!
AnnotationCodegen.forMethod(methodVisitor, typeMapper)!!.genAnnotations(descriptor, asmMethod.getReturnType())
val jvmMethodSignature = state.getTypeMapper().mapSignature(staticFunctionDescriptor)
if (state.getClassBuilderMode() == ClassBuilderMode.FULL && flags and Opcodes.ACC_NATIVE == 0) {
methodVisitor.visitCode();
val iv = InstructionAdapter(methodVisitor)
val classDescriptor = descriptor.getContainingDeclaration() as ClassDescriptor
val singletonValue = StackValue.singleton(classDescriptor, typeMapper)!!
singletonValue.put(singletonValue.type, iv);
var index = 0;
for (paramType in asmMethod.getArgumentTypes()) {
iv.load(index, paramType);
index += paramType.getSize();
}
codegen.functionCodegen.generateMethod(
Synthetic(declarationOrigin.element, staticFunctionDescriptor),
jvmMethodSignature,
staticFunctionDescriptor,
object: FunctionGenerationStrategy() {
override fun generateBody(
mv: MethodVisitor,
frameMap: FrameMap,
signature: JvmMethodSignature,
context: MethodContext,
parentCodegen: MemberCodegen<out JetElement>
) {
val typeMapper = parentCodegen.typeMapper
val syntheticOrOriginalMethod = typeMapper.mapToCallableMethod(
codegen.getContext().accessibleFunctionDescriptor(descriptor),
false,
codegen.getContext()
)
syntheticOrOriginalMethod.invokeWithoutAssertions(iv)
iv.areturn(asmMethod.getReturnType());
methodVisitor.visitEnd();
}
val iv = InstructionAdapter(mv)
val classDescriptor = descriptor.getContainingDeclaration() as ClassDescriptor
val singletonValue = StackValue.singleton(classDescriptor, typeMapper)
singletonValue.put(singletonValue.type, iv);
var index = 0;
val asmMethod = signature.getAsmMethod()
for (paramType in asmMethod.getArgumentTypes()) {
iv.load(index, paramType);
index += paramType.getSize();
}
val syntheticOrOriginalMethod = typeMapper.mapToCallableMethod(
codegen.getContext().accessibleFunctionDescriptor(descriptor),
false,
codegen.getContext()
)
syntheticOrOriginalMethod.invokeWithoutAssertions(iv)
iv.areturn(asmMethod.getReturnType());
}
}
)
}
}
@@ -480,7 +480,7 @@ public abstract class StackValue {
}
private static StackValue platformStaticCallIfPresent(@NotNull StackValue resultReceiver, @NotNull CallableDescriptor descriptor) {
if (AnnotationsPackage.isPlatformStaticInObject(descriptor)) {
if (AnnotationsPackage.isPlatformStaticInObjectOrClass(descriptor)) {
if (resultReceiver.canHaveSideEffects()) {
return coercion(resultReceiver, Type.VOID_TYPE);
}
@@ -1414,7 +1414,7 @@ public abstract class StackValue {
return callableMethod != null ? callableMethod.getReceiverClass() : typeMapper.mapType(extensionReceiver.getType());
}
else if (dispatchReceiver != null) {
if (AnnotationsPackage.isPlatformStaticInObject(descriptor)) {
if (AnnotationsPackage.isPlatformStaticInObjectOrClass(descriptor)) {
return Type.VOID_TYPE;
}
else {
@@ -488,7 +488,7 @@ public class JetTypeMapper {
else {
if (isStaticDeclaration(functionDescriptor) ||
isAccessor(functionDescriptor) ||
AnnotationsPackage.isPlatformStaticInObject(functionDescriptor)) {
AnnotationsPackage.isPlatformStaticInObjectOrClass(functionDescriptor)) {
invokeOpcode = INVOKESTATIC;
}
else if (isInterface) {