Removed obsolete code in codegen for 'var' parameters captured in closure. 'Var' parameters are forbidden now.

This commit is contained in:
Evgeny Gerashchenko
2013-10-31 17:47:40 +04:00
parent e625a3a869
commit 28ef7495af
4 changed files with 23 additions and 133 deletions
@@ -51,8 +51,6 @@ public class CodegenUtil {
private CodegenUtil() { private CodegenUtil() {
} }
private static final Random RANDOM = new Random(55L);
public static boolean isInterface(DeclarationDescriptor descriptor) { public static boolean isInterface(DeclarationDescriptor descriptor) {
if (descriptor instanceof ClassDescriptor) { if (descriptor instanceof ClassDescriptor) {
ClassKind kind = ((ClassDescriptor) descriptor).getKind(); ClassKind kind = ((ClassDescriptor) descriptor).getKind();
@@ -85,18 +83,6 @@ public class CodegenUtil {
return invokeDescriptor; return invokeDescriptor;
} }
public static String createTmpVariableName(Collection<String> existingNames) {
String prefix = "tmp";
int i = RANDOM.nextInt(Integer.MAX_VALUE);
String name = prefix + i;
while (existingNames.contains(name)) {
i++;
name = prefix + i;
}
return name;
}
public static JvmMethodSignature erasedInvokeSignature(FunctionDescriptor fd) { public static JvmMethodSignature erasedInvokeSignature(FunctionDescriptor fd) {
BothSignatureWriter signatureWriter = new BothSignatureWriter(BothSignatureWriter.Mode.METHOD, false); BothSignatureWriter signatureWriter = new BothSignatureWriter(BothSignatureWriter.Mode.METHOD, false);
@@ -99,7 +99,6 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
private final CodegenStatementVisitor statementVisitor; private final CodegenStatementVisitor statementVisitor;
private final Stack<BlockStackElement> blockStackElements = new Stack<BlockStackElement>(); private final Stack<BlockStackElement> blockStackElements = new Stack<BlockStackElement>();
private final Collection<String> localVariableNames = new HashSet<String>();
@Nullable @Nullable
private final MemberCodegen parentCodegen; private final MemberCodegen parentCodegen;
@@ -176,13 +175,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
this.returnType = returnType; this.returnType = returnType;
this.state = state; this.state = state;
this.methodVisitor = v; this.methodVisitor = v;
this.v = new InstructionAdapter(methodVisitor) { this.v = new InstructionAdapter(methodVisitor);
@Override
public void visitLocalVariable(String name, String desc, String signature, Label start, Label end, int index) {
super.visitLocalVariable(name, desc, signature, start, end, index);
localVariableNames.add(name);
}
};
this.bindingContext = state.getBindingContext(); this.bindingContext = state.getBindingContext();
this.context = context; this.context = context;
this.statementVisitor = new CodegenStatementVisitor(this); this.statementVisitor = new CodegenStatementVisitor(this);
@@ -213,10 +206,6 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
return bindingContext; return bindingContext;
} }
public Collection<String> getLocalVariableNamesForExpression() {
return localVariableNames;
}
@Nullable @Nullable
@Override @Override
public MemberCodegen getParentCodegen() { public MemberCodegen getParentCodegen() {
@@ -42,7 +42,6 @@ import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.psi.JetNamedFunction; import org.jetbrains.jet.lang.psi.JetNamedFunction;
import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.java.JvmAbi; import org.jetbrains.jet.lang.resolve.java.JvmAbi;
import org.jetbrains.jet.lang.resolve.name.Name;
import java.io.PrintWriter; import java.io.PrintWriter;
import java.io.StringWriter; import java.io.StringWriter;
@@ -50,7 +49,8 @@ import java.util.*;
import static org.jetbrains.asm4.Opcodes.*; import static org.jetbrains.asm4.Opcodes.*;
import static org.jetbrains.jet.codegen.AsmUtil.*; import static org.jetbrains.jet.codegen.AsmUtil.*;
import static org.jetbrains.jet.codegen.CodegenUtil.*; import static org.jetbrains.jet.codegen.CodegenUtil.isCallInsideSameClassAsDeclared;
import static org.jetbrains.jet.codegen.CodegenUtil.isCallInsideSameModuleAsDeclared;
import static org.jetbrains.jet.codegen.JvmSerializationBindings.*; import static org.jetbrains.jet.codegen.JvmSerializationBindings.*;
import static org.jetbrains.jet.codegen.binding.CodegenBinding.asmTypeForAnonymousClass; import static org.jetbrains.jet.codegen.binding.CodegenBinding.asmTypeForAnonymousClass;
import static org.jetbrains.jet.codegen.binding.CodegenBinding.isLocalNamedFun; import static org.jetbrains.jet.codegen.binding.CodegenBinding.isLocalNamedFun;
@@ -136,8 +136,6 @@ public class FunctionCodegen extends ParentCodegenAwareImpl {
getThisTypeForFunction(functionDescriptor, methodContext), getThisTypeForFunction(functionDescriptor, methodContext),
new Label(), new Label(),
new Label(), new Label(),
new HashSet<String>(getParameterNamesAsStrings(functionDescriptor)),
Collections.<Name, Label>emptyMap(),
methodContext.getContextKind() methodContext.getContextKind()
); );
return; return;
@@ -265,10 +263,6 @@ public class FunctionCodegen extends ParentCodegenAwareImpl {
@NotNull JvmMethodSignature signature, @NotNull JvmMethodSignature signature,
@NotNull FunctionGenerationStrategy strategy @NotNull FunctionGenerationStrategy strategy
) { ) {
Collection<String> localVariableNames = new HashSet<String>(getParameterNamesAsStrings(functionDescriptor));
Map<Name, Label> labelsForSharedVars = new HashMap<Name, Label>();
mv.visitCode(); mv.visitCode();
Label methodBegin = new Label(); Label methodBegin = new Label();
@@ -287,15 +281,12 @@ public class FunctionCodegen extends ParentCodegenAwareImpl {
Label methodEntry = new Label(); Label methodEntry = new Label();
mv.visitLabel(methodEntry); mv.visitLabel(methodEntry);
context.setMethodStartLabel(methodEntry); context.setMethodStartLabel(methodEntry);
labelsForSharedVars.putAll(createSharedVarsForParameters(mv, functionDescriptor, frameMap));
if (!JetTypeMapper.isAccessor(functionDescriptor)) { if (!JetTypeMapper.isAccessor(functionDescriptor)) {
genNotNullAssertionsForParameters(new InstructionAdapter(mv), state, functionDescriptor, frameMap); genNotNullAssertionsForParameters(new InstructionAdapter(mv), state, functionDescriptor, frameMap);
} }
strategy.generateBody(mv, signature, context, getParentCodegen()); strategy.generateBody(mv, signature, context, getParentCodegen());
localVariableNames.addAll(strategy.getLocalVariableNames());
} }
Label methodEnd = new Label(); Label methodEnd = new Label();
@@ -303,28 +294,16 @@ public class FunctionCodegen extends ParentCodegenAwareImpl {
Type thisType = getThisTypeForFunction(functionDescriptor, context); Type thisType = getThisTypeForFunction(functionDescriptor, context);
generateLocalVariableTable(mv, signature, functionDescriptor, thisType, methodBegin, methodEnd, localVariableNames, labelsForSharedVars, context.getContextKind()); generateLocalVariableTable(mv, signature, functionDescriptor, thisType, methodBegin, methodEnd, context.getContextKind());
} }
@NotNull private static void generateLocalVariableTable(
private static List<String> getParameterNamesAsStrings(@NotNull FunctionDescriptor functionDescriptor) {
List<ValueParameterDescriptor> parameters = functionDescriptor.getValueParameters();
List<String> result = new ArrayList<String>(parameters.size());
for (ValueParameterDescriptor parameter : parameters) {
result.add(parameter.getName().asString());
}
return result;
}
private void generateLocalVariableTable(
@NotNull MethodVisitor mv, @NotNull MethodVisitor mv,
@NotNull JvmMethodSignature jvmMethodSignature, @NotNull JvmMethodSignature jvmMethodSignature,
@NotNull FunctionDescriptor functionDescriptor, @NotNull FunctionDescriptor functionDescriptor,
@Nullable Type thisType, @Nullable Type thisType,
@NotNull Label methodBegin, @NotNull Label methodBegin,
@NotNull Label methodEnd, @NotNull Label methodEnd,
@NotNull Collection<String> localVariableNames,
@NotNull Map<Name, Label> labelsForSharedVars,
@NotNull OwnerKind ownerKind @NotNull OwnerKind ownerKind
) { ) {
Iterator<ValueParameterDescriptor> valueParameters = functionDescriptor.getValueParameters().iterator(); Iterator<ValueParameterDescriptor> valueParameters = functionDescriptor.getValueParameters().iterator();
@@ -345,69 +324,25 @@ public class FunctionCodegen extends ParentCodegenAwareImpl {
for (int i = 0; i < params.size(); i++) { for (int i = 0; i < params.size(); i++) {
JvmMethodParameterSignature param = params.get(i); JvmMethodParameterSignature param = params.get(i);
JvmMethodParameterKind kind = param.getKind(); JvmMethodParameterKind kind = param.getKind();
String parameterName = "$" + param.getKind().name().toLowerCase(); String parameterName;
if (needIndexForVar(kind)) { if (kind == JvmMethodParameterKind.VALUE) {
parameterName = parameterName + "$" + i; ValueParameterDescriptor parameter = valueParameters.next();
parameterName = parameter.getName().asString();
}
else {
String lowercaseKind = kind.name().toLowerCase();
parameterName = needIndexForVar(kind)
? "$" + lowercaseKind + "$" + i
: "$" + lowercaseKind;
} }
Type type = param.getAsmType(); Type type = param.getAsmType();
if (kind == JvmMethodParameterKind.VALUE) {
ValueParameterDescriptor parameter = valueParameters.next();
Label divideLabel = labelsForSharedVars.get(parameter.getName());
parameterName = parameter.getName().asString();
if (divideLabel != null) {
mv.visitLocalVariable(parameterName, type.getDescriptor(), null, methodBegin, divideLabel, shift);
String nameForSharedVar = createTmpVariableName(localVariableNames);
localVariableNames.add(nameForSharedVar);
Type sharedVarType = typeMapper.getSharedVarType(parameter);
mv.visitLocalVariable(nameForSharedVar, sharedVarType.getDescriptor(), null, divideLabel, methodEnd, shift);
shift += Math.max(type.getSize(), sharedVarType.getSize());
continue;
}
}
mv.visitLocalVariable(parameterName, type.getDescriptor(), null, methodBegin, methodEnd, shift); mv.visitLocalVariable(parameterName, type.getDescriptor(), null, methodBegin, methodEnd, shift);
shift += type.getSize(); shift += type.getSize();
} }
} }
@NotNull
private Map<Name, Label> createSharedVarsForParameters(
@NotNull MethodVisitor mv,
@NotNull FunctionDescriptor functionDescriptor,
@NotNull FrameMap frameMap
) {
Map<Name, Label> labelsForSharedVars = new HashMap<Name, Label>();
for (ValueParameterDescriptor parameter : functionDescriptor.getValueParameters()) {
Type sharedVarType = typeMapper.getSharedVarType(parameter);
if (sharedVarType == null) {
continue;
}
Type localVarType = typeMapper.mapType(parameter);
int index = frameMap.getIndex(parameter);
mv.visitTypeInsn(NEW, sharedVarType.getInternalName());
mv.visitInsn(DUP);
mv.visitInsn(DUP);
mv.visitMethodInsn(INVOKESPECIAL, sharedVarType.getInternalName(), "<init>", "()V");
mv.visitVarInsn(localVarType.getOpcode(ILOAD), index);
mv.visitFieldInsn(PUTFIELD, sharedVarType.getInternalName(), "ref", StackValue.refType(localVarType).getDescriptor());
Label labelForSharedVar = new Label();
mv.visitLabel(labelForSharedVar);
labelsForSharedVars.put(parameter.getName(), labelForSharedVar);
mv.visitVarInsn(sharedVarType.getOpcode(ISTORE), index);
}
return labelsForSharedVars;
}
private static void generateStaticDelegateMethodBody( private static void generateStaticDelegateMethodBody(
@NotNull MethodVisitor mv, @NotNull MethodVisitor mv,
@NotNull Method asmMethod, @NotNull Method asmMethod,
@@ -431,7 +366,7 @@ public class FunctionCodegen extends ParentCodegenAwareImpl {
iv.areturn(asmMethod.getReturnType()); iv.areturn(asmMethod.getReturnType());
} }
private boolean needIndexForVar(JvmMethodParameterKind kind) { private static boolean needIndexForVar(JvmMethodParameterKind kind) {
return kind == JvmMethodParameterKind.SHARED_VAR || kind == JvmMethodParameterKind.SUPER_CALL_PARAM; return kind == JvmMethodParameterKind.SHARED_VAR || kind == JvmMethodParameterKind.SUPER_CALL_PARAM;
} }
@@ -518,7 +453,7 @@ public class FunctionCodegen extends ParentCodegenAwareImpl {
} }
for (Method overridden : bridgesToGenerate) { for (Method overridden : bridgesToGenerate) {
generateBridge(owner, state, v, jvmSignature, functionDescriptor, overridden); generateBridge(state, v, jvmSignature, functionDescriptor, overridden);
} }
} }
@@ -637,14 +572,13 @@ public class FunctionCodegen extends ParentCodegenAwareImpl {
Iterator<ValueParameterDescriptor> iterator = paramDescrs.iterator(); Iterator<ValueParameterDescriptor> iterator = paramDescrs.iterator();
int countOfExtraVarsInMethodArgs = 0; int countOfExtraVarsInMethodArgs = 0;
List<JvmMethodParameterSignature> params = signature.getKotlinParameterTypes();
for (int i = 0; i < params.size(); i++) { for (JvmMethodParameterSignature parameterSignature : signature.getKotlinParameterTypes()) {
JvmMethodParameterSignature parameterSignature = params.get(i);
if (parameterSignature.getKind() != JvmMethodParameterKind.VALUE) { if (parameterSignature.getKind() != JvmMethodParameterKind.VALUE) {
countOfExtraVarsInMethodArgs++; countOfExtraVarsInMethodArgs++;
frameMap.enterTemp(parameterSignature.getAsmType()); frameMap.enterTemp(parameterSignature.getAsmType());
} else { }
else {
frameMap.enter(iterator.next(), parameterSignature.getAsmType()); frameMap.enter(iterator.next(), parameterSignature.getAsmType());
} }
} }
@@ -677,7 +611,7 @@ public class FunctionCodegen extends ParentCodegenAwareImpl {
iv.load(frameMap.getIndex(parameterDescriptor), t); iv.load(frameMap.getIndex(parameterDescriptor), t);
} }
CallableMethod method = null; CallableMethod method;
if (functionDescriptor instanceof ConstructorDescriptor) { if (functionDescriptor instanceof ConstructorDescriptor) {
method = state.getTypeMapper().mapToCallableMethod((ConstructorDescriptor) functionDescriptor); method = state.getTypeMapper().mapToCallableMethod((ConstructorDescriptor) functionDescriptor);
} else { } else {
@@ -707,9 +641,7 @@ public class FunctionCodegen extends ParentCodegenAwareImpl {
var += ownerType.getSize(); var += ownerType.getSize();
} }
List<JvmMethodParameterSignature> params = signature.getKotlinParameterTypes(); for (JvmMethodParameterSignature parameterSignature : signature.getKotlinParameterTypes()) {
for (int i = 0; i < params.size(); i++) {
JvmMethodParameterSignature parameterSignature = params.get(i);
if (parameterSignature.getKind() != JvmMethodParameterKind.VALUE) { if (parameterSignature.getKind() != JvmMethodParameterKind.VALUE) {
Type type = parameterSignature.getAsmType(); Type type = parameterSignature.getAsmType();
iv.load(var, type); iv.load(var, type);
@@ -767,7 +699,6 @@ public class FunctionCodegen extends ParentCodegenAwareImpl {
} }
private static void generateBridge( private static void generateBridge(
CodegenContext owner,
GenerationState state, GenerationState state,
ClassBuilder v, ClassBuilder v,
Method jvmSignature, Method jvmSignature,
@@ -30,7 +30,7 @@ import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
public abstract class FunctionGenerationStrategy { public abstract class FunctionGenerationStrategy {
private final Collection<String> localVariableNames = new ArrayList<String>();
private FrameMap frameMap; private FrameMap frameMap;
public abstract void generateBody( public abstract void generateBody(
@@ -40,15 +40,6 @@ public abstract class FunctionGenerationStrategy {
@Nullable MemberCodegen parentCodegen @Nullable MemberCodegen parentCodegen
); );
protected void addLocalVariableName(@NotNull String name) {
localVariableNames.add(name);
}
@NotNull
public Collection<String> getLocalVariableNames() {
return localVariableNames;
}
@NotNull @NotNull
protected FrameMap createFrameMap(@NotNull JetTypeMapper typeMapper, @NotNull MethodContext context) { protected FrameMap createFrameMap(@NotNull JetTypeMapper typeMapper, @NotNull MethodContext context) {
return context.prepareFrame(typeMapper); return context.prepareFrame(typeMapper);
@@ -99,15 +90,8 @@ public abstract class FunctionGenerationStrategy {
ExpressionCodegen codegen = new ExpressionCodegen(mv, getFrameMap(state.getTypeMapper(), context), ExpressionCodegen codegen = new ExpressionCodegen(mv, getFrameMap(state.getTypeMapper(), context),
signature.getAsmMethod().getReturnType(), context, state, parentCodegen); signature.getAsmMethod().getReturnType(), context, state, parentCodegen);
doGenerateBody(codegen, signature); doGenerateBody(codegen, signature);
generateLocalVarNames(codegen);
} }
public abstract void doGenerateBody(@NotNull ExpressionCodegen codegen, @NotNull JvmMethodSignature signature); public abstract void doGenerateBody(@NotNull ExpressionCodegen codegen, @NotNull JvmMethodSignature signature);
private void generateLocalVarNames(@NotNull ExpressionCodegen codegen) {
for (String name : codegen.getLocalVariableNamesForExpression()) {
addLocalVariableName(name);
}
}
} }
} }