CaprutedParamInfo refactoring
This commit is contained in:
@@ -32,6 +32,7 @@ import org.jetbrains.asm4.MethodVisitor;
|
||||
import org.jetbrains.asm4.Type;
|
||||
import org.jetbrains.asm4.commons.InstructionAdapter;
|
||||
import org.jetbrains.asm4.commons.Method;
|
||||
import org.jetbrains.asm4.tree.MethodNode;
|
||||
import org.jetbrains.jet.codegen.asm.InlineCodegen;
|
||||
import org.jetbrains.jet.codegen.asm.InlineCodegenUtil;
|
||||
import org.jetbrains.jet.codegen.asm.Inliner;
|
||||
@@ -85,7 +86,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
|
||||
|
||||
private int myLastLineNumber = -1;
|
||||
|
||||
final InstructionAdapter v;
|
||||
InstructionAdapter v;
|
||||
final MethodVisitor methodVisitor;
|
||||
final FrameMap myFrameMap;
|
||||
final JetTypeMapper typeMapper;
|
||||
|
||||
@@ -23,6 +23,7 @@ import org.jetbrains.asm4.Label;
|
||||
import org.jetbrains.asm4.Type;
|
||||
import org.jetbrains.asm4.commons.InstructionAdapter;
|
||||
import org.jetbrains.asm4.commons.Method;
|
||||
import org.jetbrains.asm4.tree.MethodNode;
|
||||
import org.jetbrains.jet.codegen.intrinsics.IntrinsicMethod;
|
||||
import org.jetbrains.jet.codegen.state.GenerationState;
|
||||
import org.jetbrains.jet.codegen.state.JetTypeMapper;
|
||||
@@ -364,7 +365,7 @@ public abstract class StackValue {
|
||||
}
|
||||
|
||||
public static class Local extends StackValue {
|
||||
final int index;
|
||||
public final int index;
|
||||
|
||||
private Local(int index, Type type) {
|
||||
super(type);
|
||||
@@ -811,9 +812,9 @@ public abstract class StackValue {
|
||||
}
|
||||
|
||||
|
||||
static class Field extends StackValueWithSimpleReceiver {
|
||||
final Type owner;
|
||||
final String name;
|
||||
public static class Field extends StackValueWithSimpleReceiver {
|
||||
public final Type owner;
|
||||
public final String name;
|
||||
|
||||
public Field(Type type, Type owner, String name, boolean isStatic) {
|
||||
super(type, isStatic);
|
||||
|
||||
@@ -18,6 +18,7 @@ package org.jetbrains.jet.codegen.asm;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.asm4.Type;
|
||||
import org.jetbrains.jet.codegen.StackValue;
|
||||
import org.jetbrains.jet.lang.resolve.java.AsmTypeConstants;
|
||||
|
||||
public class CapturedParamInfo extends ParameterInfo {
|
||||
@@ -30,8 +31,13 @@ public class CapturedParamInfo extends ParameterInfo {
|
||||
|
||||
public static final CapturedParamInfo STUB = new CapturedParamInfo("", AsmTypeConstants.OBJECT_TYPE, true, -1, -1);
|
||||
|
||||
public CapturedParamInfo(@NotNull String fieldName, @NotNull Type type, boolean skipped, int remapIndex, int index) {
|
||||
super(type, skipped, remapIndex, index);
|
||||
public CapturedParamInfo(@NotNull String fieldName, @NotNull Type type, boolean skipped, int index, int remapIndex) {
|
||||
super(type, skipped, index, remapIndex);
|
||||
this.fieldName = fieldName;
|
||||
}
|
||||
|
||||
public CapturedParamInfo(@NotNull String fieldName, @NotNull Type type, boolean skipped, int index, StackValue remapIndex) {
|
||||
super(type, skipped, index, remapIndex);
|
||||
this.fieldName = fieldName;
|
||||
}
|
||||
|
||||
@@ -55,4 +61,27 @@ public class CapturedParamInfo extends ParameterInfo {
|
||||
public void setRecapturedFrom(LambdaInfo recapturedFrom) {
|
||||
this.recapturedFrom = recapturedFrom;
|
||||
}
|
||||
|
||||
|
||||
public CapturedParamInfo newRemapIndex(int newRamapIndex) {
|
||||
return clone(index, newRamapIndex);
|
||||
}
|
||||
|
||||
public CapturedParamInfo newIndex(int newIndex) {
|
||||
return clone(newIndex, getRemapIndex());
|
||||
}
|
||||
|
||||
public CapturedParamInfo clone(int newIndex, int newRamapIndex) {
|
||||
CapturedParamInfo capturedParamInfo = new CapturedParamInfo(fieldName, type, isSkipped, newIndex, newRamapIndex);
|
||||
capturedParamInfo.setLambda(lambda);
|
||||
capturedParamInfo.setRecapturedFrom(recapturedFrom);
|
||||
return capturedParamInfo;
|
||||
}
|
||||
|
||||
public CapturedParamInfo clone(int newIndex, StackValue newRamapIndex) {
|
||||
CapturedParamInfo capturedParamInfo = new CapturedParamInfo(fieldName, type, isSkipped, newIndex, newRamapIndex);
|
||||
capturedParamInfo.setLambda(lambda);
|
||||
capturedParamInfo.setRecapturedFrom(recapturedFrom);
|
||||
return capturedParamInfo;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,6 +38,7 @@ import org.jetbrains.jet.codegen.state.GenerationState;
|
||||
import org.jetbrains.jet.codegen.state.JetTypeMapper;
|
||||
import org.jetbrains.jet.descriptors.serialization.descriptors.DeserializedSimpleFunctionDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.*;
|
||||
import org.jetbrains.jet.lang.descriptors.impl.AnonymousFunctionDescriptor;
|
||||
import org.jetbrains.jet.lang.psi.*;
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||
import org.jetbrains.jet.lang.resolve.BindingContextUtils;
|
||||
@@ -191,7 +192,7 @@ public class InlineCodegen implements ParentCodegenAware, Inliner {
|
||||
codegen.getContext(), call);
|
||||
MethodInliner inliner = new MethodInliner(node, parameters, info, null, new LambdaFieldRemapper()); //with captured
|
||||
|
||||
VarRemapper.ParamRemapper remapper = new VarRemapper.ParamRemapper(parameters, new VarRemapper.ShiftRemapper(initialFrameSize, null));
|
||||
VarRemapper.ParamRemapper remapper = new VarRemapper.ParamRemapper(parameters, initialFrameSize);
|
||||
|
||||
inliner.doTransformAndMerge(codegen.getInstructionAdapter(), remapper);
|
||||
generateClosuresBodies();
|
||||
@@ -245,13 +246,13 @@ public class InlineCodegen implements ParentCodegenAware, Inliner {
|
||||
if (!disabled && notSeparateInline && Type.VOID_TYPE != type) {
|
||||
//TODO remap only inlinable closure => otherwise we could get a lot of problem
|
||||
boolean couldBeRemapped = !shouldPutValue(type, stackValue, codegen.getContext(), valueParameterDescriptor);
|
||||
int remappedIndex = couldBeRemapped ? ((StackValue.Local) stackValue).getIndex() : -1;
|
||||
StackValue remappedIndex = couldBeRemapped ? stackValue : null;
|
||||
|
||||
ParameterInfo info = new ParameterInfo(type, false, remappedIndex, couldBeRemapped ? -1 : codegen.getFrameMap().enterTemp(type));
|
||||
ParameterInfo info = new ParameterInfo(type, false, couldBeRemapped ? -1 : codegen.getFrameMap().enterTemp(type), remappedIndex);
|
||||
|
||||
if (index >= 0 && couldBeRemapped) {
|
||||
CapturedParamInfo capturedParamInfo = activeLambda.getCapturedVars().get(index);
|
||||
capturedParamInfo.setRemapIndex(info.getInlinedIndex());
|
||||
capturedParamInfo.setRemapIndex(remappedIndex != null ? remappedIndex : StackValue.local(info.getIndex(), info.getType()));
|
||||
}
|
||||
|
||||
doWithParameter(info);
|
||||
@@ -267,7 +268,17 @@ public class InlineCodegen implements ParentCodegenAware, Inliner {
|
||||
// return false;
|
||||
// }
|
||||
//}
|
||||
return false == (stackValue != null && stackValue instanceof StackValue.Local);
|
||||
boolean shouldPut = false == (stackValue != null && stackValue instanceof StackValue.Local);
|
||||
if (shouldPut) {
|
||||
//we could recapture field of anonymous objects cause they couldn't change
|
||||
if ((stackValue instanceof StackValue.Extension || stackValue instanceof StackValue.Field) && codegen.getContext().getContextDescriptor() instanceof AnonymousFunctionDescriptor) {
|
||||
if (descriptor != null && !InlineUtil.hasNoinlineAnnotation(descriptor)) {
|
||||
//check type of context
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return shouldPut;
|
||||
}
|
||||
|
||||
private void doWithParameter(ParameterInfo info) {
|
||||
@@ -301,7 +312,7 @@ public class InlineCodegen implements ParentCodegenAware, Inliner {
|
||||
|
||||
if (!isStaticMethod(functionDescriptor, context)) {
|
||||
Type type = AsmTypeConstants.OBJECT_TYPE;
|
||||
ParameterInfo info = new ParameterInfo(type, false, -1, codegen.getFrameMap().enterTemp(type));
|
||||
ParameterInfo info = new ParameterInfo(type, false, codegen.getFrameMap().enterTemp(type), -1);
|
||||
recordParamInfo(info, false);
|
||||
}
|
||||
|
||||
@@ -310,7 +321,7 @@ public class InlineCodegen implements ParentCodegenAware, Inliner {
|
||||
break;
|
||||
}
|
||||
Type type = param.getAsmType();
|
||||
ParameterInfo info = new ParameterInfo(type, false, -1, codegen.getFrameMap().enterTemp(type));
|
||||
ParameterInfo info = new ParameterInfo(type, false, codegen.getFrameMap().enterTemp(type), -1);
|
||||
recordParamInfo(info, false);
|
||||
}
|
||||
|
||||
|
||||
@@ -59,9 +59,9 @@ public class InlineFieldRemapper extends LambdaFieldRemapper {
|
||||
|
||||
AbstractInsnNode prev = getPreviousNoLabelNoLine(fieldInsnNode);
|
||||
|
||||
assert prev.getType() == AbstractInsnNode.VAR_INSN;
|
||||
VarInsnNode loadThis = (VarInsnNode) prev;
|
||||
assert /*loadThis.var == info.getCapturedVarsSize() - 1 && */loadThis.getOpcode() == Opcodes.ALOAD;
|
||||
assert prev.getType() == AbstractInsnNode.VAR_INSN || prev.getType() == AbstractInsnNode.FIELD_INSN;
|
||||
AbstractInsnNode loadThis = prev;
|
||||
assert /*loadThis.var == info.getCapturedVarsSize() - 1 && */loadThis.getOpcode() == Opcodes.ALOAD || loadThis.getOpcode() == Opcodes.GETSTATIC;
|
||||
|
||||
int opcode = Opcodes.GETSTATIC;
|
||||
|
||||
|
||||
@@ -33,9 +33,10 @@ public class LambdaFieldRemapper {
|
||||
public AbstractInsnNode doTransform(MethodNode node, FieldInsnNode fieldInsnNode, CapturedParamInfo capturedField) {
|
||||
AbstractInsnNode prev = getPreviousNoLabelNoLine(fieldInsnNode);
|
||||
|
||||
assert prev.getType() == AbstractInsnNode.VAR_INSN;
|
||||
VarInsnNode loadThis = (VarInsnNode) prev;
|
||||
assert /*loadThis.var == info.getCapturedVarsSize() - 1 && */loadThis.getOpcode() == Opcodes.ALOAD;
|
||||
assert prev.getType() == AbstractInsnNode.VAR_INSN || prev.getType() == AbstractInsnNode.FIELD_INSN;
|
||||
AbstractInsnNode loadThis = prev;
|
||||
int opcode1 = loadThis.getOpcode();
|
||||
assert /*loadThis.var == info.getCapturedVarsSize() - 1 && */opcode1 == Opcodes.ALOAD || opcode1 == Opcodes.GETSTATIC;
|
||||
|
||||
int opcode = fieldInsnNode.getOpcode() == Opcodes.GETFIELD ? capturedField.getType().getOpcode(Opcodes.ILOAD) : capturedField.getType().getOpcode(Opcodes.ISTORE);
|
||||
VarInsnNode insn = new VarInsnNode(opcode, capturedField.getIndex());
|
||||
|
||||
@@ -25,11 +25,9 @@ import org.jetbrains.jet.codegen.context.EnclosedValueDescriptor;
|
||||
import org.jetbrains.jet.codegen.state.JetTypeMapper;
|
||||
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor;
|
||||
import org.jetbrains.jet.lang.psi.JetFunctionLiteral;
|
||||
import org.jetbrains.jet.lang.psi.JetFunctionLiteralExpression;
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||
import org.jetbrains.jet.lang.resolve.java.JvmClassName;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
@@ -125,7 +123,7 @@ public class LambdaInfo {
|
||||
|
||||
@NotNull
|
||||
public static CapturedParamInfo getCapturedParamInfo(@NotNull EnclosedValueDescriptor descriptor, int index) {
|
||||
return new CapturedParamInfo(descriptor.getFieldName(), descriptor.getType(), false, -1, index);
|
||||
return new CapturedParamInfo(descriptor.getFieldName(), descriptor.getType(), false, index, -1);
|
||||
}
|
||||
|
||||
private void shiftParams(int shift) {
|
||||
|
||||
@@ -18,7 +18,6 @@ package org.jetbrains.jet.codegen.asm;
|
||||
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.asm4.*;
|
||||
@@ -34,7 +33,6 @@ import org.jetbrains.jet.codegen.ClosureCodegen;
|
||||
import org.jetbrains.jet.codegen.FieldInfo;
|
||||
import org.jetbrains.jet.codegen.state.GenerationState;
|
||||
import org.jetbrains.jet.codegen.state.JetTypeMapper;
|
||||
import org.jetbrains.jet.lang.resolve.BindingContextUtils;
|
||||
import org.jetbrains.jet.lang.resolve.name.FqName;
|
||||
|
||||
import java.io.IOException;
|
||||
@@ -125,7 +123,7 @@ public class LambdaTransformer {
|
||||
InlineFieldRemapper remapper = new InlineFieldRemapper(oldLambdaType.getInternalName(), newLambdaType.getInternalName(), parameters, invocation.getRecapturedLambdas());
|
||||
MethodInliner inliner = new MethodInliner(invoke, parameters, info.subInline(info.nameGenerator.subGenerator("lambda")), oldLambdaType,
|
||||
remapper);
|
||||
inliner.doTransformAndMerge(invokeVisitor, new VarRemapper.ParamRemapper(parameters, null), remapper, false);
|
||||
inliner.doTransformAndMerge(invokeVisitor, new VarRemapper.ParamRemapper(parameters, 0), remapper, false);
|
||||
invokeVisitor.visitMaxs(-1, -1);
|
||||
|
||||
generateConstructorAndFields(classBuilder, builder, invocation);
|
||||
|
||||
@@ -158,7 +158,7 @@ public class MethodInliner {
|
||||
MethodInliner inliner = new MethodInliner(info.getNode(), params, parent.subInline(parent.nameGenerator.subGenerator("lambda")), info.getLambdaClassType(),
|
||||
capturedRemapper);
|
||||
|
||||
VarRemapper.ParamRemapper remapper = new VarRemapper.ParamRemapper(params, new VarRemapper.ShiftRemapper(valueParamShift, null));
|
||||
VarRemapper.ParamRemapper remapper = new VarRemapper.ParamRemapper(params, valueParamShift);
|
||||
inliner.doTransformAndMerge(this.mv, remapper); //TODO add skipped this and receiver
|
||||
|
||||
Method bridge = typeMapper.mapSignature(ClosureCodegen.getInvokeFunction(info.getFunctionDescriptor())).getAsmMethod();
|
||||
@@ -343,7 +343,7 @@ public class MethodInliner {
|
||||
for (ValueParameterDescriptor parameter : valueParameters) {
|
||||
Type type = typeMapper.mapType(parameter.getType());
|
||||
int paramIndex = index++;
|
||||
result.add(new ParameterInfo(type, false, -1, paramIndex));
|
||||
result.add(new ParameterInfo(type, false, paramIndex, -1));
|
||||
if (type.getSize() == 2) {
|
||||
result.add(ParameterInfo.STUB);
|
||||
}
|
||||
@@ -351,7 +351,7 @@ public class MethodInliner {
|
||||
} else {
|
||||
for (Type type : types) {
|
||||
int paramIndex = index++;
|
||||
result.add(new ParameterInfo(type, false, -1, paramIndex));
|
||||
result.add(new ParameterInfo(type, false, paramIndex, -1));
|
||||
if (type.getSize() == 2) {
|
||||
result.add(ParameterInfo.STUB);
|
||||
}
|
||||
|
||||
@@ -17,45 +17,46 @@
|
||||
package org.jetbrains.jet.codegen.asm;
|
||||
|
||||
import org.jetbrains.asm4.Type;
|
||||
import org.jetbrains.jet.codegen.StackValue;
|
||||
import org.jetbrains.jet.lang.resolve.java.AsmTypeConstants;
|
||||
|
||||
class ParameterInfo {
|
||||
|
||||
public static final ParameterInfo STUB = new ParameterInfo(AsmTypeConstants.OBJECT_TYPE, true, -1, -1);
|
||||
|
||||
private int index;
|
||||
protected final int index;
|
||||
|
||||
public final Type type;
|
||||
|
||||
public final boolean isSkipped;
|
||||
|
||||
private int remapIndex;
|
||||
private StackValue remapIndex;
|
||||
|
||||
public LambdaInfo lambda;
|
||||
|
||||
ParameterInfo(Type type, boolean skipped, int remapIndex, int index) {
|
||||
ParameterInfo(Type type, boolean skipped, int index, int remapIndex) {
|
||||
this(type, skipped, index, remapIndex == -1 ? null : StackValue.local(remapIndex, type));
|
||||
}
|
||||
|
||||
ParameterInfo(Type type, boolean skipped, int index, StackValue stackValue) {
|
||||
this.type = type;
|
||||
this.isSkipped = skipped;
|
||||
this.remapIndex = remapIndex;
|
||||
this.remapIndex = stackValue;
|
||||
this.index = index;
|
||||
}
|
||||
|
||||
public boolean isSkippedOrRemapped() {
|
||||
return isSkipped || remapIndex != -1;
|
||||
return isSkipped || remapIndex != null;
|
||||
}
|
||||
|
||||
public boolean isRemapped() {
|
||||
return remapIndex != -1;
|
||||
return remapIndex != null;
|
||||
}
|
||||
|
||||
public int getRemapIndex() {
|
||||
public StackValue getRemapIndex() {
|
||||
return remapIndex;
|
||||
}
|
||||
|
||||
public int getInlinedIndex() {
|
||||
return remapIndex != -1 ? getRemapIndex() : getIndex();
|
||||
}
|
||||
|
||||
public int getIndex() {
|
||||
return index;
|
||||
}
|
||||
@@ -78,10 +79,10 @@ class ParameterInfo {
|
||||
}
|
||||
|
||||
public void setRemapIndex(int remapIndex) {
|
||||
this.remapIndex = remapIndex;
|
||||
this.remapIndex = StackValue.local(remapIndex, type);
|
||||
}
|
||||
|
||||
public void setIndex(int index) {
|
||||
this.index = index;
|
||||
public void setRemapIndex(StackValue remapIndex) {
|
||||
this.remapIndex = remapIndex;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -63,12 +63,7 @@ public class Parameters implements Iterable<ParameterInfo> {
|
||||
public static List<CapturedParamInfo> transformList(List<CapturedParamInfo> capturedParams, int realSize) {
|
||||
List<CapturedParamInfo> result = new ArrayList<CapturedParamInfo>();
|
||||
for (CapturedParamInfo capturedParamInfo : capturedParams) {
|
||||
CapturedParamInfo newInfo =
|
||||
new CapturedParamInfo(capturedParamInfo.getFieldName(), capturedParamInfo.getType(), capturedParamInfo.isSkipped,
|
||||
capturedParamInfo.getIndex(), result.size() + realSize);
|
||||
|
||||
newInfo.setLambda(capturedParamInfo.getLambda());
|
||||
newInfo.setRecapturedFrom(capturedParamInfo.getRecapturedFrom());
|
||||
CapturedParamInfo newInfo = capturedParamInfo.clone(result.size() + realSize, capturedParamInfo.getIndex());
|
||||
|
||||
result.add(newInfo);
|
||||
|
||||
@@ -82,10 +77,7 @@ public class Parameters implements Iterable<ParameterInfo> {
|
||||
public static List<CapturedParamInfo> addStubs(List<CapturedParamInfo> capturedParams, int realSize) {
|
||||
List<CapturedParamInfo> result = new ArrayList<CapturedParamInfo>();
|
||||
for (CapturedParamInfo capturedParamInfo : capturedParams) {
|
||||
CapturedParamInfo newInfo = new CapturedParamInfo(capturedParamInfo.getFieldName(), capturedParamInfo.getType(), capturedParamInfo.isSkipped,
|
||||
capturedParamInfo.getRemapIndex(), result.size() + realSize);
|
||||
newInfo.setLambda(capturedParamInfo.getLambda());
|
||||
newInfo.setRecapturedFrom(capturedParamInfo.getRecapturedFrom());
|
||||
CapturedParamInfo newInfo = capturedParamInfo.newIndex(result.size() + realSize);
|
||||
result.add(newInfo);
|
||||
if (capturedParamInfo.getType().getSize() == 2) {
|
||||
result.add(CapturedParamInfo.STUB);
|
||||
|
||||
@@ -37,25 +37,26 @@ public class ParametersBuilder {
|
||||
}
|
||||
|
||||
public ParametersBuilder addThis(Type type, boolean skipped) {
|
||||
addParameter(new ParameterInfo(type, skipped, -1, nextIndex));
|
||||
addParameter(new ParameterInfo(type, skipped, nextIndex, -1));
|
||||
return this;
|
||||
}
|
||||
|
||||
public ParametersBuilder addNextParameter(Type type, boolean skipped, @Nullable ParameterInfo original) {
|
||||
addParameter(new ParameterInfo(type, skipped, original != null ? original.getIndex() : -1 , nextIndex));
|
||||
addParameter(new ParameterInfo(type, skipped, nextIndex, original != null ? original.getIndex() : -1));
|
||||
return this;
|
||||
}
|
||||
|
||||
public CapturedParamInfo addCapturedParam(String fieldName, Type type, boolean skipped, @Nullable ParameterInfo original) {
|
||||
return addCapturedParameter(new CapturedParamInfo(fieldName, type, skipped, original != null ? original.getIndex() : -1, nextCaptured));
|
||||
return addCapturedParameter(new CapturedParamInfo(fieldName, type, skipped, nextCaptured,
|
||||
original != null ? original.getIndex() : -1));
|
||||
}
|
||||
|
||||
public CapturedParamInfo addAdditionalCapturedParam(String fieldName, Type type, boolean skipped, @Nullable ParameterInfo original) {
|
||||
CapturedParamInfo capturedParamInfo =
|
||||
new CapturedParamInfo(fieldName, type, skipped, original != null ? original.getIndex() : -1, nextCaptured);
|
||||
additionalCapturedParams.add(capturedParamInfo);
|
||||
return capturedParamInfo;
|
||||
}
|
||||
//public CapturedParamInfo addAdditionalCapturedParam(String fieldName, Type type, boolean skipped, @Nullable ParameterInfo original) {
|
||||
// CapturedParamInfo capturedParamInfo =
|
||||
// new CapturedParamInfo(fieldName, type, skipped, original != null ? original.getIndex() : -1, nextCaptured);
|
||||
// additionalCapturedParams.add(capturedParamInfo);
|
||||
// return capturedParamInfo;
|
||||
//}
|
||||
|
||||
private void addParameter(ParameterInfo info) {
|
||||
params.add(info);
|
||||
|
||||
@@ -30,7 +30,7 @@ public class RemapVisitor extends InstructionAdapter {
|
||||
|
||||
private final boolean remapReturn;
|
||||
|
||||
protected RemapVisitor(MethodVisitor mv, Label end, VarRemapper remapper, boolean remapReturn) {
|
||||
protected RemapVisitor(MethodVisitor mv, Label end, VarRemapper.ParamRemapper remapper, boolean remapReturn) {
|
||||
super(InlineCodegenUtil.API, mv);
|
||||
this.end = end;
|
||||
this.remapper = remapper;
|
||||
@@ -49,13 +49,12 @@ public class RemapVisitor extends InstructionAdapter {
|
||||
|
||||
@Override
|
||||
public void visitIincInsn(int var, int increment) {
|
||||
super.visitIincInsn(remapper.remap(var), increment);
|
||||
remapper.visitIincInsn(var, increment, mv);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitVarInsn(int opcode, int var) {
|
||||
int newVar = remapper.remap(var);
|
||||
super.visitVarInsn(opcode, newVar);
|
||||
remapper.visitVarInsn(opcode, var, new InstructionAdapter(mv));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -16,72 +16,41 @@
|
||||
|
||||
package org.jetbrains.jet.codegen.asm;
|
||||
|
||||
import java.util.List;
|
||||
import org.jetbrains.asm4.MethodVisitor;
|
||||
import org.jetbrains.asm4.Opcodes;
|
||||
import org.jetbrains.asm4.Type;
|
||||
import org.jetbrains.asm4.commons.InstructionAdapter;
|
||||
import org.jetbrains.asm4.tree.FieldInsnNode;
|
||||
import org.jetbrains.jet.codegen.StackValue;
|
||||
import org.jetbrains.jet.lang.resolve.java.AsmTypeConstants;
|
||||
|
||||
public abstract class VarRemapper {
|
||||
|
||||
|
||||
|
||||
public static class ShiftRemapper extends VarRemapper {
|
||||
|
||||
private final int shift;
|
||||
|
||||
public ShiftRemapper(int shift, VarRemapper remapper) {
|
||||
super(remapper);
|
||||
this.shift = shift;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int doRemap(int index) {
|
||||
return index + shift;
|
||||
}
|
||||
}
|
||||
|
||||
public static class ClosureRemapper extends ShiftRemapper {
|
||||
|
||||
private final LambdaInfo info;
|
||||
private final List<ParameterInfo> originalParams;
|
||||
private final int capturedSize;
|
||||
|
||||
public ClosureRemapper(LambdaInfo info, int valueParametersShift, List<ParameterInfo> originalParams) {
|
||||
super(valueParametersShift, null);
|
||||
this.info = info;
|
||||
this.originalParams = originalParams;
|
||||
capturedSize = info.getCapturedVarsSize();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int doRemap(int index) {
|
||||
if (index < capturedSize) {
|
||||
return originalParams.get(info.getParamOffset() + index).getInlinedIndex();
|
||||
}
|
||||
return super.doRemap(index - capturedSize);
|
||||
}
|
||||
}
|
||||
|
||||
public static class ParamRemapper extends VarRemapper {
|
||||
|
||||
private final int allParamsSize;
|
||||
private final Parameters params;
|
||||
private final int actualParamsSize;
|
||||
|
||||
private final int [] remapIndex;
|
||||
private final StackValue [] remapIndex;
|
||||
|
||||
public ParamRemapper(Parameters params, VarRemapper parent) {
|
||||
super(parent);
|
||||
private int additionalShift;
|
||||
|
||||
public ParamRemapper(Parameters params, int additionalShift) {
|
||||
this.additionalShift = additionalShift;
|
||||
this.allParamsSize = params.totalSize();
|
||||
this.params = params;
|
||||
|
||||
int realSize = 0;
|
||||
remapIndex = new int [params.totalSize()];
|
||||
remapIndex = new StackValue [params.totalSize()];
|
||||
|
||||
int index = 0;
|
||||
for (ParameterInfo info : params) {
|
||||
if (!info.isSkippedOrRemapped()) {
|
||||
remapIndex[index] = realSize;
|
||||
remapIndex[index] = StackValue.local(realSize, AsmTypeConstants.OBJECT_TYPE);
|
||||
realSize += info.getType().getSize();
|
||||
} else {
|
||||
remapIndex[index] = info.isRemapped() ? info.getRemapIndex() : -1;
|
||||
remapIndex[index] = info.isRemapped() ? info.getRemapIndex() : null;
|
||||
}
|
||||
index++;
|
||||
}
|
||||
@@ -90,59 +59,51 @@ public abstract class VarRemapper {
|
||||
}
|
||||
|
||||
@Override
|
||||
public int doRemap(int index) {
|
||||
public StackValue doRemap(int index) {
|
||||
int remappedIndex;
|
||||
|
||||
if (index < allParamsSize) {
|
||||
ParameterInfo info = params.get(index);
|
||||
remappedIndex = remapIndex[index];
|
||||
if (info.isSkipped || remappedIndex == -1) {
|
||||
StackValue remapped = remapIndex[index];
|
||||
if (info.isSkipped || remapped == null) {
|
||||
throw new RuntimeException("Trying to access skipped parameter: " + info.type + " at " +index);
|
||||
}
|
||||
if (info.isRemapped()) {
|
||||
return remappedIndex;
|
||||
return remapped;
|
||||
} else {
|
||||
remappedIndex = ((StackValue.Local)remapped).index;
|
||||
}
|
||||
} else {
|
||||
remappedIndex = actualParamsSize - params.totalSize() + index; //captured params not used directly in this inlined method, they used in closure
|
||||
}
|
||||
|
||||
if (parent == null) {
|
||||
return remappedIndex;
|
||||
}
|
||||
|
||||
return parent.doRemap(remappedIndex);
|
||||
return StackValue.local(remappedIndex + additionalShift, AsmTypeConstants.OBJECT_TYPE);
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean nestedRemmapper;
|
||||
|
||||
protected VarRemapper parent;
|
||||
|
||||
public VarRemapper(VarRemapper parent) {
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
public int remap(int index) {
|
||||
if (nestedRemmapper) {
|
||||
return index;
|
||||
}
|
||||
public StackValue remap(int index) {
|
||||
return doRemap(index);
|
||||
}
|
||||
|
||||
abstract public int doRemap(int index);
|
||||
|
||||
public void setNestedRemap(boolean nestedRemap) {
|
||||
nestedRemmapper = nestedRemap;
|
||||
public void visitIincInsn(int var, int increment, MethodVisitor mv) {
|
||||
StackValue remap = remap(var);
|
||||
assert remap instanceof StackValue.Local;
|
||||
mv.visitIincInsn(((StackValue.Local) remap).index, increment);
|
||||
}
|
||||
|
||||
|
||||
public static int getActualSize(List<ParameterInfo> params) {
|
||||
int size = 0;
|
||||
for (ParameterInfo paramInfo : params) {
|
||||
if (!paramInfo.isSkippedOrRemapped()) {
|
||||
size += paramInfo.getType().getSize();
|
||||
}
|
||||
public void visitVarInsn(int opcode, int var, InstructionAdapter mv) {
|
||||
StackValue remap = remap(var);
|
||||
if (remap instanceof StackValue.Local) {
|
||||
mv.visitVarInsn(opcode, ((StackValue.Local) remap).index);
|
||||
} else {
|
||||
//Type stub = Type.getObjectType("STUB");
|
||||
//String descriptor = stub.getDescriptor();
|
||||
//
|
||||
//mv.visitFieldInsn(Opcodes.GETSTATIC, stub.getInternalName(), "$$$this$skip", descriptor);
|
||||
remap.put(remap.type, mv);
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
abstract public StackValue doRemap(int index);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user