Call generator refactoring

This commit is contained in:
Mikhael Bogdanov
2014-02-25 13:54:37 +04:00
parent e7603d2e62
commit ead2f84a29
5 changed files with 154 additions and 161 deletions
@@ -0,0 +1,93 @@
/*
* Copyright 2010-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.jet.codegen;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.asm4.Type;
import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor;
import org.jetbrains.jet.lang.psi.JetExpression;
import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCall;
public interface CallGenerator {
public class DefaultCallGenerator implements CallGenerator {
private ExpressionCodegen codegen;
public DefaultCallGenerator(ExpressionCodegen codegen) {
this.codegen = codegen;
}
@Override
public void genCall(
CallableMethod callableMethod,
ResolvedCall<?> resolvedCall, int mask,
ExpressionCodegen codegen
) {
if (mask == 0) {
callableMethod.invokeWithNotNullAssertion(codegen.v, codegen.getState(), resolvedCall);
}
else {
callableMethod.invokeDefaultWithNotNullAssertion(codegen.v, codegen.getState(), resolvedCall, mask);
}
}
@Override
public void afterParameterPut(Type type, StackValue stackValue, ValueParameterDescriptor valueParameterDescriptor) {
}
@Override
public void putHiddenParams() {
}
@Override
public void genValueAndPut(
@NotNull ValueParameterDescriptor valueParameterDescriptor,
@NotNull JetExpression argumentExpression,
@NotNull Type parameterType
) {
StackValue value = codegen.gen(argumentExpression);
value.put(parameterType, codegen.v);
}
@Override
public void putCapturedValueOnStack(
@NotNull StackValue stackValue, @NotNull Type valueType, int paramIndex
) {
stackValue.put(stackValue.type, codegen.v);
}
};
void genCall(CallableMethod callableMethod, ResolvedCall<?> resolvedCall, int mask, ExpressionCodegen codegen);
void afterParameterPut(Type type, StackValue stackValue, ValueParameterDescriptor valueParameterDescriptor);
void genValueAndPut(
@NotNull ValueParameterDescriptor valueParameterDescriptor,
@NotNull JetExpression argumentExpression,
@NotNull Type parameterType
);
void putCapturedValueOnStack(
@NotNull StackValue stackValue,
@NotNull Type valueType, int paramIndex
);
void putHiddenParams();
}
@@ -25,7 +25,6 @@ import org.jetbrains.asm4.MethodVisitor;
import org.jetbrains.asm4.Type; import org.jetbrains.asm4.Type;
import org.jetbrains.asm4.commons.InstructionAdapter; import org.jetbrains.asm4.commons.InstructionAdapter;
import org.jetbrains.asm4.commons.Method; import org.jetbrains.asm4.commons.Method;
import org.jetbrains.jet.codegen.inline.CallGenerator;
import org.jetbrains.jet.codegen.binding.CalculatedClosure; import org.jetbrains.jet.codegen.binding.CalculatedClosure;
import org.jetbrains.jet.codegen.context.CodegenContext; import org.jetbrains.jet.codegen.context.CodegenContext;
import org.jetbrains.jet.codegen.context.LocalLookup; import org.jetbrains.jet.codegen.context.LocalLookup;
@@ -154,7 +153,7 @@ public class ClosureCodegen extends ParentCodegenAwareImpl {
v.anew(asmType); v.anew(asmType);
v.dup(); v.dup();
codegen.pushClosureOnStack(closure, false, CallGenerator.NOT_INLINE); codegen.pushClosureOnStack(closure, false, codegen.defaulCallGenerator);
v.invokespecial(asmType.getInternalName(), "<init>", constructor.getDescriptor()); v.invokespecial(asmType.getInternalName(), "<init>", constructor.getDescriptor());
} }
return StackValue.onStack(asmType); return StackValue.onStack(asmType);
@@ -33,7 +33,6 @@ import org.jetbrains.asm4.Type;
import org.jetbrains.asm4.commons.InstructionAdapter; import org.jetbrains.asm4.commons.InstructionAdapter;
import org.jetbrains.asm4.commons.Method; import org.jetbrains.asm4.commons.Method;
import org.jetbrains.jet.codegen.inline.InlineCodegen; import org.jetbrains.jet.codegen.inline.InlineCodegen;
import org.jetbrains.jet.codegen.inline.CallGenerator;
import org.jetbrains.jet.codegen.inline.NameGenerator; import org.jetbrains.jet.codegen.inline.NameGenerator;
import org.jetbrains.jet.codegen.binding.CalculatedClosure; import org.jetbrains.jet.codegen.binding.CalculatedClosure;
import org.jetbrains.jet.codegen.binding.CodegenBinding; import org.jetbrains.jet.codegen.binding.CodegenBinding;
@@ -84,7 +83,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
private int myLastLineNumber = -1; private int myLastLineNumber = -1;
InstructionAdapter v; public final InstructionAdapter v;
final MethodVisitor methodVisitor; final MethodVisitor methodVisitor;
final FrameMap myFrameMap; final FrameMap myFrameMap;
final JetTypeMapper typeMapper; final JetTypeMapper typeMapper;
@@ -109,6 +108,8 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
@NotNull @NotNull
private final TailRecursionCodegen tailRecursionCodegen; private final TailRecursionCodegen tailRecursionCodegen;
public final CallGenerator defaulCallGenerator;
public CalculatedClosure generateObjectLiteral(GenerationState state, JetObjectLiteralExpression literal) { public CalculatedClosure generateObjectLiteral(GenerationState state, JetObjectLiteralExpression literal) {
JetObjectDeclaration objectDeclaration = literal.getObjectDeclaration(); JetObjectDeclaration objectDeclaration = literal.getObjectDeclaration();
@@ -178,6 +179,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
this.context = context; this.context = context;
this.statementVisitor = new CodegenStatementVisitor(this); this.statementVisitor = new CodegenStatementVisitor(this);
this.tailRecursionCodegen = new TailRecursionCodegen(context, this, this.v, state); this.tailRecursionCodegen = new TailRecursionCodegen(context, this, this.v, state);
this.defaulCallGenerator = new CallGenerator.DefaultCallGenerator(this);
} }
public GenerationState getState() { public GenerationState getState() {
@@ -1334,7 +1336,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
v.anew(type); v.anew(type);
v.dup(); v.dup();
pushClosureOnStack(closure, false, CallGenerator.NOT_INLINE); pushClosureOnStack(closure, false, defaulCallGenerator);
JetDelegatorToSuperCall superCall = closure.getSuperCall(); JetDelegatorToSuperCall superCall = closure.getSuperCall();
if (superCall != null) { if (superCall != null) {
@@ -1355,7 +1357,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
return StackValue.onStack(type); return StackValue.onStack(type);
} }
public void pushClosureOnStack(CalculatedClosure closure, boolean ignoreThisAndReceiver, CallGenerator callGenerator) { public void pushClosureOnStack(@Nullable CalculatedClosure closure, boolean ignoreThisAndReceiver, @NotNull CallGenerator callGenerator) {
if (closure != null) { if (closure != null) {
int paramIndex = 0; int paramIndex = 0;
if (!ignoreThisAndReceiver) { if (!ignoreThisAndReceiver) {
@@ -1364,20 +1366,14 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
StackValue thisOrOuter = generateThisOrOuter(captureThis, false); StackValue thisOrOuter = generateThisOrOuter(captureThis, false);
assert !isPrimitive(thisOrOuter.type) : "This or outer should be non primitive: " + thisOrOuter.type; assert !isPrimitive(thisOrOuter.type) : "This or outer should be non primitive: " + thisOrOuter.type;
if (callGenerator.shouldPutValue(thisOrOuter.type, thisOrOuter, null)) { callGenerator.putCapturedValueOnStack(thisOrOuter, thisOrOuter.type, paramIndex++);
thisOrOuter.put(thisOrOuter.type, v);
}
callGenerator.putCapturedInLocal(thisOrOuter.type, thisOrOuter, null, paramIndex++);
} }
JetType captureReceiver = closure.getCaptureReceiverType(); JetType captureReceiver = closure.getCaptureReceiverType();
if (captureReceiver != null) { if (captureReceiver != null) {
Type asmType = typeMapper.mapType(captureReceiver); Type asmType = typeMapper.mapType(captureReceiver);
StackValue.Local capturedReceiver = StackValue.local(context.isStatic() ? 0 : 1, asmType); StackValue.Local capturedReceiver = StackValue.local(context.isStatic() ? 0 : 1, asmType);
if (callGenerator.shouldPutValue(asmType, capturedReceiver, null)) { callGenerator.putCapturedValueOnStack(capturedReceiver, capturedReceiver.type, paramIndex++);
capturedReceiver.put(asmType, v);
}
callGenerator.putCapturedInLocal(asmType, capturedReceiver, null, paramIndex++);
} }
} }
@@ -1387,10 +1383,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
sharedVarType = typeMapper.mapType((VariableDescriptor) entry.getKey()); sharedVarType = typeMapper.mapType((VariableDescriptor) entry.getKey());
} }
StackValue capturedVar = entry.getValue().getOuterValue(this); StackValue capturedVar = entry.getValue().getOuterValue(this);
if (callGenerator.shouldPutValue(sharedVarType, capturedVar, null)) { callGenerator.putCapturedValueOnStack(capturedVar, sharedVarType, paramIndex++);
capturedVar.put(sharedVarType, v);
}
callGenerator.putCapturedInLocal(sharedVarType, capturedVar, null, paramIndex++);
} }
} }
} }
@@ -2123,7 +2116,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
descriptor instanceof SimpleFunctionDescriptor && descriptor instanceof SimpleFunctionDescriptor &&
((SimpleFunctionDescriptor) descriptor).getInlineStrategy().isInline(); ((SimpleFunctionDescriptor) descriptor).getInlineStrategy().isInline();
CallGenerator callGenerator = !isInline ? CallGenerator.NOT_INLINE : CallGenerator callGenerator = !isInline ? defaulCallGenerator :
new InlineCodegen(this, state, (SimpleFunctionDescriptor) unwrapFakeOverride( new InlineCodegen(this, state, (SimpleFunctionDescriptor) unwrapFakeOverride(
(CallableMemberDescriptor) descriptor.getOriginal()), call); (CallableMemberDescriptor) descriptor.getOriginal()), call);
@@ -2136,7 +2129,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
receiver.put(receiver.type, v); receiver.put(receiver.type, v);
} }
assert callGenerator == CallGenerator.NOT_INLINE || !hasDefaultArguments(resolvedCall) && !tailRecursionCodegen.isTailRecursion(resolvedCall) : assert callGenerator == defaulCallGenerator || !hasDefaultArguments(resolvedCall) && !tailRecursionCodegen.isTailRecursion(resolvedCall) :
"Method with defaults or tail recursive couldn't be inlined " + descriptor; "Method with defaults or tail recursive couldn't be inlined " + descriptor;
pushArgumentsAndInvoke(resolvedCall, callableMethod, callGenerator); pushArgumentsAndInvoke(resolvedCall, callableMethod, callGenerator);
@@ -2152,18 +2145,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
return; return;
} }
if (mask == 0) { callGenerator.genCall(callable, resolvedCall, mask, this);
if (callGenerator != CallGenerator.NOT_INLINE) {
callGenerator.inlineCall(callable, getParentCodegen().getBuilder().getVisitor());
} else {
callable.invokeWithNotNullAssertion(v, state, resolvedCall);
}
}
else {
callable.invokeDefaultWithNotNullAssertion(v, state, resolvedCall, mask);
}
callGenerator.leaveTemps();
} }
private void genThisAndReceiverFromResolvedCall( private void genThisAndReceiverFromResolvedCall(
@@ -2339,7 +2321,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
throw new IllegalStateException(); throw new IllegalStateException();
} }
callGenerator = callGenerator != null ? callGenerator : CallGenerator.NOT_INLINE; callGenerator = callGenerator != null ? callGenerator : defaulCallGenerator;
int mask = 0; int mask = 0;
for (Iterator<ValueParameterDescriptor> iterator = valueParameters.iterator(); iterator.hasNext(); ) { for (Iterator<ValueParameterDescriptor> iterator = valueParameters.iterator(); iterator.hasNext(); ) {
@@ -2356,25 +2338,16 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
JetExpression argumentExpression = valueArgument.getArgumentExpression(); JetExpression argumentExpression = valueArgument.getArgumentExpression();
assert argumentExpression != null : valueArgument.asElement().getText(); assert argumentExpression != null : valueArgument.asElement().getText();
//TODO deparenthisise callGenerator.genValueAndPut(valueParameter, argumentExpression, parameterType);
if (callGenerator.isInliningClosure(argumentExpression, valueParameter)) {
callGenerator.rememberClosure((JetFunctionLiteralExpression) argumentExpression, parameterType);
} else {
StackValue value = gen(argumentExpression);
if (callGenerator.shouldPutValue(parameterType, value, valueParameter)) {
value.put(parameterType, v);
}
callGenerator.putInLocal(parameterType, value, valueParameter);
}
} else if (resolvedValueArgument instanceof DefaultValueArgument) { } else if (resolvedValueArgument instanceof DefaultValueArgument) {
pushDefaultValueOnStack(parameterType, v); pushDefaultValueOnStack(parameterType, v);
mask |= (1 << valueParameter.getIndex()); mask |= (1 << valueParameter.getIndex());
callGenerator.putInLocal(parameterType, null, valueParameter); callGenerator.afterParameterPut(parameterType, null, valueParameter);
} }
else if (resolvedValueArgument instanceof VarargValueArgument) { else if (resolvedValueArgument instanceof VarargValueArgument) {
VarargValueArgument valueArgument = (VarargValueArgument) resolvedValueArgument; VarargValueArgument valueArgument = (VarargValueArgument) resolvedValueArgument;
genVarargs(valueParameter, valueArgument); genVarargs(valueParameter, valueArgument);
callGenerator.putInLocal(parameterType, null, valueParameter); callGenerator.afterParameterPut(parameterType, null, valueParameter);
} }
else { else {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
@@ -3319,7 +3292,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
//Resolved call to local class constructor doesn't have resolvedCall.getThisObject() and resolvedCall.getReceiverArgument() //Resolved call to local class constructor doesn't have resolvedCall.getThisObject() and resolvedCall.getReceiverArgument()
//so we need generate closure on stack //so we need generate closure on stack
//See StackValue.receiver for more info //See StackValue.receiver for more info
pushClosureOnStack(closure, resolvedCall.getThisObject().exists() || resolvedCall.getReceiverArgument().exists(), CallGenerator.NOT_INLINE); pushClosureOnStack(closure, resolvedCall.getThisObject().exists() || resolvedCall.getReceiverArgument().exists(), defaulCallGenerator);
ConstructorDescriptor originalOfSamAdapter = (ConstructorDescriptor) SamCodegenUtil.getOriginalIfSamAdapter(constructorDescriptor); ConstructorDescriptor originalOfSamAdapter = (ConstructorDescriptor) SamCodegenUtil.getOriginalIfSamAdapter(constructorDescriptor);
CallableMethod method = typeMapper.mapToCallableMethod(originalOfSamAdapter == null ? constructorDescriptor : originalOfSamAdapter); CallableMethod method = typeMapper.mapToCallableMethod(originalOfSamAdapter == null ? constructorDescriptor : originalOfSamAdapter);
@@ -3874,11 +3847,6 @@ The "returned" value of try expression with no finally is either the last expres
throw new IllegalStateException("Script codegen should be present in codegen tree"); throw new IllegalStateException("Script codegen should be present in codegen tree");
} }
@NotNull
public InstructionAdapter getInstructionAdapter() {
return v;
}
@NotNull @NotNull
public FrameMap getFrameMap() { public FrameMap getFrameMap() {
return myFrameMap; return myFrameMap;
@@ -1,93 +0,0 @@
/*
* Copyright 2010-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.jet.codegen.inline;
import org.jetbrains.asm4.ClassVisitor;
import org.jetbrains.asm4.Type;
import org.jetbrains.jet.codegen.CallableMethod;
import org.jetbrains.jet.codegen.StackValue;
import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor;
import org.jetbrains.jet.lang.psi.JetExpression;
import org.jetbrains.jet.lang.psi.JetFunctionLiteralExpression;
public interface CallGenerator {
CallGenerator NOT_INLINE = new CallGenerator() {
@Override
public void inlineCall(
CallableMethod callableMethod, ClassVisitor visitor
) {
throw new UnsupportedOperationException();
}
@Override
public void putInLocal(Type type, StackValue stackValue, ValueParameterDescriptor valueParameterDescriptor) {
}
@Override
public void putCapturedInLocal(
Type type, StackValue stackValue, ValueParameterDescriptor valueParameterDescriptor, int index
) {
}
@Override
public void leaveTemps() {
}
@Override
public boolean isInliningClosure(JetExpression expression, ValueParameterDescriptor valueParameterDescriptora) {
return false;
}
@Override
public void rememberClosure(JetFunctionLiteralExpression expression, Type type) {
throw new UnsupportedOperationException();
}
@Override
public void putHiddenParams() {
}
@Override
public boolean shouldPutValue(
Type type, StackValue stackValue,
ValueParameterDescriptor descriptor
) {
return true;
}
};
void inlineCall(CallableMethod callableMethod, ClassVisitor visitor);
void putInLocal(Type type, StackValue stackValue, ValueParameterDescriptor valueParameterDescriptor);
void putCapturedInLocal(Type type, StackValue stackValue, ValueParameterDescriptor valueParameterDescriptor, int index);
boolean shouldPutValue(Type type, StackValue stackValue, ValueParameterDescriptor descriptor);
void putHiddenParams();
void leaveTemps();
boolean isInliningClosure(JetExpression expression, ValueParameterDescriptor valueParameterDescriptora);
void rememberClosure(JetFunctionLiteralExpression expression, Type type);
}
@@ -20,7 +20,6 @@ import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiElement; import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jetbrains.asm4.ClassVisitor;
import org.jetbrains.asm4.MethodVisitor; import org.jetbrains.asm4.MethodVisitor;
import org.jetbrains.asm4.Opcodes; import org.jetbrains.asm4.Opcodes;
import org.jetbrains.asm4.Type; import org.jetbrains.asm4.Type;
@@ -43,6 +42,7 @@ import org.jetbrains.jet.lang.descriptors.impl.AnonymousFunctionDescriptor;
import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.BindingContextUtils; import org.jetbrains.jet.lang.resolve.BindingContextUtils;
import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCall;
import org.jetbrains.jet.lang.resolve.java.AsmTypeConstants; import org.jetbrains.jet.lang.resolve.java.AsmTypeConstants;
import org.jetbrains.jet.lang.types.lang.InlineStrategy; import org.jetbrains.jet.lang.types.lang.InlineStrategy;
import org.jetbrains.jet.lang.types.lang.InlineUtil; import org.jetbrains.jet.lang.types.lang.InlineUtil;
@@ -119,7 +119,9 @@ public class InlineCodegen implements ParentCodegenAware, CallGenerator {
@Override @Override
public void inlineCall(CallableMethod callableMethod, ClassVisitor visitor) { public void genCall(CallableMethod callableMethod, ResolvedCall<?> resolvedCall, int mask, ExpressionCodegen codegen) {
assert mask == 0 : "Default method invocation couldn't be inlined " + resolvedCall;
MethodNode node = null; MethodNode node = null;
try { try {
@@ -131,13 +133,15 @@ public class InlineCodegen implements ParentCodegenAware, CallGenerator {
} }
catch (Exception e) { catch (Exception e) {
String text = getNodeText(node); String text = getNodeText(node);
PsiElement element = BindingContextUtils.descriptorToDeclaration(bindingContext, codegen.getContext().getContextDescriptor()); PsiElement element = BindingContextUtils.descriptorToDeclaration(bindingContext, this.codegen.getContext().getContextDescriptor());
throw new CompilationException("Couldn't inline method call '" + throw new CompilationException("Couldn't inline method call '" +
functionDescriptor.getName() + functionDescriptor.getName() +
"' into \n" + (element != null ? element.getText() : "null psi element " + codegen.getContext().getContextDescriptor()) + "' into \n" + (element != null ? element.getText() : "null psi element " + this.codegen.getContext().getContextDescriptor()) +
"\ncause: " + "\ncause: " +
text, e, call.getCallElement()); text, e, call.getCallElement());
} }
leaveTemps();
} }
@NotNull @NotNull
@@ -203,7 +207,7 @@ public class InlineCodegen implements ParentCodegenAware, CallGenerator {
VarRemapper.ParamRemapper remapper = new VarRemapper.ParamRemapper(parameters, initialFrameSize); VarRemapper.ParamRemapper remapper = new VarRemapper.ParamRemapper(parameters, initialFrameSize);
inliner.doTransformAndMerge(codegen.getInstructionAdapter(), remapper); inliner.doTransformAndMerge(codegen.v, remapper);
} }
@@ -242,13 +246,12 @@ public class InlineCodegen implements ParentCodegenAware, CallGenerator {
@Override @Override
public void putInLocal(@NotNull Type type, @Nullable StackValue stackValue, ValueParameterDescriptor valueParameterDescriptor) { public void afterParameterPut(@NotNull Type type, @Nullable StackValue stackValue, ValueParameterDescriptor valueParameterDescriptor) {
putCapturedInLocal(type, stackValue, valueParameterDescriptor, -1); putCapturedInLocal(type, stackValue, valueParameterDescriptor, -1);
} }
@Override
public void putCapturedInLocal( public void putCapturedInLocal(
@NotNull Type type, @Nullable StackValue stackValue, @Nullable ValueParameterDescriptor valueParameterDescriptor, int index @NotNull Type type, @Nullable StackValue stackValue, @Nullable ValueParameterDescriptor valueParameterDescriptor, int capturedParamIndex
) { ) {
if (!asFunctionInline && Type.VOID_TYPE != type) { if (!asFunctionInline && Type.VOID_TYPE != type) {
//TODO remap only inlinable closure => otherwise we could get a lot of problem //TODO remap only inlinable closure => otherwise we could get a lot of problem
@@ -257,8 +260,8 @@ public class InlineCodegen implements ParentCodegenAware, CallGenerator {
ParameterInfo info = new ParameterInfo(type, false, couldBeRemapped ? -1 : codegen.getFrameMap().enterTemp(type), remappedIndex); ParameterInfo info = new ParameterInfo(type, false, couldBeRemapped ? -1 : codegen.getFrameMap().enterTemp(type), remappedIndex);
if (index >= 0 && couldBeRemapped) { if (capturedParamIndex >= 0 && couldBeRemapped) {
CapturedParamInfo capturedParamInfo = activeLambda.getCapturedVars().get(index); CapturedParamInfo capturedParamInfo = activeLambda.getCapturedVars().get(capturedParamIndex);
capturedParamInfo.setRemapValue(remappedIndex != null ? remappedIndex : StackValue.local(info.getIndex(), info.getType())); capturedParamInfo.setRemapValue(remappedIndex != null ? remappedIndex : StackValue.local(info.getIndex(), info.getType()));
} }
@@ -266,9 +269,7 @@ public class InlineCodegen implements ParentCodegenAware, CallGenerator {
} }
} }
/*descriptor is null for captured vars*/ /*descriptor is null for captured vars*/
@Override
public boolean shouldPutValue( public boolean shouldPutValue(
@NotNull Type type, @NotNull Type type,
@Nullable StackValue stackValue, @Nullable StackValue stackValue,
@@ -324,7 +325,7 @@ public class InlineCodegen implements ParentCodegenAware, CallGenerator {
if (!info.isSkippedOrRemapped()) { if (!info.isSkippedOrRemapped()) {
int index = info.getIndex(); int index = info.getIndex();
Type type = info.type; Type type = info.type;
StackValue.local(index, type).store(type, codegen.getInstructionAdapter()); StackValue.local(index, type).store(type, codegen.v);
} }
} }
@@ -353,7 +354,6 @@ public class InlineCodegen implements ParentCodegenAware, CallGenerator {
} }
} }
@Override
public void leaveTemps() { public void leaveTemps() {
FrameMap frameMap = codegen.getFrameMap(); FrameMap frameMap = codegen.getFrameMap();
for (ListIterator<? extends ParameterInfo> iterator = actualParameters.listIterator(actualParameters.size()); iterator.hasPrevious(); ) { for (ListIterator<? extends ParameterInfo> iterator = actualParameters.listIterator(actualParameters.size()); iterator.hasPrevious(); ) {
@@ -364,14 +364,12 @@ public class InlineCodegen implements ParentCodegenAware, CallGenerator {
} }
} }
@Override public static boolean isInliningClosure(JetExpression expression, ValueParameterDescriptor valueParameterDescriptora) {
public boolean isInliningClosure(JetExpression expression, ValueParameterDescriptor valueParameterDescriptora) {
//TODO deparenthisise //TODO deparenthisise
return expression instanceof JetFunctionLiteralExpression && return expression instanceof JetFunctionLiteralExpression &&
!InlineUtil.hasNoinlineAnnotation(valueParameterDescriptora); !InlineUtil.hasNoinlineAnnotation(valueParameterDescriptora);
} }
@Override
public void rememberClosure(JetFunctionLiteralExpression expression, Type type) { public void rememberClosure(JetFunctionLiteralExpression expression, Type type) {
ParameterInfo closureInfo = new ParameterInfo(type, true, -1, -1); ParameterInfo closureInfo = new ParameterInfo(type, true, -1, -1);
int index = recordParamInfo(closureInfo, true); int index = recordParamInfo(closureInfo, true);
@@ -450,4 +448,32 @@ public class InlineCodegen implements ParentCodegenAware, CallGenerator {
private static String descriptorName(DeclarationDescriptor descriptor) { private static String descriptorName(DeclarationDescriptor descriptor) {
return DescriptorRenderer.SHORT_NAMES_IN_TYPES.render(descriptor); return DescriptorRenderer.SHORT_NAMES_IN_TYPES.render(descriptor);
} }
@Override
public void genValueAndPut(
@NotNull ValueParameterDescriptor valueParameterDescriptor,
@NotNull JetExpression argumentExpression,
@NotNull Type parameterType
) {
//TODO deparenthisise
if (isInliningClosure(argumentExpression, valueParameterDescriptor)) {
rememberClosure((JetFunctionLiteralExpression) argumentExpression, parameterType);
} else {
StackValue value = codegen.gen(argumentExpression);
if (shouldPutValue(parameterType, value, valueParameterDescriptor)) {
value.put(parameterType, codegen.v);
}
afterParameterPut(parameterType, value, valueParameterDescriptor);
}
}
@Override
public void putCapturedValueOnStack(
@NotNull StackValue stackValue, @NotNull Type valueType, int paramIndex
) {
if (shouldPutValue(stackValue.type, stackValue, null)) {
stackValue.put(stackValue.type, codegen.v);
}
putCapturedInLocal(stackValue.type, stackValue, null, paramIndex);
}
} }