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:
@@ -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");
|
||||||
|
|||||||
Reference in New Issue
Block a user