Revert "Introduce a stackmap frame verifier for CF code"
This reverts commit 01161586431ad4e286177dec855daf0183ed6392.
Revert "Test stackmap validation of method with handlers and no frames"
This reverts commit 6fba3ad26661dc50480b3a8edaa9b5a8e2d0ef9b.
Change-Id: I41587f0d6b1b1a8178ca6e130c4525811e5c4c95
Reason for revert: Breaks bots
diff --git a/src/main/java/com/android/tools/r8/L8.java b/src/main/java/com/android/tools/r8/L8.java
index 45fdff1..332b864 100644
--- a/src/main/java/com/android/tools/r8/L8.java
+++ b/src/main/java/com/android/tools/r8/L8.java
@@ -93,24 +93,15 @@
ExceptionUtils.withD8CompilationHandler(
options.reporter,
() -> {
- // TODO(b/164396438): Remove when stack map tables are fixed.
- options.testing.readInputStackMaps = false;
options.cfToCfDesugar = true;
desugar(app, options, executorService);
options.cfToCfDesugar = false;
});
assert !options.cfToCfDesugar;
if (shrink) {
- AndroidApp r8CommandInputApp = r8Command.getInputApp();
- InternalOptions r8CommandInternalOptions = r8Command.getInternalOptions();
- // TODO(b/164396438): Remove when stack map tables are fixed.
- r8CommandInternalOptions.testing.readInputStackMaps = false;
- R8.runForTesting(r8CommandInputApp, r8CommandInternalOptions);
+ R8.run(r8Command, executorService);
} else if (d8Command != null) {
- InternalOptions d8InternalOptions = d8Command.getInternalOptions();
- // TODO(b/164396438): Remove when stack map tables are fixed.
- d8InternalOptions.testing.readInputStackMaps = false;
- D8.runForTesting(d8Command.getInputApp(), d8InternalOptions);
+ D8.run(d8Command, executorService);
}
} finally {
executorService.shutdown();
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfArithmeticBinop.java b/src/main/java/com/android/tools/r8/cf/code/CfArithmeticBinop.java
index 9bdd175..f128f76 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfArithmeticBinop.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfArithmeticBinop.java
@@ -4,11 +4,9 @@
package com.android.tools.r8.cf.code;
import com.android.tools.r8.cf.CfPrinter;
-import com.android.tools.r8.cf.code.CfFrame.FrameType;
import com.android.tools.r8.errors.Unreachable;
import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.graph.DexProgramClass;
-import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.GraphLens;
import com.android.tools.r8.graph.InitClassLens;
import com.android.tools.r8.graph.ProgramMethod;
@@ -183,17 +181,4 @@
InliningConstraints inliningConstraints, DexProgramClass context) {
return inliningConstraints.forBinop();
}
-
- @Override
- public void evaluate(
- CfFrameVerificationHelper frameBuilder,
- DexType context,
- DexType returnType,
- DexItemFactory factory,
- InitClassLens initClassLens) {
- // ..., value1, value2 →
- // ..., result
- FrameType frameType = FrameType.fromNumericType(type, factory);
- frameBuilder.popAndDiscard(frameType, frameType).push(frameType);
- }
}
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfArrayLength.java b/src/main/java/com/android/tools/r8/cf/code/CfArrayLength.java
index 445f48c..5757b8c 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfArrayLength.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfArrayLength.java
@@ -6,7 +6,6 @@
import com.android.tools.r8.cf.CfPrinter;
import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.graph.DexProgramClass;
-import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.GraphLens;
import com.android.tools.r8.graph.InitClassLens;
import com.android.tools.r8.graph.ProgramMethod;
@@ -58,16 +57,4 @@
InliningConstraints inliningConstraints, DexProgramClass context) {
return inliningConstraints.forArrayLength();
}
-
- @Override
- public void evaluate(
- CfFrameVerificationHelper frameBuilder,
- DexType context,
- DexType returnType,
- DexItemFactory factory,
- InitClassLens initClassLens) {
- // ..., arrayref →
- // ..., length
- frameBuilder.popAndDiscard(factory.objectArrayType).push(factory.intType);
- }
}
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfArrayLoad.java b/src/main/java/com/android/tools/r8/cf/code/CfArrayLoad.java
index 3fe2ab4..7993e8e 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfArrayLoad.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfArrayLoad.java
@@ -4,11 +4,9 @@
package com.android.tools.r8.cf.code;
import com.android.tools.r8.cf.CfPrinter;
-import com.android.tools.r8.cf.code.CfFrame.FrameType;
import com.android.tools.r8.errors.Unreachable;
import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.graph.DexProgramClass;
-import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.GraphLens;
import com.android.tools.r8.graph.InitClassLens;
import com.android.tools.r8.graph.ProgramMethod;
@@ -104,17 +102,4 @@
InliningConstraints inliningConstraints, DexProgramClass context) {
return inliningConstraints.forArrayGet();
}
-
- @Override
- public void evaluate(
- CfFrameVerificationHelper frameBuilder,
- DexType context,
- DexType returnType,
- DexItemFactory factory,
- InitClassLens initClassLens) {
- // ..., arrayref, index →
- // ..., value
- frameBuilder.popAndDiscard(factory.objectArrayType, factory.intType);
- frameBuilder.push(FrameType.fromMemberType(type, factory));
- }
}
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfArrayStore.java b/src/main/java/com/android/tools/r8/cf/code/CfArrayStore.java
index 7fbdbe5..1c16397 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfArrayStore.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfArrayStore.java
@@ -4,11 +4,9 @@
package com.android.tools.r8.cf.code;
import com.android.tools.r8.cf.CfPrinter;
-import com.android.tools.r8.cf.code.CfFrame.FrameType;
import com.android.tools.r8.errors.Unreachable;
import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.graph.DexProgramClass;
-import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.GraphLens;
import com.android.tools.r8.graph.InitClassLens;
import com.android.tools.r8.graph.ProgramMethod;
@@ -94,18 +92,4 @@
InliningConstraints inliningConstraints, DexProgramClass context) {
return inliningConstraints.forArrayPut();
}
-
- @Override
- public void evaluate(
- CfFrameVerificationHelper frameBuilder,
- DexType context,
- DexType returnType,
- DexItemFactory factory,
- InitClassLens initClassLens) {
- // ..., arrayref, index, value →
- // ...
- frameBuilder
- .popAndDiscard(FrameType.fromMemberType(type, factory))
- .popAndDiscard(factory.objectArrayType, factory.intType);
- }
}
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfCheckCast.java b/src/main/java/com/android/tools/r8/cf/code/CfCheckCast.java
index 632c6b8..e263d02 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfCheckCast.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfCheckCast.java
@@ -76,16 +76,4 @@
InliningConstraints inliningConstraints, DexProgramClass context) {
return inliningConstraints.forCheckCast(type, context);
}
-
- @Override
- public void evaluate(
- CfFrameVerificationHelper frameBuilder,
- DexType context,
- DexType returnType,
- DexItemFactory factory,
- InitClassLens initClassLens) {
- // ..., objectref →
- // ..., objectref
- frameBuilder.popAndDiscard(factory.objectType).push(type);
- }
}
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfCmp.java b/src/main/java/com/android/tools/r8/cf/code/CfCmp.java
index 7692221..1eeb6b4 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfCmp.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfCmp.java
@@ -4,11 +4,9 @@
package com.android.tools.r8.cf.code;
import com.android.tools.r8.cf.CfPrinter;
-import com.android.tools.r8.cf.code.CfFrame.FrameType;
import com.android.tools.r8.errors.Unreachable;
import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.graph.DexProgramClass;
-import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.GraphLens;
import com.android.tools.r8.graph.InitClassLens;
import com.android.tools.r8.graph.ProgramMethod;
@@ -108,17 +106,4 @@
InliningConstraints inliningConstraints, DexProgramClass context) {
return inliningConstraints.forBinop();
}
-
- @Override
- public void evaluate(
- CfFrameVerificationHelper frameBuilder,
- DexType context,
- DexType returnType,
- DexItemFactory factory,
- InitClassLens initClassLens) {
- // ..., value1, value2 →
- // ..., result
- FrameType frameType = FrameType.fromNumericType(type, factory);
- frameBuilder.popAndDiscard(frameType, frameType).push(factory.intType);
- }
}
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfConstClass.java b/src/main/java/com/android/tools/r8/cf/code/CfConstClass.java
index 2f311ca..2bb2444 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfConstClass.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfConstClass.java
@@ -99,16 +99,4 @@
InliningConstraints inliningConstraints, DexProgramClass context) {
return inliningConstraints.forConstClass(type, context);
}
-
- @Override
- public void evaluate(
- CfFrameVerificationHelper frameBuilder,
- DexType context,
- DexType returnType,
- DexItemFactory factory,
- InitClassLens initClassLens) {
- // ... →
- // ..., value
- frameBuilder.push(factory.classType);
- }
}
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfConstMethodHandle.java b/src/main/java/com/android/tools/r8/cf/code/CfConstMethodHandle.java
index 4fdcae7..d058eca 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfConstMethodHandle.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfConstMethodHandle.java
@@ -8,7 +8,6 @@
import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.graph.DexMethodHandle;
import com.android.tools.r8.graph.DexProgramClass;
-import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.GraphLens;
import com.android.tools.r8.graph.InitClassLens;
import com.android.tools.r8.graph.ProgramMethod;
@@ -77,16 +76,4 @@
InliningConstraints inliningConstraints, DexProgramClass context) {
return inliningConstraints.forConstMethodHandle();
}
-
- @Override
- public void evaluate(
- CfFrameVerificationHelper frameBuilder,
- DexType context,
- DexType returnType,
- DexItemFactory factory,
- InitClassLens initClassLens) {
- // ... →
- // ..., value
- frameBuilder.push(factory.methodHandleType);
- }
}
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfConstMethodType.java b/src/main/java/com/android/tools/r8/cf/code/CfConstMethodType.java
index 091da44..e59a64e 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfConstMethodType.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfConstMethodType.java
@@ -8,7 +8,6 @@
import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.graph.DexProgramClass;
import com.android.tools.r8.graph.DexProto;
-import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.GraphLens;
import com.android.tools.r8.graph.InitClassLens;
import com.android.tools.r8.graph.ProgramMethod;
@@ -75,16 +74,4 @@
InliningConstraints inliningConstraints, DexProgramClass context) {
return inliningConstraints.forConstMethodType();
}
-
- @Override
- public void evaluate(
- CfFrameVerificationHelper frameBuilder,
- DexType context,
- DexType returnType,
- DexItemFactory factory,
- InitClassLens initClassLens) {
- // ... →
- // ..., value
- frameBuilder.push(factory.methodTypeType);
- }
}
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfConstNull.java b/src/main/java/com/android/tools/r8/cf/code/CfConstNull.java
index 70da104..e5740e7 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfConstNull.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfConstNull.java
@@ -6,7 +6,6 @@
import com.android.tools.r8.cf.CfPrinter;
import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.graph.DexProgramClass;
-import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.GraphLens;
import com.android.tools.r8.graph.InitClassLens;
import com.android.tools.r8.graph.ProgramMethod;
@@ -50,16 +49,4 @@
InliningConstraints inliningConstraints, DexProgramClass context) {
return inliningConstraints.forConstInstruction();
}
-
- @Override
- public void evaluate(
- CfFrameVerificationHelper frameBuilder,
- DexType context,
- DexType returnType,
- DexItemFactory factory,
- InitClassLens initClassLens) {
- // ... →
- // ..., value
- frameBuilder.push(DexItemFactory.nullValueType);
- }
}
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfConstNumber.java b/src/main/java/com/android/tools/r8/cf/code/CfConstNumber.java
index 001810a..642eeb9 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfConstNumber.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfConstNumber.java
@@ -7,7 +7,6 @@
import com.android.tools.r8.errors.Unreachable;
import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.graph.DexProgramClass;
-import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.GraphLens;
import com.android.tools.r8.graph.InitClassLens;
import com.android.tools.r8.graph.ProgramMethod;
@@ -148,16 +147,4 @@
InliningConstraints inliningConstraints, DexProgramClass context) {
return inliningConstraints.forConstInstruction();
}
-
- @Override
- public void evaluate(
- CfFrameVerificationHelper frameBuilder,
- DexType context,
- DexType returnType,
- DexItemFactory factory,
- InitClassLens initClassLens) {
- // ... →
- // ..., value
- frameBuilder.push(type.toPrimitiveType().toDexType(factory));
- }
}
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfConstString.java b/src/main/java/com/android/tools/r8/cf/code/CfConstString.java
index 9c3795e..9037875 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfConstString.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfConstString.java
@@ -7,7 +7,6 @@
import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.graph.DexProgramClass;
import com.android.tools.r8.graph.DexString;
-import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.GraphLens;
import com.android.tools.r8.graph.InitClassLens;
import com.android.tools.r8.graph.ProgramMethod;
@@ -80,16 +79,4 @@
InliningConstraints inliningConstraints, DexProgramClass context) {
return inliningConstraints.forConstInstruction();
}
-
- @Override
- public void evaluate(
- CfFrameVerificationHelper frameBuilder,
- DexType context,
- DexType returnType,
- DexItemFactory factory,
- InitClassLens initClassLens) {
- // ... →
- // ..., value
- frameBuilder.push(factory.stringType);
- }
}
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfDexItemBasedConstString.java b/src/main/java/com/android/tools/r8/cf/code/CfDexItemBasedConstString.java
index 76728c3..bdc470f 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfDexItemBasedConstString.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfDexItemBasedConstString.java
@@ -9,7 +9,6 @@
import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.graph.DexProgramClass;
import com.android.tools.r8.graph.DexReference;
-import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.GraphLens;
import com.android.tools.r8.graph.InitClassLens;
import com.android.tools.r8.graph.ProgramMethod;
@@ -97,16 +96,4 @@
InliningConstraints inliningConstraints, DexProgramClass context) {
return inliningConstraints.forDexItemBasedConstString(item, context);
}
-
- @Override
- public void evaluate(
- CfFrameVerificationHelper frameBuilder,
- DexType context,
- DexType returnType,
- DexItemFactory factory,
- InitClassLens initClassLens) {
- // ... →
- // ..., value
- frameBuilder.push(factory.stringType);
- }
}
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfFieldInstruction.java b/src/main/java/com/android/tools/r8/cf/code/CfFieldInstruction.java
index a9113cb..3cff4ee 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfFieldInstruction.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfFieldInstruction.java
@@ -152,37 +152,4 @@
throw new Unreachable("Unexpected opcode " + opcode);
}
}
-
- @Override
- public void evaluate(
- CfFrameVerificationHelper frameBuilder,
- DexType context,
- DexType returnType,
- DexItemFactory factory,
- InitClassLens initClassLens) {
- switch (opcode) {
- case Opcodes.GETFIELD:
- // ..., objectref →
- // ..., value
- frameBuilder.popAndDiscard(field.holder).push(field.type);
- return;
- case Opcodes.GETSTATIC:
- // ..., →
- // ..., value
- frameBuilder.push(field.type);
- return;
- case Opcodes.PUTFIELD:
- // ..., objectref, value →
- // ...,
- frameBuilder.popAndDiscard(field.holder, field.type);
- return;
- case Opcodes.PUTSTATIC:
- // ..., value →
- // ...
- frameBuilder.pop(field.type);
- return;
- default:
- throw new Unreachable("Unexpected opcode " + opcode);
- }
- }
}
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfFrame.java b/src/main/java/com/android/tools/r8/cf/code/CfFrame.java
index d07d010..f392338 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfFrame.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfFrame.java
@@ -7,15 +7,12 @@
import com.android.tools.r8.cf.CfPrinter;
import com.android.tools.r8.errors.Unreachable;
-import com.android.tools.r8.graph.CfCodeStackMapValidatingException;
import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.graph.DexProgramClass;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.GraphLens;
import com.android.tools.r8.graph.InitClassLens;
import com.android.tools.r8.graph.ProgramMethod;
-import com.android.tools.r8.ir.code.MemberType;
-import com.android.tools.r8.ir.code.NumericType;
import com.android.tools.r8.ir.conversion.CfSourceCode;
import com.android.tools.r8.ir.conversion.CfState;
import com.android.tools.r8.ir.conversion.IRBuilder;
@@ -23,10 +20,7 @@
import com.android.tools.r8.ir.optimize.Inliner.ConstraintWithTarget;
import com.android.tools.r8.ir.optimize.InliningConstraints;
import com.android.tools.r8.naming.NamingLens;
-import it.unimi.dsi.fastutil.ints.Int2ReferenceAVLTreeMap;
import it.unimi.dsi.fastutil.ints.Int2ReferenceSortedMap;
-import java.util.ArrayDeque;
-import java.util.Deque;
import java.util.List;
import java.util.Objects;
import org.objectweb.asm.MethodVisitor;
@@ -40,8 +34,8 @@
return new InitializedType(type);
}
- public static FrameType uninitializedNew(CfLabel label, DexType typeToInitialize) {
- return new UninitializedNew(label, typeToInitialize);
+ public static FrameType uninitializedNew(CfLabel label) {
+ return new UninitializedNew(label);
}
public static FrameType uninitializedThis() {
@@ -52,14 +46,6 @@
return Top.SINGLETON;
}
- public static FrameType oneWord() {
- return OneWord.SINGLETON;
- }
-
- public static FrameType twoWord() {
- return TwoWord.SINGLETON;
- }
-
abstract Object getTypeOpcode(GraphLens graphLens, NamingLens namingLens);
public boolean isWide() {
@@ -86,54 +72,11 @@
return null;
}
- public DexType getUninitializedNewType() {
- return null;
- }
-
public boolean isTop() {
return false;
}
- public boolean isOneWord() {
- return false;
- }
-
- public boolean isTwoWord() {
- return false;
- }
-
private FrameType() {}
-
- public static FrameType fromMemberType(MemberType memberType, DexItemFactory factory) {
- switch (memberType) {
- case OBJECT:
- return FrameType.initialized(factory.objectType);
- case BOOLEAN_OR_BYTE:
- return FrameType.initialized(factory.intType);
- case CHAR:
- return FrameType.initialized(factory.intType);
- case SHORT:
- return FrameType.initialized(factory.intType);
- case INT:
- return FrameType.initialized(factory.intType);
- case FLOAT:
- return FrameType.initialized(factory.floatType);
- case LONG:
- return FrameType.initialized(factory.longType);
- case DOUBLE:
- return FrameType.initialized(factory.doubleType);
- case INT_OR_FLOAT:
- return FrameType.oneWord();
- case LONG_OR_DOUBLE:
- return FrameType.twoWord();
- default:
- throw new Unreachable("Unexpected MemberType: " + memberType);
- }
- }
-
- public static FrameType fromNumericType(NumericType numericType, DexItemFactory factory) {
- return FrameType.initialized(numericType.dexTypeFor(factory));
- }
}
@Override
@@ -157,7 +100,7 @@
@Override
public String toString() {
- return "Initialized(" + type.toString() + ")";
+ return type.toString();
}
@Override
@@ -220,11 +163,9 @@
private static class UninitializedNew extends FrameType {
private final CfLabel label;
- private final DexType type;
- private UninitializedNew(CfLabel label, DexType type) {
+ private UninitializedNew(CfLabel label) {
this.label = label;
- this.type = type;
}
@Override
@@ -246,15 +187,9 @@
public CfLabel getUninitializedLabel() {
return label;
}
-
- @Override
- public DexType getUninitializedNewType() {
- return type;
- }
}
private static class UninitializedThis extends FrameType {
-
private UninitializedThis() {}
@Override
@@ -273,60 +208,10 @@
}
}
- private static class OneWord extends FrameType {
-
- private static final OneWord SINGLETON = new OneWord();
-
- @Override
- Object getTypeOpcode(GraphLens graphLens, NamingLens namingLens) {
- throw new Unreachable("Should only be used for verification");
- }
-
- @Override
- public boolean isOneWord() {
- return true;
- }
-
- @Override
- public String toString() {
- return "oneword";
- }
- }
-
- private static class TwoWord extends FrameType {
-
- private static final TwoWord SINGLETON = new TwoWord();
-
- @Override
- Object getTypeOpcode(GraphLens graphLens, NamingLens namingLens) {
- throw new Unreachable("Should only be used for verification");
- }
-
- @Override
- public boolean isWide() {
- return true;
- }
-
- @Override
- public boolean isTwoWord() {
- return true;
- }
-
- @Override
- public String toString() {
- return "twoword";
- }
- }
-
private final Int2ReferenceSortedMap<FrameType> locals;
- private final Deque<FrameType> stack;
+ private final List<FrameType> stack;
- // TODO(mkroghj): Temporary constructor to satisfy compilation of CfCode generated code.
public CfFrame(Int2ReferenceSortedMap<FrameType> locals, List<FrameType> stack) {
- this(locals, new ArrayDeque<>(stack));
- }
-
- public CfFrame(Int2ReferenceSortedMap<FrameType> locals, Deque<FrameType> stack) {
assert locals.values().stream().allMatch(Objects::nonNull);
assert stack.stream().allMatch(Objects::nonNull);
this.locals = locals;
@@ -337,7 +222,7 @@
return locals;
}
- public Deque<FrameType> getStack() {
+ public List<FrameType> getStack() {
return stack;
}
@@ -367,9 +252,8 @@
return null;
}
Object[] stackTypes = new Object[stackCount];
- int index = 0;
- for (FrameType frameType : stack) {
- stackTypes[index++] = frameType.getTypeOpcode(graphLens, namingLens);
+ for (int i = 0; i < stackCount; i++) {
+ stackTypes[i] = stack.get(i).getTypeOpcode(graphLens, namingLens);
}
return stackTypes;
}
@@ -421,6 +305,7 @@
@Override
public void buildIR(IRBuilder builder, CfState state, CfSourceCode code) {
+ // TODO(mathiasr): Verify stack map frames before building IR.
code.setStateFromFrame(this);
}
@@ -434,46 +319,4 @@
InliningConstraints inliningConstraints, DexProgramClass context) {
return ConstraintWithTarget.ALWAYS;
}
-
- @Override
- public void evaluate(
- CfFrameVerificationHelper frameBuilder,
- DexType context,
- DexType returnType,
- DexItemFactory factory,
- InitClassLens initClassLens) {
- frameBuilder.verifyFrameAndSet(this);
- }
-
- public CfFrame markInstantiated(FrameType uninitializedType, DexType initType) {
- if (uninitializedType.isInitialized()) {
- throw CfCodeStackMapValidatingException.error(
- "Cannot instantiate already instantiated type " + uninitializedType);
- }
- Int2ReferenceSortedMap<FrameType> newLocals = new Int2ReferenceAVLTreeMap<>();
- for (int var : locals.keySet()) {
- newLocals.put(var, getInitializedFrameType(uninitializedType, locals.get(var), initType));
- }
- Deque<FrameType> newStack = new ArrayDeque<>();
- for (FrameType frameType : stack) {
- newStack.addLast(getInitializedFrameType(uninitializedType, frameType, initType));
- }
- return new CfFrame(newLocals, newStack);
- }
-
- private FrameType getInitializedFrameType(FrameType unInit, FrameType other, DexType newType) {
- assert !unInit.isInitialized();
- if (other.isInitialized()) {
- return other;
- }
- if (unInit.isUninitializedThis() && other.isUninitializedThis()) {
- return FrameType.initialized(newType);
- }
- if (unInit.isUninitializedNew()
- && other.isUninitializedNew()
- && unInit.getUninitializedLabel() == other.getUninitializedLabel()) {
- return FrameType.initialized(newType);
- }
- return other;
- }
}
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfFrameVerificationHelper.java b/src/main/java/com/android/tools/r8/cf/code/CfFrameVerificationHelper.java
deleted file mode 100644
index 259ad12..0000000
--- a/src/main/java/com/android/tools/r8/cf/code/CfFrameVerificationHelper.java
+++ /dev/null
@@ -1,379 +0,0 @@
-// Copyright (c) 2020, the R8 project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.android.tools.r8.cf.code;
-
-import com.android.tools.r8.cf.code.CfFrame.FrameType;
-import com.android.tools.r8.graph.CfCodeStackMapValidatingException;
-import com.android.tools.r8.graph.DexItemFactory;
-import com.android.tools.r8.graph.DexType;
-import com.android.tools.r8.utils.MapUtils;
-import com.android.tools.r8.utils.collections.ImmutableDeque;
-import com.android.tools.r8.utils.collections.ImmutableInt2ReferenceSortedMap;
-import com.google.common.collect.Sets;
-import it.unimi.dsi.fastutil.ints.Int2ReferenceAVLTreeMap;
-import it.unimi.dsi.fastutil.ints.Int2ReferenceSortedMap;
-import java.util.ArrayDeque;
-import java.util.Arrays;
-import java.util.Deque;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.function.BiPredicate;
-
-public class CfFrameVerificationHelper {
-
- private final CfFrame NO_FRAME =
- new CfFrame(
- ImmutableInt2ReferenceSortedMap.<FrameType>builder().build(), ImmutableDeque.of());
-
- private final Deque<FrameType> throwStack;
-
- private CfFrame currentFrame = NO_FRAME;
- private final DexType context;
- private final Map<CfLabel, CfFrame> stateMap;
- private final BiPredicate<DexType, DexType> isJavaAssignable;
- private final DexItemFactory factory;
- private final List<CfTryCatch> tryCatchRanges;
-
- private final Deque<CfTryCatch> currentCatchRanges = new ArrayDeque<>();
- private final Set<CfLabel> tryCatchRangeLabels;
-
- public CfFrameVerificationHelper(
- DexType context,
- Map<CfLabel, CfFrame> stateMap,
- List<CfTryCatch> tryCatchRanges,
- BiPredicate<DexType, DexType> isJavaAssignable,
- DexItemFactory factory) {
- this.context = context;
- this.stateMap = stateMap;
- this.tryCatchRanges = tryCatchRanges;
- this.isJavaAssignable = isJavaAssignable;
- this.factory = factory;
- throwStack = ImmutableDeque.of(FrameType.initialized(factory.throwableType));
- // Compute all labels that marks a start or end to catch ranges.
- tryCatchRangeLabels = Sets.newIdentityHashSet();
- for (CfTryCatch tryCatchRange : tryCatchRanges) {
- tryCatchRangeLabels.add(tryCatchRange.start);
- tryCatchRangeLabels.add(tryCatchRange.end);
- }
- }
-
- public DexItemFactory factory() {
- return factory;
- }
-
- public FrameType readLocal(int index, DexType expectedType) {
- verifyFrameIsSet();
- FrameType frameType = currentFrame.getLocals().get(index);
- if (frameType == null) {
- throw CfCodeStackMapValidatingException.error("No local at index " + index);
- }
- verifyIsAssignable(frameType, expectedType);
- return frameType;
- }
-
- public void storeLocal(int index, FrameType frameType) {
- verifyFrameIsSet();
- currentFrame.getLocals().put(index, frameType);
- }
-
- public FrameType pop() {
- verifyFrameIsSet();
- if (currentFrame.getStack().isEmpty()) {
- throw CfCodeStackMapValidatingException.error("Cannot pop() from an empty stack");
- }
- return currentFrame.getStack().removeLast();
- }
-
- public FrameType pop(DexType expectedType) {
- FrameType frameType = pop();
- verifyIsAssignable(frameType, expectedType);
- return frameType;
- }
-
- public CfFrameVerificationHelper popAndDiscard(DexType... expectedTypes) {
- verifyFrameIsSet();
- for (int i = expectedTypes.length - 1; i >= 0; i--) {
- pop(expectedTypes[i]);
- }
- return this;
- }
-
- public FrameType pop(FrameType expectedType) {
- FrameType frameType = pop();
- verifyIsAssignable(frameType, expectedType);
- return frameType;
- }
-
- public CfFrameVerificationHelper popAndDiscard(FrameType... expectedTypes) {
- verifyFrameIsSet();
- for (int i = expectedTypes.length - 1; i >= 0; i--) {
- pop(expectedTypes[i]);
- }
- return this;
- }
-
- public void popAndInitialize(DexType context, DexType methodHolder) {
- verifyFrameIsSet();
- FrameType objectRef = pop(factory.objectType);
- CfFrame newFrame =
- currentFrame.markInstantiated(
- objectRef, objectRef.isUninitializedNew() ? methodHolder : context);
- setNoFrame();
- verifyFrameAndSet(newFrame);
- }
-
- public CfFrameVerificationHelper push(FrameType type) {
- verifyFrameIsSet();
- currentFrame.getStack().addLast(type);
- return this;
- }
-
- public CfFrameVerificationHelper push(DexType type) {
- return push(FrameType.initialized(type));
- }
-
- public CfFrameVerificationHelper seenLabel(CfLabel label) {
- if (tryCatchRangeLabels.contains(label)) {
- for (CfTryCatch tryCatchRange : tryCatchRanges) {
- if (tryCatchRange.start == label) {
- currentCatchRanges.add(tryCatchRange);
- // We can have fall-through into this range requiring the current frame being
- // assignable to the handler frame. This is handled for locals when we see a throwing
- // instruction, but we can validate here that the stack will be a single element stack
- // [throwable].
- CfFrame destinationFrame = stateMap.get(tryCatchRange.start);
- if (destinationFrame == null) {
- throw CfCodeStackMapValidatingException.error("No frame for target catch range target");
- }
- verifyStackIsAssignable(
- destinationFrame.getStack(), throwStack, factory, isJavaAssignable);
- }
- }
- currentCatchRanges.removeIf(currentRange -> currentRange.end == label);
- }
- return this;
- }
-
- private void verifyFrameIsSet() {
- if (currentFrame == NO_FRAME) {
- throw CfCodeStackMapValidatingException.error("Unexpected state change");
- }
- }
-
- public void verifyFrameAndSet(CfFrame newFrame) {
- if (currentFrame != NO_FRAME) {
- verifyFrame(newFrame);
- }
- setFrame(newFrame);
- }
-
- private void setFrame(CfFrame frame) {
- assert frame != NO_FRAME;
- currentFrame =
- new CfFrame(
- new Int2ReferenceAVLTreeMap<>(frame.getLocals()), new ArrayDeque<>(frame.getStack()));
- }
-
- public void verifyExceptionEdges() {
- for (CfTryCatch currentCatchRange : currentCatchRanges) {
- for (CfLabel target : currentCatchRange.targets) {
- CfFrame destinationFrame = stateMap.get(target);
- if (destinationFrame == null) {
- throw CfCodeStackMapValidatingException.error("No frame for target catch range target");
- }
- // We have to check all current handler targets have assignable locals and a 1-element
- // stack assignable to throwable. It is not required that the the thrown error is
- // handled.
- verifyLocalsIsAssignable(
- currentFrame.getLocals(), destinationFrame.getLocals(), factory, isJavaAssignable);
- }
- }
- }
-
- public CfFrame getFrame() {
- return currentFrame;
- }
-
- public void verifyTarget(CfLabel label) {
- verifyFrame(stateMap.get(label));
- }
-
- public void verifyFrame(CfFrame destinationFrame) {
- if (destinationFrame == null) {
- throw CfCodeStackMapValidatingException.error("No destination frame");
- }
- verifyFrame(destinationFrame.getLocals(), destinationFrame.getStack());
- }
-
- public void verifyFrame(Int2ReferenceSortedMap<FrameType> locals, Deque<FrameType> stack) {
- verifyIsAssignable(
- currentFrame.getLocals(),
- currentFrame.getStack(),
- locals,
- stack,
- factory,
- isJavaAssignable);
- }
-
- public void setNoFrame() {
- currentFrame = NO_FRAME;
- }
-
- public void clearStack() {
- verifyFrameIsSet();
- currentFrame.getStack().clear();
- }
-
- public void verifyIsAssignable(FrameType source, DexType target) {
- if (!source.isInitialized()) {
- if (source.isUninitializedThis() && target == context) {
- return;
- }
- if (target == factory.objectType) {
- return;
- }
- throw CfCodeStackMapValidatingException.error(
- "The expected type " + source + " is not assignable to " + target.toSourceString());
- }
- if (!isJavaAssignable.test(source.getInitializedType(), target)) {
- throw CfCodeStackMapValidatingException.error(
- "The expected type " + source + " is not assignable to " + target.toSourceString());
- }
- }
-
- public void verifyIsAssignable(FrameType source, FrameType target) {
- if (!canBeAssigned(source, target, factory, isJavaAssignable)) {
- throw CfCodeStackMapValidatingException.error(
- "The expected type " + source + " is not assignable to " + target);
- }
- }
-
- // Based on https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.10.1.4.
- public static void verifyIsAssignable(
- Int2ReferenceSortedMap<FrameType> sourceLocals,
- Deque<FrameType> sourceStack,
- Int2ReferenceSortedMap<FrameType> destLocals,
- Deque<FrameType> destStack,
- DexItemFactory factory,
- BiPredicate<DexType, DexType> isJavaAssignable) {
- verifyLocalsIsAssignable(sourceLocals, destLocals, factory, isJavaAssignable);
- verifyStackIsAssignable(sourceStack, destStack, factory, isJavaAssignable);
- }
-
- private static void verifyLocalsIsAssignable(
- Int2ReferenceSortedMap<FrameType> sourceLocals,
- Int2ReferenceSortedMap<FrameType> destLocals,
- DexItemFactory factory,
- BiPredicate<DexType, DexType> isJavaAssignable) {
- final int localsLastKey = sourceLocals.isEmpty() ? -1 : sourceLocals.lastIntKey();
- final int otherLocalsLastKey = destLocals.isEmpty() ? -1 : destLocals.lastIntKey();
- if (localsLastKey < otherLocalsLastKey) {
- throw CfCodeStackMapValidatingException.error(
- "Source locals "
- + MapUtils.toString(sourceLocals)
- + " have different local indices than "
- + MapUtils.toString(destLocals));
- }
- for (int i = 0; i < otherLocalsLastKey; i++) {
- final FrameType sourceType =
- sourceLocals.containsKey(i) ? sourceLocals.get(i) : FrameType.top();
- final FrameType destinationType =
- destLocals.containsKey(i) ? destLocals.get(i) : FrameType.top();
- if (!canBeAssigned(sourceType, destinationType, factory, isJavaAssignable)) {
- throw CfCodeStackMapValidatingException.error(
- "Could not assign '"
- + MapUtils.toString(sourceLocals)
- + "' to '"
- + MapUtils.toString(destLocals)
- + "'. The local at index "
- + i
- + " with '"
- + sourceType
- + "' not being assignable to '"
- + destinationType
- + "'");
- }
- }
- }
-
- private static void verifyStackIsAssignable(
- Deque<FrameType> sourceStack,
- Deque<FrameType> destStack,
- DexItemFactory factory,
- BiPredicate<DexType, DexType> isJavaAssignable) {
- if (sourceStack.size() != destStack.size()) {
- throw CfCodeStackMapValidatingException.error(
- "Source stack "
- + Arrays.toString(sourceStack.toArray())
- + " and destination stack "
- + Arrays.toString(destStack.toArray())
- + " is not the same size");
- }
- final Iterator<FrameType> otherIterator = destStack.iterator();
- int i = 0;
- for (FrameType sourceType : sourceStack) {
- final FrameType destinationType = otherIterator.next();
- if (!canBeAssigned(sourceType, destinationType, factory, isJavaAssignable)) {
- throw CfCodeStackMapValidatingException.error(
- "Could not assign '"
- + Arrays.toString(sourceStack.toArray())
- + "' to '"
- + Arrays.toString(destStack.toArray())
- + "'. The stack value at index "
- + i
- + " (from bottom) with '"
- + sourceType
- + "' not being assignable to '"
- + destinationType
- + "'");
- }
- i++;
- }
- }
-
- // Based on https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.10.1.2.
- public static boolean canBeAssigned(
- FrameType source,
- FrameType target,
- DexItemFactory factory,
- BiPredicate<DexType, DexType> isJavaAssignable) {
- if (target.isTop()) {
- return true;
- }
- if (source.isTop()) {
- return false;
- }
- if (source.isWide() != target.isWide()) {
- return false;
- }
- if (target.isOneWord() || target.isTwoWord()) {
- return true;
- }
- if (source.isUninitializedThis() && target.isUninitializedThis()) {
- return true;
- }
- if (source.isUninitializedNew() && target.isUninitializedNew()) {
- // TODO(b/168190134): Allow for picking the offset from the target if not set.
- DexType uninitializedNewTypeSource = source.getUninitializedNewType();
- DexType uninitializedNewTypeTarget = target.getUninitializedNewType();
- return uninitializedNewTypeSource == null
- || uninitializedNewTypeTarget == null
- || uninitializedNewTypeSource == uninitializedNewTypeTarget;
- }
- // TODO(b/168190267): Clean-up the lattice.
- if (!source.isInitialized()
- && target.isInitialized()
- && target.getInitializedType() == factory.objectType) {
- return true;
- }
- if (source.isInitialized() && target.isInitialized()) {
- // Both are instantiated types and we resort to primitive tyoe/java type hierarchy checking.
- return isJavaAssignable.test(source.getInitializedType(), target.getInitializedType());
- }
- return false;
- }
-}
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfGoto.java b/src/main/java/com/android/tools/r8/cf/code/CfGoto.java
index b771a83..0cd79d4 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfGoto.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfGoto.java
@@ -6,7 +6,6 @@
import com.android.tools.r8.cf.CfPrinter;
import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.graph.DexProgramClass;
-import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.GraphLens;
import com.android.tools.r8.graph.InitClassLens;
import com.android.tools.r8.graph.ProgramMethod;
@@ -75,15 +74,4 @@
InliningConstraints inliningConstraints, DexProgramClass context) {
return inliningConstraints.forJumpInstruction();
}
-
- @Override
- public void evaluate(
- CfFrameVerificationHelper frameBuilder,
- DexType context,
- DexType returnType,
- DexItemFactory factory,
- InitClassLens initClassLens) {
- frameBuilder.verifyTarget(target);
- frameBuilder.setNoFrame();
- }
}
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfIf.java b/src/main/java/com/android/tools/r8/cf/code/CfIf.java
index e879201..31497fd 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfIf.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfIf.java
@@ -7,7 +7,6 @@
import com.android.tools.r8.errors.Unreachable;
import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.graph.DexProgramClass;
-import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.GraphLens;
import com.android.tools.r8.graph.InitClassLens;
import com.android.tools.r8.graph.ProgramMethod;
@@ -108,18 +107,4 @@
InliningConstraints inliningConstraints, DexProgramClass context) {
return inliningConstraints.forJumpInstruction();
}
-
- @Override
- public void evaluate(
- CfFrameVerificationHelper frameBuilder,
- DexType context,
- DexType returnType,
- DexItemFactory factory,
- InitClassLens initClassLens) {
- // ..., value →
- // ...
- frameBuilder.pop(
- type.isObject() ? factory.objectType : type.toPrimitiveType().toDexType(factory));
- frameBuilder.verifyTarget(target);
- }
}
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfIfCmp.java b/src/main/java/com/android/tools/r8/cf/code/CfIfCmp.java
index cfac04a..47cbcad 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfIfCmp.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfIfCmp.java
@@ -7,7 +7,6 @@
import com.android.tools.r8.errors.Unreachable;
import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.graph.DexProgramClass;
-import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.GraphLens;
import com.android.tools.r8.graph.InitClassLens;
import com.android.tools.r8.graph.ProgramMethod;
@@ -109,19 +108,4 @@
InliningConstraints inliningConstraints, DexProgramClass context) {
return inliningConstraints.forJumpInstruction();
}
-
- @Override
- public void evaluate(
- CfFrameVerificationHelper frameBuilder,
- DexType context,
- DexType returnType,
- DexItemFactory factory,
- InitClassLens initClassLens) {
- // ..., value1, value2 →
- // ...
- DexType type =
- this.type.isObject() ? factory.objectType : this.type.toPrimitiveType().toDexType(factory);
- frameBuilder.popAndDiscard(type, type);
- frameBuilder.verifyTarget(target);
- }
}
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfIinc.java b/src/main/java/com/android/tools/r8/cf/code/CfIinc.java
index 2ce5912..4a37601 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfIinc.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfIinc.java
@@ -6,7 +6,6 @@
import com.android.tools.r8.cf.CfPrinter;
import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.graph.DexProgramClass;
-import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.GraphLens;
import com.android.tools.r8.graph.InitClassLens;
import com.android.tools.r8.graph.ProgramMethod;
@@ -66,14 +65,4 @@
InliningConstraints inliningConstraints, DexProgramClass context) {
return ConstraintWithTarget.ALWAYS;
}
-
- @Override
- public void evaluate(
- CfFrameVerificationHelper frameBuilder,
- DexType context,
- DexType returnType,
- DexItemFactory factory,
- InitClassLens initClassLens) {
- frameBuilder.readLocal(var, factory.intType);
- }
}
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfInitClass.java b/src/main/java/com/android/tools/r8/cf/code/CfInitClass.java
index 92c55e3..b12d10e 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfInitClass.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfInitClass.java
@@ -85,16 +85,4 @@
InliningConstraints inliningConstraints, DexProgramClass context) {
return inliningConstraints.forInitClass(clazz, context);
}
-
- @Override
- public void evaluate(
- CfFrameVerificationHelper frameBuilder,
- DexType context,
- DexType returnType,
- DexItemFactory factory,
- InitClassLens initClassLens) {
- // ..., →
- // ..., value
- frameBuilder.push(clazz);
- }
}
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfInstanceOf.java b/src/main/java/com/android/tools/r8/cf/code/CfInstanceOf.java
index f6d375c..c34d576 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfInstanceOf.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfInstanceOf.java
@@ -84,16 +84,4 @@
InliningConstraints inliningConstraints, DexProgramClass context) {
return inliningConstraints.forInstanceOf(type, context);
}
-
- @Override
- public void evaluate(
- CfFrameVerificationHelper frameBuilder,
- DexType context,
- DexType returnType,
- DexItemFactory factory,
- InitClassLens initClassLens) {
- // ..., objectref →
- // ..., result
- frameBuilder.popAndDiscard(factory.objectType).push(factory.intType);
- }
}
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfInstruction.java b/src/main/java/com/android/tools/r8/cf/code/CfInstruction.java
index 6fde72a..da09f7b 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfInstruction.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfInstruction.java
@@ -8,7 +8,6 @@
import com.android.tools.r8.graph.DexClassAndMethod;
import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.graph.DexProgramClass;
-import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.GraphLens;
import com.android.tools.r8.graph.InitClassLens;
import com.android.tools.r8.graph.ProgramMethod;
@@ -146,14 +145,6 @@
return false;
}
- public CfThrow asThrow() {
- return null;
- }
-
- public boolean isThrow() {
- return false;
- }
-
public CfDexItemBasedConstString asDexItemBasedConstString() {
return null;
}
@@ -167,10 +158,6 @@
return false;
}
- public boolean isReturnVoid() {
- return false;
- }
-
/** Return true if this instruction is CfIf or CfIfCmp. */
public boolean isConditionalJump() {
return false;
@@ -196,11 +183,4 @@
public abstract ConstraintWithTarget inliningConstraint(
InliningConstraints inliningConstraints, DexProgramClass context);
-
- public abstract void evaluate(
- CfFrameVerificationHelper frameBuilder,
- DexType context,
- DexType returnType,
- DexItemFactory factory,
- InitClassLens initClassLens);
}
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfInvoke.java b/src/main/java/com/android/tools/r8/cf/code/CfInvoke.java
index a997728..4f21538 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfInvoke.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfInvoke.java
@@ -305,29 +305,6 @@
return inliningConstraints.forInvoke(target, type, context);
}
- @Override
- public void evaluate(
- CfFrameVerificationHelper frameBuilder,
- DexType context,
- DexType returnType,
- DexItemFactory factory,
- InitClassLens initClassLens) {
- // ..., objectref, [arg1, [arg2 ...]] →
- // ... [ returnType ]
- // OR, for static method calls:
- // ..., [arg1, [arg2 ...]] →
- // ...
- frameBuilder.popAndDiscard(this.method.proto.parameters.values);
- if (opcode == Opcodes.INVOKESPECIAL && method.isInstanceInitializer(factory)) {
- frameBuilder.popAndInitialize(context, method.holder);
- } else if (opcode != Opcodes.INVOKESTATIC) {
- frameBuilder.pop(method.holder);
- }
- if (this.method.proto.returnType != factory.voidType) {
- frameBuilder.push(this.method.proto.returnType);
- }
- }
-
private static boolean noNeedToUseGraphLens(
DexMethod method, Invoke.Type type, GraphLens graphLens) {
assert graphLens.lookupMethod(method, null, type).getType() == type;
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfInvokeDynamic.java b/src/main/java/com/android/tools/r8/cf/code/CfInvokeDynamic.java
index 26ad7fc..a455305 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfInvokeDynamic.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfInvokeDynamic.java
@@ -130,19 +130,4 @@
InliningConstraints inliningConstraints, DexProgramClass context) {
return inliningConstraints.forInvokeCustom();
}
-
- @Override
- public void evaluate(
- CfFrameVerificationHelper frameBuilder,
- DexType context,
- DexType returnType,
- DexItemFactory factory,
- InitClassLens initClassLens) {
- // ..., [arg1, [arg2 ...]] →
- // ...
- frameBuilder.popAndDiscard(callSite.methodProto.parameters.values);
- if (callSite.methodProto.returnType != factory.voidType) {
- frameBuilder.push(callSite.methodProto.returnType);
- }
- }
}
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfJsrRet.java b/src/main/java/com/android/tools/r8/cf/code/CfJsrRet.java
index 231de99..47ee09b 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfJsrRet.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfJsrRet.java
@@ -5,10 +5,8 @@
import com.android.tools.r8.cf.CfPrinter;
import com.android.tools.r8.errors.CompilationError;
-import com.android.tools.r8.graph.CfCodeStackMapValidatingException;
import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.graph.DexProgramClass;
-import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.GraphLens;
import com.android.tools.r8.graph.InitClassLens;
import com.android.tools.r8.graph.ProgramMethod;
@@ -62,18 +60,6 @@
throw error();
}
- @Override
- public void evaluate(
- CfFrameVerificationHelper frameBuilder,
- DexType context,
- DexType returnType,
- DexItemFactory factory,
- InitClassLens initClassLens) {
- // JSR/RET instructions cannot be verified since we have not type-checking way for addresses
- // on the stack/locals. We have to abandon.
- throw CfCodeStackMapValidatingException.error("Unexpected JSR/RET instruction");
- }
-
public int getLocal() {
return local;
}
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfLabel.java b/src/main/java/com/android/tools/r8/cf/code/CfLabel.java
index f89662f..b27fd00 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfLabel.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfLabel.java
@@ -6,7 +6,6 @@
import com.android.tools.r8.cf.CfPrinter;
import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.graph.DexProgramClass;
-import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.GraphLens;
import com.android.tools.r8.graph.InitClassLens;
import com.android.tools.r8.graph.ProgramMethod;
@@ -73,14 +72,4 @@
InliningConstraints inliningConstraints, DexProgramClass context) {
return ConstraintWithTarget.ALWAYS;
}
-
- @Override
- public void evaluate(
- CfFrameVerificationHelper frameBuilder,
- DexType context,
- DexType returnType,
- DexItemFactory factory,
- InitClassLens initClassLens) {
- // This is a no-op.
- }
}
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfLoad.java b/src/main/java/com/android/tools/r8/cf/code/CfLoad.java
index 60bac1d..17e0ecd 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfLoad.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfLoad.java
@@ -7,7 +7,6 @@
import com.android.tools.r8.errors.Unreachable;
import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.graph.DexProgramClass;
-import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.GraphLens;
import com.android.tools.r8.graph.InitClassLens;
import com.android.tools.r8.graph.ProgramMethod;
@@ -102,19 +101,4 @@
InliningConstraints inliningConstraints, DexProgramClass context) {
return inliningConstraints.forLoad();
}
-
- @Override
- public void evaluate(
- CfFrameVerificationHelper frameBuilder,
- DexType context,
- DexType returnType,
- DexItemFactory factory,
- InitClassLens initClassLens) {
- // ... →
- // ..., objectref
- frameBuilder.push(
- frameBuilder.readLocal(
- getLocalIndex(),
- type.isObject() ? factory.objectType : type.toPrimitiveType().toDexType(factory)));
- }
}
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfLogicalBinop.java b/src/main/java/com/android/tools/r8/cf/code/CfLogicalBinop.java
index 50915c2..19a3bfe 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfLogicalBinop.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfLogicalBinop.java
@@ -4,11 +4,9 @@
package com.android.tools.r8.cf.code;
import com.android.tools.r8.cf.CfPrinter;
-import com.android.tools.r8.cf.code.CfFrame.FrameType;
import com.android.tools.r8.errors.Unreachable;
import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.graph.DexProgramClass;
-import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.GraphLens;
import com.android.tools.r8.graph.InitClassLens;
import com.android.tools.r8.graph.ProgramMethod;
@@ -155,27 +153,4 @@
InliningConstraints inliningConstraints, DexProgramClass context) {
return inliningConstraints.forBinop();
}
-
- @Override
- public void evaluate(
- CfFrameVerificationHelper frameBuilder,
- DexType context,
- DexType returnType,
- DexItemFactory factory,
- InitClassLens initClassLens) {
- // ..., value1, value2 →
- // ..., result
- FrameType value1Type = FrameType.fromNumericType(type, factory);
- FrameType value2Type;
- switch (opcode) {
- case And:
- case Or:
- case Xor:
- value2Type = value1Type;
- break;
- default:
- value2Type = FrameType.initialized(factory.intType);
- }
- frameBuilder.popAndDiscard(value1Type, value2Type).push(value1Type);
- }
}
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfMonitor.java b/src/main/java/com/android/tools/r8/cf/code/CfMonitor.java
index 9f02171..24b580b 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfMonitor.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfMonitor.java
@@ -4,10 +4,8 @@
package com.android.tools.r8.cf.code;
import com.android.tools.r8.cf.CfPrinter;
-import com.android.tools.r8.cf.code.CfFrame.FrameType;
import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.graph.DexProgramClass;
-import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.GraphLens;
import com.android.tools.r8.graph.InitClassLens;
import com.android.tools.r8.graph.ProgramMethod;
@@ -68,16 +66,4 @@
InliningConstraints inliningConstraints, DexProgramClass context) {
return inliningConstraints.forMonitor();
}
-
- @Override
- public void evaluate(
- CfFrameVerificationHelper frameBuilder,
- DexType context,
- DexType returnType,
- DexItemFactory factory,
- InitClassLens initClassLens) {
- // ..., objectref →
- // ...
- frameBuilder.pop(FrameType.initialized(factory.objectType));
- }
}
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfMultiANewArray.java b/src/main/java/com/android/tools/r8/cf/code/CfMultiANewArray.java
index 5d4eac2..33f4244 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfMultiANewArray.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfMultiANewArray.java
@@ -81,19 +81,4 @@
InliningConstraints inliningConstraints, DexProgramClass context) {
return inliningConstraints.forInvokeMultiNewArray(type, context);
}
-
- @Override
- public void evaluate(
- CfFrameVerificationHelper frameBuilder,
- DexType context,
- DexType returnType,
- DexItemFactory factory,
- InitClassLens initClassLens) {
- // ..., count1, [count2, ...] →
- // ..., arrayref
- for (int i = 0; i < dimensions; i++) {
- frameBuilder.pop(factory.intType);
- }
- frameBuilder.push(type);
- }
}
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfNeg.java b/src/main/java/com/android/tools/r8/cf/code/CfNeg.java
index fa7140a..88274b3 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfNeg.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfNeg.java
@@ -4,11 +4,9 @@
package com.android.tools.r8.cf.code;
import com.android.tools.r8.cf.CfPrinter;
-import com.android.tools.r8.cf.code.CfFrame.FrameType;
import com.android.tools.r8.errors.Unreachable;
import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.graph.DexProgramClass;
-import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.GraphLens;
import com.android.tools.r8.graph.InitClassLens;
import com.android.tools.r8.graph.ProgramMethod;
@@ -97,17 +95,4 @@
InliningConstraints inliningConstraints, DexProgramClass context) {
return inliningConstraints.forUnop();
}
-
- @Override
- public void evaluate(
- CfFrameVerificationHelper frameBuilder,
- DexType context,
- DexType returnType,
- DexItemFactory factory,
- InitClassLens initClassLens) {
- // ..., value →
- // ..., result
- FrameType frameType = FrameType.fromNumericType(type, factory);
- frameBuilder.popAndDiscard(frameType).push(frameType);
- }
}
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfNew.java b/src/main/java/com/android/tools/r8/cf/code/CfNew.java
index d65bfd8..83b7e63 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfNew.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfNew.java
@@ -4,7 +4,6 @@
package com.android.tools.r8.cf.code;
import com.android.tools.r8.cf.CfPrinter;
-import com.android.tools.r8.cf.code.CfFrame.FrameType;
import com.android.tools.r8.graph.DexClassAndMethod;
import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.graph.DexProgramClass;
@@ -73,16 +72,4 @@
InliningConstraints inliningConstraints, DexProgramClass context) {
return inliningConstraints.forNewInstance(type, context);
}
-
- @Override
- public void evaluate(
- CfFrameVerificationHelper frameBuilder,
- DexType context,
- DexType returnType,
- DexItemFactory factory,
- InitClassLens initClassLens) {
- // ... →
- // ..., objectref
- frameBuilder.push(FrameType.uninitializedNew(new CfLabel(), type));
- }
}
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfNewArray.java b/src/main/java/com/android/tools/r8/cf/code/CfNewArray.java
index 872a317..3c9a746 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfNewArray.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfNewArray.java
@@ -123,17 +123,4 @@
InliningConstraints inliningConstraints, DexProgramClass context) {
return inliningConstraints.forNewArrayEmpty(type, context);
}
-
- @Override
- public void evaluate(
- CfFrameVerificationHelper frameBuilder,
- DexType context,
- DexType returnType,
- DexItemFactory factory,
- InitClassLens initClassLens) {
- // ..., count →
- // ..., arrayref
- assert type.isArrayType();
- frameBuilder.popAndDiscard(factory.intType).push(type);
- }
}
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfNop.java b/src/main/java/com/android/tools/r8/cf/code/CfNop.java
index 3e51685..e2b6044 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfNop.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfNop.java
@@ -6,7 +6,6 @@
import com.android.tools.r8.cf.CfPrinter;
import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.graph.DexProgramClass;
-import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.GraphLens;
import com.android.tools.r8.graph.InitClassLens;
import com.android.tools.r8.graph.ProgramMethod;
@@ -54,14 +53,4 @@
InliningConstraints inliningConstraints, DexProgramClass context) {
return ConstraintWithTarget.ALWAYS;
}
-
- @Override
- public void evaluate(
- CfFrameVerificationHelper frameBuilder,
- DexType context,
- DexType returnType,
- DexItemFactory factory,
- InitClassLens initClassLens) {
- // This is an actual Nop.
- }
}
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfNumberConversion.java b/src/main/java/com/android/tools/r8/cf/code/CfNumberConversion.java
index 510ea41..ce3ab3b 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfNumberConversion.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfNumberConversion.java
@@ -4,11 +4,9 @@
package com.android.tools.r8.cf.code;
import com.android.tools.r8.cf.CfPrinter;
-import com.android.tools.r8.cf.code.CfFrame.FrameType;
import com.android.tools.r8.errors.Unreachable;
import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.graph.DexProgramClass;
-import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.GraphLens;
import com.android.tools.r8.graph.InitClassLens;
import com.android.tools.r8.graph.ProgramMethod;
@@ -168,18 +166,4 @@
InliningConstraints inliningConstraints, DexProgramClass context) {
return inliningConstraints.forUnop();
}
-
- @Override
- public void evaluate(
- CfFrameVerificationHelper frameBuilder,
- DexType context,
- DexType returnType,
- DexItemFactory factory,
- InitClassLens initClassLens) {
- // ..., value →
- // ..., result
- frameBuilder
- .popAndDiscard(FrameType.fromNumericType(from, factory))
- .push(FrameType.fromNumericType(to, factory));
- }
}
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfPosition.java b/src/main/java/com/android/tools/r8/cf/code/CfPosition.java
index 6f159d0..e30be70 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfPosition.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfPosition.java
@@ -6,7 +6,6 @@
import com.android.tools.r8.cf.CfPrinter;
import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.graph.DexProgramClass;
-import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.GraphLens;
import com.android.tools.r8.graph.InitClassLens;
import com.android.tools.r8.graph.ProgramMethod;
@@ -82,14 +81,4 @@
InliningConstraints inliningConstraints, DexProgramClass context) {
return ConstraintWithTarget.ALWAYS;
}
-
- @Override
- public void evaluate(
- CfFrameVerificationHelper frameBuilder,
- DexType context,
- DexType returnType,
- DexItemFactory factory,
- InitClassLens initClassLens) {
- // This is a no-op.
- }
}
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfReturn.java b/src/main/java/com/android/tools/r8/cf/code/CfReturn.java
index 3cd20f6..c5198d1 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfReturn.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfReturn.java
@@ -7,7 +7,6 @@
import com.android.tools.r8.errors.Unreachable;
import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.graph.DexProgramClass;
-import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.GraphLens;
import com.android.tools.r8.graph.InitClassLens;
import com.android.tools.r8.graph.ProgramMethod;
@@ -90,16 +89,4 @@
InliningConstraints inliningConstraints, DexProgramClass context) {
return inliningConstraints.forReturn();
}
-
- @Override
- public void evaluate(
- CfFrameVerificationHelper frameBuilder,
- DexType context,
- DexType returnType,
- DexItemFactory factory,
- InitClassLens initClassLens) {
- assert returnType != null;
- frameBuilder.popAndDiscard(returnType);
- frameBuilder.setNoFrame();
- }
}
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfReturnVoid.java b/src/main/java/com/android/tools/r8/cf/code/CfReturnVoid.java
index 239da2d..8f7bb37 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfReturnVoid.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfReturnVoid.java
@@ -6,7 +6,6 @@
import com.android.tools.r8.cf.CfPrinter;
import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.graph.DexProgramClass;
-import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.GraphLens;
import com.android.tools.r8.graph.InitClassLens;
import com.android.tools.r8.graph.ProgramMethod;
@@ -50,11 +49,6 @@
}
@Override
- public boolean isReturnVoid() {
- return true;
- }
-
- @Override
public void buildIR(IRBuilder builder, CfState state, CfSourceCode code) {
builder.addReturn();
}
@@ -64,14 +58,4 @@
InliningConstraints inliningConstraints, DexProgramClass context) {
return inliningConstraints.forReturn();
}
-
- @Override
- public void evaluate(
- CfFrameVerificationHelper frameBuilder,
- DexType context,
- DexType returnType,
- DexItemFactory factory,
- InitClassLens initClassLens) {
- frameBuilder.setNoFrame();
- }
}
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfStackInstruction.java b/src/main/java/com/android/tools/r8/cf/code/CfStackInstruction.java
index 7aeac09..a7a39b6 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfStackInstruction.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfStackInstruction.java
@@ -4,12 +4,10 @@
package com.android.tools.r8.cf.code;
import com.android.tools.r8.cf.CfPrinter;
-import com.android.tools.r8.cf.code.CfFrame.FrameType;
import com.android.tools.r8.errors.CompilationError;
import com.android.tools.r8.errors.Unreachable;
import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.graph.DexProgramClass;
-import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.GraphLens;
import com.android.tools.r8.graph.InitClassLens;
import com.android.tools.r8.graph.ProgramMethod;
@@ -331,167 +329,4 @@
InliningConstraints inliningConstraints, DexProgramClass context) {
return ConstraintWithTarget.ALWAYS;
}
-
- @Override
- public void evaluate(
- CfFrameVerificationHelper frameBuilder,
- DexType context,
- DexType returnType,
- DexItemFactory factory,
- InitClassLens initClassLens) {
-
- switch (opcode) {
- case Pop:
- // ..., value →
- // ...
- frameBuilder.pop(FrameType.oneWord());
- return;
- case Pop2:
- // ..., value2, value1 →
- // ...
- // or, for double and long:
- // ..., value →
- // ...
- final FrameType pop = frameBuilder.pop();
- if (!pop.isWide()) {
- frameBuilder.verifyIsAssignable(pop, FrameType.oneWord());
- frameBuilder.pop(FrameType.oneWord());
- }
- return;
- case Dup:
- {
- // ..., value →
- // ..., value, value
- FrameType topValue = frameBuilder.pop(FrameType.oneWord());
- frameBuilder.push(topValue).push(topValue);
- return;
- }
- case DupX1:
- {
- // ..., value2, value1 →
- // ..., value1, value2, value1
- FrameType value1 = frameBuilder.pop(FrameType.oneWord());
- FrameType value2 = frameBuilder.pop(FrameType.oneWord());
- frameBuilder.push(value1).push(value2).push(value1);
- return;
- }
- case DupX2:
- {
- // ..., value3, value2, value1 →
- // ..., value1, value3, value2, value1
- // or, if value2 is double or long:
- // ..., value2, value1 →
- // ..., value1, value2, value1
- FrameType value1 = frameBuilder.pop(FrameType.oneWord());
- FrameType value2 = frameBuilder.pop();
- if (!value2.isWide()) {
- frameBuilder.verifyIsAssignable(value2, FrameType.oneWord());
- FrameType value3 = frameBuilder.pop(FrameType.oneWord());
- frameBuilder.push(value1).push(value3);
- } else {
- frameBuilder.push(value1);
- }
- frameBuilder.push(value2).push(value1);
- return;
- }
- case Dup2:
- {
- // ..., value2, value1 →
- // ..., value2, value1, value2, value1
- // or, for value1 being long or double:
- // ..., value →
- // ..., value, value
- FrameType value1 = frameBuilder.pop();
- if (!value1.isWide()) {
- frameBuilder.verifyIsAssignable(value1, FrameType.oneWord());
- FrameType value2 = frameBuilder.pop(FrameType.oneWord());
- frameBuilder.push(value2).push(value1).push(value2);
- } else {
- frameBuilder.push(value1);
- }
- frameBuilder.push(value1);
- return;
- }
- case Dup2X1:
- {
- // ..., value3, value2, value1 →
- // ..., value2, value1, value3, value2, value1
- // or, for value1 being a long or double:
- // ..., value2, value1 →
- // ..., value1, value2, value1
- FrameType value1 = frameBuilder.pop();
- FrameType value2 = frameBuilder.pop(FrameType.oneWord());
- if (!value1.isWide()) {
- frameBuilder.verifyIsAssignable(value1, FrameType.oneWord());
- FrameType value3 = frameBuilder.pop(FrameType.oneWord());
- frameBuilder.push(value2).push(value1).push(value3);
- } else {
- frameBuilder.push(value1);
- }
- frameBuilder.push(value2);
- frameBuilder.push(value1);
- return;
- }
- case Dup2X2:
- {
- // (1)
- // ..., value4, value3, value2, value1 →
- // ..., value2, value1, value4, value3, value2, value1
- // (2) OR, if value1 is long or double
- // ..., value3, value2, value1 →
- // ..., value1, value3, value2, value1
- // (3) OR if value3 is long or double
- // ..., value3, value2, value1 →
- // ..., value2, value1, value3, value2, value1
- // (4) OR, where value1 and value2 is double or long:
- // ..., value2, value1 →
- // ..., value1, value2, value1
- FrameType value1 = frameBuilder.pop();
- FrameType value2 = frameBuilder.pop();
- if (!value1.isWide()) {
- FrameType value3 = frameBuilder.pop();
- if (!value3.isWide()) {
- // (1)
- frameBuilder.verifyIsAssignable(value1, FrameType.oneWord());
- frameBuilder.verifyIsAssignable(value2, FrameType.oneWord());
- frameBuilder.verifyIsAssignable(value3, FrameType.oneWord());
- FrameType value4 = frameBuilder.pop(FrameType.oneWord());
- frameBuilder
- .push(value2)
- .push(value1)
- .push(value4)
- .push(value3)
- .push(value2)
- .push(value1);
- } else {
- // (3)
- frameBuilder.verifyIsAssignable(value1, FrameType.oneWord());
- frameBuilder.verifyIsAssignable(value2, FrameType.oneWord());
- frameBuilder.push(value2).push(value1).push(value3).push(value2).push(value1);
- }
- } else if (!value2.isWide()) {
- // (2)
- frameBuilder.verifyIsAssignable(value2, FrameType.oneWord());
- FrameType value3 = frameBuilder.pop(FrameType.oneWord());
- frameBuilder.push(value1).push(value3).push(value2).push(value1);
- } else {
- // (4)
- assert value2.isWide();
- frameBuilder.push(value1).push(value2).push(value1);
- }
- return;
- }
- case Swap:
- {
- // ..., value2, value1 →
- // ..., value1, value2
- FrameType value1 = frameBuilder.pop(FrameType.oneWord());
- FrameType value2 = frameBuilder.pop(FrameType.oneWord());
- frameBuilder.push(value1).push(value2);
- return;
- }
- default:
- throw new Unreachable("Invalid opcode for CfStackInstruction");
- }
- }
}
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfStore.java b/src/main/java/com/android/tools/r8/cf/code/CfStore.java
index 5d7081f..d46d3a3 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfStore.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfStore.java
@@ -4,11 +4,9 @@
package com.android.tools.r8.cf.code;
import com.android.tools.r8.cf.CfPrinter;
-import com.android.tools.r8.cf.code.CfFrame.FrameType;
import com.android.tools.r8.errors.Unreachable;
import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.graph.DexProgramClass;
-import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.GraphLens;
import com.android.tools.r8.graph.InitClassLens;
import com.android.tools.r8.graph.ProgramMethod;
@@ -102,42 +100,4 @@
InliningConstraints inliningConstraints, DexProgramClass context) {
return inliningConstraints.forStore();
}
-
- @Override
- public void evaluate(
- CfFrameVerificationHelper frameBuilder,
- DexType context,
- DexType returnType,
- DexItemFactory factory,
- InitClassLens initClassLens) {
- // ..., ref →
- // ...
- FrameType pop = frameBuilder.pop();
- switch (type) {
- case OBJECT:
- frameBuilder.verifyIsAssignable(pop, factory.objectType);
- frameBuilder.storeLocal(var, pop);
- return;
- case INT:
- frameBuilder.verifyIsAssignable(pop, factory.intType);
- frameBuilder.storeLocal(var, FrameType.initialized(factory.intType));
- return;
- case FLOAT:
- frameBuilder.verifyIsAssignable(pop, factory.floatType);
- frameBuilder.storeLocal(var, FrameType.initialized(factory.floatType));
- return;
- case LONG:
- frameBuilder.verifyIsAssignable(pop, factory.longType);
- frameBuilder.storeLocal(var, FrameType.initialized(factory.longType));
- frameBuilder.storeLocal(var + 1, FrameType.initialized(factory.longType));
- return;
- case DOUBLE:
- frameBuilder.verifyIsAssignable(pop, factory.doubleType);
- frameBuilder.storeLocal(var, FrameType.initialized(factory.doubleType));
- frameBuilder.storeLocal(var + 1, FrameType.initialized(factory.doubleType));
- return;
- default:
- throw new Unreachable("Unexpected type " + type);
- }
- }
}
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfSwitch.java b/src/main/java/com/android/tools/r8/cf/code/CfSwitch.java
index 03f6d09..edc5244 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfSwitch.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfSwitch.java
@@ -6,7 +6,6 @@
import com.android.tools.r8.cf.CfPrinter;
import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.graph.DexProgramClass;
-import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.GraphLens;
import com.android.tools.r8.graph.InitClassLens;
import com.android.tools.r8.graph.ProgramMethod;
@@ -118,20 +117,4 @@
InliningConstraints inliningConstraints, DexProgramClass context) {
return inliningConstraints.forJumpInstruction();
}
-
- @Override
- public void evaluate(
- CfFrameVerificationHelper frameBuilder,
- DexType context,
- DexType returnType,
- DexItemFactory factory,
- InitClassLens initClassLens) {
- // ..., index/key →
- // ...
- frameBuilder.pop(factory.intType);
- frameBuilder.verifyTarget(defaultTarget);
- for (CfLabel target : targets) {
- frameBuilder.verifyTarget(target);
- }
- }
}
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfThrow.java b/src/main/java/com/android/tools/r8/cf/code/CfThrow.java
index 7205017..aaa7280 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfThrow.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfThrow.java
@@ -6,7 +6,6 @@
import com.android.tools.r8.cf.CfPrinter;
import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.graph.DexProgramClass;
-import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.GraphLens;
import com.android.tools.r8.graph.InitClassLens;
import com.android.tools.r8.graph.ProgramMethod;
@@ -29,16 +28,6 @@
}
@Override
- public boolean isThrow() {
- return true;
- }
-
- @Override
- public CfThrow asThrow() {
- return this;
- }
-
- @Override
public void write(
ProgramMethod context,
DexItemFactory dexItemFactory,
@@ -71,18 +60,4 @@
InliningConstraints inliningConstraints, DexProgramClass context) {
return inliningConstraints.forJumpInstruction();
}
-
- @Override
- public void evaluate(
- CfFrameVerificationHelper frameBuilder,
- DexType context,
- DexType returnType,
- DexItemFactory factory,
- InitClassLens initClassLens) {
- // ..., objectref →
- // objectref
- frameBuilder.pop(factory.throwableType);
- // The exception edges are verified in CfCode since this is a throwing instruction.
- frameBuilder.setNoFrame();
- }
}
diff --git a/src/main/java/com/android/tools/r8/graph/AccessFlags.java b/src/main/java/com/android/tools/r8/graph/AccessFlags.java
index 4bbcead..8792d0c 100644
--- a/src/main/java/com/android/tools/r8/graph/AccessFlags.java
+++ b/src/main/java/com/android/tools/r8/graph/AccessFlags.java
@@ -233,15 +233,11 @@
}
private boolean wasSet(int flag) {
- return isSet(originalFlags, flag);
+ return (originalFlags & flag) != 0;
}
protected boolean isSet(int flag) {
- return isSet(modifiedFlags, flag);
- }
-
- public static boolean isSet(int flag, int flags) {
- return (flags & flag) != 0;
+ return (modifiedFlags & flag) != 0;
}
protected void set(int flag) {
diff --git a/src/main/java/com/android/tools/r8/graph/CfCode.java b/src/main/java/com/android/tools/r8/graph/CfCode.java
index d9d9730..b74a480 100644
--- a/src/main/java/com/android/tools/r8/graph/CfCode.java
+++ b/src/main/java/com/android/tools/r8/graph/CfCode.java
@@ -5,15 +5,11 @@
import static com.android.tools.r8.graph.DexCode.FAKE_THIS_PREFIX;
import static com.android.tools.r8.graph.DexCode.FAKE_THIS_SUFFIX;
-import static com.android.tools.r8.ir.conversion.CfSourceCode.canThrowHelper;
-import static org.objectweb.asm.Opcodes.ACC_STATIC;
import static org.objectweb.asm.Opcodes.V1_5;
import static org.objectweb.asm.Opcodes.V1_6;
import com.android.tools.r8.cf.CfPrinter;
import com.android.tools.r8.cf.code.CfFrame;
-import com.android.tools.r8.cf.code.CfFrame.FrameType;
-import com.android.tools.r8.cf.code.CfFrameVerificationHelper;
import com.android.tools.r8.cf.code.CfIinc;
import com.android.tools.r8.cf.code.CfInstruction;
import com.android.tools.r8.cf.code.CfLabel;
@@ -23,11 +19,7 @@
import com.android.tools.r8.cf.code.CfTryCatch;
import com.android.tools.r8.errors.InvalidDebugInfoException;
import com.android.tools.r8.errors.Unimplemented;
-import com.android.tools.r8.errors.Unreachable;
-import com.android.tools.r8.graph.RewrittenPrototypeDescription.ArgumentInfo;
-import com.android.tools.r8.graph.RewrittenPrototypeDescription.ArgumentInfoCollection;
import com.android.tools.r8.ir.code.IRCode;
-import com.android.tools.r8.ir.code.MemberType;
import com.android.tools.r8.ir.code.NumberGenerator;
import com.android.tools.r8.ir.code.Position;
import com.android.tools.r8.ir.conversion.CfSourceCode;
@@ -43,19 +35,13 @@
import com.android.tools.r8.utils.InternalOptions;
import com.google.common.base.Strings;
import it.unimi.dsi.fastutil.ints.Int2IntArrayMap;
-import it.unimi.dsi.fastutil.ints.Int2ReferenceAVLTreeMap;
import it.unimi.dsi.fastutil.ints.Int2ReferenceArrayMap;
import it.unimi.dsi.fastutil.ints.Int2ReferenceMap;
-import it.unimi.dsi.fastutil.ints.Int2ReferenceSortedMap;
-import java.util.ArrayDeque;
-import java.util.ArrayList;
import java.util.BitSet;
import java.util.Collections;
-import java.util.IdentityHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
-import java.util.function.BiPredicate;
import org.objectweb.asm.Label;
import org.objectweb.asm.MethodVisitor;
@@ -313,7 +299,6 @@
@Override
public IRCode buildIR(ProgramMethod method, AppView<?> appView, Origin origin) {
- // TODO(b/164396438): Assert that we can validate frames.
return internalBuildPossiblyWithLocals(method, method, appView, null, null, origin, null);
}
@@ -328,7 +313,6 @@
MethodProcessor methodProcessor) {
assert valueNumberGenerator != null;
assert callerPosition != null;
- // TODO(b/164396438): Assert that we can validate frames.
return internalBuildPossiblyWithLocals(
context, method, appView, valueNumberGenerator, callerPosition, origin, methodProcessor);
}
@@ -542,6 +526,7 @@
// IR processing.
inliningConstraints.disallowStaticInterfaceMethodCalls();
}
+
// Model a synchronized method as having a monitor instruction.
ConstraintWithTarget constraint =
method.getDefinition().isSynchronized()
@@ -594,254 +579,4 @@
new LocalVariableInfo(
thisLocalInfo.index, debugLocalInfo, thisLocalInfo.start, thisLocalInfo.end));
}
-
- public boolean verifyFrames(
- DexEncodedMethod method, AppView<?> appView, Origin origin, boolean applyProtoTypeChanges) {
- if (!appView.options().testing.readInputStackMaps
- || appView.options().testing.disableStackMapVerification) {
- return true;
- }
- if (method.hasClassFileVersion() && method.getClassFileVersion() <= V1_6) {
- return true;
- }
- if (!method.isInstanceInitializer()
- && appView
- .graphLens()
- .getOriginalMethodSignature(method.method)
- .isInstanceInitializer(appView.dexItemFactory())) {
- // We cannot verify instance initializers if they are moved.
- return true;
- }
- // Build a map from labels to frames.
- Map<CfLabel, CfFrame> stateMap = new IdentityHashMap<>();
- List<CfLabel> labels = new ArrayList<>();
- boolean requireStackMapFrame = !tryCatchRanges.isEmpty();
- for (CfInstruction instruction : instructions) {
- if (instruction.isFrame()) {
- CfFrame frame = instruction.asFrame();
- if (!labels.isEmpty()) {
- for (CfLabel label : labels) {
- if (stateMap.containsKey(label)) {
- appView
- .options()
- .reporter
- .error(
- CfCodeStackMapValidatingException.multipleFramesForLabel(
- origin,
- appView.graphLens().getOriginalMethodSignature(method.method),
- appView));
- return false;
- }
- stateMap.put(label, frame);
- }
- } else if (instruction != instructions.get(0)) {
- // From b/168212806, it is possible that the first instruction is a frame.
- appView
- .options()
- .reporter
- .error(
- CfCodeStackMapValidatingException.unexpectedStackMapFrame(
- origin,
- appView.graphLens().getOriginalMethodSignature(method.method),
- appView));
- return false;
- }
- }
- // We are trying to map a frame to a label, but we can have positions in between, so skip
- // those.
- if (instruction.isPosition()) {
- continue;
- } else if (instruction.isLabel()) {
- labels.add(instruction.asLabel());
- } else {
- labels.clear();
- }
- if (!requireStackMapFrame) {
- requireStackMapFrame = instruction.isJump() && !finalAndExitInstruction(instruction);
- }
- }
- // If there are no frames but we have seen a jump instruction, we cannot verify the stack map.
- if (requireStackMapFrame && stateMap.isEmpty()) {
- appView
- .options()
- .reporter
- .error(
- CfCodeStackMapValidatingException.noFramesForMethodWithJumps(
- origin, appView.graphLens().getOriginalMethodSignature(method.method), appView));
- return false;
- }
- DexType context = appView.graphLens().lookupType(method.holder());
- DexType returnType = appView.graphLens().lookupType(method.method.getReturnType());
- RewrittenPrototypeDescription rewrittenDescription = RewrittenPrototypeDescription.none();
- if (applyProtoTypeChanges) {
- rewrittenDescription =
- appView.graphLens().lookupPrototypeChangesForMethodDefinition(method.method);
- if (!rewrittenDescription.isEmpty()
- && rewrittenDescription.getRewrittenReturnInfo() != null) {
- returnType = rewrittenDescription.getRewrittenReturnInfo().getOldType();
- }
- }
- CfFrameVerificationHelper builder =
- new CfFrameVerificationHelper(
- context,
- stateMap,
- tryCatchRanges,
- isAssignablePredicate(appView),
- appView.dexItemFactory());
- if (stateMap.containsKey(null)) {
- assert !shouldComputeInitialFrame();
- builder.verifyFrameAndSet(stateMap.get(null));
- } else if (shouldComputeInitialFrame()) {
- builder.verifyFrameAndSet(
- new CfFrame(
- computeInitialLocals(context, method, rewrittenDescription), new ArrayDeque<>()));
- }
- for (int i = 0; i < instructions.size(); i++) {
- CfInstruction instruction = instructions.get(i);
- try {
- // Check the exceptional edge prior to evaluating the instruction. The local state is stable
- // at this point as store operations are not throwing and the current stack does not
- // affect the exceptional transfer (the exception edge is always a singleton stack).
- if (canThrowHelper(instruction, appView.options().isGeneratingClassFiles())) {
- assert !instruction.isStore();
- builder.verifyExceptionEdges();
- }
- instruction.evaluate(
- builder, context, returnType, appView.dexItemFactory(), appView.initClassLens());
- } catch (CfCodeStackMapValidatingException ex) {
- appView
- .options()
- .reporter
- .error(
- CfCodeStackMapValidatingException.toDiagnostics(
- origin,
- appView.graphLens().getOriginalMethodSignature(method.method),
- i,
- instruction,
- ex.getMessage(),
- appView));
- return false;
- }
- }
- return true;
- }
-
- private boolean finalAndExitInstruction(CfInstruction instruction) {
- boolean isReturnOrThrow = instruction.isThrow() || instruction.isReturn();
- if (!isReturnOrThrow) {
- return false;
- }
- for (int i = instructions.size() - 1; i >= 0; i--) {
- CfInstruction instr = instructions.get(i);
- if (instr == instruction) {
- return true;
- }
- if (instr.isPosition() || instr.isLabel()) {
- continue;
- }
- return false;
- }
- throw new Unreachable("Instruction " + instruction + " should be in instructions");
- }
-
- private boolean shouldComputeInitialFrame() {
- for (CfInstruction instruction : instructions) {
- if (instruction.isFrame()) {
- return false;
- } else if (!instruction.isLabel() && !instruction.isPosition()) {
- return true;
- }
- }
- // We should never see a method with only labels and positions.
- assert false;
- return true;
- }
-
- private Int2ReferenceSortedMap<FrameType> computeInitialLocals(
- DexType context, DexEncodedMethod method, RewrittenPrototypeDescription protoTypeChanges) {
- int accessFlags =
- protoTypeChanges.isEmpty()
- ? method.accessFlags.modifiedFlags
- : method.accessFlags.originalFlags;
- Int2ReferenceSortedMap<FrameType> initialLocals = new Int2ReferenceAVLTreeMap<>();
- int index = 0;
- if (method.isInstanceInitializer()) {
- initialLocals.put(index++, FrameType.uninitializedThis());
- } else if (!MethodAccessFlags.isSet(ACC_STATIC, accessFlags)) {
- initialLocals.put(index++, FrameType.initialized(context));
- }
- ArgumentInfoCollection argumentsInfo = protoTypeChanges.getArgumentInfoCollection();
- DexType[] parameters = method.method.proto.parameters.values;
- int originalNumberOfArguments =
- parameters.length
- + argumentsInfo.numberOfRemovedArguments()
- + initialLocals.size()
- - protoTypeChanges.numberOfExtraParameters();
- int argumentIndex = index;
- int usedArgumentIndex = 0;
- while (argumentIndex < originalNumberOfArguments) {
- ArgumentInfo argumentInfo = argumentsInfo.getArgumentInfo(argumentIndex++);
- DexType localType;
- if (argumentInfo.isRemovedArgumentInfo()) {
- localType = argumentInfo.asRemovedArgumentInfo().getType();
- } else {
- if (argumentInfo.isRewrittenTypeInfo()) {
- assert parameters[usedArgumentIndex] == argumentInfo.asRewrittenTypeInfo().getNewType();
- localType = argumentInfo.asRewrittenTypeInfo().getOldType();
- } else {
- localType = parameters[usedArgumentIndex];
- }
- usedArgumentIndex++;
- }
- FrameType frameType = FrameType.initialized(localType);
- initialLocals.put(index++, frameType);
- if (localType.isWideType()) {
- initialLocals.put(index++, frameType);
- }
- }
- return initialLocals;
- }
-
- private BiPredicate<DexType, DexType> isAssignablePredicate(AppView<?> appView) {
- return (source, target) -> isAssignable(source, target, appView);
- }
-
- // Rules found at https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.10.1.2
- private boolean isAssignable(DexType source, DexType target, AppView<?> appView) {
- DexItemFactory factory = appView.dexItemFactory();
- source = byteCharShortOrBooleanToInt(source, factory);
- target = byteCharShortOrBooleanToInt(target, factory);
- if (source == target) {
- return true;
- }
- if (source.isPrimitiveType() || target.isPrimitiveType()) {
- return false;
- }
- // Both are now references - everything is assignable to object.
- if (target == factory.objectType) {
- return true;
- }
- // isAssignable(null, class(_, _)).
- // isAssignable(null, arrayOf(_)).
- if (source == DexItemFactory.nullValueType) {
- return true;
- }
- if (target.isArrayType() != target.isArrayType()) {
- return false;
- }
- if (target.isArrayType()) {
- return isAssignable(
- target.toArrayElementType(factory), target.toArrayElementType(factory), appView);
- }
- // TODO(b/166570659): Do a sub-type check that allows for missing classes in hierarchy.
- return MemberType.fromDexType(source) == MemberType.fromDexType(target);
- }
-
- private DexType byteCharShortOrBooleanToInt(DexType type, DexItemFactory factory) {
- // byte, char, short and boolean has verification type int.
- if (type.isByteType() || type.isCharType() || type.isShortType() || type.isBooleanType()) {
- return factory.intType;
- }
- return type;
- }
}
diff --git a/src/main/java/com/android/tools/r8/graph/CfCodeDiagnostics.java b/src/main/java/com/android/tools/r8/graph/CfCodeDiagnostics.java
deleted file mode 100644
index 764a812..0000000
--- a/src/main/java/com/android/tools/r8/graph/CfCodeDiagnostics.java
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright (c) 2020, the R8 project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.android.tools.r8.graph;
-
-import com.android.tools.r8.Diagnostic;
-import com.android.tools.r8.origin.Origin;
-import com.android.tools.r8.position.MethodPosition;
-import com.android.tools.r8.position.Position;
-
-public class CfCodeDiagnostics implements Diagnostic {
-
- @Override
- public Origin getOrigin() {
- return origin;
- }
-
- @Override
- public Position getPosition() {
- return methodPosition;
- }
-
- @Override
- public String getDiagnosticMessage() {
- return diagnosticMessage;
- }
-
- private final Origin origin;
- private final MethodPosition methodPosition;
- private final String diagnosticMessage;
-
- CfCodeDiagnostics(Origin origin, DexMethod method, String diagnosticMessage) {
- this.origin = origin;
- this.methodPosition = new MethodPosition(method.asMethodReference());
- this.diagnosticMessage = diagnosticMessage;
- }
-}
diff --git a/src/main/java/com/android/tools/r8/graph/CfCodeStackMapValidatingException.java b/src/main/java/com/android/tools/r8/graph/CfCodeStackMapValidatingException.java
deleted file mode 100644
index 6c54a1a..0000000
--- a/src/main/java/com/android/tools/r8/graph/CfCodeStackMapValidatingException.java
+++ /dev/null
@@ -1,68 +0,0 @@
-// Copyright (c) 2020, the R8 project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.android.tools.r8.graph;
-
-import com.android.tools.r8.cf.code.CfInstruction;
-import com.android.tools.r8.origin.Origin;
-
-public class CfCodeStackMapValidatingException extends RuntimeException {
-
- private CfCodeStackMapValidatingException(String message) {
- super(message);
- }
-
- public static CfCodeStackMapValidatingException error(String messsage) {
- return new CfCodeStackMapValidatingException(messsage);
- }
-
- public static CfCodeDiagnostics unexpectedStackMapFrame(
- Origin origin, DexMethod method, AppView<?> appView) {
- StringBuilder sb = new StringBuilder("Unexpected stack map frame without target");
- if (appView.enableWholeProgramOptimizations()) {
- sb.append(" In later version of R8, the method may be assumed not reachable.");
- }
- return new CfCodeDiagnostics(origin, method, sb.toString());
- }
-
- public static CfCodeDiagnostics multipleFramesForLabel(
- Origin origin, DexMethod method, AppView<?> appView) {
- StringBuilder sb = new StringBuilder("Multiple frames for label");
- if (appView.enableWholeProgramOptimizations()) {
- sb.append(" In later version of R8, the method may be assumed not reachable.");
- }
- return new CfCodeDiagnostics(origin, method, sb.toString());
- }
-
- public static CfCodeDiagnostics noFramesForMethodWithJumps(
- Origin origin, DexMethod method, AppView<?> appView) {
- StringBuilder sb =
- new StringBuilder("Expected stack map table for method with non-linear control flow.");
- if (appView.enableWholeProgramOptimizations()) {
- sb.append(" In later version of R8, the method may be assumed not reachable.");
- }
- return new CfCodeDiagnostics(origin, method, sb.toString());
- }
-
- public static CfCodeDiagnostics toDiagnostics(
- Origin origin,
- DexMethod method,
- int instructionIndex,
- CfInstruction instruction,
- String detailMessage,
- AppView<?> appView) {
- StringBuilder sb =
- new StringBuilder("Invalid stack map table at ")
- .append(instructionIndex)
- .append(": ")
- .append(instruction)
- .append(", error: ")
- .append(detailMessage)
- .append(".");
- if (appView.enableWholeProgramOptimizations()) {
- sb.append(" In later version of R8, the method may be assumed not reachable.");
- }
- return new CfCodeDiagnostics(origin, method, sb.toString());
- }
-}
diff --git a/src/main/java/com/android/tools/r8/graph/DexMethod.java b/src/main/java/com/android/tools/r8/graph/DexMethod.java
index c2caa61..26f114f 100644
--- a/src/main/java/com/android/tools/r8/graph/DexMethod.java
+++ b/src/main/java/com/android/tools/r8/graph/DexMethod.java
@@ -232,7 +232,7 @@
&& proto == dexItemFactory.deserializeLambdaMethodProto;
}
- public boolean isInstanceInitializer(DexItemFactory factory) {
- return factory.isConstructor(this);
+ public boolean isInstanceInitializer(DexDefinitionSupplier definitions) {
+ return definitions.dexItemFactory().isConstructor(this);
}
}
diff --git a/src/main/java/com/android/tools/r8/graph/LazyCfCode.java b/src/main/java/com/android/tools/r8/graph/LazyCfCode.java
index ff71ef8..b0e0312 100644
--- a/src/main/java/com/android/tools/r8/graph/LazyCfCode.java
+++ b/src/main/java/com/android/tools/r8/graph/LazyCfCode.java
@@ -67,10 +67,8 @@
import it.unimi.dsi.fastutil.ints.Int2ReferenceAVLTreeMap;
import it.unimi.dsi.fastutil.ints.Int2ReferenceMap;
import it.unimi.dsi.fastutil.ints.Int2ReferenceSortedMap;
-import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Collections;
-import java.util.Deque;
import java.util.HashMap;
import java.util.IdentityHashMap;
import java.util.List;
@@ -212,9 +210,7 @@
@Override
public IRCode buildIR(ProgramMethod method, AppView<?> appView, Origin origin) {
- CfCode cfCode = asCfCode();
- cfCode.verifyFrames(method.getDefinition(), appView, origin, true);
- return cfCode.buildIR(method, appView, origin);
+ return asCfCode().buildIR(method, appView, origin);
}
@Override
@@ -226,11 +222,15 @@
Position callerPosition,
Origin origin,
MethodProcessor methodProcessor) {
- CfCode cfCode = asCfCode();
- cfCode.verifyFrames(
- method.getDefinition(), appView, origin, methodProcessor.shouldApplyCodeRewritings(method));
- return cfCode.buildInliningIR(
- context, method, appView, valueNumberGenerator, callerPosition, origin, methodProcessor);
+ return asCfCode()
+ .buildInliningIR(
+ context,
+ method,
+ appView,
+ valueNumberGenerator,
+ callerPosition,
+ origin,
+ methodProcessor);
}
@Override
@@ -387,7 +387,7 @@
int frameType, int nLocals, Object[] localTypes, int nStack, Object[] stackTypes) {
assert frameType == Opcodes.F_NEW;
Int2ReferenceSortedMap<FrameType> parsedLocals = parseLocals(nLocals, localTypes);
- Deque<FrameType> parsedStack = parseStack(nStack, stackTypes);
+ List<FrameType> parsedStack = parseStack(nStack, stackTypes);
instructions.add(new CfFrame(parsedLocals, parsedStack));
}
@@ -405,8 +405,8 @@
return types;
}
- private Deque<FrameType> parseStack(int nStack, Object[] stackTypes) {
- Deque<FrameType> dexStack = new ArrayDeque<>(nStack);
+ private List<FrameType> parseStack(int nStack, Object[] stackTypes) {
+ List<FrameType> dexStack = new ArrayList<>(nStack);
for (int i = 0; i < nStack; i++) {
dexStack.add(getFrameType(stackTypes[i]));
}
@@ -415,7 +415,7 @@
private FrameType getFrameType(Object localType) {
if (localType instanceof Label) {
- return FrameType.uninitializedNew(getLabel((Label) localType), null);
+ return FrameType.uninitializedNew(getLabel((Label) localType));
} else if (localType == Opcodes.UNINITIALIZED_THIS) {
return FrameType.uninitializedThis();
} else if (localType == null || localType == Opcodes.TOP) {
@@ -989,11 +989,12 @@
private static DebugParsingOptions getParsingOptions(
JarApplicationReader application, boolean reachabilitySensitive) {
- // TODO(b/166841731): We should compute our own from the compressed format.
int parsingOptions =
- application.options.testing.readInputStackMaps
+ (application.options.enableCfByteCodePassThrough
+ || application.options.testing.readInputStackMaps)
? ClassReader.EXPAND_FRAMES
: ClassReader.SKIP_FRAMES;
+
ProguardConfiguration configuration = application.options.getProguardConfiguration();
if (configuration == null) {
return new DebugParsingOptions(true, true, parsingOptions);
diff --git a/src/main/java/com/android/tools/r8/ir/code/InvokeDirect.java b/src/main/java/com/android/tools/r8/ir/code/InvokeDirect.java
index 6d452e1..020254f 100644
--- a/src/main/java/com/android/tools/r8/ir/code/InvokeDirect.java
+++ b/src/main/java/com/android/tools/r8/ir/code/InvokeDirect.java
@@ -166,7 +166,7 @@
if (instructionMayHaveSideEffects(appView, context)) {
return DeadInstructionResult.notDead();
}
- if (!getInvokedMethod().isInstanceInitializer(appView.dexItemFactory())) {
+ if (!getInvokedMethod().isInstanceInitializer(appView)) {
return DeadInstructionResult.deadIfOutValueIsDead();
}
// Super-constructor calls cannot be removed.
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/CfBuilder.java b/src/main/java/com/android/tools/r8/ir/conversion/CfBuilder.java
index f7f2155..9055230 100644
--- a/src/main/java/com/android/tools/r8/ir/conversion/CfBuilder.java
+++ b/src/main/java/com/android/tools/r8/ir/conversion/CfBuilder.java
@@ -59,6 +59,7 @@
import it.unimi.dsi.fastutil.ints.Int2ReferenceSortedMap;
import java.util.ArrayDeque;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.Deque;
import java.util.HashMap;
import java.util.HashSet;
@@ -529,14 +530,13 @@
private void addFrame(BasicBlock block) {
List<TypeInfo> stack = registerAllocator.getTypesAtBlockEntry(block).stack;
- Deque<FrameType> stackTypes;
+ List<FrameType> stackTypes;
if (block.entry().isMoveException()) {
assert stack.isEmpty();
StackValue exception = (StackValue) block.entry().outValue();
- stackTypes = new ArrayDeque<>();
- stackTypes.add(getFrameType(block, exception.getTypeInfo()));
+ stackTypes = Collections.singletonList(getFrameType(block, exception.getTypeInfo()));
} else {
- stackTypes = new ArrayDeque<>(stack.size());
+ stackTypes = new ArrayList<>(stack.size());
for (TypeInfo typeInfo : stack) {
stackTypes.add(getFrameType(block, typeInfo));
}
@@ -577,11 +577,8 @@
FrameType res;
Instruction definition;
if (typeInfo instanceof NewInstanceInfo) {
- NewInstanceInfo newInstanceInfo = (NewInstanceInfo) typeInfo;
- definition = newInstanceInfo.newInstance;
- res =
- FrameType.uninitializedNew(
- newInstanceLabels.get(definition), newInstanceInfo.getDexType());
+ definition = ((NewInstanceInfo) typeInfo).newInstance;
+ res = FrameType.uninitializedNew(newInstanceLabels.get(definition));
} else if (typeInfo instanceof ThisInstanceInfo) {
definition = ((ThisInstanceInfo) typeInfo).thisArgument;
res = FrameType.uninitializedThis();
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/CfSourceCode.java b/src/main/java/com/android/tools/r8/ir/conversion/CfSourceCode.java
index f7e8a90..d4c8040 100644
--- a/src/main/java/com/android/tools/r8/ir/conversion/CfSourceCode.java
+++ b/src/main/java/com/android/tools/r8/ir/conversion/CfSourceCode.java
@@ -292,11 +292,7 @@
// This is the only instruction that differ in throwing between DEX and CF. If we find more
// consider rewriting CfInstruction.canThrow to take in options.
private boolean canThrowHelper(CfInstruction instruction) {
- return canThrowHelper(instruction, internalOutputMode.isGeneratingClassFiles());
- }
-
- public static boolean canThrowHelper(CfInstruction instruction, boolean isGeneratingClassFiles) {
- if (isGeneratingClassFiles
+ if (internalOutputMode.isGeneratingClassFiles()
&& (instruction.isConstString() || instruction.isDexItemBasedConstString())) {
return false;
}
@@ -609,9 +605,8 @@
for (Int2ReferenceMap.Entry<FrameType> entry : frameLocals.int2ReferenceEntrySet()) {
locals[entry.getIntKey()] = convertUninitialized(entry.getValue());
}
- int index = 0;
- for (FrameType frameType : frame.getStack()) {
- stack[index++] = convertUninitialized(frameType);
+ for (int i = 0; i < stack.length; i++) {
+ stack[i] = convertUninitialized(frame.getStack().get(i));
}
state.setStateFromFrame(
locals, stack, getCanonicalDebugPositionAtOffset(currentInstructionIndex));
diff --git a/src/main/java/com/android/tools/r8/relocator/RelocatorCommand.java b/src/main/java/com/android/tools/r8/relocator/RelocatorCommand.java
index 7da1116..b8355c3 100644
--- a/src/main/java/com/android/tools/r8/relocator/RelocatorCommand.java
+++ b/src/main/java/com/android/tools/r8/relocator/RelocatorCommand.java
@@ -157,6 +157,8 @@
options.dataResourceConsumer = consumer.getDataResourceConsumer();
// Set debug to ensure that we are writing all information to the application writer.
options.debug = true;
+ // We need to read stack maps since we are not processing anything.
+ options.testing.readInputStackMaps = true;
return options;
}
diff --git a/src/main/java/com/android/tools/r8/utils/InternalOptions.java b/src/main/java/com/android/tools/r8/utils/InternalOptions.java
index ae7a9d7..cf31dec 100644
--- a/src/main/java/com/android/tools/r8/utils/InternalOptions.java
+++ b/src/main/java/com/android/tools/r8/utils/InternalOptions.java
@@ -1257,13 +1257,12 @@
public boolean enableForceNestBasedAccessDesugaringForTest = false;
public boolean verifyKeptGraphInfo = false;
- public boolean readInputStackMaps = true;
- public boolean disableStackMapVerification = false;
-
// Force each call of application read to dump its inputs to a file, which is subsequently
// deleted. Useful to check that our dump functionality does not cause compilation failure.
public boolean dumpAll = false;
+ public boolean readInputStackMaps = false;
+
// Option for testing outlining with interface array arguments, see b/132420510.
public boolean allowOutlinerInterfaceArrayArguments = false;
diff --git a/src/main/java/com/android/tools/r8/utils/MapUtils.java b/src/main/java/com/android/tools/r8/utils/MapUtils.java
index 3009e49..3929e87 100644
--- a/src/main/java/com/android/tools/r8/utils/MapUtils.java
+++ b/src/main/java/com/android/tools/r8/utils/MapUtils.java
@@ -4,7 +4,6 @@
package com.android.tools.r8.utils;
-import com.android.tools.r8.utils.StringUtils.BraceType;
import java.util.Map;
public class MapUtils {
@@ -12,9 +11,4 @@
public static <T> void removeIdentityMappings(Map<T, T> map) {
map.entrySet().removeIf(entry -> entry.getKey() == entry.getValue());
}
-
- public static String toString(Map<?, ?> map) {
- return StringUtils.join(
- map.entrySet(), ",", BraceType.TUBORG, entry -> entry.getKey() + ":" + entry.getValue());
- }
}
diff --git a/src/main/java/com/android/tools/r8/utils/collections/ImmutableDeque.java b/src/main/java/com/android/tools/r8/utils/collections/ImmutableDeque.java
deleted file mode 100644
index 17c5e4a..0000000
--- a/src/main/java/com/android/tools/r8/utils/collections/ImmutableDeque.java
+++ /dev/null
@@ -1,115 +0,0 @@
-// Copyright (c) 2020, the R8 project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.android.tools.r8.utils.collections;
-
-import com.android.tools.r8.errors.Unreachable;
-import java.util.ArrayDeque;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Deque;
-import java.util.function.Predicate;
-
-@SuppressWarnings("NullableProblems")
-public class ImmutableDeque<T> extends ArrayDeque<T> {
-
- private boolean isClosed = false;
-
- private ImmutableDeque(Collection<T> items) {
- super(items);
- }
-
- private void close() {
- isClosed = true;
- }
-
- @Override
- public void push(T t) {
- throw new Unreachable("Modification not allowed on immutable structure");
- }
-
- @Override
- public T pop() {
- throw new Unreachable("Modification not allowed on immutable structure");
- }
-
- @Override
- public void addFirst(T t) {
- throw new Unreachable("Modification not allowed on immutable structure");
- }
-
- @Override
- public void addLast(T t) {
- if (isClosed) {
- throw new Unreachable("Modification not allowed on immutable structure");
- } else {
- super.addLast(t);
- }
- }
-
- @Override
- public boolean removeFirstOccurrence(Object o) {
- throw new Unreachable("Modification not allowed on immutable structure");
- }
-
- @Override
- public boolean remove(Object o) {
- throw new Unreachable("Modification not allowed on immutable structure");
- }
-
- @Override
- public T removeFirst() {
- throw new Unreachable("Modification not allowed on immutable structure");
- }
-
- @Override
- public boolean removeAll(Collection<?> c) {
- throw new Unreachable("Modification not allowed on immutable structure");
- }
-
- @Override
- public boolean removeIf(Predicate<? super T> filter) {
- throw new Unreachable("Modification not allowed on immutable structure");
- }
-
- @Override
- public boolean removeLastOccurrence(Object o) {
- throw new Unreachable("Modification not allowed on immutable structure");
- }
-
- @Override
- public T removeLast() {
- throw new Unreachable("Modification not allowed on immutable structure");
- }
-
- @Override
- public T remove() {
- throw new Unreachable("Modification not allowed on immutable structure");
- }
-
- @Override
- public boolean add(T t) {
- if (isClosed) {
- throw new Unreachable("Modification not allowed on immutable structure");
- } else {
- return super.add(t);
- }
- }
-
- @Override
- public boolean addAll(Collection<? extends T> c) {
- if (isClosed) {
- throw new Unreachable("Modification not allowed on immutable structure");
- } else {
- return super.addAll(c);
- }
- }
-
- @SafeVarargs
- public static <T> Deque<T> of(T... items) {
- ImmutableDeque<T> deque = new ImmutableDeque<>(Arrays.asList(items));
- deque.close();
- return deque;
- }
-}
diff --git a/src/test/java/com/android/tools/r8/CfFrontendExamplesTest.java b/src/test/java/com/android/tools/r8/CfFrontendExamplesTest.java
index cea34f9..2ae20c9 100644
--- a/src/test/java/com/android/tools/r8/CfFrontendExamplesTest.java
+++ b/src/test/java/com/android/tools/r8/CfFrontendExamplesTest.java
@@ -310,7 +310,12 @@
.addProguardConfiguration(ImmutableList.of("-keepattributes *"), Origin.unknown())
.setOutput(outputJar, OutputMode.ClassFile)
.build();
- ToolHelper.runR8(command, options -> options.skipIR = true);
+ ToolHelper.runR8(
+ command,
+ options -> {
+ options.skipIR = true;
+ options.testing.readInputStackMaps = true;
+ });
ArchiveClassFileProvider expected = new ArchiveClassFileProvider(inputJar);
ArchiveClassFileProvider actual = new ArchiveClassFileProvider(outputJar);
assertEquals(getSortedDescriptorList(expected), getSortedDescriptorList(actual));
diff --git a/src/test/java/com/android/tools/r8/R8RunArtTestsTest.java b/src/test/java/com/android/tools/r8/R8RunArtTestsTest.java
index d9ed43f..eddf1ee 100644
--- a/src/test/java/com/android/tools/r8/R8RunArtTestsTest.java
+++ b/src/test/java/com/android/tools/r8/R8RunArtTestsTest.java
@@ -1193,7 +1193,6 @@
private static Map<String, Consumer<InternalOptions>> configurations =
ImmutableMap.of(
// Has a new-instance instruction that attempts to instantiate an interface.
- "162-method-resolution", options -> options.testing.disableStackMapVerification = true,
"435-new-instance", options -> options.testing.allowTypeErrors = true);
private static List<String> failuresToTriage = ImmutableList.of(
@@ -1791,7 +1790,7 @@
builder
.addLibraryFiles(ToolHelper.getAndroidJar(AndroidApiLevel.getDefault()));
}
- ToolHelper.runD8(builder, compilationOptions::accept);
+ D8.run(builder.build());
break;
}
case R8:
diff --git a/src/test/java/com/android/tools/r8/TestDiagnosticMessagesImpl.java b/src/test/java/com/android/tools/r8/TestDiagnosticMessagesImpl.java
index 3935988..ab5027b 100644
--- a/src/test/java/com/android/tools/r8/TestDiagnosticMessagesImpl.java
+++ b/src/test/java/com/android/tools/r8/TestDiagnosticMessagesImpl.java
@@ -282,7 +282,6 @@
return assertDiagnosticThatMatches(getInfos(), "info", matcher);
}
- @Override
public TestDiagnosticMessages assertWarningThatMatches(Matcher<Diagnostic> matcher) {
return assertDiagnosticThatMatches(getWarnings(), "warning", matcher);
}
diff --git a/src/test/java/com/android/tools/r8/cf/stackmap/StackMapVerificationNoFrameForHandlerTest.java b/src/test/java/com/android/tools/r8/cf/stackmap/StackMapVerificationNoFrameForHandlerTest.java
deleted file mode 100644
index 292747e..0000000
--- a/src/test/java/com/android/tools/r8/cf/stackmap/StackMapVerificationNoFrameForHandlerTest.java
+++ /dev/null
@@ -1,266 +0,0 @@
-// Copyright (c) 2020, the R8 project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.android.tools.r8.cf.stackmap;
-
-import static com.android.tools.r8.DiagnosticsMatcher.diagnosticMessage;
-import static org.hamcrest.CoreMatchers.containsString;
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.junit.Assert.assertThrows;
-import static org.junit.Assert.assertTrue;
-
-import com.android.tools.r8.CompilationFailedException;
-import com.android.tools.r8.R8FullTestBuilder;
-import com.android.tools.r8.SingleTestRunResult;
-import com.android.tools.r8.TestBase;
-import com.android.tools.r8.TestBuilder;
-import com.android.tools.r8.TestParameters;
-import com.android.tools.r8.references.Reference;
-import com.android.tools.r8.utils.BooleanUtils;
-import java.util.List;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-import org.junit.runners.Parameterized.Parameters;
-import org.objectweb.asm.ClassWriter;
-import org.objectweb.asm.Label;
-import org.objectweb.asm.MethodVisitor;
-import org.objectweb.asm.Opcodes;
-
-@RunWith(Parameterized.class)
-public class StackMapVerificationNoFrameForHandlerTest extends TestBase {
-
- private final TestParameters parameters;
- private final boolean includeFrameInHandler;
- private final String EXPECTED_OUTPUT = "Hello World!";
- private final String EXPECTED_VERIFY_ERROR =
- "Expected stack map table for method with non-linear control flow";
-
- @Parameters(name = "{0}")
- public static List<Object[]> data() {
- return buildParameters(
- getTestParameters().withAllRuntimesAndApiLevels().build(), BooleanUtils.values());
- }
-
- public StackMapVerificationNoFrameForHandlerTest(
- TestParameters parameters, boolean includeFrameInHandler) {
- this.parameters = parameters;
- this.includeFrameInHandler = includeFrameInHandler;
- }
-
- @Test
- public void testRuntime() throws Exception {
- TestBuilder<? extends SingleTestRunResult<?>, ?> builder =
- testForRuntime(parameters)
- .addProgramClassFileData(
- includeFrameInHandler
- ? MainDump.dump()
- : transformer(MainDump.dump(), Reference.classFromClass(Main.class))
- .stripFrames("main")
- .transform());
- if (includeFrameInHandler) {
- builder
- .run(parameters.getRuntime(), Main.class)
- .assertSuccessWithOutputLines(EXPECTED_OUTPUT);
- } else if (parameters.isCfRuntime()) {
- builder
- .run(parameters.getRuntime(), Main.class)
- .assertFailureWithErrorThatMatches(
- containsString("java.lang.VerifyError: Expecting a stackmap frame at branch target"));
- } else {
- assertTrue(parameters.isDexRuntime());
- CompilationFailedException compilationFailedException =
- assertThrows(
- CompilationFailedException.class,
- () -> {
- builder.run(parameters.getRuntime(), Main.class);
- });
- assertThat(
- compilationFailedException.getCause().getMessage(),
- containsString(EXPECTED_VERIFY_ERROR));
- }
- }
-
- @Test
- public void testHandlerR8() throws Exception {
- R8FullTestBuilder builder =
- testForR8(parameters.getBackend())
- .addProgramClassFileData(
- includeFrameInHandler
- ? MainDump.dump()
- : transformer(MainDump.dump(), Reference.classFromClass(Main.class))
- .stripFrames("main")
- .transform())
- .addKeepMainRule(Main.class)
- .setMinApi(parameters.getApiLevel());
- if (includeFrameInHandler) {
- builder
- .run(parameters.getRuntime(), Main.class)
- .assertSuccessWithOutputLines(EXPECTED_OUTPUT);
- } else {
- assertThrows(
- CompilationFailedException.class,
- () -> {
- builder.compileWithExpectedDiagnostics(
- diagnostics -> {
- diagnostics.assertOnlyErrors();
- diagnostics.assertErrorsMatch(
- diagnosticMessage(containsString(EXPECTED_VERIFY_ERROR)));
- });
- });
- }
- }
-
- public static class Main {
-
- public static void main(String[] args) {
- try {
- getThrowable(new Throwable());
- } catch (Throwable e) {
- }
- System.out.println("Hello World!");
- }
-
- public static Throwable getThrowable(Throwable throwable) {
- if (System.currentTimeMillis() > 0) {
- return new RuntimeException(throwable);
- } else {
- throw new ClassCastException();
- }
- }
- }
-
- /**
- * The dump is mostly the code obtained from the Main class above, however, some instructions are
- * removed to have the frames being the same with linear flow:
- *
- * <pre>
- * try {
- * getThrowable(new Throwable());
- * pop
- * goto lbl3
- * } catch (Throwable e) {
- * astore(1);
- * goto lbl3
- * }
- * lbl3
- * System.out.println("Hello World!");
- * </pre>
- *
- * becomes:
- *
- * <pre>
- * try {
- * getThrowable(new Throwable());
- * } catch (Throwable e) {
- * pop;
- * }
- * lbl3
- * System.out.println("Hello World!");
- * </pre>
- */
- public static class MainDump implements Opcodes {
-
- public static byte[] dump() {
-
- ClassWriter classWriter = new ClassWriter(0);
- MethodVisitor methodVisitor;
-
- classWriter.visit(
- V1_8,
- ACC_PUBLIC | ACC_SUPER,
- "com/android/tools/r8/cf/stackmap/StackMapVerificationNoFrameForHandlerTest$Main",
- null,
- "java/lang/Object",
- null);
-
- classWriter.visitInnerClass(
- "com/android/tools/r8/cf/stackmap/StackMapVerificationNoFrameForHandlerTest$Main",
- "com/android/tools/r8/cf/stackmap/StackMapVerificationNoFrameForHandlerTest",
- "Main",
- ACC_PUBLIC | ACC_STATIC);
-
- {
- methodVisitor = classWriter.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
- methodVisitor.visitCode();
- methodVisitor.visitVarInsn(ALOAD, 0);
- methodVisitor.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false);
- methodVisitor.visitInsn(RETURN);
- methodVisitor.visitMaxs(1, 1);
- methodVisitor.visitEnd();
- }
- {
- methodVisitor =
- classWriter.visitMethod(
- ACC_PUBLIC | ACC_STATIC, "main", "([Ljava/lang/String;)V", null, null);
- methodVisitor.visitCode();
- Label label0 = new Label();
- Label label1 = new Label();
- Label label2 = new Label();
- methodVisitor.visitTryCatchBlock(label0, label1, label2, "java/lang/Throwable");
- methodVisitor.visitLabel(label0);
- methodVisitor.visitTypeInsn(NEW, "java/lang/Throwable");
- methodVisitor.visitInsn(DUP);
- methodVisitor.visitMethodInsn(INVOKESPECIAL, "java/lang/Throwable", "<init>", "()V", false);
- methodVisitor.visitMethodInsn(
- INVOKESTATIC,
- "com/android/tools/r8/cf/stackmap/StackMapVerificationNoFrameForHandlerTest$Main",
- "getThrowable",
- "(Ljava/lang/Throwable;)Ljava/lang/Throwable;",
- false);
- methodVisitor.visitLabel(label1);
- methodVisitor.visitLabel(label2);
- methodVisitor.visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[] {"java/lang/Throwable"});
- methodVisitor.visitInsn(POP);
- Label label3 = new Label();
- methodVisitor.visitLabel(label3);
- methodVisitor.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
- methodVisitor.visitLdcInsn("Hello World!");
- methodVisitor.visitMethodInsn(
- INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);
- methodVisitor.visitInsn(RETURN);
- methodVisitor.visitMaxs(2, 2);
- methodVisitor.visitEnd();
- }
- {
- methodVisitor =
- classWriter.visitMethod(
- ACC_PUBLIC | ACC_STATIC,
- "getThrowable",
- "(Ljava/lang/Throwable;)Ljava/lang/Throwable;",
- null,
- null);
- methodVisitor.visitCode();
- methodVisitor.visitMethodInsn(
- INVOKESTATIC, "java/lang/System", "currentTimeMillis", "()J", false);
- methodVisitor.visitInsn(LCONST_0);
- methodVisitor.visitInsn(LCMP);
- Label label0 = new Label();
- methodVisitor.visitJumpInsn(IFLE, label0);
- methodVisitor.visitTypeInsn(NEW, "java/lang/RuntimeException");
- methodVisitor.visitInsn(DUP);
- methodVisitor.visitVarInsn(ALOAD, 0);
- methodVisitor.visitMethodInsn(
- INVOKESPECIAL,
- "java/lang/RuntimeException",
- "<init>",
- "(Ljava/lang/Throwable;)V",
- false);
- methodVisitor.visitInsn(ARETURN);
- methodVisitor.visitLabel(label0);
- methodVisitor.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
- methodVisitor.visitTypeInsn(NEW, "java/lang/ClassCastException");
- methodVisitor.visitInsn(DUP);
- methodVisitor.visitMethodInsn(
- INVOKESPECIAL, "java/lang/ClassCastException", "<init>", "()V", false);
- methodVisitor.visitInsn(ATHROW);
- methodVisitor.visitMaxs(4, 1);
- methodVisitor.visitEnd();
- }
- classWriter.visitEnd();
-
- return classWriter.toByteArray();
- }
- }
-}
diff --git a/src/test/java/com/android/tools/r8/cfmethodgeneration/MethodGenerationBase.java b/src/test/java/com/android/tools/r8/cfmethodgeneration/MethodGenerationBase.java
index 164259f..e190074 100644
--- a/src/test/java/com/android/tools/r8/cfmethodgeneration/MethodGenerationBase.java
+++ b/src/test/java/com/android/tools/r8/cfmethodgeneration/MethodGenerationBase.java
@@ -28,6 +28,7 @@
import java.util.Calendar;
import java.util.List;
import java.util.TreeSet;
+import java.util.function.Consumer;
public abstract class MethodGenerationBase extends TestBase {
@@ -74,17 +75,18 @@
}
// Running this method will regenerate / overwrite the content of the generated class.
- protected void generateMethodsAndWriteThemToFile() throws IOException {
- FileUtils.writeToFile(getGeneratedFile(), null, generateMethods().getBytes());
+ protected void generateMethodsAndWriteThemToFile(Consumer<InternalOptions> optionsConsumer)
+ throws IOException {
+ FileUtils.writeToFile(getGeneratedFile(), null, generateMethods(optionsConsumer).getBytes());
}
// Running this method generate the content of the generated class but does not overwrite it.
- protected String generateMethods() throws IOException {
+ protected String generateMethods(Consumer<InternalOptions> optionsConsumer) throws IOException {
CfCodePrinter codePrinter = new CfCodePrinter();
File tempFile = File.createTempFile("output-", ".java");
- readMethodTemplatesInto(codePrinter);
+ readMethodTemplatesInto(codePrinter, optionsConsumer);
generateRawOutput(codePrinter, tempFile.toPath());
String result = formatRawOutput(tempFile.toPath());
@@ -92,8 +94,10 @@
return result;
}
- private void readMethodTemplatesInto(CfCodePrinter codePrinter) throws IOException {
+ private void readMethodTemplatesInto(
+ CfCodePrinter codePrinter, Consumer<InternalOptions> optionsConsumer) throws IOException {
InternalOptions options = new InternalOptions();
+ optionsConsumer.accept(options);
JarClassFileReader reader =
new JarClassFileReader(
new JarApplicationReader(options),
diff --git a/src/test/java/com/android/tools/r8/code/PassThroughTest.java b/src/test/java/com/android/tools/r8/code/PassThroughTest.java
index cb93c83..673f3a2 100644
--- a/src/test/java/com/android/tools/r8/code/PassThroughTest.java
+++ b/src/test/java/com/android/tools/r8/code/PassThroughTest.java
@@ -91,6 +91,7 @@
internalOptions -> {
internalOptions.testing.cfByteCodePassThrough =
method -> !method.name.toString().equals("<init>");
+ internalOptions.testing.readInputStackMaps = true;
})
.compile()
.writeToZip(outputJar)
diff --git a/src/test/java/com/android/tools/r8/desugar/BasicTestDependenciesDesugaringTest.java b/src/test/java/com/android/tools/r8/desugar/BasicTestDependenciesDesugaringTest.java
index 6a6e8d7..20c7e0e 100644
--- a/src/test/java/com/android/tools/r8/desugar/BasicTestDependenciesDesugaringTest.java
+++ b/src/test/java/com/android/tools/r8/desugar/BasicTestDependenciesDesugaringTest.java
@@ -69,7 +69,7 @@
private Path toCompile;
private List<Path> classpath;
- public BasicTestDependenciesDesugaringTest(String name, String toCompile, String classpath) {
+ public BasicTestDependenciesDesugaringTest(String name, String toCompile, String classpath) {
this.name = name;
this.toCompile = Paths.get(toCompile);
this.classpath = Arrays.asList(classpath.split(CLASSPATH_SEPARATOR)).stream()
@@ -87,10 +87,7 @@
.addProgramFiles(toCompile)
.addLibraryFiles(ToolHelper.getAndroidJar(AndroidApiLevel.K))
.setMinApiLevel(AndroidApiLevel.K.getLevel()),
- options -> {
- options.interfaceMethodDesugaring = OffOrAuto.Auto;
- options.testing.disableStackMapVerification = name.equals("espresso-core-3.0.0.jar");
- });
+ options -> options.interfaceMethodDesugaring = OffOrAuto.Auto);
}
@Test
@@ -104,9 +101,6 @@
.addProgramFiles(toCompile)
.addLibraryFiles(ToolHelper.getAndroidJar(AndroidApiLevel.K))
.setMinApiLevel(AndroidApiLevel.K.getLevel()),
- options -> {
- options.interfaceMethodDesugaring = OffOrAuto.Off;
- options.testing.disableStackMapVerification = name.equals("espresso-core-3.0.0.jar");
- });
+ options -> options.interfaceMethodDesugaring = OffOrAuto.Off);
}
}
diff --git a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/DesugaredLibraryTestBase.java b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/DesugaredLibraryTestBase.java
index afc19d9..b68997a 100644
--- a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/DesugaredLibraryTestBase.java
+++ b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/DesugaredLibraryTestBase.java
@@ -188,7 +188,6 @@
stringBuilder.append(string);
}
- @Override
public void finished(DiagnosticsHandler handler) {
assert stringBuilder != null;
assert result == null;
diff --git a/src/test/java/com/android/tools/r8/enumunboxing/GenerateEnumUnboxingMethods.java b/src/test/java/com/android/tools/r8/enumunboxing/GenerateEnumUnboxingMethods.java
index 54a405c..4abe533 100644
--- a/src/test/java/com/android/tools/r8/enumunboxing/GenerateEnumUnboxingMethods.java
+++ b/src/test/java/com/android/tools/r8/enumunboxing/GenerateEnumUnboxingMethods.java
@@ -11,6 +11,7 @@
import com.android.tools.r8.cfmethodgeneration.MethodGenerationBase;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.utils.FileUtils;
+import com.android.tools.r8.utils.InternalOptions;
import com.google.common.collect.ImmutableList;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
@@ -50,6 +51,9 @@
return METHOD_TEMPLATE_CLASSES;
}
+ private static void setReadInputStackMap(InternalOptions options) {
+ options.testing.readInputStackMaps = true;
+ }
@Test
public void testEnumUtilityMethodsGenerated() throws Exception {
@@ -57,10 +61,12 @@
sorted.sort(Comparator.comparing(Class::getTypeName));
assertEquals("Classes should be listed in sorted order", sorted, getMethodTemplateClasses());
assertEquals(
- FileUtils.readTextFile(getGeneratedFile(), StandardCharsets.UTF_8), generateMethods());
+ FileUtils.readTextFile(getGeneratedFile(), StandardCharsets.UTF_8),
+ generateMethods(GenerateEnumUnboxingMethods::setReadInputStackMap));
}
public static void main(String[] args) throws Exception {
- new GenerateEnumUnboxingMethods(null).generateMethodsAndWriteThemToFile();
+ new GenerateEnumUnboxingMethods(null)
+ .generateMethodsAndWriteThemToFile(GenerateEnumUnboxingMethods::setReadInputStackMap);
}
}
diff --git a/src/test/java/com/android/tools/r8/internal/YouTubeProguardJarVerificationTest.java b/src/test/java/com/android/tools/r8/internal/YouTubeProguardJarVerificationTest.java
index 5092831..7c02878 100644
--- a/src/test/java/com/android/tools/r8/internal/YouTubeProguardJarVerificationTest.java
+++ b/src/test/java/com/android/tools/r8/internal/YouTubeProguardJarVerificationTest.java
@@ -4,8 +4,6 @@
package com.android.tools.r8.internal;
import com.android.tools.r8.CompilationMode;
-import com.android.tools.r8.R8RunArtTestsTest.CompilerUnderTest;
-import com.google.common.collect.ImmutableList;
import org.junit.Test;
public class YouTubeProguardJarVerificationTest extends YouTubeCompilationBase {
@@ -16,23 +14,11 @@
@Test
public void buildDebugFromProguardJar() throws Exception {
- runAndCheckVerification(
- CompilerUnderTest.R8,
- CompilationMode.DEBUG,
- base + APK,
- null,
- options -> options.testing.disableStackMapVerification = true,
- ImmutableList.of(base + PG_JAR));
+ runR8AndCheckVerification(CompilationMode.DEBUG, PG_JAR);
}
@Test
public void buildReleaseFromProguardJar() throws Exception {
- runAndCheckVerification(
- CompilerUnderTest.R8,
- CompilationMode.RELEASE,
- base + APK,
- null,
- options -> options.testing.disableStackMapVerification = true,
- ImmutableList.of(base + PG_JAR));
+ runR8AndCheckVerification(CompilationMode.RELEASE, PG_JAR);
}
}
diff --git a/src/test/java/com/android/tools/r8/ir/desugar/backports/GenerateBackportMethods.java b/src/test/java/com/android/tools/r8/ir/desugar/backports/GenerateBackportMethods.java
index 05c11c4..cd417d1 100644
--- a/src/test/java/com/android/tools/r8/ir/desugar/backports/GenerateBackportMethods.java
+++ b/src/test/java/com/android/tools/r8/ir/desugar/backports/GenerateBackportMethods.java
@@ -12,6 +12,7 @@
import com.android.tools.r8.cfmethodgeneration.MethodGenerationBase;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.utils.FileUtils;
+import com.android.tools.r8.utils.InternalOptions;
import com.google.common.collect.ImmutableList;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
@@ -68,16 +69,22 @@
return METHOD_TEMPLATE_CLASSES;
}
+ private static void setReadInputStackMap(InternalOptions options) {
+ options.testing.readInputStackMaps = true;
+ }
+
@Test
public void testBackportsGenerated() throws Exception {
ArrayList<Class<?>> sorted = new ArrayList<>(getMethodTemplateClasses());
sorted.sort(Comparator.comparing(Class::getTypeName));
assertEquals("Classes should be listed in sorted order", sorted, getMethodTemplateClasses());
assertEquals(
- FileUtils.readTextFile(getGeneratedFile(), StandardCharsets.UTF_8), generateMethods());
+ FileUtils.readTextFile(getGeneratedFile(), StandardCharsets.UTF_8),
+ generateMethods(GenerateBackportMethods::setReadInputStackMap));
}
public static void main(String[] args) throws Exception {
- new GenerateBackportMethods(null).generateMethodsAndWriteThemToFile();
+ new GenerateBackportMethods(null)
+ .generateMethodsAndWriteThemToFile(GenerateBackportMethods::setReadInputStackMap);
}
}
diff --git a/src/test/java/com/android/tools/r8/ir/optimize/B148366506.java b/src/test/java/com/android/tools/r8/ir/optimize/B148366506.java
index 1fa9b16..e89e6cd5 100644
--- a/src/test/java/com/android/tools/r8/ir/optimize/B148366506.java
+++ b/src/test/java/com/android/tools/r8/ir/optimize/B148366506.java
@@ -49,7 +49,7 @@
MethodVisitor methodVisitor;
classWriter.visit(
- V1_6,
+ V1_7,
ACC_PUBLIC | ACC_SUPER,
"d/b/c/e/e/a/b/a",
null,
diff --git a/src/test/java/com/android/tools/r8/ir/optimize/uninstantiatedtypes/B146957343.java b/src/test/java/com/android/tools/r8/ir/optimize/uninstantiatedtypes/B146957343.java
index 4ca57c1..3940548 100644
--- a/src/test/java/com/android/tools/r8/ir/optimize/uninstantiatedtypes/B146957343.java
+++ b/src/test/java/com/android/tools/r8/ir/optimize/uninstantiatedtypes/B146957343.java
@@ -52,6 +52,7 @@
.addOptionsModification(
options -> options.enableUninstantiatedTypeOptimizationForInterfaces = true)
.compile()
+ .disassemble()
.run(parameters.getRuntime(), Main.class)
.assertFailureWithErrorThatThrows(NullPointerException.class);
}
diff --git a/src/test/java/com/android/tools/r8/regress/b113347830/B113347830.java b/src/test/java/com/android/tools/r8/regress/b113347830/B113347830.java
index 397f703..a62622e 100644
--- a/src/test/java/com/android/tools/r8/regress/b113347830/B113347830.java
+++ b/src/test/java/com/android/tools/r8/regress/b113347830/B113347830.java
@@ -3,35 +3,21 @@
// BSD-style license that can be found in the LICENSE file.
package com.android.tools.r8.regress.b113347830;
+import com.android.tools.r8.D8;
+import com.android.tools.r8.D8Command;
import com.android.tools.r8.DexIndexedConsumer;
-import com.android.tools.r8.TestBase;
-import com.android.tools.r8.TestParameters;
-import com.android.tools.r8.TestParametersCollection;
import com.android.tools.r8.ToolHelper;
+import com.android.tools.r8.origin.Origin;
import jasmin.ClassFile;
import java.io.ByteArrayOutputStream;
import java.nio.file.Files;
import java.nio.file.Paths;
import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-import org.junit.runners.Parameterized.Parameters;
-@RunWith(Parameterized.class)
-public class B113347830 extends TestBase {
+public class B113347830 {
public static final Class CLASS = B113347830.class;
public static final String NAME = CLASS.getSimpleName();
- private final TestParameters parameters;
-
- @Parameters(name = "{0}")
- public static TestParametersCollection data() {
- return getTestParameters().withNoneRuntime().build();
- }
-
- public B113347830(TestParameters parameters) {
- this.parameters = parameters;
- }
@Test
public void test() throws Exception {
@@ -46,11 +32,11 @@
jasminFile.write(out);
byte[] bytes = out.toByteArray();
- testForD8(Backend.DEX)
- .addProgramClassFileData(bytes)
- .setDisableDesugaring(true)
- .setProgramConsumer(DexIndexedConsumer.emptyConsumer())
- .addOptionsModification(options -> options.testing.disableStackMapVerification = true)
- .compile();
+ D8.run(
+ D8Command.builder()
+ .addClassProgramData(bytes, Origin.unknown())
+ .setDisableDesugaring(true)
+ .setProgramConsumer(DexIndexedConsumer.emptyConsumer())
+ .build());
}
}
diff --git a/src/test/java/com/android/tools/r8/regress/b77842465/Regress77842465Dump.java b/src/test/java/com/android/tools/r8/regress/b77842465/Regress77842465Dump.java
index 51af1ed..7a5aaea 100644
--- a/src/test/java/com/android/tools/r8/regress/b77842465/Regress77842465Dump.java
+++ b/src/test/java/com/android/tools/r8/regress/b77842465/Regress77842465Dump.java
@@ -23,7 +23,7 @@
MethodVisitor mv;
cw.visit(
- V1_6, ACC_PUBLIC + ACC_FINAL + ACC_SUPER, CLASS_INTERNAL, null, "java/lang/Object", null);
+ V1_7, ACC_PUBLIC + ACC_FINAL + ACC_SUPER, CLASS_INTERNAL, null, "java/lang/Object", null);
{
fv = cw.visitField(0, "b", "I", null, null);
diff --git a/src/test/java/com/android/tools/r8/regress/b78493232/Regress78493232_WithPhi.java b/src/test/java/com/android/tools/r8/regress/b78493232/Regress78493232_WithPhi.java
index a2ca851..0afec27 100644
--- a/src/test/java/com/android/tools/r8/regress/b78493232/Regress78493232_WithPhi.java
+++ b/src/test/java/com/android/tools/r8/regress/b78493232/Regress78493232_WithPhi.java
@@ -65,7 +65,6 @@
.addProgramClasses(CLASSES)
.addProgramClassFileData(CLASS_BYTES)
.setMinApi(parameters.getApiLevel())
- .addOptionsModification(options -> options.testing.readInputStackMaps = false)
.run(parameters.getRuntime(), MAIN);
checkResult(result);
}
@@ -89,7 +88,6 @@
.treeShaking(treeShake)
.noMinification()
.setMinApi(parameters.getApiLevel())
- .addOptionsModification(options -> options.testing.readInputStackMaps = false)
.addKeepMainRule(MAIN)
.run(parameters.getRuntime(), MAIN);
checkResult(result);
diff --git a/src/test/java/com/android/tools/r8/rewrite/assertions/AssertionConfigurationKotlinTest.java b/src/test/java/com/android/tools/r8/rewrite/assertions/AssertionConfigurationKotlinTest.java
index 0be3ece..a0049f4 100644
--- a/src/test/java/com/android/tools/r8/rewrite/assertions/AssertionConfigurationKotlinTest.java
+++ b/src/test/java/com/android/tools/r8/rewrite/assertions/AssertionConfigurationKotlinTest.java
@@ -481,12 +481,14 @@
runR8Test(
builder -> {
builder.addAssertionsConfiguration(AssertionsConfiguration.Builder::enableAllAssertions);
+ builder.addOptionsModification(options -> options.testing.readInputStackMaps = true);
},
inspector -> checkAssertionCodeEnabled(inspector, true),
allAssertionsExpectedLines());
runR8Test(
builder -> {
builder.addAssertionsConfiguration(AssertionsConfiguration.Builder::enableAllAssertions);
+ builder.addOptionsModification(options -> options.testing.readInputStackMaps = true);
},
inspector -> checkAssertionCodeEnabled(inspector, true),
allAssertionsExpectedLines(),
diff --git a/src/test/java/com/android/tools/r8/shaking/keptgraph/WhyAreYouKeepingAllTest.java b/src/test/java/com/android/tools/r8/shaking/keptgraph/WhyAreYouKeepingAllTest.java
index cd6e4a3..de762ac 100644
--- a/src/test/java/com/android/tools/r8/shaking/keptgraph/WhyAreYouKeepingAllTest.java
+++ b/src/test/java/com/android/tools/r8/shaking/keptgraph/WhyAreYouKeepingAllTest.java
@@ -54,7 +54,8 @@
.assertStdoutThatMatches(containsString("referenced in keep rule"))
// TODO(b/124655065): We should always know the reason for keeping.
// It is OK if this starts failing while the kept-graph API is incomplete, in which case
- // replace the 'not(containsString(' by just 'containsString('.
+ // replace
+ // the 'not(containsString(' by just 'containsString('.
.assertStdoutThatMatches(not(containsString("kept for unknown reasons")));
}
}
diff --git a/src/test/java/com/android/tools/r8/transformers/ClassFileTransformer.java b/src/test/java/com/android/tools/r8/transformers/ClassFileTransformer.java
index 84621b6..c84415e 100644
--- a/src/test/java/com/android/tools/r8/transformers/ClassFileTransformer.java
+++ b/src/test/java/com/android/tools/r8/transformers/ClassFileTransformer.java
@@ -627,7 +627,7 @@
void visitTryCatchBlock(Label start, Label end, Label handler, String type);
}
- private MethodVisitor redirectVisitTryCatchBlock(
+ private MethodVisitor redirectVistiTryCatchBlock(
MethodVisitor visitor, VisitTryCatchBlockCallback callback) {
return new MethodVisitor(ASM7, visitor) {
@Override
@@ -649,7 +649,7 @@
end,
handler,
type,
- redirectVisitTryCatchBlock(this, super::visitTryCatchBlock));
+ redirectVistiTryCatchBlock(this, super::visitTryCatchBlock));
} else {
super.visitTryCatchBlock(start, end, handler, type);
}
@@ -685,18 +685,4 @@
}
});
}
-
- public ClassFileTransformer stripFrames(String methodName) {
- return addMethodTransformer(
- new MethodTransformer() {
-
- @Override
- public void visitFrame(
- int type, int numLocal, Object[] local, int numStack, Object[] stack) {
- if (!getContext().method.getMethodName().equals(methodName)) {
- super.visitFrame(type, numLocal, local, numStack, stack);
- }
- }
- });
- }
}