Refactor ExpressionCodegen#invokeMethodWithArguments

- for inlining purposes, take ResolvedCall.getCall() instead of a separate
  parameter
- split into two methods, the other one will be used for a more granular code
  generation of a method call
This commit is contained in:
Alexander Udalov
2014-07-09 23:20:20 +04:00
parent 04b54e9cb7
commit 288bbcae36
2 changed files with 28 additions and 20 deletions
@@ -80,7 +80,8 @@ import static org.jetbrains.jet.lang.psi.PsiPackage.JetPsiFactory;
import static org.jetbrains.jet.lang.resolve.BindingContext.*; import static org.jetbrains.jet.lang.resolve.BindingContext.*;
import static org.jetbrains.jet.lang.resolve.BindingContextUtils.getNotNull; import static org.jetbrains.jet.lang.resolve.BindingContextUtils.getNotNull;
import static org.jetbrains.jet.lang.resolve.BindingContextUtils.isVarCapturedInClosure; import static org.jetbrains.jet.lang.resolve.BindingContextUtils.isVarCapturedInClosure;
import static org.jetbrains.jet.lang.resolve.bindingContextUtil.BindingContextUtilPackage.*; import static org.jetbrains.jet.lang.resolve.bindingContextUtil.BindingContextUtilPackage.getResolvedCall;
import static org.jetbrains.jet.lang.resolve.bindingContextUtil.BindingContextUtilPackage.getResolvedCallWithAssert;
import static org.jetbrains.jet.lang.resolve.java.AsmTypeConstants.*; import static org.jetbrains.jet.lang.resolve.java.AsmTypeConstants.*;
import static org.jetbrains.jet.lang.resolve.java.JvmAnnotationNames.KotlinSyntheticClass; import static org.jetbrains.jet.lang.resolve.java.JvmAnnotationNames.KotlinSyntheticClass;
import static org.jetbrains.jet.lang.resolve.java.diagnostics.DiagnosticsPackage.OtherOrigin; import static org.jetbrains.jet.lang.resolve.java.diagnostics.DiagnosticsPackage.OtherOrigin;
@@ -2049,7 +2050,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
if (callable instanceof CallableMethod) { if (callable instanceof CallableMethod) {
CallableMethod callableMethod = (CallableMethod) callable; CallableMethod callableMethod = (CallableMethod) callable;
invokeMethodWithArguments(call, callableMethod, resolvedCall, receiver); invokeMethodWithArguments(callableMethod, resolvedCall, receiver);
//noinspection ConstantConditions //noinspection ConstantConditions
Type returnType = typeMapper.mapReturnType(resolvedCall.getResultingDescriptor()); Type returnType = typeMapper.mapReturnType(resolvedCall.getResultingDescriptor());
StackValue.coerce(callableMethod.getReturnType(), returnType, v); StackValue.coerce(callableMethod.getReturnType(), returnType, v);
@@ -2112,27 +2113,34 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
} }
public void invokeMethodWithArguments( public void invokeMethodWithArguments(
@Nullable Call call,
@NotNull CallableMethod callableMethod, @NotNull CallableMethod callableMethod,
@NotNull ResolvedCall<?> resolvedCall, @NotNull ResolvedCall<?> resolvedCall,
@NotNull StackValue receiver @NotNull StackValue receiver
) { ) {
CallableDescriptor descriptor = resolvedCall.getResultingDescriptor();
JetElement callElement = call != null ? call.getCallElement() : null;
CallGenerator callGenerator = getOrCreateCallGenerator(descriptor, callElement);
if (resolvedCall instanceof VariableAsFunctionResolvedCall) { if (resolvedCall instanceof VariableAsFunctionResolvedCall) {
resolvedCall = ((VariableAsFunctionResolvedCall) resolvedCall).getFunctionCall(); resolvedCall = ((VariableAsFunctionResolvedCall) resolvedCall).getFunctionCall();
} }
CallableDescriptor descriptor = resolvedCall.getResultingDescriptor();
CallGenerator callGenerator = getOrCreateCallGenerator(descriptor, resolvedCall.getCall().getCallElement());
assert callGenerator == defaultCallGenerator || !tailRecursionCodegen.isTailRecursion(resolvedCall) : assert callGenerator == defaultCallGenerator || !tailRecursionCodegen.isTailRecursion(resolvedCall) :
"Tail recursive method couldn't be inlined " + descriptor; "Tail recursive method can't be inlined: " + descriptor;
ArgumentGenerator argumentGenerator = new CallBasedArgumentGenerator(this, callGenerator, descriptor.getValueParameters(), ArgumentGenerator argumentGenerator = new CallBasedArgumentGenerator(this, callGenerator, descriptor.getValueParameters(),
callableMethod.getValueParameterTypes()); callableMethod.getValueParameterTypes());
if (!(descriptor instanceof ConstructorDescriptor)) { // otherwise already invokeMethodWithArguments(callableMethod, resolvedCall, receiver, callGenerator, argumentGenerator);
}
private void invokeMethodWithArguments(
@NotNull CallableMethod callableMethod,
@NotNull ResolvedCall<?> resolvedCall,
@NotNull StackValue receiver,
@NotNull CallGenerator callGenerator,
@NotNull ArgumentGenerator argumentGenerator
) {
if (!(resolvedCall.getResultingDescriptor() instanceof ConstructorDescriptor)) { // otherwise already
receiver = StackValue.receiver(resolvedCall, receiver, this, callableMethod); receiver = StackValue.receiver(resolvedCall, receiver, this, callableMethod);
receiver.put(receiver.type, v); receiver.put(receiver.type, v);
} }
@@ -2140,7 +2148,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
callGenerator.putHiddenParams(); callGenerator.putHiddenParams();
List<ResolvedValueArgument> valueArguments = resolvedCall.getValueArgumentsByIndex(); List<ResolvedValueArgument> valueArguments = resolvedCall.getValueArgumentsByIndex();
assert valueArguments != null : "Failed to arrange value arguments by index: " + descriptor; assert valueArguments != null : "Failed to arrange value arguments by index: " + resolvedCall.getResultingDescriptor();
int mask = argumentGenerator.generate(valueArguments); int mask = argumentGenerator.generate(valueArguments);
@@ -2159,13 +2167,15 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
@NotNull @NotNull
protected CallGenerator getOrCreateCallGenerator(@NotNull CallableDescriptor descriptor, @Nullable JetElement callElement) { protected CallGenerator getOrCreateCallGenerator(@NotNull CallableDescriptor descriptor, @Nullable JetElement callElement) {
if (callElement == null) return defaultCallGenerator;
boolean isInline = state.isInlineEnabled() && boolean isInline = state.isInlineEnabled() &&
descriptor instanceof SimpleFunctionDescriptor && descriptor instanceof SimpleFunctionDescriptor &&
((SimpleFunctionDescriptor) descriptor).getInlineStrategy().isInline(); ((SimpleFunctionDescriptor) descriptor).getInlineStrategy().isInline();
if (!isInline) return defaultCallGenerator;
return !isInline || callElement == null ? defaultCallGenerator : SimpleFunctionDescriptor original = DescriptorUtils.unwrapFakeOverride((SimpleFunctionDescriptor) descriptor.getOriginal());
new InlineCodegen(this, state, (SimpleFunctionDescriptor) DescriptorUtils.unwrapFakeOverride( return new InlineCodegen(this, state, original, callElement);
(CallableMemberDescriptor) descriptor.getOriginal()), callElement);
} }
public void generateReceiverValue(@NotNull ReceiverValue receiverValue, @NotNull Type type) { public void generateReceiverValue(@NotNull ReceiverValue receiverValue, @NotNull Type type) {
@@ -2949,8 +2959,6 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
@NotNull Type lhsType, @NotNull Type lhsType,
boolean keepReturnValue boolean keepReturnValue
) { ) {
Call call = getCallWithAssert(expression, bindingContext);
StackValue value = gen(expression.getLeft()); StackValue value = gen(expression.getLeft());
if (keepReturnValue) { if (keepReturnValue) {
value.dupReceiver(v); value.dupReceiver(v);
@@ -2958,7 +2966,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
value.put(lhsType, v); value.put(lhsType, v);
StackValue receiver = StackValue.onStack(lhsType); StackValue receiver = StackValue.onStack(lhsType);
invokeMethodWithArguments(call, callable, resolvedCall, receiver); invokeMethodWithArguments(callable, resolvedCall, receiver);
if (keepReturnValue) { if (keepReturnValue) {
value.store(callable.getReturnType(), v); value.store(callable.getReturnType(), v);
@@ -3264,7 +3272,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
ConstructorDescriptor originalOfSamAdapter = (ConstructorDescriptor) SamCodegenUtil.getOriginalIfSamAdapter(constructor); ConstructorDescriptor originalOfSamAdapter = (ConstructorDescriptor) SamCodegenUtil.getOriginalIfSamAdapter(constructor);
CallableMethod method = typeMapper.mapToCallableMethod(originalOfSamAdapter == null ? constructor : originalOfSamAdapter); CallableMethod method = typeMapper.mapToCallableMethod(originalOfSamAdapter == null ? constructor : originalOfSamAdapter);
invokeMethodWithArguments(null, method, resolvedCall, StackValue.none()); invokeMethodWithArguments(method, resolvedCall, StackValue.none());
return StackValue.onStack(type); return StackValue.onStack(type);
} }
@@ -1582,7 +1582,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
superCallable.invokeWithNotNullAssertion(codegen.v, state, resolvedCall); superCallable.invokeWithNotNullAssertion(codegen.v, state, resolvedCall);
} }
else { else {
codegen.invokeMethodWithArguments(null, superCallable, resolvedCall, StackValue.none()); codegen.invokeMethodWithArguments(superCallable, resolvedCall, StackValue.none());
} }
} }
@@ -1667,7 +1667,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
CallableMethod method = typeMapper.mapToCallableMethod((ConstructorDescriptor) resolvedCall.getResultingDescriptor()); CallableMethod method = typeMapper.mapToCallableMethod((ConstructorDescriptor) resolvedCall.getResultingDescriptor());
codegen.invokeMethodWithArguments(null, method, resolvedCall, StackValue.none()); codegen.invokeMethodWithArguments(method, resolvedCall, StackValue.none());
} }
else { else {
iv.invokespecial(implClass.getInternalName(), "<init>", "(Ljava/lang/String;I)V"); iv.invokespecial(implClass.getInternalName(), "<init>", "(Ljava/lang/String;I)V");