From 24cb18d751e8043cbfdce72f91349f365d2d9f95 Mon Sep 17 00:00:00 2001 From: liannacasper <67953602+liannacasper@users.noreply.github.com> Date: Tue, 7 Apr 2026 18:20:57 +0300 Subject: [PATCH 01/38] Add CI workflow for cn1playground language smoke tests --- .github/workflows/cn1playground-language.yml | 39 ++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 .github/workflows/cn1playground-language.yml diff --git a/.github/workflows/cn1playground-language.yml b/.github/workflows/cn1playground-language.yml new file mode 100644 index 0000000000..bf6c59addf --- /dev/null +++ b/.github/workflows/cn1playground-language.yml @@ -0,0 +1,39 @@ +name: CN1 Playground Language Tests + +on: + pull_request: + types: [opened, synchronize, reopened, ready_for_review] + paths: + - 'scripts/cn1playground/**' + - '.github/workflows/cn1playground-language.yml' + push: + branches: [main, master] + paths: + - 'scripts/cn1playground/**' + - '.github/workflows/cn1playground-language.yml' + workflow_dispatch: + +permissions: + contents: read + +jobs: + language-smoke: + name: Playground language smoke + runs-on: ubuntu-latest + + steps: + - name: Check out repository + uses: actions/checkout@v4 + + - name: Set up Java 8 + uses: actions/setup-java@v4 + with: + distribution: temurin + java-version: '8' + cache: maven + + - name: Run playground language smoke tests + run: | + set -euo pipefail + cd scripts/cn1playground + tools/run-playground-smoke-tests.sh From da4aed416f6397668c485252d652ff0c58ab53bb Mon Sep 17 00:00:00 2001 From: liannacasper <67953602+liannacasper@users.noreply.github.com> Date: Tue, 7 Apr 2026 18:27:13 +0300 Subject: [PATCH 02/38] Fix playground workflow script invocation permissions --- .github/workflows/cn1playground-language.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/cn1playground-language.yml b/.github/workflows/cn1playground-language.yml index bf6c59addf..e940c8fbc7 100644 --- a/.github/workflows/cn1playground-language.yml +++ b/.github/workflows/cn1playground-language.yml @@ -36,4 +36,4 @@ jobs: run: | set -euo pipefail cd scripts/cn1playground - tools/run-playground-smoke-tests.sh + bash tools/run-playground-smoke-tests.sh From 3cd3e096b6247b0976fe9b28a5528e60588c5b2a Mon Sep 17 00:00:00 2001 From: liannacasper <67953602+liannacasper@users.noreply.github.com> Date: Tue, 7 Apr 2026 18:40:13 +0300 Subject: [PATCH 03/38] Fix registry generator classpath for JDK8 tools API --- .../tools/generate-cn1-access-registry.sh | 22 ++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/scripts/cn1playground/tools/generate-cn1-access-registry.sh b/scripts/cn1playground/tools/generate-cn1-access-registry.sh index f4a6a2d38d..2a1e393941 100755 --- a/scripts/cn1playground/tools/generate-cn1-access-registry.sh +++ b/scripts/cn1playground/tools/generate-cn1-access-registry.sh @@ -62,9 +62,25 @@ else fi mkdir -p "$BUILD_DIR" -javac -d "$BUILD_DIR" "$SRC" +TOOLS_JAR="${JAVA_HOME:-}/lib/tools.jar" +EXTRA_CP="" +if [ -f "$TOOLS_JAR" ]; then + EXTRA_CP="$TOOLS_JAR" +fi + +if [ -n "$EXTRA_CP" ]; then + javac -cp "$EXTRA_CP" -d "$BUILD_DIR" "$SRC" +else + javac -d "$BUILD_DIR" "$SRC" +fi + +RUNTIME_CP="$BUILD_DIR" +if [ -n "$EXTRA_CP" ]; then + RUNTIME_CP="$BUILD_DIR:$EXTRA_CP" +fi + if [ -n "$CN1_SOURCE_ROOTS_VALUE" ]; then - CN1_SOURCE_ROOTS="$CN1_SOURCE_ROOTS_VALUE" java -cp "$BUILD_DIR" com.codenameone.playground.tools.GenerateCN1AccessRegistry "$OUT" + CN1_SOURCE_ROOTS="$CN1_SOURCE_ROOTS_VALUE" java -cp "$RUNTIME_CP" com.codenameone.playground.tools.GenerateCN1AccessRegistry "$OUT" else - java -cp "$BUILD_DIR" com.codenameone.playground.tools.GenerateCN1AccessRegistry "$OUT" + java -cp "$RUNTIME_CP" com.codenameone.playground.tools.GenerateCN1AccessRegistry "$OUT" fi From b29fbaea90cd3b6fb9b425aa1bf41ea72d231084 Mon Sep 17 00:00:00 2001 From: liannacasper <67953602+liannacasper@users.noreply.github.com> Date: Tue, 7 Apr 2026 18:54:20 +0300 Subject: [PATCH 04/38] Use Java 17 and portable checks in playground smoke CI --- .github/workflows/cn1playground-language.yml | 4 ++-- scripts/cn1playground/tools/run-playground-smoke-tests.sh | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/cn1playground-language.yml b/.github/workflows/cn1playground-language.yml index e940c8fbc7..73dc6828f3 100644 --- a/.github/workflows/cn1playground-language.yml +++ b/.github/workflows/cn1playground-language.yml @@ -25,11 +25,11 @@ jobs: - name: Check out repository uses: actions/checkout@v4 - - name: Set up Java 8 + - name: Set up Java 17 uses: actions/setup-java@v4 with: distribution: temurin - java-version: '8' + java-version: '17' cache: maven - name: Run playground language smoke tests diff --git a/scripts/cn1playground/tools/run-playground-smoke-tests.sh b/scripts/cn1playground/tools/run-playground-smoke-tests.sh index 2e25794b41..1bc912a5b1 100644 --- a/scripts/cn1playground/tools/run-playground-smoke-tests.sh +++ b/scripts/cn1playground/tools/run-playground-smoke-tests.sh @@ -8,14 +8,14 @@ echo "Regenerating CN1 access registry from release sources..." CN1_ACCESS_USE_LOCAL_SOURCES=false bash "$ROOT/tools/generate-cn1-access-registry.sh" echo "Verifying Component is present in generated registry..." -if ! rg -q 'index.put\("com\.codename1\.ui\.Component"' "$ROOT/common/src/main/java/bsh/cn1/GeneratedCN1Access.java"; then +if ! grep -q 'index.put("com.codename1.ui.Component"' "$ROOT/common/src/main/java/bsh/cn1/GeneratedCN1Access.java"; then echo "GeneratedCN1Access is missing com.codename1.ui.Component" >&2 exit 1 fi echo "Verifying key com.codename1.ui classes are present in generated registry..." for cls in Button Container Dialog Display Form Label List TextField BrowserComponent; do - if ! rg -q "index.put\\(\"com\\.codename1\\.ui\\.${cls}\"" "$ROOT/common/src/main/java/bsh/cn1/GeneratedCN1Access.java"; then + if ! grep -q "index.put(\"com.codename1.ui.${cls}\"" "$ROOT/common/src/main/java/bsh/cn1/GeneratedCN1Access.java"; then echo "GeneratedCN1Access is missing com.codename1.ui.${cls}" >&2 exit 1 fi @@ -23,7 +23,7 @@ done echo "Verifying package-private/internal sentinel classes are NOT generated..." for cls in com.codename1.ui.Accessor com.codename1.io.IOAccessor; do - if rg -q "index.put\\(\"${cls}\"" "$ROOT/common/src/main/java/bsh/cn1/GeneratedCN1Access.java"; then + if grep -q "index.put(\"${cls}\"" "$ROOT/common/src/main/java/bsh/cn1/GeneratedCN1Access.java"; then echo "GeneratedCN1Access unexpectedly includes internal class ${cls}" >&2 exit 1 fi From 73abb3b08cf2037e89e521248014b4338f28c5ac Mon Sep 17 00:00:00 2001 From: liannacasper <67953602+liannacasper@users.noreply.github.com> Date: Tue, 7 Apr 2026 19:02:12 +0300 Subject: [PATCH 05/38] Build dependent modules in playground smoke Maven step --- scripts/cn1playground/tools/run-playground-smoke-tests.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/cn1playground/tools/run-playground-smoke-tests.sh b/scripts/cn1playground/tools/run-playground-smoke-tests.sh index 1bc912a5b1..e4d1bfaf51 100644 --- a/scripts/cn1playground/tools/run-playground-smoke-tests.sh +++ b/scripts/cn1playground/tools/run-playground-smoke-tests.sh @@ -29,6 +29,6 @@ for cls in com.codename1.ui.Accessor com.codename1.io.IOAccessor; do fi done -mvn -pl common -DskipTests test-compile org.codehaus.mojo:exec-maven-plugin:3.0.0:java \ +mvn -pl common -am -DskipTests test-compile org.codehaus.mojo:exec-maven-plugin:3.0.0:java \ -Dexec.classpathScope=test \ -Dexec.mainClass=com.codenameone.playground.PlaygroundSmokeHarness From e91778b3e51fae06dcf8c355196369f9d4ec6abb Mon Sep 17 00:00:00 2001 From: liannacasper <67953602+liannacasper@users.noreply.github.com> Date: Tue, 7 Apr 2026 19:08:27 +0300 Subject: [PATCH 06/38] Run playground smoke harness from common module classpath --- scripts/cn1playground/tools/run-playground-smoke-tests.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/scripts/cn1playground/tools/run-playground-smoke-tests.sh b/scripts/cn1playground/tools/run-playground-smoke-tests.sh index e4d1bfaf51..3b60ebbc0d 100644 --- a/scripts/cn1playground/tools/run-playground-smoke-tests.sh +++ b/scripts/cn1playground/tools/run-playground-smoke-tests.sh @@ -29,6 +29,7 @@ for cls in com.codename1.ui.Accessor com.codename1.io.IOAccessor; do fi done -mvn -pl common -am -DskipTests test-compile org.codehaus.mojo:exec-maven-plugin:3.0.0:java \ +mvn -pl common -am -DskipTests test-compile +mvn -f common/pom.xml -DskipTests org.codehaus.mojo:exec-maven-plugin:3.0.0:java \ -Dexec.classpathScope=test \ -Dexec.mainClass=com.codenameone.playground.PlaygroundSmokeHarness From 1f9482d14d22144b693b95a547d5b98ab9951d7e Mon Sep 17 00:00:00 2001 From: liannacasper <67953602+liannacasper@users.noreply.github.com> Date: Tue, 7 Apr 2026 19:28:11 +0300 Subject: [PATCH 07/38] Run playground smoke tests under Xvfb in CI --- .github/workflows/cn1playground-language.yml | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/.github/workflows/cn1playground-language.yml b/.github/workflows/cn1playground-language.yml index 73dc6828f3..de946be799 100644 --- a/.github/workflows/cn1playground-language.yml +++ b/.github/workflows/cn1playground-language.yml @@ -32,8 +32,16 @@ jobs: java-version: '17' cache: maven + - name: Ensure Xvfb is available + run: | + set -euo pipefail + if ! command -v xvfb-run >/dev/null 2>&1; then + sudo apt-get update + sudo apt-get install -y xvfb + fi + - name: Run playground language smoke tests run: | set -euo pipefail cd scripts/cn1playground - bash tools/run-playground-smoke-tests.sh + xvfb-run -a bash tools/run-playground-smoke-tests.sh From e1285ac4dc8639279a03837aecd1947525b67f57 Mon Sep 17 00:00:00 2001 From: liannacasper <67953602+liannacasper@users.noreply.github.com> Date: Tue, 7 Apr 2026 20:01:05 +0300 Subject: [PATCH 08/38] Install reactor artifacts before running playground harness --- scripts/cn1playground/tools/run-playground-smoke-tests.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/cn1playground/tools/run-playground-smoke-tests.sh b/scripts/cn1playground/tools/run-playground-smoke-tests.sh index 3b60ebbc0d..86cf61ba76 100644 --- a/scripts/cn1playground/tools/run-playground-smoke-tests.sh +++ b/scripts/cn1playground/tools/run-playground-smoke-tests.sh @@ -29,7 +29,7 @@ for cls in com.codename1.ui.Accessor com.codename1.io.IOAccessor; do fi done -mvn -pl common -am -DskipTests test-compile +mvn -pl common -am -DskipTests install mvn -f common/pom.xml -DskipTests org.codehaus.mojo:exec-maven-plugin:3.0.0:java \ -Dexec.classpathScope=test \ -Dexec.mainClass=com.codenameone.playground.PlaygroundSmokeHarness From 792e546ff7ea7cb65cd3dfca21c2e6e3b9ecc0f5 Mon Sep 17 00:00:00 2001 From: liannacasper <67953602+liannacasper@users.noreply.github.com> Date: Tue, 7 Apr 2026 20:40:23 +0300 Subject: [PATCH 09/38] Force smoke harness process exit after success --- .../com/codenameone/playground/PlaygroundSmokeHarness.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/scripts/cn1playground/common/src/test/java/com/codenameone/playground/PlaygroundSmokeHarness.java b/scripts/cn1playground/common/src/test/java/com/codenameone/playground/PlaygroundSmokeHarness.java index c7ac006b9f..c03bb872df 100644 --- a/scripts/cn1playground/common/src/test/java/com/codenameone/playground/PlaygroundSmokeHarness.java +++ b/scripts/cn1playground/common/src/test/java/com/codenameone/playground/PlaygroundSmokeHarness.java @@ -26,6 +26,9 @@ public static void main(String[] args) throws Exception { smokeComponentTypeResolvesWithoutExplicitImport(); smokeUIManagerClassImportDoesNotCollideWithGlobals(); System.out.println("Playground smoke tests passed."); + // Codename One/JavaSE initialization may leave non-daemon threads running. + // Force a clean exit so CI jobs don't hang after successful completion. + System.exit(0); } private static void smokeGeneratedRegistry() throws Exception { From a6903ea8a2bc19a58a30a356cf9e1230af5ae038 Mon Sep 17 00:00:00 2001 From: liannacasper <67953602+liannacasper@users.noreply.github.com> Date: Tue, 7 Apr 2026 21:01:20 +0300 Subject: [PATCH 10/38] Add playground syntax matrix harness to smoke test pipeline --- .../PlaygroundSyntaxMatrixHarness.java | 133 ++++++++++++++++++ .../tools/run-playground-smoke-tests.sh | 3 + 2 files changed, 136 insertions(+) create mode 100644 scripts/cn1playground/common/src/test/java/com/codenameone/playground/PlaygroundSyntaxMatrixHarness.java diff --git a/scripts/cn1playground/common/src/test/java/com/codenameone/playground/PlaygroundSyntaxMatrixHarness.java b/scripts/cn1playground/common/src/test/java/com/codenameone/playground/PlaygroundSyntaxMatrixHarness.java new file mode 100644 index 0000000000..2ffef33d5d --- /dev/null +++ b/scripts/cn1playground/common/src/test/java/com/codenameone/playground/PlaygroundSyntaxMatrixHarness.java @@ -0,0 +1,133 @@ +package com.codenameone.playground; + +import com.codename1.ui.Component; +import com.codename1.ui.Container; +import com.codename1.ui.Display; +import com.codename1.ui.Form; +import com.codename1.ui.layouts.BorderLayout; +import java.util.ArrayList; +import java.util.List; + +/** + * Syntax regression matrix for Playground language support. + * + *
When adding new syntax support, update the expected outcome for the + * relevant test case from FAILURE to SUCCESS.
+ */ +public final class PlaygroundSyntaxMatrixHarness { + private PlaygroundSyntaxMatrixHarness() { + } + + private enum ExpectedOutcome { + SUCCESS, + FAILURE + } + + private static final class Case { + final String name; + final ExpectedOutcome expected; + final String script; + + Case(String name, ExpectedOutcome expected, String script) { + this.name = name; + this.expected = expected; + this.script = script; + } + } + + public static void main(String[] args) { + ListWhen adding new syntax support, update the expected outcome for the - * relevant test case from FAILURE to SUCCESS.
+ * Table-driven syntax regression matrix for playground language support. */ public final class PlaygroundSyntaxMatrixHarness { private PlaygroundSyntaxMatrixHarness() { @@ -20,18 +16,21 @@ private PlaygroundSyntaxMatrixHarness() { private enum ExpectedOutcome { SUCCESS, - FAILURE + PARSE_ERROR, + EVAL_ERROR } private static final class Case { final String name; - final ExpectedOutcome expected; - final String script; + final String sourceSnippet; + final ExpectedOutcome expectedOutcome; + final String expectedDiagnosticSubstring; - Case(String name, ExpectedOutcome expected, String script) { + Case(String name, String sourceSnippet, ExpectedOutcome expectedOutcome, String expectedDiagnosticSubstring) { this.name = name; - this.expected = expected; - this.script = script; + this.sourceSnippet = sourceSnippet; + this.expectedOutcome = expectedOutcome; + this.expectedDiagnosticSubstring = expectedDiagnosticSubstring; } } @@ -39,9 +38,9 @@ public static void main(String[] args) { int exitCode = 0; try { ListNote: for classes whose version is {@link Opcodes#V1_7} of more, this option requires - * valid stack map frames. The maximum stack size is then computed from these frames, and from the - * bytecode instructions in between. If stack map frames are not present or must be recomputed, - * used {@link #COMPUTE_FRAMES} instead. - * - * @see #ClassWriter(int) - */ - public static final int COMPUTE_MAXS = 1; - - /** - * A flag to automatically compute the stack map frames of methods from scratch. If this flag is - * set, then the calls to the {@link MethodVisitor#visitFrame} method are ignored, and the stack - * map frames are recomputed from the methods bytecode. The arguments of the {@link - * MethodVisitor#visitMaxs} method are also ignored and recomputed from the bytecode. In other - * words, {@link #COMPUTE_FRAMES} implies {@link #COMPUTE_MAXS}. - * - * @see #ClassWriter(int) - */ - public static final int COMPUTE_FRAMES = 2; - - // Note: fields are ordered as in the ClassFile structure, and those related to attributes are - // ordered as in Section 4.7 of the JVMS. - - /** - * The minor_version and major_version fields of the JVMS ClassFile structure. minor_version is - * stored in the 16 most significant bits, and major_version in the 16 least significant bits. - */ - private int version; - - /** The symbol table for this class (contains the constant_pool and the BootstrapMethods). */ - private final SymbolTable symbolTable; - - /** - * The access_flags field of the JVMS ClassFile structure. This field can contain ASM specific - * access flags, such as {@link Opcodes#ACC_DEPRECATED}, which are removed when generating the - * ClassFile structure. - */ - private int accessFlags; - - /** The this_class field of the JVMS ClassFile structure. */ - private int thisClass; - - /** The super_class field of the JVMS ClassFile structure. */ - private int superClass; - - /** The interface_count field of the JVMS ClassFile structure. */ - private int interfaceCount; - - /** The 'interfaces' array of the JVMS ClassFile structure. */ - private int[] interfaces; - - /** - * The fields of this class, stored in a linked list of {@link FieldWriter} linked via their - * {@link FieldWriter#fv} field. This field stores the first element of this list. - */ - private FieldWriter firstField; - - /** - * The fields of this class, stored in a linked list of {@link FieldWriter} linked via their - * {@link FieldWriter#fv} field. This field stores the last element of this list. - */ - private FieldWriter lastField; - - /** - * The methods of this class, stored in a linked list of {@link MethodWriter} linked via their - * {@link MethodWriter#mv} field. This field stores the first element of this list. - */ - private MethodWriter firstMethod; - - /** - * The methods of this class, stored in a linked list of {@link MethodWriter} linked via their - * {@link MethodWriter#mv} field. This field stores the last element of this list. - */ - private MethodWriter lastMethod; - - /** The number_of_classes field of the InnerClasses attribute, or 0. */ - private int numberOfInnerClasses; - - /** The 'classes' array of the InnerClasses attribute, or null. */ - private ByteVector innerClasses; - - /** The class_index field of the EnclosingMethod attribute, or 0. */ - private int enclosingClassIndex; - - /** The method_index field of the EnclosingMethod attribute. */ - private int enclosingMethodIndex; - - /** The signature_index field of the Signature attribute, or 0. */ - private int signatureIndex; - - /** The source_file_index field of the SourceFile attribute, or 0. */ - private int sourceFileIndex; - - /** The debug_extension field of the SourceDebugExtension attribute, or null. */ - private ByteVector debugExtension; - - /** - * The first non standard attribute of this class. The next ones can be accessed with the {@link - * Attribute#nextAttribute} field. May be null. - * - *
WARNING: this list stores the attributes in the reverse order of their visit. - * firstAttribute is actually the last attribute visited in {@link #visitAttribute}. The {@link - * #toByteArray} method writes the attributes in the order defined by this list, i.e. in the - * reverse order specified by the user. - */ - private Attribute firstAttribute; - - /** - * Indicates what must be automatically computed in {@link MethodWriter}. Must be one of {@link - * MethodWriter#COMPUTE_NOTHING}, {@link MethodWriter#COMPUTE_MAX_STACK_AND_LOCAL}, {@link - * MethodWriter#COMPUTE_INSERTED_FRAMES}, or {@link MethodWriter#COMPUTE_ALL_FRAMES}. - */ - private int compute; - - // ----------------------------------------------------------------------------------------------- - // Constructor - // ----------------------------------------------------------------------------------------------- - - /** - * Constructs a new {@link ClassWriter} object and enables optimizations for "mostly add" bytecode - * transformations. These optimizations are the following: - * - *
WARNING: this list stores the attributes in the reverse order of their visit. - * firstAttribute is actually the last attribute visited in {@link #visitAttribute}. The {@link - * #putFieldInfo} method writes the attributes in the order defined by this list, i.e. in the - * reverse order specified by the user. - */ - private Attribute firstAttribute; - - // ----------------------------------------------------------------------------------------------- - // Constructor - // ----------------------------------------------------------------------------------------------- - - /** - * Constructs a new {@link FieldWriter}. - * - * @param symbolTable where the constants used in this FieldWriter must be stored. - * @param access the field's access flags (see {@link Opcodes}). - * @param name the field's name. - * @param descriptor the field's descriptor (see {@link Type}). - * @param signature the field's signature. May be null. - * @param constantValue the field's constant value. May be null. - */ - FieldWriter( - final SymbolTable symbolTable, - final int access, - final String name, - final String descriptor, - final String signature, - final Object constantValue) { - super(Opcodes.ASM6); - this.symbolTable = symbolTable; - this.accessFlags = access; - this.nameIndex = symbolTable.addConstantUtf8(name); - this.descriptorIndex = symbolTable.addConstantUtf8(descriptor); - if (signature != null) { - this.signatureIndex = symbolTable.addConstantUtf8(signature); - } - if (constantValue != null) { - this.constantValueIndex = symbolTable.addConstant(constantValue).index; - } - } - - // ----------------------------------------------------------------------------------------------- - // Implementation of the FieldVisitor abstract class - // ----------------------------------------------------------------------------------------------- - - @Override - public void visitAttribute(final Attribute attribute) { - // Store the attributes in the reverse order of their visit by this method. - attribute.nextAttribute = firstAttribute; - firstAttribute = attribute; - } - - @Override - public void visitEnd() { - // Nothing to do. - } - - // ----------------------------------------------------------------------------------------------- - // Utility methods - // ----------------------------------------------------------------------------------------------- - - /** - * Returns the size of the field_info JVMS structure generated by this FieldWriter. Also adds the - * names of the attributes of this field in the constant pool. - * - * @return the size in bytes of the field_info JVMS structure. - */ - int computeFieldInfoSize() { - // The access_flags, name_index, descriptor_index and attributes_count fields use 8 bytes. - int size = 8; - // For ease of reference, we use here the same attribute order as in Section 4.7 of the JVMS. - if (constantValueIndex != 0) { - // ConstantValue attributes always use 8 bytes. - symbolTable.addConstantUtf8(Constants.CONSTANT_VALUE); - size += 8; - } - // Before Java 1.5, synthetic fields are represented with a Synthetic attribute. - if ((accessFlags & Opcodes.ACC_SYNTHETIC) != 0 - && symbolTable.getMajorVersion() < Opcodes.V1_5) { - // Synthetic attributes always use 6 bytes. - symbolTable.addConstantUtf8(Constants.SYNTHETIC); - size += 6; - } - if (signatureIndex != 0) { - // Signature attributes always use 8 bytes. - symbolTable.addConstantUtf8(Constants.SIGNATURE); - size += 8; - } - // ACC_DEPRECATED is ASM specific, the ClassFile format uses a Deprecated attribute instead. - if ((accessFlags & Opcodes.ACC_DEPRECATED) != 0) { - // Deprecated attributes always use 6 bytes. - symbolTable.addConstantUtf8(Constants.DEPRECATED); - size += 6; - } - if (firstAttribute != null) { - size += firstAttribute.computeAttributesSize(symbolTable); - } - return size; - } - - /** - * Puts the content of the field_info JVMS structure generated by this FieldWriter into the given - * ByteVector. - * - * @param output where the field_info structure must be put. - */ - void putFieldInfo(final ByteVector output) { - boolean useSyntheticAttribute = symbolTable.getMajorVersion() < Opcodes.V1_5; - // Put the access_flags, name_index and descriptor_index fields. - int mask = useSyntheticAttribute ? Opcodes.ACC_SYNTHETIC : 0; - output.putShort(accessFlags & ~mask).putShort(nameIndex).putShort(descriptorIndex); - // Compute and put the attributes_count field. - // For ease of reference, we use here the same attribute order as in Section 4.7 of the JVMS. - int attributesCount = 0; - if (constantValueIndex != 0) { - ++attributesCount; - } - if ((accessFlags & Opcodes.ACC_SYNTHETIC) != 0 && useSyntheticAttribute) { - ++attributesCount; - } - if (signatureIndex != 0) { - ++attributesCount; - } - if ((accessFlags & Opcodes.ACC_DEPRECATED) != 0) { - ++attributesCount; - } - if (firstAttribute != null) { - attributesCount += firstAttribute.getAttributeCount(); - } - output.putShort(attributesCount); - // Put the field_info attributes. - // For ease of reference, we use here the same attribute order as in Section 4.7 of the JVMS. - if (constantValueIndex != 0) { - output - .putShort(symbolTable.addConstantUtf8(Constants.CONSTANT_VALUE)) - .putInt(2) - .putShort(constantValueIndex); - } - if ((accessFlags & Opcodes.ACC_SYNTHETIC) != 0 && useSyntheticAttribute) { - output.putShort(symbolTable.addConstantUtf8(Constants.SYNTHETIC)).putInt(0); - } - if (signatureIndex != 0) { - output - .putShort(symbolTable.addConstantUtf8(Constants.SIGNATURE)) - .putInt(2) - .putShort(signatureIndex); - } - if ((accessFlags & Opcodes.ACC_DEPRECATED) != 0) { - output.putShort(symbolTable.addConstantUtf8(Constants.DEPRECATED)).putInt(0); - } - if (firstAttribute != null) { - firstAttribute.putAttributes(symbolTable, output); - } - } - - /** - * Collects the attributes of this field into the given set of attribute prototypes. - * - * @param attributePrototypes a set of attribute prototypes. - */ - final void collectAttributePrototypes(final Attribute.Set attributePrototypes) { - attributePrototypes.addAttributes(firstAttribute); - } -} diff --git a/scripts/cn1playground/common/src/main/java/bsh/org/objectweb/asm/Frame.java b/scripts/cn1playground/common/src/main/java/bsh/org/objectweb/asm/Frame.java deleted file mode 100644 index 22d1a32a4c..0000000000 --- a/scripts/cn1playground/common/src/main/java/bsh/org/objectweb/asm/Frame.java +++ /dev/null @@ -1,1467 +0,0 @@ -// ASM: a very small and fast Java bytecode manipulation framework -// Copyright (c) 2000-2011 INRIA, France Telecom -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions -// are met: -// 1. Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// 2. Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// 3. Neither the name of the copyright holders nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF -// THE POSSIBILITY OF SUCH DAMAGE. -package bsh.org.objectweb.asm; - -/** - * The input and output stack map frames of a basic block. - * - *
Stack map frames are computed in two steps: - * - *
Output stack map frames are computed relatively to the input frame of the basic block, which - * is not yet known when output frames are computed. It is therefore necessary to be able to - * represent abstract types such as "the type at position x in the input frame locals" or "the type - * at position x from the top of the input frame stack" or even "the type at position x in the input - * frame, with y more (or less) array dimensions". This explains the rather complicated type format - * used in this class, explained below. - * - *
The local variables and the operand stack of input and output frames contain values called - * "abstract types" hereafter. An abstract type is represented with 4 fields named DIM, KIND, FLAGS - * and VALUE, packed in a single int value for better performance and memory efficiency: - * - *
- * ===================================== - * |.DIM|KIND|FLAG|...............VALUE| - * ===================================== - *- * - *
Output frames can contain abstract types of any kind and with a positive or negative array - * dimension (and even unassigned types, represented by 0 - which does not correspond to any valid - * abstract type value). Input frames can only contain CONSTANT_KIND, REFERENCE_KIND or - * UNINITIALIZED_KIND abstract types of positive or null array dimension. In all cases the type - * table contains only internal type names (array type descriptors are forbidden - array dimensions - * must be represented through the DIM field). - * - *
The LONG and DOUBLE types are always represented by using two slots (LONG + TOP or DOUBLE + - * TOP), for local variables as well as in the operand stack. This is necessary to be able to - * simulate DUPx_y instructions, whose effect would be dependent on the concrete types represented - * by the abstract types in the stack (which are not always known). - * - * @author Eric Bruneton - */ -class Frame { - - // Constants used in the StackMapTable attribute. - // See https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.7.4. - - static final int SAME_FRAME = 0; - static final int SAME_LOCALS_1_STACK_ITEM_FRAME = 64; - static final int RESERVED = 128; - static final int SAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED = 247; - static final int CHOP_FRAME = 248; - static final int SAME_FRAME_EXTENDED = 251; - static final int APPEND_FRAME = 252; - static final int FULL_FRAME = 255; - - static final int ITEM_TOP = 0; - static final int ITEM_INTEGER = 1; - static final int ITEM_FLOAT = 2; - static final int ITEM_DOUBLE = 3; - static final int ITEM_LONG = 4; - static final int ITEM_NULL = 5; - static final int ITEM_UNINITIALIZED_THIS = 6; - static final int ITEM_OBJECT = 7; - static final int ITEM_UNINITIALIZED = 8; - // Additional, ASM specific constants used in abstract types below. - private static final int ITEM_ASM_BOOLEAN = 9; - private static final int ITEM_ASM_BYTE = 10; - private static final int ITEM_ASM_CHAR = 11; - private static final int ITEM_ASM_SHORT = 12; - - // Bitmasks to get each field of an abstract type. - - private static final int DIM_MASK = 0xF0000000; - private static final int KIND_MASK = 0x0F000000; - private static final int FLAGS_MASK = 0x00F00000; - private static final int VALUE_MASK = 0x000FFFFF; - - // Constants to manipulate the DIM field of an abstract type. - - /** The number of right shift bits to use to get the array dimensions of an abstract type. */ - private static final int DIM_SHIFT = 28; - - /** The constant to be added to an abstract type to get one with one more array dimension. */ - private static final int ARRAY_OF = +1 << DIM_SHIFT; - - /** The constant to be added to an abstract type to get one with one less array dimension. */ - private static final int ELEMENT_OF = -1 << DIM_SHIFT; - - // Possible values for the KIND field of an abstract type. - - private static final int CONSTANT_KIND = 0x01000000; - private static final int REFERENCE_KIND = 0x02000000; - private static final int UNINITIALIZED_KIND = 0x03000000; - private static final int LOCAL_KIND = 0x04000000; - private static final int STACK_KIND = 0x05000000; - - // Possible flags for the FLAGS field of an abstract type. - - /** - * A flag used for LOCAL_KIND and STACK_KIND abstract types, indicating that if the resolved, - * concrete type is LONG or DOUBLE, TOP should be used instead (because the value has been - * partially overridden with an xSTORE instruction). - */ - private static final int TOP_IF_LONG_OR_DOUBLE_FLAG = 0x00100000 & FLAGS_MASK; - - // Useful predefined abstract types (all the possible CONSTANT_KIND types). - - private static final int TOP = CONSTANT_KIND | ITEM_TOP; - private static final int BOOLEAN = CONSTANT_KIND | ITEM_ASM_BOOLEAN; - private static final int BYTE = CONSTANT_KIND | ITEM_ASM_BYTE; - private static final int CHAR = CONSTANT_KIND | ITEM_ASM_CHAR; - private static final int SHORT = CONSTANT_KIND | ITEM_ASM_SHORT; - private static final int INTEGER = CONSTANT_KIND | ITEM_INTEGER; - private static final int FLOAT = CONSTANT_KIND | ITEM_FLOAT; - private static final int LONG = CONSTANT_KIND | ITEM_LONG; - private static final int DOUBLE = CONSTANT_KIND | ITEM_DOUBLE; - private static final int NULL = CONSTANT_KIND | ITEM_NULL; - private static final int UNINITIALIZED_THIS = CONSTANT_KIND | ITEM_UNINITIALIZED_THIS; - - // ----------------------------------------------------------------------------------------------- - // Instance fields - // ----------------------------------------------------------------------------------------------- - - /** The basic block to which these input and output stack map frames correspond. */ - Label owner; - - /** The input stack map frame locals. This is an array of abstract types. */ - private int[] inputLocals; - - /** The input stack map frame stack. This is an array of abstract types. */ - private int[] inputStack; - - /** The output stack map frame locals. This is an array of abstract types. */ - private int[] outputLocals; - - /** The output stack map frame stack. This is an array of abstract types. */ - private int[] outputStack; - - /** - * The start of the output stack, relatively to the input stack. This offset is always negative or - * null. A null offset means that the output stack must be appended to the input stack. A -n - * offset means that the first n output stack elements must replace the top n input stack - * elements, and that the other elements must be appended to the input stack. - */ - private short outputStackStart; - - /** The index of the top stack element in {@link #outputStack}. */ - private short outputStackTop; - - /** The number of types that are initialized in the basic block. See {@link #initializations}. */ - private int initializationCount; - - /** - * The abstract types that are initialized in the basic block. A constructor invocation on an - * UNINITIALIZED or UNINITIALIZED_THIS abstract type must replace every occurrence of this - * type in the local variables and in the operand stack. This cannot be done during the first step - * of the algorithm since, during this step, the local variables and the operand stack types are - * still abstract. It is therefore necessary to store the abstract types of the constructors which - * are invoked in the basic block, in order to do this replacement during the second step of the - * algorithm, where the frames are fully computed. Note that this array can contain abstract types - * that are relative to the input locals or to the input stack. - */ - private int[] initializations; - - // ----------------------------------------------------------------------------------------------- - // Static methods to get abstract types from other type formats - // ----------------------------------------------------------------------------------------------- - - /** - * Returns the abstract type corresponding to the given public API frame element type. - * - * @param symbolTable the type table to use to lookup and store type {@link Symbol}. - * @param type a frame element type described using the same format as in {@link - * MethodVisitor#visitFrame}, i.e. either {@link Opcodes#TOP}, {@link Opcodes#INTEGER}, {@link - * Opcodes#FLOAT}, {@link Opcodes#LONG}, {@link Opcodes#DOUBLE}, {@link Opcodes#NULL}, or - * {@link Opcodes#UNINITIALIZED_THIS}, or the internal name of a class, or a Label designating - * a NEW instruction (for uninitialized types). - * @return the abstract type corresponding to the given frame element type. - */ - static int getAbstractTypeFromApiFormat(final SymbolTable symbolTable, final Object type) { - if (type instanceof Integer) { - return CONSTANT_KIND | ((Integer) type).intValue(); - } else if (type instanceof String) { - String descriptor = Type.getObjectType((String) type).getDescriptor(); - return getAbstractTypeFromDescriptor(symbolTable, descriptor, 0); - } else { - return UNINITIALIZED_KIND - | symbolTable.addUninitializedType("", ((Label) type).bytecodeOffset); - } - } - - /** - * Returns the abstract type corresponding to the internal name of a class. - * - * @param symbolTable the type table to use to lookup and store type {@link Symbol}. - * @param internalName the internal name of a class. This must not be an array type - * descriptor. - * @return the abstract type value corresponding to the given internal name. - */ - static int getAbstractTypeFromInternalName( - final SymbolTable symbolTable, final String internalName) { - return REFERENCE_KIND | symbolTable.addType(internalName); - } - - /** - * Returns the abstract type corresponding to the given type descriptor. - * - * @param symbolTable the type table to use to lookup and store type {@link Symbol}. - * @param buffer a string ending with a type descriptor. - * @param offset the start offset of the type descriptor in buffer. - * @return the abstract type corresponding to the given type descriptor. - */ - private static int getAbstractTypeFromDescriptor( - final SymbolTable symbolTable, final String buffer, final int offset) { - String internalName; - switch (buffer.charAt(offset)) { - case 'V': - return 0; - case 'Z': - case 'C': - case 'B': - case 'S': - case 'I': - return INTEGER; - case 'F': - return FLOAT; - case 'J': - return LONG; - case 'D': - return DOUBLE; - case 'L': - internalName = buffer.substring(offset + 1, buffer.length() - 1); - return REFERENCE_KIND | symbolTable.addType(internalName); - case '[': - int elementDescriptorOffset = offset + 1; - while (buffer.charAt(elementDescriptorOffset) == '[') { - ++elementDescriptorOffset; - } - int typeValue; - switch (buffer.charAt(elementDescriptorOffset)) { - case 'Z': - typeValue = BOOLEAN; - break; - case 'C': - typeValue = CHAR; - break; - case 'B': - typeValue = BYTE; - break; - case 'S': - typeValue = SHORT; - break; - case 'I': - typeValue = INTEGER; - break; - case 'F': - typeValue = FLOAT; - break; - case 'J': - typeValue = LONG; - break; - case 'D': - typeValue = DOUBLE; - break; - case 'L': - internalName = buffer.substring(elementDescriptorOffset + 1, buffer.length() - 1); - typeValue = REFERENCE_KIND | symbolTable.addType(internalName); - break; - default: - throw new IllegalArgumentException(); - } - return ((elementDescriptorOffset - offset) << DIM_SHIFT) | typeValue; - default: - throw new IllegalArgumentException(); - } - } - - // ----------------------------------------------------------------------------------------------- - // Constructor - // ----------------------------------------------------------------------------------------------- - - /** - * Constructs a new Frame. - * - * @param owner the basic block to which these input and output stack map frames correspond. - */ - Frame(final Label owner) { - this.owner = owner; - } - - /** - * Sets this frame to the value of the given frame. - * - *
WARNING: after this method is called the two frames share the same data structures. It is - * recommended to discard the given frame to avoid unexpected side effects. - * - * @param frame The new frame value. - */ - final void copyFrom(final Frame frame) { - inputLocals = frame.inputLocals; - inputStack = frame.inputStack; - outputStackStart = 0; - outputLocals = frame.outputLocals; - outputStack = frame.outputStack; - outputStackTop = frame.outputStackTop; - initializationCount = frame.initializationCount; - initializations = frame.initializations; - } - - // ----------------------------------------------------------------------------------------------- - // Methods related to the input frame - // ----------------------------------------------------------------------------------------------- - - /** - * Sets the input frame from the given method description. This method is used to initialize the - * first frame of a method, which is implicit (i.e. not stored explicitly in the StackMapTable - * attribute). - * - * @param symbolTable the type table to use to lookup and store type {@link Symbol}. - * @param access the method's access flags. - * @param descriptor the method descriptor. - * @param maxLocals the maximum number of local variables of the method. - */ - final void setInputFrameFromDescriptor( - final SymbolTable symbolTable, - final int access, - final String descriptor, - final int maxLocals) { - inputLocals = new int[maxLocals]; - inputStack = new int[0]; - int inputLocalIndex = 0; - if ((access & Opcodes.ACC_STATIC) == 0) { - if ((access & Constants.ACC_CONSTRUCTOR) == 0) { - inputLocals[inputLocalIndex++] = - REFERENCE_KIND | symbolTable.addType(symbolTable.getClassName()); - } else { - inputLocals[inputLocalIndex++] = UNINITIALIZED_THIS; - } - } - for (Type argumentType : Type.getArgumentTypes(descriptor)) { - int abstractType = - getAbstractTypeFromDescriptor(symbolTable, argumentType.getDescriptor(), 0); - inputLocals[inputLocalIndex++] = abstractType; - if (abstractType == LONG || abstractType == DOUBLE) { - inputLocals[inputLocalIndex++] = TOP; - } - } - while (inputLocalIndex < maxLocals) { - inputLocals[inputLocalIndex++] = TOP; - } - } - - /** - * Sets the input frame from the given public API frame description. - * - * @param symbolTable the type table to use to lookup and store type {@link Symbol}. - * @param nLocal the number of local variables. - * @param local the local variable types, described using the same format as in {@link - * MethodVisitor#visitFrame}. - * @param nStack the number of operand stack elements. - * @param stack the operand stack types, described using the same format as in {@link - * MethodVisitor#visitFrame}. - */ - final void setInputFrameFromApiFormat( - final SymbolTable symbolTable, - final int nLocal, - final Object[] local, - final int nStack, - final Object[] stack) { - int inputLocalIndex = 0; - for (int i = 0; i < nLocal; ++i) { - inputLocals[inputLocalIndex++] = getAbstractTypeFromApiFormat(symbolTable, local[i]); - if (local[i] == Opcodes.LONG || local[i] == Opcodes.DOUBLE) { - inputLocals[inputLocalIndex++] = TOP; - } - } - while (inputLocalIndex < inputLocals.length) { - inputLocals[inputLocalIndex++] = TOP; - } - int nStackTop = 0; - for (int i = 0; i < nStack; ++i) { - if (stack[i] == Opcodes.LONG || stack[i] == Opcodes.DOUBLE) { - ++nStackTop; - } - } - inputStack = new int[nStack + nStackTop]; - int inputStackIndex = 0; - for (int i = 0; i < nStack; ++i) { - inputStack[inputStackIndex++] = getAbstractTypeFromApiFormat(symbolTable, stack[i]); - if (stack[i] == Opcodes.LONG || stack[i] == Opcodes.DOUBLE) { - inputStack[inputStackIndex++] = TOP; - } - } - outputStackTop = 0; - initializationCount = 0; - } - - final int getInputStackSize() { - return inputStack.length; - } - - // ----------------------------------------------------------------------------------------------- - // Methods related to the output frame - // ----------------------------------------------------------------------------------------------- - - /** - * Returns the abstract type stored at the given local variable index in the output frame. - * - * @param localIndex the index of the local variable whose value must be returned. - * @return the abstract type stored at the given local variable index in the output frame. - */ - private int getLocal(final int localIndex) { - if (outputLocals == null || localIndex >= outputLocals.length) { - // If this local has never been assigned in this basic block, it is still equal to its value - // in the input frame. - return LOCAL_KIND | localIndex; - } else { - int abstractType = outputLocals[localIndex]; - if (abstractType == 0) { - // If this local has never been assigned in this basic block, so it is still equal to its - // value in the input frame. - abstractType = outputLocals[localIndex] = LOCAL_KIND | localIndex; - } - return abstractType; - } - } - - /** - * Replaces the abstract type stored at the given local variable index in the output frame. - * - * @param localIndex the index of the output frame local variable that must be set. - * @param abstractType the value that must be set. - */ - private void setLocal(final int localIndex, final int abstractType) { - // Create and/or resize the output local variables array if necessary. - if (outputLocals == null) { - outputLocals = new int[10]; - } - int outputLocalsLength = outputLocals.length; - if (localIndex >= outputLocalsLength) { - int[] newOutputLocals = new int[Math.max(localIndex + 1, 2 * outputLocalsLength)]; - System.arraycopy(outputLocals, 0, newOutputLocals, 0, outputLocalsLength); - outputLocals = newOutputLocals; - } - // Set the local variable. - outputLocals[localIndex] = abstractType; - } - - /** - * Pushes the given abstract type on the output frame stack. - * - * @param abstractType an abstract type. - */ - private void push(final int abstractType) { - // Create and/or resize the output stack array if necessary. - if (outputStack == null) { - outputStack = new int[10]; - } - int outputStackLength = outputStack.length; - if (outputStackTop >= outputStackLength) { - int[] newOutputStack = new int[Math.max(outputStackTop + 1, 2 * outputStackLength)]; - System.arraycopy(outputStack, 0, newOutputStack, 0, outputStackLength); - outputStack = newOutputStack; - } - // Pushes the abstract type on the output stack. - outputStack[outputStackTop++] = abstractType; - // Updates the maximum size reached by the output stack, if needed (note that this size is - // relative to the input stack size, which is not known yet). - short outputStackSize = (short) (outputStackStart + outputStackTop); - if (outputStackSize > owner.outputStackMax) { - owner.outputStackMax = outputStackSize; - } - } - - /** - * Pushes the abstract type corresponding to the given descriptor on the output frame stack. - * - * @param symbolTable the type table to use to lookup and store type {@link Symbol}. - * @param descriptor a type or method descriptor (in which case its return type is pushed). - */ - private void push(final SymbolTable symbolTable, final String descriptor) { - int typeDescriptorOffset = descriptor.charAt(0) == '(' ? descriptor.indexOf(')') + 1 : 0; - int abstractType = getAbstractTypeFromDescriptor(symbolTable, descriptor, typeDescriptorOffset); - if (abstractType != 0) { - push(abstractType); - if (abstractType == LONG || abstractType == DOUBLE) { - push(TOP); - } - } - } - - /** - * Pops an abstract type from the output frame stack and returns its value. - * - * @return the abstract type that has been popped from the output frame stack. - */ - private int pop() { - if (outputStackTop > 0) { - return outputStack[--outputStackTop]; - } else { - // If the output frame stack is empty, pop from the input stack. - return STACK_KIND | -(--outputStackStart); - } - } - - /** - * Pops the given number of abstract types from the output frame stack. - * - * @param elements the number of abstract types that must be popped. - */ - private void pop(final int elements) { - if (outputStackTop >= elements) { - outputStackTop -= elements; - } else { - // If the number of elements to be popped is greater than the number of elements in the output - // stack, clear it, and pop the remaining elements from the input stack. - outputStackStart -= elements - outputStackTop; - outputStackTop = 0; - } - } - - /** - * Pops as many abstract types from the output frame stack as described by the given descriptor. - * - * @param descriptor a type or method descriptor (in which case its argument types are popped). - */ - private void pop(final String descriptor) { - char firstDescriptorChar = descriptor.charAt(0); - if (firstDescriptorChar == '(') { - pop((Type.getArgumentsAndReturnSizes(descriptor) >> 2) - 1); - } else if (firstDescriptorChar == 'J' || firstDescriptorChar == 'D') { - pop(2); - } else { - pop(1); - } - } - - // ----------------------------------------------------------------------------------------------- - // Methods to handle uninitialized types - // ----------------------------------------------------------------------------------------------- - - /** - * Adds an abstract type to the list of types on which a constructor is invoked in the basic - * block. - * - * @param abstractType an abstract type on a which a constructor is invoked. - */ - private void addInitializedType(final int abstractType) { - // Create and/or resize the initializations array if necessary. - if (initializations == null) { - initializations = new int[2]; - } - int initializationsLength = initializations.length; - if (initializationCount >= initializationsLength) { - int[] newInitializations = - new int[Math.max(initializationCount + 1, 2 * initializationsLength)]; - System.arraycopy(initializations, 0, newInitializations, 0, initializationsLength); - initializations = newInitializations; - } - // Store the abstract type. - initializations[initializationCount++] = abstractType; - } - - /** - * Returns the "initialized" abstract type corresponding to the given abstract type. - * - * @param symbolTable the type table to use to lookup and store type {@link Symbol}. - * @param abstractType an abstract type. - * @return the REFERENCE_KIND abstract type corresponding to abstractType if it is - * UNINITIALIZED_THIS or an UNINITIALIZED_KIND abstract type for one of the types on which a - * constructor is invoked in the basic block. Otherwise returns abstractType. - */ - private int getInitializedType(final SymbolTable symbolTable, final int abstractType) { - if (abstractType == UNINITIALIZED_THIS - || (abstractType & (DIM_MASK | KIND_MASK)) == UNINITIALIZED_KIND) { - for (int i = 0; i < initializationCount; ++i) { - int initializedType = initializations[i]; - int dim = initializedType & DIM_MASK; - int kind = initializedType & KIND_MASK; - int value = initializedType & VALUE_MASK; - if (kind == LOCAL_KIND) { - initializedType = dim + inputLocals[value]; - } else if (kind == STACK_KIND) { - initializedType = dim + inputStack[inputStack.length - value]; - } - if (abstractType == initializedType) { - if (abstractType == UNINITIALIZED_THIS) { - return REFERENCE_KIND | symbolTable.addType(symbolTable.getClassName()); - } else { - return REFERENCE_KIND - | symbolTable.addType(symbolTable.getType(abstractType & VALUE_MASK).value); - } - } - } - } - return abstractType; - } - - // ----------------------------------------------------------------------------------------------- - // Main method, to simulate the execution of each instruction on the output frame - // ----------------------------------------------------------------------------------------------- - - /** - * Simulates the action of the given instruction on the output stack frame. - * - * @param opcode the opcode of the instruction. - * @param arg the numeric operand of the instruction, if any. - * @param argSymbol the Symbol operand of the instruction, if any. - * @param symbolTable the type table to use to lookup and store type {@link Symbol}. - */ - void execute( - final int opcode, final int arg, final Symbol argSymbol, final SymbolTable symbolTable) { - // Abstract types popped from the stack or read from local variables. - int abstractType1; - int abstractType2; - int abstractType3; - int abstractType4; - switch (opcode) { - case Opcodes.NOP: - case Opcodes.INEG: - case Opcodes.LNEG: - case Opcodes.FNEG: - case Opcodes.DNEG: - case Opcodes.I2B: - case Opcodes.I2C: - case Opcodes.I2S: - case Opcodes.GOTO: - case Opcodes.RETURN: - break; - case Opcodes.ACONST_NULL: - push(NULL); - break; - case Opcodes.ICONST_M1: - case Opcodes.ICONST_0: - case Opcodes.ICONST_1: - case Opcodes.ICONST_2: - case Opcodes.ICONST_3: - case Opcodes.ICONST_4: - case Opcodes.ICONST_5: - case Opcodes.BIPUSH: - case Opcodes.SIPUSH: - case Opcodes.ILOAD: - push(INTEGER); - break; - case Opcodes.LCONST_0: - case Opcodes.LCONST_1: - case Opcodes.LLOAD: - push(LONG); - push(TOP); - break; - case Opcodes.FCONST_0: - case Opcodes.FCONST_1: - case Opcodes.FCONST_2: - case Opcodes.FLOAD: - push(FLOAT); - break; - case Opcodes.DCONST_0: - case Opcodes.DCONST_1: - case Opcodes.DLOAD: - push(DOUBLE); - push(TOP); - break; - case Opcodes.LDC: - switch (argSymbol.tag) { - case Symbol.CONSTANT_INTEGER_TAG: - push(INTEGER); - break; - case Symbol.CONSTANT_LONG_TAG: - push(LONG); - push(TOP); - break; - case Symbol.CONSTANT_FLOAT_TAG: - push(FLOAT); - break; - case Symbol.CONSTANT_DOUBLE_TAG: - push(DOUBLE); - push(TOP); - break; - case Symbol.CONSTANT_CLASS_TAG: - push(REFERENCE_KIND | symbolTable.addType("java/lang/Class")); - break; - case Symbol.CONSTANT_STRING_TAG: - push(REFERENCE_KIND | symbolTable.addType("java/lang/String")); - break; - case Symbol.CONSTANT_METHOD_TYPE_TAG: - push(REFERENCE_KIND | symbolTable.addType("java/lang/invoke/MethodType")); - break; - case Symbol.CONSTANT_METHOD_HANDLE_TAG: - push(REFERENCE_KIND | symbolTable.addType("java/lang/invoke/MethodHandle")); - break; - case Symbol.CONSTANT_DYNAMIC_TAG: - push(symbolTable, argSymbol.value); - break; - default: - throw new AssertionError(); - } - break; - case Opcodes.ALOAD: - push(getLocal(arg)); - break; - case Opcodes.LALOAD: - case Opcodes.D2L: - pop(2); - push(LONG); - push(TOP); - break; - case Opcodes.DALOAD: - case Opcodes.L2D: - pop(2); - push(DOUBLE); - push(TOP); - break; - case Opcodes.AALOAD: - pop(1); - abstractType1 = pop(); - push(abstractType1 == NULL ? abstractType1 : ELEMENT_OF + abstractType1); - break; - case Opcodes.ISTORE: - case Opcodes.FSTORE: - case Opcodes.ASTORE: - abstractType1 = pop(); - setLocal(arg, abstractType1); - if (arg > 0) { - int previousLocalType = getLocal(arg - 1); - if (previousLocalType == LONG || previousLocalType == DOUBLE) { - setLocal(arg - 1, TOP); - } else if ((previousLocalType & KIND_MASK) == LOCAL_KIND - || (previousLocalType & KIND_MASK) == STACK_KIND) { - // The type of the previous local variable is not known yet, but if it later appears - // to be LONG or DOUBLE, we should then use TOP instead. - setLocal(arg - 1, previousLocalType | TOP_IF_LONG_OR_DOUBLE_FLAG); - } - } - break; - case Opcodes.LSTORE: - case Opcodes.DSTORE: - pop(1); - abstractType1 = pop(); - setLocal(arg, abstractType1); - setLocal(arg + 1, TOP); - if (arg > 0) { - int previousLocalType = getLocal(arg - 1); - if (previousLocalType == LONG || previousLocalType == DOUBLE) { - setLocal(arg - 1, TOP); - } else if ((previousLocalType & KIND_MASK) == LOCAL_KIND - || (previousLocalType & KIND_MASK) == STACK_KIND) { - // The type of the previous local variable is not known yet, but if it later appears - // to be LONG or DOUBLE, we should then use TOP instead. - setLocal(arg - 1, previousLocalType | TOP_IF_LONG_OR_DOUBLE_FLAG); - } - } - break; - case Opcodes.IASTORE: - case Opcodes.BASTORE: - case Opcodes.CASTORE: - case Opcodes.SASTORE: - case Opcodes.FASTORE: - case Opcodes.AASTORE: - pop(3); - break; - case Opcodes.LASTORE: - case Opcodes.DASTORE: - pop(4); - break; - case Opcodes.POP: - case Opcodes.IFEQ: - case Opcodes.IFNE: - case Opcodes.IFLT: - case Opcodes.IFGE: - case Opcodes.IFGT: - case Opcodes.IFLE: - case Opcodes.IRETURN: - case Opcodes.FRETURN: - case Opcodes.ARETURN: - case Opcodes.TABLESWITCH: - case Opcodes.LOOKUPSWITCH: - case Opcodes.ATHROW: - case Opcodes.MONITORENTER: - case Opcodes.MONITOREXIT: - case Opcodes.IFNULL: - case Opcodes.IFNONNULL: - pop(1); - break; - case Opcodes.POP2: - case Opcodes.IF_ICMPEQ: - case Opcodes.IF_ICMPNE: - case Opcodes.IF_ICMPLT: - case Opcodes.IF_ICMPGE: - case Opcodes.IF_ICMPGT: - case Opcodes.IF_ICMPLE: - case Opcodes.IF_ACMPEQ: - case Opcodes.IF_ACMPNE: - case Opcodes.LRETURN: - case Opcodes.DRETURN: - pop(2); - break; - case Opcodes.DUP: - abstractType1 = pop(); - push(abstractType1); - push(abstractType1); - break; - case Opcodes.DUP_X1: - abstractType1 = pop(); - abstractType2 = pop(); - push(abstractType1); - push(abstractType2); - push(abstractType1); - break; - case Opcodes.DUP_X2: - abstractType1 = pop(); - abstractType2 = pop(); - abstractType3 = pop(); - push(abstractType1); - push(abstractType3); - push(abstractType2); - push(abstractType1); - break; - case Opcodes.DUP2: - abstractType1 = pop(); - abstractType2 = pop(); - push(abstractType2); - push(abstractType1); - push(abstractType2); - push(abstractType1); - break; - case Opcodes.DUP2_X1: - abstractType1 = pop(); - abstractType2 = pop(); - abstractType3 = pop(); - push(abstractType2); - push(abstractType1); - push(abstractType3); - push(abstractType2); - push(abstractType1); - break; - case Opcodes.DUP2_X2: - abstractType1 = pop(); - abstractType2 = pop(); - abstractType3 = pop(); - abstractType4 = pop(); - push(abstractType2); - push(abstractType1); - push(abstractType4); - push(abstractType3); - push(abstractType2); - push(abstractType1); - break; - case Opcodes.SWAP: - abstractType1 = pop(); - abstractType2 = pop(); - push(abstractType1); - push(abstractType2); - break; - case Opcodes.IALOAD: - case Opcodes.BALOAD: - case Opcodes.CALOAD: - case Opcodes.SALOAD: - case Opcodes.IADD: - case Opcodes.ISUB: - case Opcodes.IMUL: - case Opcodes.IDIV: - case Opcodes.IREM: - case Opcodes.IAND: - case Opcodes.IOR: - case Opcodes.IXOR: - case Opcodes.ISHL: - case Opcodes.ISHR: - case Opcodes.IUSHR: - case Opcodes.L2I: - case Opcodes.D2I: - case Opcodes.FCMPL: - case Opcodes.FCMPG: - pop(2); - push(INTEGER); - break; - case Opcodes.LADD: - case Opcodes.LSUB: - case Opcodes.LMUL: - case Opcodes.LDIV: - case Opcodes.LREM: - case Opcodes.LAND: - case Opcodes.LOR: - case Opcodes.LXOR: - pop(4); - push(LONG); - push(TOP); - break; - case Opcodes.FALOAD: - case Opcodes.FADD: - case Opcodes.FSUB: - case Opcodes.FMUL: - case Opcodes.FDIV: - case Opcodes.FREM: - case Opcodes.L2F: - case Opcodes.D2F: - pop(2); - push(FLOAT); - break; - case Opcodes.DADD: - case Opcodes.DSUB: - case Opcodes.DMUL: - case Opcodes.DDIV: - case Opcodes.DREM: - pop(4); - push(DOUBLE); - push(TOP); - break; - case Opcodes.LSHL: - case Opcodes.LSHR: - case Opcodes.LUSHR: - pop(3); - push(LONG); - push(TOP); - break; - case Opcodes.IINC: - setLocal(arg, INTEGER); - break; - case Opcodes.I2L: - case Opcodes.F2L: - pop(1); - push(LONG); - push(TOP); - break; - case Opcodes.I2F: - pop(1); - push(FLOAT); - break; - case Opcodes.I2D: - case Opcodes.F2D: - pop(1); - push(DOUBLE); - push(TOP); - break; - case Opcodes.F2I: - case Opcodes.ARRAYLENGTH: - case Opcodes.INSTANCEOF: - pop(1); - push(INTEGER); - break; - case Opcodes.LCMP: - case Opcodes.DCMPL: - case Opcodes.DCMPG: - pop(4); - push(INTEGER); - break; - case Opcodes.JSR: - case Opcodes.RET: - throw new IllegalArgumentException("JSR/RET are not supported with computeFrames option"); - case Opcodes.GETSTATIC: - push(symbolTable, argSymbol.value); - break; - case Opcodes.PUTSTATIC: - pop(argSymbol.value); - break; - case Opcodes.GETFIELD: - pop(1); - push(symbolTable, argSymbol.value); - break; - case Opcodes.PUTFIELD: - pop(argSymbol.value); - pop(); - break; - case Opcodes.INVOKEVIRTUAL: - case Opcodes.INVOKESPECIAL: - case Opcodes.INVOKESTATIC: - case Opcodes.INVOKEINTERFACE: - pop(argSymbol.value); - if (opcode != Opcodes.INVOKESTATIC) { - abstractType1 = pop(); - if (opcode == Opcodes.INVOKESPECIAL && argSymbol.name.charAt(0) == '<') { - addInitializedType(abstractType1); - } - } - push(symbolTable, argSymbol.value); - break; - case Opcodes.INVOKEDYNAMIC: - pop(argSymbol.value); - push(symbolTable, argSymbol.value); - break; - case Opcodes.NEW: - push(UNINITIALIZED_KIND | symbolTable.addUninitializedType(argSymbol.value, arg)); - break; - case Opcodes.NEWARRAY: - pop(); - switch (arg) { - case Opcodes.T_BOOLEAN: - push(ARRAY_OF | BOOLEAN); - break; - case Opcodes.T_CHAR: - push(ARRAY_OF | CHAR); - break; - case Opcodes.T_BYTE: - push(ARRAY_OF | BYTE); - break; - case Opcodes.T_SHORT: - push(ARRAY_OF | SHORT); - break; - case Opcodes.T_INT: - push(ARRAY_OF | INTEGER); - break; - case Opcodes.T_FLOAT: - push(ARRAY_OF | FLOAT); - break; - case Opcodes.T_DOUBLE: - push(ARRAY_OF | DOUBLE); - break; - case Opcodes.T_LONG: - push(ARRAY_OF | LONG); - break; - default: - throw new IllegalArgumentException(); - } - break; - case Opcodes.ANEWARRAY: - String arrayElementType = argSymbol.value; - pop(); - if (arrayElementType.charAt(0) == '[') { - push(symbolTable, '[' + arrayElementType); - } else { - push(ARRAY_OF | REFERENCE_KIND | symbolTable.addType(arrayElementType)); - } - break; - case Opcodes.CHECKCAST: - String castType = argSymbol.value; - pop(); - if (castType.charAt(0) == '[') { - push(symbolTable, castType); - } else { - push(REFERENCE_KIND | symbolTable.addType(castType)); - } - break; - case Opcodes.MULTIANEWARRAY: - pop(arg); - push(symbolTable, argSymbol.value); - break; - default: - throw new IllegalArgumentException(); - } - } - - // ----------------------------------------------------------------------------------------------- - // Frame merging methods, used in the second step of the stack map frame computation algorithm - // ----------------------------------------------------------------------------------------------- - - /** - * Merges the input frame of the given {@link Frame} with the input and output frames of this - * {@link Frame}. Returns true if the given frame has been changed by this operation (the - * input and output frames of this {@link Frame} are never changed). - * - * @param symbolTable the type table to use to lookup and store type {@link Symbol}. - * @param dstFrame the {@link Frame} whose input frame must be updated. This should be the frame - * of a successor, in the control flow graph, of the basic block corresponding to this frame. - * @param catchTypeIndex if 'frame' corresponds to an exception handler basic block, the type - * table index of the caught exception type, otherwise 0. - * @return true if the input frame of 'frame' has been changed by this operation. - */ - final boolean merge( - final SymbolTable symbolTable, final Frame dstFrame, final int catchTypeIndex) { - boolean frameChanged = false; - - // Compute the concrete types of the local variables at the end of the basic block corresponding - // to this frame, by resolving its abstract output types, and merge these concrete types with - // those of the local variables in the input frame of dstFrame. - int nLocal = inputLocals.length; - int nStack = inputStack.length; - if (dstFrame.inputLocals == null) { - dstFrame.inputLocals = new int[nLocal]; - frameChanged = true; - } - for (int i = 0; i < nLocal; ++i) { - int concreteOutputType; - if (outputLocals != null && i < outputLocals.length) { - int abstractOutputType = outputLocals[i]; - if (abstractOutputType == 0) { - // If the local variable has never been assigned in this basic block, it is equal to its - // value at the beginning of the block. - concreteOutputType = inputLocals[i]; - } else { - int dim = abstractOutputType & DIM_MASK; - int kind = abstractOutputType & KIND_MASK; - if (kind == LOCAL_KIND) { - // By definition, a LOCAL_KIND type designates the concrete type of a local variable at - // the beginning of the basic block corresponding to this frame (which is known when - // this method is called, but was not when the abstract type was computed). - concreteOutputType = dim + inputLocals[abstractOutputType & VALUE_MASK]; - if ((abstractOutputType & TOP_IF_LONG_OR_DOUBLE_FLAG) != 0 - && (concreteOutputType == LONG || concreteOutputType == DOUBLE)) { - concreteOutputType = TOP; - } - } else if (kind == STACK_KIND) { - // By definition, a STACK_KIND type designates the concrete type of a local variable at - // the beginning of the basic block corresponding to this frame (which is known when - // this method is called, but was not when the abstract type was computed). - concreteOutputType = dim + inputStack[nStack - (abstractOutputType & VALUE_MASK)]; - if ((abstractOutputType & TOP_IF_LONG_OR_DOUBLE_FLAG) != 0 - && (concreteOutputType == LONG || concreteOutputType == DOUBLE)) { - concreteOutputType = TOP; - } - } else { - concreteOutputType = abstractOutputType; - } - } - } else { - // If the local variable has never been assigned in this basic block, it is equal to its - // value at the beginning of the block. - concreteOutputType = inputLocals[i]; - } - // concreteOutputType might be an uninitialized type from the input locals or from the input - // stack. However, if a constructor has been called for this class type in the basic block, - // then this type is no longer uninitialized at the end of basic block. - if (initializations != null) { - concreteOutputType = getInitializedType(symbolTable, concreteOutputType); - } - frameChanged |= merge(symbolTable, concreteOutputType, dstFrame.inputLocals, i); - } - - // If dstFrame is an exception handler block, it can be reached from any instruction of the - // basic block corresponding to this frame, in particular from the first one. Therefore, the - // input locals of dstFrame should be compatible (i.e. merged) with the input locals of this - // frame (and the input stack of dstFrame should be compatible, i.e. merged, with a one - // element stack containing the caught exception type). - if (catchTypeIndex > 0) { - for (int i = 0; i < nLocal; ++i) { - frameChanged |= merge(symbolTable, inputLocals[i], dstFrame.inputLocals, i); - } - if (dstFrame.inputStack == null) { - dstFrame.inputStack = new int[1]; - frameChanged = true; - } - frameChanged |= merge(symbolTable, catchTypeIndex, dstFrame.inputStack, 0); - return frameChanged; - } - - // Compute the concrete types of the stack operands at the end of the basic block corresponding - // to this frame, by resolving its abstract output types, and merge these concrete types with - // those of the stack operands in the input frame of dstFrame. - int nInputStack = inputStack.length + outputStackStart; - if (dstFrame.inputStack == null) { - dstFrame.inputStack = new int[nInputStack + outputStackTop]; - frameChanged = true; - } - // First, do this for the stack operands that have not been popped in the basic block - // corresponding to this frame, and which are therefore equal to their value in the input - // frame (except for uninitialized types, which may have been initialized). - for (int i = 0; i < nInputStack; ++i) { - int concreteOutputType = inputStack[i]; - if (initializations != null) { - concreteOutputType = getInitializedType(symbolTable, concreteOutputType); - } - frameChanged |= merge(symbolTable, concreteOutputType, dstFrame.inputStack, i); - } - // Then, do this for the stack operands that have pushed in the basic block (this code is the - // same as the one above for local variables). - for (int i = 0; i < outputStackTop; ++i) { - int concreteOutputType; - int abstractOutputType = outputStack[i]; - int dim = abstractOutputType & DIM_MASK; - int kind = abstractOutputType & KIND_MASK; - if (kind == LOCAL_KIND) { - concreteOutputType = dim + inputLocals[abstractOutputType & VALUE_MASK]; - if ((abstractOutputType & TOP_IF_LONG_OR_DOUBLE_FLAG) != 0 - && (concreteOutputType == LONG || concreteOutputType == DOUBLE)) { - concreteOutputType = TOP; - } - } else if (kind == STACK_KIND) { - concreteOutputType = dim + inputStack[nStack - (abstractOutputType & VALUE_MASK)]; - if ((abstractOutputType & TOP_IF_LONG_OR_DOUBLE_FLAG) != 0 - && (concreteOutputType == LONG || concreteOutputType == DOUBLE)) { - concreteOutputType = TOP; - } - } else { - concreteOutputType = abstractOutputType; - } - if (initializations != null) { - concreteOutputType = getInitializedType(symbolTable, concreteOutputType); - } - frameChanged |= merge(symbolTable, concreteOutputType, dstFrame.inputStack, nInputStack + i); - } - return frameChanged; - } - - /** - * Merges the type at the given index in the given abstract type array with the given type. - * Returns true if the type array has been modified by this operation. - * - * @param symbolTable the type table to use to lookup and store type {@link Symbol}. - * @param sourceType the abstract type with which the abstract type array element must be merged. - * This type should be of {@link #CONSTANT_KIND}, {@link #REFERENCE_KIND} or {@link - * #UNINITIALIZED_KIND} kind, with positive or null array dimensions. - * @param dstTypes an array of abstract types. These types should be of {@link #CONSTANT_KIND}, - * {@link #REFERENCE_KIND} or {@link #UNINITIALIZED_KIND} kind, with positive or null array - * dimensions. - * @param dstIndex the index of the type that must be merged in dstTypes. - * @return true if the type array has been modified by this operation. - */ - private static boolean merge( - final SymbolTable symbolTable, - final int sourceType, - final int[] dstTypes, - final int dstIndex) { - int dstType = dstTypes[dstIndex]; - if (dstType == sourceType) { - // If the types are equal, merge(sourceType, dstType) = dstType, so there is no change. - return false; - } - int srcType = sourceType; - if ((sourceType & ~DIM_MASK) == NULL) { - if (dstType == NULL) { - return false; - } - srcType = NULL; - } - if (dstType == 0) { - // If dstTypes[dstIndex] has never been assigned, merge(srcType, dstType) = srcType. - dstTypes[dstIndex] = srcType; - return true; - } - int mergedType; - if ((dstType & DIM_MASK) != 0 || (dstType & KIND_MASK) == REFERENCE_KIND) { - // If dstType is a reference type of any array dimension. - if (srcType == NULL) { - // If srcType is the NULL type, merge(srcType, dstType) = dstType, so there is no change. - return false; - } else if ((srcType & (DIM_MASK | KIND_MASK)) == (dstType & (DIM_MASK | KIND_MASK))) { - // If srcType has the same array dimension and the same kind as dstType. - if ((dstType & KIND_MASK) == REFERENCE_KIND) { - // If srcType and dstType are reference types with the same array dimension, - // merge(srcType, dstType) = dim(srcType) | common super class of srcType and dstType. - mergedType = - (srcType & DIM_MASK) - | REFERENCE_KIND - | symbolTable.addMergedType(srcType & VALUE_MASK, dstType & VALUE_MASK); - } else { - // If srcType and dstType are array types of equal dimension but different element types, - // merge(srcType, dstType) = dim(srcType) - 1 | java/lang/Object. - int mergedDim = ELEMENT_OF + (srcType & DIM_MASK); - mergedType = mergedDim | REFERENCE_KIND | symbolTable.addType("java/lang/Object"); - } - } else if ((srcType & DIM_MASK) != 0 || (srcType & KIND_MASK) == REFERENCE_KIND) { - // If srcType is any other reference or array type, - // merge(srcType, dstType) = min(srcDdim, dstDim) | java/lang/Object - // where srcDim is the array dimension of srcType, minus 1 if srcType is an array type - // with a non reference element type (and similarly for dstDim). - int srcDim = srcType & DIM_MASK; - if (srcDim != 0 && (srcType & KIND_MASK) != REFERENCE_KIND) { - srcDim = ELEMENT_OF + srcDim; - } - int dstDim = dstType & DIM_MASK; - if (dstDim != 0 && (dstType & KIND_MASK) != REFERENCE_KIND) { - dstDim = ELEMENT_OF + dstDim; - } - mergedType = - Math.min(srcDim, dstDim) | REFERENCE_KIND | symbolTable.addType("java/lang/Object"); - } else { - // If srcType is any other type, merge(srcType, dstType) = TOP. - mergedType = TOP; - } - } else if (dstType == NULL) { - // If dstType is the NULL type, merge(srcType, dstType) = srcType, or TOP if srcType is not a - // an array type or a reference type. - mergedType = - (srcType & DIM_MASK) != 0 || (srcType & KIND_MASK) == REFERENCE_KIND ? srcType : TOP; - } else { - // If dstType is any other type, merge(srcType, dstType) = TOP whatever srcType. - mergedType = TOP; - } - if (mergedType != dstType) { - dstTypes[dstIndex] = mergedType; - return true; - } - return false; - } - - // ----------------------------------------------------------------------------------------------- - // Frame output methods, to generate StackMapFrame attributes - // ----------------------------------------------------------------------------------------------- - - /** - * Makes the given {@link MethodWriter} visit the input frame of this {@link Frame}. The visit is - * done with the {@link MethodWriter#visitFrameStart}, {@link MethodWriter#visitAbstractType} and - * {@link MethodWriter#visitFrameEnd} methods. - * - * @param methodWriter the {@link MethodWriter} that should visit the input frame of this {@link - * Frame}. - */ - final void accept(final MethodWriter methodWriter) { - // Compute the number of locals, ignoring TOP types that are just after a LONG or a DOUBLE, and - // all trailing TOP types. - int[] localTypes = inputLocals; - int nLocal = 0; - int nTrailingTop = 0; - int i = 0; - while (i < localTypes.length) { - int localType = localTypes[i]; - i += (localType == LONG || localType == DOUBLE) ? 2 : 1; - if (localType == TOP) { - nTrailingTop++; - } else { - nLocal += nTrailingTop + 1; - nTrailingTop = 0; - } - } - // Compute the stack size, ignoring TOP types that are just after a LONG or a DOUBLE. - int[] stackTypes = inputStack; - int nStack = 0; - i = 0; - while (i < stackTypes.length) { - int stackType = stackTypes[i]; - i += (stackType == LONG || stackType == DOUBLE) ? 2 : 1; - nStack++; - } - // Visit the frame and its content. - int frameIndex = methodWriter.visitFrameStart(owner.bytecodeOffset, nLocal, nStack); - i = 0; - while (nLocal-- > 0) { - int localType = localTypes[i]; - i += (localType == LONG || localType == DOUBLE) ? 2 : 1; - methodWriter.visitAbstractType(frameIndex++, localType); - } - i = 0; - while (nStack-- > 0) { - int stackType = stackTypes[i]; - i += (stackType == LONG || stackType == DOUBLE) ? 2 : 1; - methodWriter.visitAbstractType(frameIndex++, stackType); - } - methodWriter.visitFrameEnd(); - } - - /** - * Put the given abstract type in the given ByteVector, using the JVMS verification_type_info - * format used in StackMapTable attributes. - * - * @param symbolTable the type table to use to lookup and store type {@link Symbol}. - * @param abstractType an abstract type, restricted to {@link Frame#CONSTANT_KIND}, {@link - * Frame#REFERENCE_KIND} or {@link Frame#UNINITIALIZED_KIND} types. - * @param output where the abstract type must be put. - * @see JVMS - * 4.7.4 - */ - static void putAbstractType( - final SymbolTable symbolTable, final int abstractType, final ByteVector output) { - int arrayDimensions = (abstractType & Frame.DIM_MASK) >> DIM_SHIFT; - if (arrayDimensions == 0) { - int typeValue = abstractType & VALUE_MASK; - switch (abstractType & KIND_MASK) { - case CONSTANT_KIND: - output.putByte(typeValue); - break; - case REFERENCE_KIND: - output - .putByte(ITEM_OBJECT) - .putShort(symbolTable.addConstantClass(symbolTable.getType(typeValue).value).index); - break; - case UNINITIALIZED_KIND: - output.putByte(ITEM_UNINITIALIZED).putShort((int) symbolTable.getType(typeValue).data); - break; - default: - throw new AssertionError(); - } - } else { - // Case of an array type, we need to build its descriptor first. - StringBuilder typeDescriptor = new StringBuilder(); - while (arrayDimensions-- > 0) { - typeDescriptor.append('['); - } - if ((abstractType & KIND_MASK) == REFERENCE_KIND) { - typeDescriptor - .append('L') - .append(symbolTable.getType(abstractType & VALUE_MASK).value) - .append(';'); - } else { - switch (abstractType & VALUE_MASK) { - case Frame.ITEM_ASM_BOOLEAN: - typeDescriptor.append('Z'); - break; - case Frame.ITEM_ASM_BYTE: - typeDescriptor.append('B'); - break; - case Frame.ITEM_ASM_CHAR: - typeDescriptor.append('C'); - break; - case Frame.ITEM_ASM_SHORT: - typeDescriptor.append('S'); - break; - case Frame.ITEM_INTEGER: - typeDescriptor.append('I'); - break; - case Frame.ITEM_FLOAT: - typeDescriptor.append('F'); - break; - case Frame.ITEM_LONG: - typeDescriptor.append('J'); - break; - case Frame.ITEM_DOUBLE: - typeDescriptor.append('D'); - break; - default: - throw new AssertionError(); - } - } - output - .putByte(ITEM_OBJECT) - .putShort(symbolTable.addConstantClass(typeDescriptor.toString()).index); - } - } -} diff --git a/scripts/cn1playground/common/src/main/java/bsh/org/objectweb/asm/Handle.java b/scripts/cn1playground/common/src/main/java/bsh/org/objectweb/asm/Handle.java deleted file mode 100644 index f4737afe73..0000000000 --- a/scripts/cn1playground/common/src/main/java/bsh/org/objectweb/asm/Handle.java +++ /dev/null @@ -1,189 +0,0 @@ -// ASM: a very small and fast Java bytecode manipulation framework -// Copyright (c) 2000-2011 INRIA, France Telecom -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions -// are met: -// 1. Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// 2. Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// 3. Neither the name of the copyright holders nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF -// THE POSSIBILITY OF SUCH DAMAGE. - -package bsh.org.objectweb.asm; - -/** - * A reference to a field or a method. - * - * @author Remi Forax - * @author Eric Bruneton - */ -public final class Handle { - - /** - * The kind of field or method designated by this Handle. Should be {@link Opcodes#H_GETFIELD}, - * {@link Opcodes#H_GETSTATIC}, {@link Opcodes#H_PUTFIELD}, {@link Opcodes#H_PUTSTATIC}, {@link - * Opcodes#H_INVOKEVIRTUAL}, {@link Opcodes#H_INVOKESTATIC}, {@link Opcodes#H_INVOKESPECIAL}, - * {@link Opcodes#H_NEWINVOKESPECIAL} or {@link Opcodes#H_INVOKEINTERFACE}. - */ - private final int tag; - - /** The internal name of the class that owns the field or method designated by this handle. */ - private final String owner; - - /** The name of the field or method designated by this handle. */ - private final String name; - - /** The descriptor of the field or method designated by this handle. */ - private final String descriptor; - - /** Whether the owner is an interface or not. */ - private final boolean isInterface; - - /** - * Constructs a new field or method handle. - * - * @param tag the kind of field or method designated by this Handle. Must be {@link - * Opcodes#H_GETFIELD}, {@link Opcodes#H_GETSTATIC}, {@link Opcodes#H_PUTFIELD}, {@link - * Opcodes#H_PUTSTATIC}, {@link Opcodes#H_INVOKEVIRTUAL}, {@link Opcodes#H_INVOKESTATIC}, - * {@link Opcodes#H_INVOKESPECIAL}, {@link Opcodes#H_NEWINVOKESPECIAL} or {@link - * Opcodes#H_INVOKEINTERFACE}. - * @param owner the internal name of the class that owns the field or method designated by this - * handle. - * @param name the name of the field or method designated by this handle. - * @param descriptor the descriptor of the field or method designated by this handle. - * @deprecated this constructor has been superseded by {@link #Handle(int, String, String, String, - * boolean)}. - */ - @Deprecated - public Handle(final int tag, final String owner, final String name, final String descriptor) { - this(tag, owner, name, descriptor, tag == Opcodes.H_INVOKEINTERFACE); - } - - /** - * Constructs a new field or method handle. - * - * @param tag the kind of field or method designated by this Handle. Must be {@link - * Opcodes#H_GETFIELD}, {@link Opcodes#H_GETSTATIC}, {@link Opcodes#H_PUTFIELD}, {@link - * Opcodes#H_PUTSTATIC}, {@link Opcodes#H_INVOKEVIRTUAL}, {@link Opcodes#H_INVOKESTATIC}, - * {@link Opcodes#H_INVOKESPECIAL}, {@link Opcodes#H_NEWINVOKESPECIAL} or {@link - * Opcodes#H_INVOKEINTERFACE}. - * @param owner the internal name of the class that owns the field or method designated by this - * handle. - * @param name the name of the field or method designated by this handle. - * @param descriptor the descriptor of the field or method designated by this handle. - * @param isInterface whether the owner is an interface or not. - */ - public Handle( - final int tag, - final String owner, - final String name, - final String descriptor, - final boolean isInterface) { - this.tag = tag; - this.owner = owner; - this.name = name; - this.descriptor = descriptor; - this.isInterface = isInterface; - } - - /** - * Returns the kind of field or method designated by this handle. - * - * @return {@link Opcodes#H_GETFIELD}, {@link Opcodes#H_GETSTATIC}, {@link Opcodes#H_PUTFIELD}, - * {@link Opcodes#H_PUTSTATIC}, {@link Opcodes#H_INVOKEVIRTUAL}, {@link - * Opcodes#H_INVOKESTATIC}, {@link Opcodes#H_INVOKESPECIAL}, {@link - * Opcodes#H_NEWINVOKESPECIAL} or {@link Opcodes#H_INVOKEINTERFACE}. - */ - public int getTag() { - return tag; - } - - /** - * Returns the internal name of the class that owns the field or method designated by this handle. - * - * @return the internal name of the class that owns the field or method designated by this handle. - */ - public String getOwner() { - return owner; - } - - /** - * Returns the name of the field or method designated by this handle. - * - * @return the name of the field or method designated by this handle. - */ - public String getName() { - return name; - } - - /** - * Returns the descriptor of the field or method designated by this handle. - * - * @return the descriptor of the field or method designated by this handle. - */ - public String getDesc() { - return descriptor; - } - - /** - * Returns true if the owner of the field or method designated by this handle is an interface. - * - * @return true if the owner of the field or method designated by this handle is an interface. - */ - public boolean isInterface() { - return isInterface; - } - - @Override - public boolean equals(final Object object) { - if (object == this) { - return true; - } - if (!(object instanceof Handle)) { - return false; - } - Handle handle = (Handle) object; - return tag == handle.tag - && isInterface == handle.isInterface - && owner.equals(handle.owner) - && name.equals(handle.name) - && descriptor.equals(handle.descriptor); - } - - @Override - public int hashCode() { - return tag - + (isInterface ? 64 : 0) - + owner.hashCode() * name.hashCode() * descriptor.hashCode(); - } - - /** - * Returns the textual representation of this handle. The textual representation is: - * - *
List of labels are used in {@link MethodWriter#computeAllFrames} and {@link - * MethodWriter#computeMaxStackAndLocal} to compute stack map frames and the maximum stack size, - * respectively, as well as in {@link #markSubroutine} and {@link #addSubroutineRetSuccessors} to - * compute the basic blocks belonging to subroutines and their outgoing edges. Outside of these - * methods, this field should be null (this property is a precondition and a postcondition of - * these methods). - */ - Label nextListElement; - - // ----------------------------------------------------------------------------------------------- - // Constructor and accessors - // ----------------------------------------------------------------------------------------------- - - /** Constructs a new label. */ - public Label() { - // Nothing to do. - } - - /** - * Returns the bytecode offset corresponding to this label. This offset is computed from the start - * of the method's bytecode. This method is intended for {@link Attribute} sub classes, and is - * normally not needed by class generators or adapters. - * - * @return the bytecode offset corresponding to this label. - * @throws IllegalStateException if this label is not resolved yet. - */ - public int getOffset() { - if ((flags & FLAG_RESOLVED) == 0) { - throw new IllegalStateException("Label offset position has not been resolved yet"); - } - return bytecodeOffset; - } - - /** - * Returns the "canonical" {@link Label} instance corresponding to this label's bytecode offset, - * if known, otherwise the label itself. The canonical instance is the first label (in the order - * of their visit by {@link MethodVisitor#visitLabel}) corresponding to this bytecode offset. It - * cannot be known for labels which have not been visited yet. - * - *
This method should only be used when the {@link MethodWriter#COMPUTE_ALL_FRAMES} option - * is used. - * - * @return the label itself if {@link #frame} is null, otherwise the Label's frame owner. This - * corresponds to the "canonical" label instance described above thanks to the way the label - * frame is set in {@link MethodWriter#visitLabel}. - */ - final Label getCanonicalInstance() { - return frame == null ? this : frame.owner; - } - - // ----------------------------------------------------------------------------------------------- - // Methods to manage line numbers - // ----------------------------------------------------------------------------------------------- - - /** - * Adds a source line number corresponding to this label. - * - * @param lineNumber a source line number (which should be strictly positive). - */ - final void addLineNumber(final int lineNumber) { - if (this.lineNumber == 0) { - this.lineNumber = (short) lineNumber; - } else { - if (otherLineNumbers == null) { - otherLineNumbers = new int[LINE_NUMBERS_CAPACITY_INCREMENT]; - } - int otherLineNumberIndex = ++otherLineNumbers[0]; - if (otherLineNumberIndex >= otherLineNumbers.length) { - int[] newLineNumbers = new int[otherLineNumbers.length + LINE_NUMBERS_CAPACITY_INCREMENT]; - System.arraycopy(otherLineNumbers, 0, newLineNumbers, 0, otherLineNumbers.length); - otherLineNumbers = newLineNumbers; - } - otherLineNumbers[otherLineNumberIndex] = lineNumber; - } - } - - /** - * Makes the given visitor visit this label and its source line numbers, if applicable. - * - * @param methodVisitor a method visitor. - * @param visitLineNumbers whether to visit of the label's source line numbers, if any. - */ - final void accept(final MethodVisitor methodVisitor, final boolean visitLineNumbers) { - methodVisitor.visitLabel(this); - if (visitLineNumbers && lineNumber != 0) { - methodVisitor.visitLineNumber(lineNumber & 0xFFFF, this); - if (otherLineNumbers != null) { - for (int i = 1; i <= otherLineNumbers[0]; ++i) { - methodVisitor.visitLineNumber(otherLineNumbers[i], this); - } - } - } - } - - // ----------------------------------------------------------------------------------------------- - // Methods to compute offsets and to manage forward references - // ----------------------------------------------------------------------------------------------- - - /** - * Puts a reference to this label in the bytecode of a method. If the bytecode offset of the label - * is known, the relative bytecode offset between the label and the instruction referencing it is - * computed and written directly. Otherwise, a null relative offset is written and a new forward - * reference is declared for this label. - * - * @param code the bytecode of the method. This is where the reference is appended. - * @param sourceInsnBytecodeOffset the bytecode offset of the instruction that contains the - * reference to be appended. - * @param wideReference whether the reference must be stored in 4 bytes (instead of 2 bytes). - */ - final void put( - final ByteVector code, final int sourceInsnBytecodeOffset, final boolean wideReference) { - if ((flags & FLAG_RESOLVED) == 0) { - if (wideReference) { - addForwardReference(sourceInsnBytecodeOffset, FORWARD_REFERENCE_TYPE_WIDE, code.length); - code.putInt(-1); - } else { - addForwardReference(sourceInsnBytecodeOffset, FORWARD_REFERENCE_TYPE_SHORT, code.length); - code.putShort(-1); - } - } else { - if (wideReference) { - code.putInt(bytecodeOffset - sourceInsnBytecodeOffset); - } else { - code.putShort(bytecodeOffset - sourceInsnBytecodeOffset); - } - } - } - - /** - * Adds a forward reference to this label. This method must be called only for a true forward - * reference, i.e. only if this label is not resolved yet. For backward references, the relative - * bytecode offset of the reference can be, and must be, computed and stored directly. - * - * @param sourceInsnBytecodeOffset the bytecode offset of the instruction that contains the - * reference stored at referenceHandle. - * @param referenceType either {@link #FORWARD_REFERENCE_TYPE_SHORT} or {@link - * #FORWARD_REFERENCE_TYPE_WIDE}. - * @param referenceHandle the offset in the bytecode where the forward reference value must be - * stored. - */ - private void addForwardReference( - final int sourceInsnBytecodeOffset, final int referenceType, final int referenceHandle) { - if (forwardReferences == null) { - forwardReferences = new int[FORWARD_REFERENCES_CAPACITY_INCREMENT]; - } - int lastElementIndex = forwardReferences[0]; - if (lastElementIndex + 2 >= forwardReferences.length) { - int[] newValues = new int[forwardReferences.length + FORWARD_REFERENCES_CAPACITY_INCREMENT]; - System.arraycopy(forwardReferences, 0, newValues, 0, forwardReferences.length); - forwardReferences = newValues; - } - forwardReferences[++lastElementIndex] = sourceInsnBytecodeOffset; - forwardReferences[++lastElementIndex] = referenceType | referenceHandle; - forwardReferences[0] = lastElementIndex; - } - - /** - * Sets the bytecode offset of this label to the given value and resolves the forward references - * to this label, if any. This method must be called when this label is added to the bytecode of - * the method, i.e. when its bytecode offset becomes known. This method fills in the blanks that - * where left in the bytecode by each forward reference previously added to this label. - * - * @param code the bytecode of the method. - * @param bytecodeOffset the bytecode offset of this label. - * @return true if a blank that was left for this label was too small to store the - * offset. In such a case the corresponding jump instruction is replaced with an equivalent - * ASM specific instruction using an unsigned two bytes offset. These ASM specific - * instructions are later replaced with standard bytecode instructions with wider offsets (4 - * bytes instead of 2), in ClassReader. - */ - final boolean resolve(final byte[] code, final int bytecodeOffset) { - this.flags |= FLAG_RESOLVED; - this.bytecodeOffset = bytecodeOffset; - if (forwardReferences == null) { - return false; - } - boolean hasAsmInstructions = false; - for (int i = forwardReferences[0]; i > 0; i -= 2) { - final int sourceInsnBytecodeOffset = forwardReferences[i - 1]; - final int reference = forwardReferences[i]; - final int relativeOffset = bytecodeOffset - sourceInsnBytecodeOffset; - int handle = reference & FORWARD_REFERENCE_HANDLE_MASK; - if ((reference & FORWARD_REFERENCE_TYPE_MASK) == FORWARD_REFERENCE_TYPE_SHORT) { - if (relativeOffset < Short.MIN_VALUE || relativeOffset > Short.MAX_VALUE) { - // Change the opcode of the jump instruction, in order to be able to find it later in - // ClassReader. These ASM specific opcodes are similar to jump instruction opcodes, except - // that the 2 bytes offset is unsigned (and can therefore represent values from 0 to - // 65535, which is sufficient since the size of a method is limited to 65535 bytes). - int opcode = code[sourceInsnBytecodeOffset] & 0xFF; - if (opcode < Opcodes.IFNULL) { - // Change IFEQ ... JSR to ASM_IFEQ ... ASM_JSR. - code[sourceInsnBytecodeOffset] = (byte) (opcode + Constants.ASM_OPCODE_DELTA); - } else { - // Change IFNULL and IFNONNULL to ASM_IFNULL and ASM_IFNONNULL. - code[sourceInsnBytecodeOffset] = (byte) (opcode + Constants.ASM_IFNULL_OPCODE_DELTA); - } - hasAsmInstructions = true; - } - code[handle++] = (byte) (relativeOffset >>> 8); - code[handle] = (byte) relativeOffset; - } else { - code[handle++] = (byte) (relativeOffset >>> 24); - code[handle++] = (byte) (relativeOffset >>> 16); - code[handle++] = (byte) (relativeOffset >>> 8); - code[handle] = (byte) relativeOffset; - } - } - return hasAsmInstructions; - } - - // ----------------------------------------------------------------------------------------------- - // Methods related to subroutines - // ----------------------------------------------------------------------------------------------- - - /** - * Finds the basic blocks that belong to the subroutine starting with the basic block - * corresponding to this label, and marks these blocks as belonging to this subroutine. This - * method follows the control flow graph to find all the blocks that are reachable from the - * current basic block WITHOUT following any jsr target. - * - *
Note: a precondition and postcondition of this method is that all labels must have a null - * {@link #nextListElement}. - * - * @param subroutineId the id of the subroutine starting with the basic block corresponding to - * this label. - */ - final void markSubroutine(final short subroutineId) { - // Data flow algorithm: put this basic block in a list of blocks to process (which are blocks - // belonging to subroutine subroutineId) and, while there are blocks to process, remove one from - // the list, mark it as belonging to the subroutine, and add its successor basic blocks in the - // control flow graph to the list of blocks to process (if not already done). - Label listOfBlocksToProcess = this; - listOfBlocksToProcess.nextListElement = EMPTY_LIST; - while (listOfBlocksToProcess != EMPTY_LIST) { - // Remove a basic block from the list of blocks to process. - Label basicBlock = listOfBlocksToProcess; - listOfBlocksToProcess = listOfBlocksToProcess.nextListElement; - basicBlock.nextListElement = null; - - // If it is not already marked as belonging to a subroutine, mark it as belonging to - // subroutineId and add its successors to the list of blocks to process (unless already done). - if (basicBlock.subroutineId == 0) { - basicBlock.subroutineId = subroutineId; - listOfBlocksToProcess = basicBlock.pushSuccessors(listOfBlocksToProcess); - } - } - } - - /** - * Finds the basic blocks that end a subroutine starting with the basic block corresponding to - * this label and, for each one of them, adds an outgoing edge to the basic block following the - * given subroutine call. In other words, completes the control flow graph by adding the edges - * corresponding to the return from this subroutine, when called from the given caller basic - * block. - * - *
Note: a precondition and postcondition of this method is that all labels must have a null
- * {@link #nextListElement}.
- *
- * @param subroutineCaller a basic block that ends with a jsr to the basic block corresponding to
- * this label. This label is supposed to correspond to the start of a subroutine.
- */
- final void addSubroutineRetSuccessors(final Label subroutineCaller) {
- // Data flow algorithm: put this basic block in a list blocks to process (which are blocks
- // belonging to a subroutine starting with this label) and, while there are blocks to process,
- // remove one from the list, put it in a list of blocks that have been processed, add a return
- // edge to the successor of subroutineCaller if applicable, and add its successor basic blocks
- // in the control flow graph to the list of blocks to process (if not already done).
- Label listOfProcessedBlocks = EMPTY_LIST;
- Label listOfBlocksToProcess = this;
- listOfBlocksToProcess.nextListElement = EMPTY_LIST;
- while (listOfBlocksToProcess != EMPTY_LIST) {
- // Move a basic block from the list of blocks to process to the list of processed blocks.
- Label basicBlock = listOfBlocksToProcess;
- listOfBlocksToProcess = basicBlock.nextListElement;
- basicBlock.nextListElement = listOfProcessedBlocks;
- listOfProcessedBlocks = basicBlock;
-
- // Add an edge from this block to the successor of the caller basic block, if this block is
- // the end of a subroutine and if this block and subroutineCaller do not belong to the same
- // subroutine.
- if ((basicBlock.flags & FLAG_SUBROUTINE_END) != 0
- && basicBlock.subroutineId != subroutineCaller.subroutineId) {
- basicBlock.outgoingEdges =
- new Edge(
- basicBlock.outputStackSize,
- // By construction, the first outgoing edge of a basic block that ends with a jsr
- // instruction leads to the jsr continuation block, i.e. where execution continues
- // when ret is called (see {@link #FLAG_SUBROUTINE_CALLER}).
- subroutineCaller.outgoingEdges.successor,
- basicBlock.outgoingEdges);
- }
- // Add its successors to the list of blocks to process. Note that {@link #pushSuccessors} does
- // not push basic blocks which are already in a list. Here this means either in the list of
- // blocks to process, or in the list of already processed blocks. This second list is
- // important to make sure we don't reprocess an already processed block.
- listOfBlocksToProcess = basicBlock.pushSuccessors(listOfBlocksToProcess);
- }
- // Reset the {@link #nextListElement} of all the basic blocks that have been processed to null,
- // so that this method can be called again with a different subroutine or subroutine caller.
- while (listOfProcessedBlocks != EMPTY_LIST) {
- Label newListOfProcessedBlocks = listOfProcessedBlocks.nextListElement;
- listOfProcessedBlocks.nextListElement = null;
- listOfProcessedBlocks = newListOfProcessedBlocks;
- }
- }
-
- /**
- * Adds the successors of this label in the method's control flow graph (except those
- * corresponding to a jsr target, and those already in a list of labels) to the given list of
- * blocks to process, and returns the new list.
- *
- * @param listOfLabelsToProcess a list of basic blocks to process, linked together with their
- * {@link #nextListElement} field.
- * @return the new list of blocks to process.
- */
- private Label pushSuccessors(final Label listOfLabelsToProcess) {
- Label newListOfLabelsToProcess = listOfLabelsToProcess;
- Edge outgoingEdge = outgoingEdges;
- while (outgoingEdge != null) {
- // By construction, the second outgoing edge of a basic block that ends with a jsr instruction
- // leads to the jsr target (see {@link #FLAG_SUBROUTINE_CALLER}).
- boolean isJsrTarget =
- (flags & Label.FLAG_SUBROUTINE_CALLER) != 0 && outgoingEdge == outgoingEdges.nextEdge;
- if (!isJsrTarget && outgoingEdge.successor.nextListElement == null) {
- // Add this successor to the list of blocks to process, if it does not already belong to a
- // list of labels.
- outgoingEdge.successor.nextListElement = newListOfLabelsToProcess;
- newListOfLabelsToProcess = outgoingEdge.successor;
- }
- outgoingEdge = outgoingEdge.nextEdge;
- }
- return newListOfLabelsToProcess;
- }
-
- // -----------------------------------------------------------------------------------------------
- // Overridden Object methods
- // -----------------------------------------------------------------------------------------------
-
- /**
- * Returns a string representation of this label.
- *
- * @return a string representation of this label.
- */
- @Override
- public String toString() {
- return "L" + System.identityHashCode(this);
- }
-}
diff --git a/scripts/cn1playground/common/src/main/java/bsh/org/objectweb/asm/MethodVisitor.java b/scripts/cn1playground/common/src/main/java/bsh/org/objectweb/asm/MethodVisitor.java
deleted file mode 100644
index e493afcbd0..0000000000
--- a/scripts/cn1playground/common/src/main/java/bsh/org/objectweb/asm/MethodVisitor.java
+++ /dev/null
@@ -1,609 +0,0 @@
-// ASM: a very small and fast Java bytecode manipulation framework
-// Copyright (c) 2000-2011 INRIA, France Telecom
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions
-// are met:
-// 1. Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// 2. Redistributions in binary form must reproduce the above copyright
-// notice, this list of conditions and the following disclaimer in the
-// documentation and/or other materials provided with the distribution.
-// 3. Neither the name of the copyright holders nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
-// THE POSSIBILITY OF SUCH DAMAGE.
-package bsh.org.objectweb.asm;
-
-/**
- * A visitor to visit a Java method. The methods of this class must be called in the following
- * order: ( visitParameter )* [ visitAnnotationDefault ] (
- * visitAnnotation | visitAnnotableParameterCount |
- * visitParameterAnnotation visitTypeAnnotation | visitAttribute )* [
- * visitCode ( visitFrame | visitXInsn | visitLabel |
- * visitInsnAnnotation | visitTryCatchBlock | visitTryCatchAnnotation |
- * visitLocalVariable | visitLocalVariableAnnotation | visitLineNumber )*
- * visitMaxs ] visitEnd. In addition, the visitXInsn and
- * visitLabel methods must be called in the sequential order of the bytecode instructions
- * of the visited code, visitInsnAnnotation must be called after the annotated
- * instruction, visitTryCatchBlock must be called before the labels passed as
- * arguments have been visited, visitTryCatchBlockAnnotation must be called after
- * the corresponding try catch block has been visited, and the visitLocalVariable,
- * visitLocalVariableAnnotation and visitLineNumber methods must be called
- * after the labels passed as arguments have been visited.
- *
- * @author Eric Bruneton
- */
-public abstract class MethodVisitor {
-
- private static final String REQUIRES_ASM5 = "This feature requires ASM5";
-
- /**
- * The ASM API version implemented by this visitor. The value of this field must be one of {@link
- * Opcodes#ASM4}, {@link Opcodes#ASM5}, {@link Opcodes#ASM6} or {@link Opcodes#ASM7_EXPERIMENTAL}.
- */
- protected final int api;
-
- /** The method visitor to which this visitor must delegate method calls. May be null. */
- protected MethodVisitor mv;
-
- /**
- * Constructs a new {@link MethodVisitor}.
- *
- * @param api the ASM API version implemented by this visitor. Must be one of {@link
- * Opcodes#ASM4}, {@link Opcodes#ASM5}, {@link Opcodes#ASM6} or {@link
- * Opcodes#ASM7_EXPERIMENTAL}.
- */
- public MethodVisitor(final int api) {
- this(api, null);
- }
-
- /**
- * Constructs a new {@link MethodVisitor}.
- *
- * @param api the ASM API version implemented by this visitor. Must be one of {@link
- * Opcodes#ASM4}, {@link Opcodes#ASM5}, {@link Opcodes#ASM6} or {@link
- * Opcodes#ASM7_EXPERIMENTAL}.
- * @param methodVisitor the method visitor to which this visitor must delegate method calls. May
- * be null.
- */
- public MethodVisitor(final int api, final MethodVisitor methodVisitor) {
- if (api != Opcodes.ASM6
- && api != Opcodes.ASM5
- && api != Opcodes.ASM4) {
- throw new IllegalArgumentException();
- }
- this.api = api;
- this.mv = methodVisitor;
- }
-
- // -----------------------------------------------------------------------------------------------
- // Parameters, annotations and non standard attributes
- // -----------------------------------------------------------------------------------------------
-
- /**
- * Visits a parameter of this method.
- *
- * @param name parameter name or null if none is provided.
- * @param access the parameter's access flags, only ACC_FINAL, ACC_SYNTHETIC
- * or/and ACC_MANDATED are allowed (see {@link Opcodes}).
- */
- public void visitParameter(final String name, final int access) {
- if (api < Opcodes.ASM5) {
- throw new UnsupportedOperationException(REQUIRES_ASM5);
- }
- if (mv != null) {
- mv.visitParameter(name, access);
- }
- }
-
- /**
- * Visits the number of method parameters that can have annotations. By default (i.e. when this
- * method is not called), all the method parameters defined by the method descriptor can have
- * annotations.
- *
- * @param parameterCount the number of method parameters than can have annotations. This number
- * must be less or equal than the number of parameter types in the method descriptor. It can
- * be strictly less when a method has synthetic parameters and when these parameters are
- * ignored when computing parameter indices for the purpose of parameter annotations (see
- * https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.7.18).
- * @param visible true to define the number of method parameters that can have
- * annotations visible at runtime, false to define the number of method parameters
- * that can have annotations invisible at runtime.
- */
- public void visitAnnotableParameterCount(final int parameterCount, final boolean visible) {
- if (mv != null) {
- mv.visitAnnotableParameterCount(parameterCount, visible);
- }
- }
-
- /**
- * Visits a non standard attribute of this method.
- *
- * @param attribute an attribute.
- */
- public void visitAttribute(final Attribute attribute) {
- if (mv != null) {
- mv.visitAttribute(attribute);
- }
- }
-
- /** Starts the visit of the method's code, if any (i.e. non abstract method). */
- public void visitCode() {
- if (mv != null) {
- mv.visitCode();
- }
- }
-
- /**
- * Visits the current state of the local variables and operand stack elements. This method must(*)
- * be called just before any instruction i that follows an unconditional branch
- * instruction such as GOTO or THROW, that is the target of a jump instruction, or that starts an
- * exception handler block. The visited types must describe the values of the local variables and
- * of the operand stack elements just before i is executed.
- *
- * (*) this is mandatory only for classes whose version is greater than or equal to {@link
- * Opcodes#V1_6}.
- *
- * The frames of a method must be given either in expanded form, or in compressed form (all frames
- * must use the same format, i.e. you must not mix expanded and compressed frames within a single
- * method):
- *
- *
nStack is 1 and
- * stack[0] contains value for the type of the stack item).
- *
- * nLocal is 1, 2 or 3 and local elements contains values
- * representing added types).
- * nLocals is 1, 2 or 3).
- *
- * if (cst instanceof Integer) {
- * // ...
- * } else if (cst instanceof Float) {
- * // ...
- * } else if (cst instanceof Long) {
- * // ...
- * } else if (cst instanceof Double) {
- * // ...
- * } else if (cst instanceof String) {
- * // ...
- * } else if (cst instanceof Type) {
- * int sort = ((Type) cst).getSort();
- * if (sort == Type.OBJECT) {
- * // ...
- * } else if (sort == Type.ARRAY) {
- * // ...
- * } else if (sort == Type.METHOD) {
- * // ...
- * } else {
- * // throw an exception
- * }
- * } else if (cst instanceof Handle) {
- * // ...
- * } else if (cst instanceof Condy) {
- * // ...
- * } else {
- * // throw an exception
- * }
- *
- *
- * @param value the constant to be loaded on the stack. This parameter must be a non null {@link
- * Integer}, a {@link Float}, a {@link Long}, a {@link Double}, a {@link String}, a {@link
- * Type} of OBJECT or ARRAY sort for .class constants, for classes whose version is
- * 49, a {@link Type} of METHOD sort for MethodType, a {@link Handle} for MethodHandle
- * constants, for classes whose version is 51 or a {@link ConstantDynamic} for a constant
- * dynamic for classes whose version is 55.
- */
- public void visitLdcInsn(final Object value) {
- if (api < Opcodes.ASM5
- && (value instanceof Handle
- || (value instanceof Type && ((Type) value).getSort() == Type.METHOD))) {
- throw new UnsupportedOperationException(REQUIRES_ASM5);
- }
- if (mv != null) {
- mv.visitLdcInsn(value);
- }
- }
-
- /**
- * Visits an IINC instruction.
- *
- * @param var index of the local variable to be incremented.
- * @param increment amount to increment the local variable by.
- */
- public void visitIincInsn(final int var, final int increment) {
- if (mv != null) {
- mv.visitIincInsn(var, increment);
- }
- }
-
- /**
- * Visits a TABLESWITCH instruction.
- *
- * @param min the minimum key value.
- * @param max the maximum key value.
- * @param dflt beginning of the default handler block.
- * @param labels beginnings of the handler blocks. labels[i] is the beginning of the
- * handler block for the min + i key.
- */
- public void visitTableSwitchInsn(
- final int min, final int max, final Label dflt, final Label... labels) {
- if (mv != null) {
- mv.visitTableSwitchInsn(min, max, dflt, labels);
- }
- }
-
- /**
- * Visits a LOOKUPSWITCH instruction.
- *
- * @param dflt beginning of the default handler block.
- * @param keys the values of the keys.
- * @param labels beginnings of the handler blocks. labels[i] is the beginning of the
- * handler block for the keys[i] key.
- */
- public void visitLookupSwitchInsn(final Label dflt, final int[] keys, final Label[] labels) {
- if (mv != null) {
- mv.visitLookupSwitchInsn(dflt, keys, labels);
- }
- }
-
- /**
- * Visits a MULTIANEWARRAY instruction.
- *
- * @param descriptor an array type descriptor (see {@link Type}).
- * @param numDimensions the number of dimensions of the array to allocate.
- */
- public void visitMultiANewArrayInsn(final String descriptor, final int numDimensions) {
- if (mv != null) {
- mv.visitMultiANewArrayInsn(descriptor, numDimensions);
- }
- }
-
- // -----------------------------------------------------------------------------------------------
- // Exceptions table entries, debug information, max stack and max locals
- // -----------------------------------------------------------------------------------------------
-
- /**
- * Visits a try catch block.
- *
- * @param start the beginning of the exception handler's scope (inclusive).
- * @param end the end of the exception handler's scope (exclusive).
- * @param handler the beginning of the exception handler's code.
- * @param type the internal name of the type of exceptions handled by the handler, or
- * null to catch any exceptions (for "finally" blocks).
- * @throws IllegalArgumentException if one of the labels has already been visited by this visitor
- * (by the {@link #visitLabel} method).
- */
- public void visitTryCatchBlock(
- final Label start, final Label end, final Label handler, final String type) {
- if (mv != null) {
- mv.visitTryCatchBlock(start, end, handler, type);
- }
- }
-
- /**
- * Visits a local variable declaration.
- *
- * @param name the name of a local variable.
- * @param descriptor the type descriptor of this local variable.
- * @param signature the type signature of this local variable. May be null if the local
- * variable type does not use generic types.
- * @param start the first instruction corresponding to the scope of this local variable
- * (inclusive).
- * @param end the last instruction corresponding to the scope of this local variable (exclusive).
- * @param index the local variable's index.
- * @throws IllegalArgumentException if one of the labels has not already been visited by this
- * visitor (by the {@link #visitLabel} method).
- */
- public void visitLocalVariable(
- final String name,
- final String descriptor,
- final String signature,
- final Label start,
- final Label end,
- final int index) {
- if (mv != null) {
- mv.visitLocalVariable(name, descriptor, signature, start, end, index);
- }
- }
-
- /**
- * Visits a line number declaration.
- *
- * @param line a line number. This number refers to the source file from which the class was
- * compiled.
- * @param start the first instruction corresponding to this line number.
- * @throws IllegalArgumentException if start has not already been visited by this visitor
- * (by the {@link #visitLabel} method).
- */
- public void visitLineNumber(final int line, final Label start) {
- if (mv != null) {
- mv.visitLineNumber(line, start);
- }
- }
-
- /**
- * Visits the maximum stack size and the maximum number of local variables of the method.
- *
- * @param maxStack maximum stack size of the method.
- * @param maxLocals maximum number of local variables for the method.
- */
- public void visitMaxs(final int maxStack, final int maxLocals) {
- if (mv != null) {
- mv.visitMaxs(maxStack, maxLocals);
- }
- }
-
- /**
- * Visits the end of the method. This method, which is the last one to be called, is used to
- * inform the visitor that all the annotations and attributes of the method have been visited.
- */
- public void visitEnd() {
- if (mv != null) {
- mv.visitEnd();
- }
- }
-}
diff --git a/scripts/cn1playground/common/src/main/java/bsh/org/objectweb/asm/MethodWriter.java b/scripts/cn1playground/common/src/main/java/bsh/org/objectweb/asm/MethodWriter.java
deleted file mode 100644
index e7afa93e87..0000000000
--- a/scripts/cn1playground/common/src/main/java/bsh/org/objectweb/asm/MethodWriter.java
+++ /dev/null
@@ -1,2068 +0,0 @@
-// ASM: a very small and fast Java bytecode manipulation framework
-// Copyright (c) 2000-2011 INRIA, France Telecom
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions
-// are met:
-// 1. Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// 2. Redistributions in binary form must reproduce the above copyright
-// notice, this list of conditions and the following disclaimer in the
-// documentation and/or other materials provided with the distribution.
-// 3. Neither the name of the copyright holders nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
-// THE POSSIBILITY OF SUCH DAMAGE.
-package bsh.org.objectweb.asm;
-
-/**
- * A {@link MethodVisitor} that generates a corresponding 'method_info' structure, as defined in the
- * Java Virtual Machine Specification (JVMS).
- *
- * @see JVMS
- * 4.6
- * @author Eric Bruneton
- * @author Eugene Kuleshov
- */
-final class MethodWriter extends MethodVisitor {
-
- /** Indicates that nothing must be computed. */
- static final int COMPUTE_NOTHING = 0;
-
- /**
- * Indicates that the maximum stack size and the maximum number of local variables must be
- * computed, from scratch.
- */
- static final int COMPUTE_MAX_STACK_AND_LOCAL = 1;
-
- /**
- * Indicates that the maximum stack size and the maximum number of local variables must be
- * computed, from the existing stack map frames. This can be done more efficiently than with the
- * control flow graph algorithm used for {@link #COMPUTE_MAX_STACK_AND_LOCAL}, by using a linear
- * scan of the bytecode instructions.
- */
- static final int COMPUTE_MAX_STACK_AND_LOCAL_FROM_FRAMES = 2;
-
- /**
- * Indicates that the stack map frames of type F_INSERT must be computed. The other frames are not
- * computed. They should all be of type F_NEW and should be sufficient to compute the content of
- * the F_INSERT frames, together with the bytecode instructions between a F_NEW and a F_INSERT
- * frame - and without any knowledge of the type hierarchy (by definition of F_INSERT).
- */
- static final int COMPUTE_INSERTED_FRAMES = 3;
-
- /**
- * Indicates that all the stack map frames must be computed. In this case the maximum stack size
- * and the maximum number of local variables is also computed.
- */
- static final int COMPUTE_ALL_FRAMES = 4;
-
- /** Indicates that {@link #STACK_SIZE_DELTA} is not applicable (not constant or never used). */
- private static final int NA = 0;
-
- /**
- * The stack size variation corresponding to each JVM opcode. The stack size variation for opcode
- * 'o' is given by the array element at index 'o'.
- *
- * @see JVMS 6
- */
- private static final int[] STACK_SIZE_DELTA = {
- 0, // nop = 0 (0x0)
- 1, // aconst_null = 1 (0x1)
- 1, // iconst_m1 = 2 (0x2)
- 1, // iconst_0 = 3 (0x3)
- 1, // iconst_1 = 4 (0x4)
- 1, // iconst_2 = 5 (0x5)
- 1, // iconst_3 = 6 (0x6)
- 1, // iconst_4 = 7 (0x7)
- 1, // iconst_5 = 8 (0x8)
- 2, // lconst_0 = 9 (0x9)
- 2, // lconst_1 = 10 (0xa)
- 1, // fconst_0 = 11 (0xb)
- 1, // fconst_1 = 12 (0xc)
- 1, // fconst_2 = 13 (0xd)
- 2, // dconst_0 = 14 (0xe)
- 2, // dconst_1 = 15 (0xf)
- 1, // bipush = 16 (0x10)
- 1, // sipush = 17 (0x11)
- 1, // ldc = 18 (0x12)
- NA, // ldc_w = 19 (0x13)
- NA, // ldc2_w = 20 (0x14)
- 1, // iload = 21 (0x15)
- 2, // lload = 22 (0x16)
- 1, // fload = 23 (0x17)
- 2, // dload = 24 (0x18)
- 1, // aload = 25 (0x19)
- NA, // iload_0 = 26 (0x1a)
- NA, // iload_1 = 27 (0x1b)
- NA, // iload_2 = 28 (0x1c)
- NA, // iload_3 = 29 (0x1d)
- NA, // lload_0 = 30 (0x1e)
- NA, // lload_1 = 31 (0x1f)
- NA, // lload_2 = 32 (0x20)
- NA, // lload_3 = 33 (0x21)
- NA, // fload_0 = 34 (0x22)
- NA, // fload_1 = 35 (0x23)
- NA, // fload_2 = 36 (0x24)
- NA, // fload_3 = 37 (0x25)
- NA, // dload_0 = 38 (0x26)
- NA, // dload_1 = 39 (0x27)
- NA, // dload_2 = 40 (0x28)
- NA, // dload_3 = 41 (0x29)
- NA, // aload_0 = 42 (0x2a)
- NA, // aload_1 = 43 (0x2b)
- NA, // aload_2 = 44 (0x2c)
- NA, // aload_3 = 45 (0x2d)
- -1, // iaload = 46 (0x2e)
- 0, // laload = 47 (0x2f)
- -1, // faload = 48 (0x30)
- 0, // daload = 49 (0x31)
- -1, // aaload = 50 (0x32)
- -1, // baload = 51 (0x33)
- -1, // caload = 52 (0x34)
- -1, // saload = 53 (0x35)
- -1, // istore = 54 (0x36)
- -2, // lstore = 55 (0x37)
- -1, // fstore = 56 (0x38)
- -2, // dstore = 57 (0x39)
- -1, // astore = 58 (0x3a)
- NA, // istore_0 = 59 (0x3b)
- NA, // istore_1 = 60 (0x3c)
- NA, // istore_2 = 61 (0x3d)
- NA, // istore_3 = 62 (0x3e)
- NA, // lstore_0 = 63 (0x3f)
- NA, // lstore_1 = 64 (0x40)
- NA, // lstore_2 = 65 (0x41)
- NA, // lstore_3 = 66 (0x42)
- NA, // fstore_0 = 67 (0x43)
- NA, // fstore_1 = 68 (0x44)
- NA, // fstore_2 = 69 (0x45)
- NA, // fstore_3 = 70 (0x46)
- NA, // dstore_0 = 71 (0x47)
- NA, // dstore_1 = 72 (0x48)
- NA, // dstore_2 = 73 (0x49)
- NA, // dstore_3 = 74 (0x4a)
- NA, // astore_0 = 75 (0x4b)
- NA, // astore_1 = 76 (0x4c)
- NA, // astore_2 = 77 (0x4d)
- NA, // astore_3 = 78 (0x4e)
- -3, // iastore = 79 (0x4f)
- -4, // lastore = 80 (0x50)
- -3, // fastore = 81 (0x51)
- -4, // dastore = 82 (0x52)
- -3, // aastore = 83 (0x53)
- -3, // bastore = 84 (0x54)
- -3, // castore = 85 (0x55)
- -3, // sastore = 86 (0x56)
- -1, // pop = 87 (0x57)
- -2, // pop2 = 88 (0x58)
- 1, // dup = 89 (0x59)
- 1, // dup_x1 = 90 (0x5a)
- 1, // dup_x2 = 91 (0x5b)
- 2, // dup2 = 92 (0x5c)
- 2, // dup2_x1 = 93 (0x5d)
- 2, // dup2_x2 = 94 (0x5e)
- 0, // swap = 95 (0x5f)
- -1, // iadd = 96 (0x60)
- -2, // ladd = 97 (0x61)
- -1, // fadd = 98 (0x62)
- -2, // dadd = 99 (0x63)
- -1, // isub = 100 (0x64)
- -2, // lsub = 101 (0x65)
- -1, // fsub = 102 (0x66)
- -2, // dsub = 103 (0x67)
- -1, // imul = 104 (0x68)
- -2, // lmul = 105 (0x69)
- -1, // fmul = 106 (0x6a)
- -2, // dmul = 107 (0x6b)
- -1, // idiv = 108 (0x6c)
- -2, // ldiv = 109 (0x6d)
- -1, // fdiv = 110 (0x6e)
- -2, // ddiv = 111 (0x6f)
- -1, // irem = 112 (0x70)
- -2, // lrem = 113 (0x71)
- -1, // frem = 114 (0x72)
- -2, // drem = 115 (0x73)
- 0, // ineg = 116 (0x74)
- 0, // lneg = 117 (0x75)
- 0, // fneg = 118 (0x76)
- 0, // dneg = 119 (0x77)
- -1, // ishl = 120 (0x78)
- -1, // lshl = 121 (0x79)
- -1, // ishr = 122 (0x7a)
- -1, // lshr = 123 (0x7b)
- -1, // iushr = 124 (0x7c)
- -1, // lushr = 125 (0x7d)
- -1, // iand = 126 (0x7e)
- -2, // land = 127 (0x7f)
- -1, // ior = 128 (0x80)
- -2, // lor = 129 (0x81)
- -1, // ixor = 130 (0x82)
- -2, // lxor = 131 (0x83)
- 0, // iinc = 132 (0x84)
- 1, // i2l = 133 (0x85)
- 0, // i2f = 134 (0x86)
- 1, // i2d = 135 (0x87)
- -1, // l2i = 136 (0x88)
- -1, // l2f = 137 (0x89)
- 0, // l2d = 138 (0x8a)
- 0, // f2i = 139 (0x8b)
- 1, // f2l = 140 (0x8c)
- 1, // f2d = 141 (0x8d)
- -1, // d2i = 142 (0x8e)
- 0, // d2l = 143 (0x8f)
- -1, // d2f = 144 (0x90)
- 0, // i2b = 145 (0x91)
- 0, // i2c = 146 (0x92)
- 0, // i2s = 147 (0x93)
- -3, // lcmp = 148 (0x94)
- -1, // fcmpl = 149 (0x95)
- -1, // fcmpg = 150 (0x96)
- -3, // dcmpl = 151 (0x97)
- -3, // dcmpg = 152 (0x98)
- -1, // ifeq = 153 (0x99)
- -1, // ifne = 154 (0x9a)
- -1, // iflt = 155 (0x9b)
- -1, // ifge = 156 (0x9c)
- -1, // ifgt = 157 (0x9d)
- -1, // ifle = 158 (0x9e)
- -2, // if_icmpeq = 159 (0x9f)
- -2, // if_icmpne = 160 (0xa0)
- -2, // if_icmplt = 161 (0xa1)
- -2, // if_icmpge = 162 (0xa2)
- -2, // if_icmpgt = 163 (0xa3)
- -2, // if_icmple = 164 (0xa4)
- -2, // if_acmpeq = 165 (0xa5)
- -2, // if_acmpne = 166 (0xa6)
- 0, // goto = 167 (0xa7)
- 1, // jsr = 168 (0xa8)
- 0, // ret = 169 (0xa9)
- -1, // tableswitch = 170 (0xaa)
- -1, // lookupswitch = 171 (0xab)
- -1, // ireturn = 172 (0xac)
- -2, // lreturn = 173 (0xad)
- -1, // freturn = 174 (0xae)
- -2, // dreturn = 175 (0xaf)
- -1, // areturn = 176 (0xb0)
- 0, // return = 177 (0xb1)
- NA, // getstatic = 178 (0xb2)
- NA, // putstatic = 179 (0xb3)
- NA, // getfield = 180 (0xb4)
- NA, // putfield = 181 (0xb5)
- NA, // invokevirtual = 182 (0xb6)
- NA, // invokespecial = 183 (0xb7)
- NA, // invokestatic = 184 (0xb8)
- NA, // invokeinterface = 185 (0xb9)
- NA, // invokedynamic = 186 (0xba)
- 1, // new = 187 (0xbb)
- 0, // newarray = 188 (0xbc)
- 0, // anewarray = 189 (0xbd)
- 0, // arraylength = 190 (0xbe)
- NA, // athrow = 191 (0xbf)
- 0, // checkcast = 192 (0xc0)
- 0, // instanceof = 193 (0xc1)
- -1, // monitorenter = 194 (0xc2)
- -1, // monitorexit = 195 (0xc3)
- NA, // wide = 196 (0xc4)
- NA, // multianewarray = 197 (0xc5)
- -1, // ifnull = 198 (0xc6)
- -1, // ifnonnull = 199 (0xc7)
- NA, // goto_w = 200 (0xc8)
- NA // jsr_w = 201 (0xc9)
- };
-
- /** Where the constants used in this MethodWriter must be stored. */
- private final SymbolTable symbolTable;
-
- // Note: fields are ordered as in the method_info structure, and those related to attributes are
- // ordered as in Section 4.7 of the JVMS.
-
- /**
- * The access_flags field of the method_info JVMS structure. This field can contain ASM specific
- * access flags, such as {@link Opcodes#ACC_DEPRECATED}, which are removed when generating the
- * ClassFile structure.
- */
- private final int accessFlags;
-
- /** The name_index field of the method_info JVMS structure. */
- private final int nameIndex;
-
- /** The descriptor_index field of the method_info JVMS structure. */
- private final int descriptorIndex;
-
- /** The descriptor of this method. */
- private final String descriptor;
-
- // Code attribute fields and sub attributes:
-
- /** The max_stack field of the Code attribute. */
- private int maxStack;
-
- /** The max_locals field of the Code attribute. */
- private int maxLocals;
-
- /** The 'code' field of the Code attribute. */
- private final ByteVector code = new ByteVector();
-
- /**
- * The first element in the exception handler list (used to generate the exception_table of the
- * Code attribute). The next ones can be accessed with the {@link Handler#nextHandler} field. May
- * be null.
- */
- private Handler firstHandler;
-
- /**
- * The last element in the exception handler list (used to generate the exception_table of the
- * Code attribute). The next ones can be accessed with the {@link Handler#nextHandler} field. May
- * be null.
- */
- private Handler lastHandler;
-
- /** The line_number_table_length field of the LineNumberTable code attribute. */
- private int lineNumberTableLength;
-
- /** The line_number_table array of the LineNumberTable code attribute, or null. */
- private ByteVector lineNumberTable;
-
- /** The local_variable_table_length field of the LocalVariableTable code attribute. */
- private int localVariableTableLength;
-
- /** The local_variable_table array of the LocalVariableTable code attribute, or null. */
- private ByteVector localVariableTable;
-
- /** The local_variable_type_table_length field of the LocalVariableTypeTable code attribute. */
- private int localVariableTypeTableLength;
-
- /**
- * The local_variable_type_table array of the LocalVariableTypeTable code attribute, or
- * null.
- */
- private ByteVector localVariableTypeTable;
-
- /** The number_of_entries field of the StackMapTable code attribute. */
- private int stackMapTableNumberOfEntries;
-
- /** The 'entries' array of the StackMapTable code attribute. */
- private ByteVector stackMapTableEntries;
-
- /**
- * The first non standard attribute of the Code attribute. The next ones can be accessed with the
- * {@link Attribute#nextAttribute} field. May be null.
- *
- * WARNING: this list stores the attributes in the reverse order of their visit. - * firstAttribute is actually the last attribute visited in {@link #visitAttribute}. The {@link - * #putMethodInfo} method writes the attributes in the order defined by this list, i.e. in the - * reverse order specified by the user. - */ - private Attribute firstCodeAttribute; - - // Other method_info attributes: - - /** The number_of_exceptions field of the Exceptions attribute. */ - private final int numberOfExceptions; - - /** The exception_index_table array of the Exceptions attribute, or null. */ - private final int[] exceptionIndexTable; - - /** The signature_index field of the Signature attribute. */ - private final int signatureIndex; - - /** The default_value field of the AnnotationDefault attribute, or null. */ - private ByteVector defaultValue; - - /** The parameters_count field of the MethodParameters attribute. */ - private int parametersCount; - - /** The 'parameters' array of the MethodParameters attribute, or null. */ - private ByteVector parameters; - - /** - * The first non standard attribute of this method. The next ones can be accessed with the {@link - * Attribute#nextAttribute} field. May be null. - * - *
WARNING: this list stores the attributes in the reverse order of their visit.
- * firstAttribute is actually the last attribute visited in {@link #visitAttribute}. The {@link
- * #putMethodInfo} method writes the attributes in the order defined by this list, i.e. in the
- * reverse order specified by the user.
- */
- private Attribute firstAttribute;
-
- // -----------------------------------------------------------------------------------------------
- // Fields used to compute the maximum stack size and number of locals, and the stack map frames
- // -----------------------------------------------------------------------------------------------
-
- /**
- * Indicates what must be computed. Must be one of {@link #COMPUTE_ALL_FRAMES}, {@link
- * #COMPUTE_INSERTED_FRAMES}, {@link #COMPUTE_MAX_STACK_AND_LOCAL} or {@link #COMPUTE_NOTHING}.
- */
- private final int compute;
-
- /**
- * The first basic block of the method. The next ones (in bytecode offset order) can be accessed
- * with the {@link Label#nextBasicBlock} field.
- */
- private Label firstBasicBlock;
-
- /**
- * The last basic block of the method (in bytecode offset order). This field is updated each time
- * a basic block is encountered, and is used to append it at the end of the basic block list.
- */
- private Label lastBasicBlock;
-
- /**
- * The current basic block, i.e. the basic block of the last visited instruction. When {@link
- * #compute} is equal to {@link #COMPUTE_MAX_STACK_AND_LOCAL} or {@link #COMPUTE_ALL_FRAMES}, this
- * field is null for unreachable code. When {@link #compute} is equal to {@link
- * #COMPUTE_MAX_STACK_AND_LOCAL_FROM_FRAMES} or {@link #COMPUTE_INSERTED_FRAMES}, this field stays
- * unchanged throughout the whole method (i.e. the whole code is seen as a single basic block;
- * indeed, the existing frames are sufficient by hypothesis to compute any intermediate frame -
- * and the maximum stack size as well - without using any control flow graph).
- */
- private Label currentBasicBlock;
-
- /**
- * The relative stack size after the last visited instruction. This size is relative to the
- * beginning of {@link #currentBasicBlock}, i.e. the true stack size after the last visited
- * instruction is equal to the {@link Label#inputStackSize} of the current basic block plus {@link
- * #relativeStackSize}. When {@link #compute} is equal to {@link
- * #COMPUTE_MAX_STACK_AND_LOCAL_FROM_FRAMES}, {@link #currentBasicBlock} is always the start of
- * the method, so this relative size is also equal to the absolute stack size after the last
- * visited instruction.
- */
- private int relativeStackSize;
-
- /**
- * The maximum relative stack size after the last visited instruction. This size is relative to
- * the beginning of {@link #currentBasicBlock}, i.e. the true maximum stack size after the last
- * visited instruction is equal to the {@link Label#inputStackSize} of the current basic block
- * plus {@link #maxRelativeStackSize}.When {@link #compute} is equal to {@link
- * #COMPUTE_MAX_STACK_AND_LOCAL_FROM_FRAMES}, {@link #currentBasicBlock} is always the start of
- * the method, so this relative size is also equal to the absolute maximum stack size after the
- * last visited instruction.
- */
- private int maxRelativeStackSize;
-
- /** The number of local variables in the last visited stack map frame. */
- private int currentLocals;
-
- /** The bytecode offset of the last frame that was written in {@link #stackMapTableEntries}. */
- private int previousFrameOffset;
-
- /**
- * The last frame that was written in {@link #stackMapTableEntries}. This field has the same
- * format as {@link #currentFrame}.
- */
- private int[] previousFrame;
-
- /**
- * The current stack map frame. The first element contains the bytecode offset of the instruction
- * to which the frame corresponds, the second element is the number of locals and the third one is
- * the number of stack elements. The local variables start at index 3 and are followed by the
- * operand stack elements. In summary frame[0] = offset, frame[1] = nLocal, frame[2] = nStack,
- * frame[3] = nLocal. Local variables and operand stack entries contain abstract types, as defined
- * in {@link Frame}, but restricted to {@link Frame#CONSTANT_KIND}, {@link Frame#REFERENCE_KIND}
- * or {@link Frame#UNINITIALIZED_KIND} abstract types. Long and double types use only one array
- * entry.
- */
- private int[] currentFrame;
-
- /** Whether this method contains subroutines. */
- private boolean hasSubroutines;
-
- // -----------------------------------------------------------------------------------------------
- // Other miscellaneous status fields
- // -----------------------------------------------------------------------------------------------
-
- /** Whether the bytecode of this method contains ASM specific instructions. */
- private boolean hasAsmInstructions;
-
- /**
- * The start offset of the last visited instruction. Used to set the offset field of type
- * annotations of type 'offset_target' (see JVMS
- * 4.7.20.1).
- */
- private int lastBytecodeOffset;
-
- /**
- * The offset in bytes in {@link SymbolTable#getSource} from which the method_info for this method
- * (excluding its first 6 bytes) must be copied, or 0.
- */
- private int sourceOffset;
-
- /**
- * The length in bytes in {@link SymbolTable#getSource} which must be copied to get the
- * method_info for this method (excluding its first 6 bytes for access_flags, name_index and
- * descriptor_index).
- */
- private int sourceLength;
-
- // -----------------------------------------------------------------------------------------------
- // Constructor and accessors
- // -----------------------------------------------------------------------------------------------
-
- /**
- * Constructs a new {@link MethodWriter}.
- *
- * @param symbolTable where the constants used in this AnnotationWriter must be stored.
- * @param access the method's access flags (see {@link Opcodes}).
- * @param name the method's name.
- * @param descriptor the method's descriptor (see {@link Type}).
- * @param signature the method's signature. May be null.
- * @param exceptions the internal names of the method's exceptions. May be null.
- * @param compute indicates what must be computed (see #compute).
- */
- MethodWriter(
- final SymbolTable symbolTable,
- final int access,
- final String name,
- final String descriptor,
- final String signature,
- final String[] exceptions,
- final int compute) {
- super(Opcodes.ASM6);
- this.symbolTable = symbolTable;
- this.accessFlags = " WARNING: this method must be called after the currently visited instruction has been put in
- * {@link #code} (if frames are computed, this method inserts a new Label to start a new basic
- * block after the current instruction).
- */
- private void endCurrentBasicBlockWithNoSuccessor() {
- if (compute == COMPUTE_ALL_FRAMES) {
- Label nextBasicBlock = new Label();
- nextBasicBlock.frame = new Frame(nextBasicBlock);
- nextBasicBlock.resolve(code.data, code.length);
- lastBasicBlock.nextBasicBlock = nextBasicBlock;
- lastBasicBlock = nextBasicBlock;
- currentBasicBlock = null;
- } else if (compute == COMPUTE_MAX_STACK_AND_LOCAL) {
- currentBasicBlock.outputStackMax = (short) maxRelativeStackSize;
- currentBasicBlock = null;
- }
- }
-
- // -----------------------------------------------------------------------------------------------
- // Utility methods: stack map frames
- // -----------------------------------------------------------------------------------------------
-
- /**
- * Starts the visit of a new stack map frame, stored in {@link #currentFrame}.
- *
- * @param offset the bytecode offset of the instruction to which the frame corresponds.
- * @param nLocal the number of local variables in the frame.
- * @param nStack the number of stack elements in the frame.
- * @return the index of the next element to be written in this frame.
- */
- int visitFrameStart(final int offset, final int nLocal, final int nStack) {
- int frameLength = 3 + nLocal + nStack;
- if (currentFrame == null || currentFrame.length < frameLength) {
- currentFrame = new int[frameLength];
- }
- currentFrame[0] = offset;
- currentFrame[1] = nLocal;
- currentFrame[2] = nStack;
- return 3;
- }
-
- /**
- * Sets an abstract type in {@link #currentFrame}.
- *
- * @param frameIndex the index of the element to be set in {@link #currentFrame}.
- * @param abstractType an abstract type.
- */
- void visitAbstractType(final int frameIndex, final int abstractType) {
- currentFrame[frameIndex] = abstractType;
- }
-
- /**
- * Ends the visit of {@link #currentFrame} by writing it in the StackMapTable entries and by
- * updating the StackMapTable number_of_entries (except if the current frame is the first one,
- * which is implicit in StackMapTable). Then resets {@link #currentFrame} to null.
- */
- void visitFrameEnd() {
- if (previousFrame != null) {
- if (stackMapTableEntries == null) {
- stackMapTableEntries = new ByteVector();
- }
- putFrame();
- ++stackMapTableNumberOfEntries;
- }
- previousFrame = currentFrame;
- currentFrame = null;
- }
-
- /** Compresses and writes {@link #currentFrame} in a new StackMapTable entry. */
- private void putFrame() {
- final int nLocal = currentFrame[1];
- final int nStack = currentFrame[2];
- if (symbolTable.getMajorVersion() < Opcodes.V1_6) {
- // Generate a StackMap attribute entry, which are always uncompressed.
- stackMapTableEntries.putShort(currentFrame[0]).putShort(nLocal);
- putAbstractTypes(3, 3 + nLocal);
- stackMapTableEntries.putShort(nStack);
- putAbstractTypes(3 + nLocal, 3 + nLocal + nStack);
- return;
- }
- final int offsetDelta =
- stackMapTableNumberOfEntries == 0
- ? currentFrame[0]
- : currentFrame[0] - previousFrame[0] - 1;
- final int previousNlocal = previousFrame[1];
- final int nLocalDelta = nLocal - previousNlocal;
- int type = Frame.FULL_FRAME;
- if (nStack == 0) {
- switch (nLocalDelta) {
- case -3:
- case -2:
- case -1:
- type = Frame.CHOP_FRAME;
- break;
- case 0:
- type = offsetDelta < 64 ? Frame.SAME_FRAME : Frame.SAME_FRAME_EXTENDED;
- break;
- case 1:
- case 2:
- case 3:
- type = Frame.APPEND_FRAME;
- break;
- default:
- // Keep the FULL_FRAME type.
- break;
- }
- } else if (nLocalDelta == 0 && nStack == 1) {
- type =
- offsetDelta < 63
- ? Frame.SAME_LOCALS_1_STACK_ITEM_FRAME
- : Frame.SAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED;
- }
- if (type != Frame.FULL_FRAME) {
- // Verify if locals are the same as in the previous frame.
- int frameIndex = 3;
- for (int i = 0; i < previousNlocal && i < nLocal; i++) {
- if (currentFrame[frameIndex] != previousFrame[frameIndex]) {
- type = Frame.FULL_FRAME;
- break;
- }
- frameIndex++;
- }
- }
- switch (type) {
- case Frame.SAME_FRAME:
- stackMapTableEntries.putByte(offsetDelta);
- break;
- case Frame.SAME_LOCALS_1_STACK_ITEM_FRAME:
- stackMapTableEntries.putByte(Frame.SAME_LOCALS_1_STACK_ITEM_FRAME + offsetDelta);
- putAbstractTypes(3 + nLocal, 4 + nLocal);
- break;
- case Frame.SAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED:
- stackMapTableEntries
- .putByte(Frame.SAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED)
- .putShort(offsetDelta);
- putAbstractTypes(3 + nLocal, 4 + nLocal);
- break;
- case Frame.SAME_FRAME_EXTENDED:
- stackMapTableEntries.putByte(Frame.SAME_FRAME_EXTENDED).putShort(offsetDelta);
- break;
- case Frame.CHOP_FRAME:
- stackMapTableEntries.putByte(Frame.SAME_FRAME_EXTENDED + nLocalDelta).putShort(offsetDelta);
- break;
- case Frame.APPEND_FRAME:
- stackMapTableEntries.putByte(Frame.SAME_FRAME_EXTENDED + nLocalDelta).putShort(offsetDelta);
- putAbstractTypes(3 + previousNlocal, 3 + nLocal);
- break;
- case Frame.FULL_FRAME:
- default:
- stackMapTableEntries.putByte(Frame.FULL_FRAME).putShort(offsetDelta).putShort(nLocal);
- putAbstractTypes(3, 3 + nLocal);
- stackMapTableEntries.putShort(nStack);
- putAbstractTypes(3 + nLocal, 3 + nLocal + nStack);
- }
- }
-
- /**
- * Puts some abstract types of {@link #currentFrame} in {@link #stackMapTableEntries} , using the
- * JVMS verification_type_info format used in StackMapTable attributes.
- *
- * @param start index of the first type in {@link #currentFrame} to write.
- * @param end index of last type in {@link #currentFrame} to write (exclusive).
- */
- private void putAbstractTypes(final int start, final int end) {
- for (int i = start; i < end; ++i) {
- Frame.putAbstractType(symbolTable, currentFrame[i], stackMapTableEntries);
- }
- }
-
- /**
- * Puts the given public API frame element type in {@link #stackMapTableEntries} , using the JVMS
- * verification_type_info format used in StackMapTable attributes.
- *
- * @param type a frame element type described using the same format as in {@link
- * MethodVisitor#visitFrame}, i.e. either {@link Opcodes#TOP}, {@link Opcodes#INTEGER}, {@link
- * Opcodes#FLOAT}, {@link Opcodes#LONG}, {@link Opcodes#DOUBLE}, {@link Opcodes#NULL}, or
- * {@link Opcodes#UNINITIALIZED_THIS}, or the internal name of a class, or a Label designating
- * a NEW instruction (for uninitialized types).
- */
- private void putFrameType(final Object type) {
- if (type instanceof Integer) {
- stackMapTableEntries.putByte(((Integer) type).intValue());
- } else if (type instanceof String) {
- stackMapTableEntries
- .putByte(Frame.ITEM_OBJECT)
- .putShort(symbolTable.addConstantClass((String) type).index);
- } else {
- stackMapTableEntries
- .putByte(Frame.ITEM_UNINITIALIZED)
- .putShort(((Label) type).bytecodeOffset);
- }
- }
-
- // -----------------------------------------------------------------------------------------------
- // Utility methods
- // -----------------------------------------------------------------------------------------------
-
- /**
- * Returns whether the attributes of this method can be copied from the attributes of the given
- * method (assuming there is no method visitor between the given ClassReader and this
- * MethodWriter). This method should only be called just after this MethodWriter has been created,
- * and before any content is visited. It returns true if the attributes corresponding to the
- * constructor arguments (at most a Signature, an Exception, a Deprecated and a Synthetic
- * attribute) are the same as the corresponding attributes in the given method.
- *
- * @param source the source ClassReader from which the attributes of this method might be copied.
- * @param methodInfoOffset the offset in 'source.b' of the method_info JVMS structure from which
- * the attributes of this method might be copied.
- * @param methodInfoLength the length in 'source.b' of the method_info JVMS structure from which
- * the attributes of this method might be copied.
- * @param hasSyntheticAttribute whether the method_info JVMS structure from which the attributes
- * of this method might be copied contains a Synthetic attribute.
- * @param hasDeprecatedAttribute whether the method_info JVMS structure from which the attributes
- * of this method might be copied contains a Deprecated attribute.
- * @param signatureIndex the constant pool index contained in the Signature attribute of the
- * method_info JVMS structure from which the attributes of this method might be copied, or 0.
- * @param exceptionsOffset the offset in 'source.b' of the Exceptions attribute of the method_info
- * JVMS structure from which the attributes of this method might be copied, or 0.
- * @return whether the attributes of this method can be copied from the attributes of the
- * method_info JVMS structure in 'source.b', between 'methodInfoOffset' and 'methodInfoOffset'
- * + 'methodInfoLength'.
- */
- boolean canCopyMethodAttributes(
- final int methodInfoOffset,
- final int methodInfoLength,
- final boolean hasSyntheticAttribute,
- final boolean hasDeprecatedAttribute,
- final int signatureIndex,
- final int exceptionsOffset) {
- boolean needSyntheticAttribute =
- symbolTable.getMajorVersion() < Opcodes.V1_5 && (accessFlags & Opcodes.ACC_SYNTHETIC) != 0;
- if (hasSyntheticAttribute != needSyntheticAttribute) {
- return false;
- }
- if (exceptionsOffset == 0) {
- if (numberOfExceptions != 0) {
- return false;
- }
- }
- // Don't copy the attributes yet, instead store their location in the source class reader so
- // they can be copied later, in {@link #putMethodInfo}. Note that we skip the 6 header bytes
- // of the method_info JVMS structure.
- this.sourceOffset = methodInfoOffset + 6;
- this.sourceLength = methodInfoLength - 6;
- return true;
- }
-
- /**
- * Returns the size of the method_info JVMS structure generated by this MethodWriter. Also add the
- * names of the attributes of this method in the constant pool.
- *
- * @return the size in bytes of the method_info JVMS structure.
- */
- int computeMethodInfoSize() {
- // If this method_info must be copied from an existing one, the size computation is trivial.
- if (sourceOffset != 0) {
- // sourceLength excludes the first 6 bytes for access_flags, name_index and descriptor_index.
- return 6 + sourceLength;
- }
- // 2 bytes each for access_flags, name_index, descriptor_index and attributes_count.
- int size = 8;
- // For ease of reference, we use here the same attribute order as in Section 4.7 of the JVMS.
- if (code.length > 0) {
- if (code.length > 65535) {
- throw new IndexOutOfBoundsException("Method code too large!");
- }
- symbolTable.addConstantUtf8(Constants.CODE);
- // The Code attribute has 6 header bytes, plus 2, 2, 4 and 2 bytes respectively for max_stack,
- // max_locals, code_length and attributes_count, plus the bytecode and the exception table.
- size += 16 + code.length + Handler.getExceptionTableSize(firstHandler);
- if (stackMapTableEntries != null) {
- boolean useStackMapTable = symbolTable.getMajorVersion() >= Opcodes.V1_6;
- symbolTable.addConstantUtf8(useStackMapTable ? Constants.STACK_MAP_TABLE : "StackMap");
- // 6 header bytes and 2 bytes for number_of_entries.
- size += 8 + stackMapTableEntries.length;
- }
- if (lineNumberTable != null) {
- symbolTable.addConstantUtf8(Constants.LINE_NUMBER_TABLE);
- // 6 header bytes and 2 bytes for line_number_table_length.
- size += 8 + lineNumberTable.length;
- }
- if (localVariableTable != null) {
- symbolTable.addConstantUtf8(Constants.LOCAL_VARIABLE_TABLE);
- // 6 header bytes and 2 bytes for local_variable_table_length.
- size += 8 + localVariableTable.length;
- }
- if (localVariableTypeTable != null) {
- symbolTable.addConstantUtf8(Constants.LOCAL_VARIABLE_TYPE_TABLE);
- // 6 header bytes and 2 bytes for local_variable_type_table_length.
- size += 8 + localVariableTypeTable.length;
- }
- if (firstCodeAttribute != null) {
- size +=
- firstCodeAttribute.computeAttributesSize(
- symbolTable, code.data, code.length, maxStack, maxLocals);
- }
- }
- if (numberOfExceptions > 0) {
- symbolTable.addConstantUtf8(Constants.EXCEPTIONS);
- size += 8 + 2 * numberOfExceptions;
- }
- boolean useSyntheticAttribute = symbolTable.getMajorVersion() < Opcodes.V1_5;
- if ((accessFlags & Opcodes.ACC_SYNTHETIC) != 0 && useSyntheticAttribute) {
- symbolTable.addConstantUtf8(Constants.SYNTHETIC);
- size += 6;
- }
- if (signatureIndex != 0) {
- symbolTable.addConstantUtf8(Constants.SIGNATURE);
- size += 8;
- }
- if ((accessFlags & Opcodes.ACC_DEPRECATED) != 0) {
- symbolTable.addConstantUtf8(Constants.DEPRECATED);
- size += 6;
- }
- if (defaultValue != null) {
- symbolTable.addConstantUtf8(Constants.ANNOTATION_DEFAULT);
- size += 6 + defaultValue.length;
- }
- if (parameters != null) {
- symbolTable.addConstantUtf8(Constants.METHOD_PARAMETERS);
- // 6 header bytes and 1 byte for parameters_count.
- size += 7 + parameters.length;
- }
- if (firstAttribute != null) {
- size += firstAttribute.computeAttributesSize(symbolTable);
- }
- return size;
- }
-
- /**
- * Puts the content of the method_info JVMS structure generated by this MethodWriter into the
- * given ByteVector.
- *
- * @param output where the method_info structure must be put.
- */
- void putMethodInfo(final ByteVector output) {
- boolean useSyntheticAttribute = symbolTable.getMajorVersion() < Opcodes.V1_5;
- int mask = useSyntheticAttribute ? Opcodes.ACC_SYNTHETIC : 0;
- output.putShort(accessFlags & ~mask).putShort(nameIndex).putShort(descriptorIndex);
- // For ease of reference, we use here the same attribute order as in Section 4.7 of the JVMS.
- int attributeCount = 0;
- if (code.length > 0) {
- ++attributeCount;
- }
- if (numberOfExceptions > 0) {
- ++attributeCount;
- }
- if ((accessFlags & Opcodes.ACC_SYNTHETIC) != 0 && useSyntheticAttribute) {
- ++attributeCount;
- }
- if (signatureIndex != 0) {
- ++attributeCount;
- }
- if ((accessFlags & Opcodes.ACC_DEPRECATED) != 0) {
- ++attributeCount;
- }
- if (defaultValue != null) {
- ++attributeCount;
- }
- if (parameters != null) {
- ++attributeCount;
- }
- if (firstAttribute != null) {
- attributeCount += firstAttribute.getAttributeCount();
- }
- // For ease of reference, we use here the same attribute order as in Section 4.7 of the JVMS.
- output.putShort(attributeCount);
- if (code.length > 0) {
- // 2, 2, 4 and 2 bytes respectively for max_stack, max_locals, code_length and
- // attributes_count, plus the bytecode and the exception table.
- int size = 10 + code.length + Handler.getExceptionTableSize(firstHandler);
- int codeAttributeCount = 0;
- if (stackMapTableEntries != null) {
- // 6 header bytes and 2 bytes for number_of_entries.
- size += 8 + stackMapTableEntries.length;
- ++codeAttributeCount;
- }
- if (lineNumberTable != null) {
- // 6 header bytes and 2 bytes for line_number_table_length.
- size += 8 + lineNumberTable.length;
- ++codeAttributeCount;
- }
- if (localVariableTable != null) {
- // 6 header bytes and 2 bytes for local_variable_table_length.
- size += 8 + localVariableTable.length;
- ++codeAttributeCount;
- }
- if (localVariableTypeTable != null) {
- // 6 header bytes and 2 bytes for local_variable_type_table_length.
- size += 8 + localVariableTypeTable.length;
- ++codeAttributeCount;
- }
- if (firstCodeAttribute != null) {
- size +=
- firstCodeAttribute.computeAttributesSize(
- symbolTable, code.data, code.length, maxStack, maxLocals);
- codeAttributeCount += firstCodeAttribute.getAttributeCount();
- }
- output
- .putShort(symbolTable.addConstantUtf8(Constants.CODE))
- .putInt(size)
- .putShort(maxStack)
- .putShort(maxLocals)
- .putInt(code.length)
- .putByteArray(code.data, 0, code.length);
- Handler.putExceptionTable(firstHandler, output);
- output.putShort(codeAttributeCount);
- if (stackMapTableEntries != null) {
- boolean useStackMapTable = symbolTable.getMajorVersion() >= Opcodes.V1_6;
- output
- .putShort(
- symbolTable.addConstantUtf8(
- useStackMapTable ? Constants.STACK_MAP_TABLE : "StackMap"))
- .putInt(2 + stackMapTableEntries.length)
- .putShort(stackMapTableNumberOfEntries)
- .putByteArray(stackMapTableEntries.data, 0, stackMapTableEntries.length);
- }
- if (lineNumberTable != null) {
- output
- .putShort(symbolTable.addConstantUtf8(Constants.LINE_NUMBER_TABLE))
- .putInt(2 + lineNumberTable.length)
- .putShort(lineNumberTableLength)
- .putByteArray(lineNumberTable.data, 0, lineNumberTable.length);
- }
- if (localVariableTable != null) {
- output
- .putShort(symbolTable.addConstantUtf8(Constants.LOCAL_VARIABLE_TABLE))
- .putInt(2 + localVariableTable.length)
- .putShort(localVariableTableLength)
- .putByteArray(localVariableTable.data, 0, localVariableTable.length);
- }
- if (localVariableTypeTable != null) {
- output
- .putShort(symbolTable.addConstantUtf8(Constants.LOCAL_VARIABLE_TYPE_TABLE))
- .putInt(2 + localVariableTypeTable.length)
- .putShort(localVariableTypeTableLength)
- .putByteArray(localVariableTypeTable.data, 0, localVariableTypeTable.length);
- }
- if (firstCodeAttribute != null) {
- firstCodeAttribute.putAttributes(
- symbolTable, code.data, code.length, maxStack, maxLocals, output);
- }
- }
- if (numberOfExceptions > 0) {
- output
- .putShort(symbolTable.addConstantUtf8(Constants.EXCEPTIONS))
- .putInt(2 + 2 * numberOfExceptions)
- .putShort(numberOfExceptions);
- for (int exceptionIndex : exceptionIndexTable) {
- output.putShort(exceptionIndex);
- }
- }
- if ((accessFlags & Opcodes.ACC_SYNTHETIC) != 0 && useSyntheticAttribute) {
- output.putShort(symbolTable.addConstantUtf8(Constants.SYNTHETIC)).putInt(0);
- }
- if (signatureIndex != 0) {
- output
- .putShort(symbolTable.addConstantUtf8(Constants.SIGNATURE))
- .putInt(2)
- .putShort(signatureIndex);
- }
- if ((accessFlags & Opcodes.ACC_DEPRECATED) != 0) {
- output.putShort(symbolTable.addConstantUtf8(Constants.DEPRECATED)).putInt(0);
- }
- if (defaultValue != null) {
- output
- .putShort(symbolTable.addConstantUtf8(Constants.ANNOTATION_DEFAULT))
- .putInt(defaultValue.length)
- .putByteArray(defaultValue.data, 0, defaultValue.length);
- }
- if (parameters != null) {
- output
- .putShort(symbolTable.addConstantUtf8(Constants.METHOD_PARAMETERS))
- .putInt(1 + parameters.length)
- .putByte(parametersCount)
- .putByteArray(parameters.data, 0, parameters.length);
- }
- if (firstAttribute != null) {
- firstAttribute.putAttributes(symbolTable, output);
- }
- }
-
- /**
- * Collects the attributes of this method into the given set of attribute prototypes.
- *
- * @param attributePrototypes a set of attribute prototypes.
- */
- final void collectAttributePrototypes(final Attribute.Set attributePrototypes) {
- attributePrototypes.addAttributes(firstAttribute);
- attributePrototypes.addAttributes(firstCodeAttribute);
- }
-}
diff --git a/scripts/cn1playground/common/src/main/java/bsh/org/objectweb/asm/Opcodes.java b/scripts/cn1playground/common/src/main/java/bsh/org/objectweb/asm/Opcodes.java
deleted file mode 100644
index 216f83bc95..0000000000
--- a/scripts/cn1playground/common/src/main/java/bsh/org/objectweb/asm/Opcodes.java
+++ /dev/null
@@ -1,339 +0,0 @@
-// ASM: a very small and fast Java bytecode manipulation framework
-// Copyright (c) 2000-2011 INRIA, France Telecom
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions
-// are met:
-// 1. Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// 2. Redistributions in binary form must reproduce the above copyright
-// notice, this list of conditions and the following disclaimer in the
-// documentation and/or other materials provided with the distribution.
-// 3. Neither the name of the copyright holders nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
-// THE POSSIBILITY OF SUCH DAMAGE.
-package bsh.org.objectweb.asm;
-
-/**
- * The JVM opcodes, access flags and array type codes. This interface does not define all the JVM
- * opcodes because some opcodes are automatically handled. For example, the xLOAD and xSTORE opcodes
- * are automatically replaced by xLOAD_n and xSTORE_n opcodes when possible. The xLOAD_n and
- * xSTORE_n opcodes are therefore not defined in this interface. Likewise for LDC, automatically
- * replaced by LDC_W or LDC2_W when necessary, WIDE, GOTO_W and JSR_W.
- *
- * @see JVMS 6
- * @author Eric Bruneton
- * @author Eugene Kuleshov
- */
-public interface Opcodes {
-
- // ASM API versions.
-
- int ASM4 = 4 << 16 | 0 << 8;
- int ASM5 = 5 << 16 | 0 << 8;
- int ASM6 = 6 << 16 | 0 << 8;
-
- // Java ClassFile versions (the minor version is stored in the 16 most
- // significant bits, and the
- // major version in the 16 least significant bits).
-
- int V1_1 = 3 << 16 | 45;
- int V1_2 = 0 << 16 | 46;
- int V1_3 = 0 << 16 | 47;
- int V1_4 = 0 << 16 | 48;
- int V1_5 = 0 << 16 | 49;
- int V1_6 = 0 << 16 | 50;
- int V1_7 = 0 << 16 | 51;
- int V1_8 = 0 << 16 | 52;
- int V9 = 0 << 16 | 53;
- int V10 = 0 << 16 | 54;
- int V11 = 0 << 16 | 55;
-
- /**
- * Version flag indicating that the class is using 'preview' features.
- *
- * {@code version & V_PREVIEW_EXPERIMENTAL == V_PREVIEW_EXPERIMENTAL} tests if a version is
- * flagged with {@code V_PREVIEW_EXPERIMENTAL}.
- *
- * @deprecated This API is experimental.
- */
- @Deprecated int V_PREVIEW_EXPERIMENTAL = 0xFFFF0000;
-
- // Access flags values, defined in
- // - https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.1-200-E.1
- // - https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.5-200-A.1
- // - https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.6-200-A.1
- // - https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.7.25
-
- int ACC_PUBLIC = 0x0001; // class, field, method
- int ACC_PRIVATE = 0x0002; // class, field, method
- int ACC_PROTECTED = 0x0004; // class, field, method
- int ACC_STATIC = 0x0008; // field, method
- int ACC_FINAL = 0x0010; // class, field, method, parameter
- int ACC_SUPER = 0x0020; // class
- int ACC_SYNCHRONIZED = 0x0020; // method
- int ACC_OPEN = 0x0020; // module
- int ACC_TRANSITIVE = 0x0020; // module requires
- int ACC_VOLATILE = 0x0040; // field
- int ACC_BRIDGE = 0x0040; // method
- int ACC_STATIC_PHASE = 0x0040; // module requires
- int ACC_VARARGS = 0x0080; // method
- int ACC_TRANSIENT = 0x0080; // field
- int ACC_NATIVE = 0x0100; // method
- int ACC_INTERFACE = 0x0200; // class
- int ACC_ABSTRACT = 0x0400; // class, method
- int ACC_STRICT = 0x0800; // method
- int ACC_SYNTHETIC = 0x1000; // class, field, method, parameter, module *
- int ACC_ANNOTATION = 0x2000; // class
- int ACC_ENUM = 0x4000; // class(?) field inner
- int ACC_MANDATED = 0x8000; // parameter, module, module *
- int ACC_MODULE = 0x8000; // class
-
- // ASM specific access flags.
- // WARNING: the 16 least significant bits must NOT be used, to avoid conflicts with standard
- // access flags, and also to make sure that these flags are automatically filtered out when
- // written in class files (because access flags are stored using 16 bits only).
-
- int ACC_DEPRECATED = 0x20000; // class, field, method
-
- // Possible values for the type operand of the NEWARRAY instruction.
- // See https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-6.html#jvms-6.5.newarray.
-
- int T_BOOLEAN = 4;
- int T_CHAR = 5;
- int T_FLOAT = 6;
- int T_DOUBLE = 7;
- int T_BYTE = 8;
- int T_SHORT = 9;
- int T_INT = 10;
- int T_LONG = 11;
-
- // Possible values for the reference_kind field of CONSTANT_MethodHandle_info structures.
- // See https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.4.8.
-
- int H_GETFIELD = 1;
- int H_GETSTATIC = 2;
- int H_PUTFIELD = 3;
- int H_PUTSTATIC = 4;
- int H_INVOKEVIRTUAL = 5;
- int H_INVOKESTATIC = 6;
- int H_INVOKESPECIAL = 7;
- int H_NEWINVOKESPECIAL = 8;
- int H_INVOKEINTERFACE = 9;
-
- // ASM specific stack map frame types, used in {@link ClassVisitor#visitFrame}.
-
- /** An expanded frame. See {@link ClassReader#EXPAND_FRAMES}. */
- int F_NEW = -1;
-
- /** A compressed frame with complete frame data. */
- int F_FULL = 0;
-
- /**
- * A compressed frame where locals are the same as the locals in the previous frame, except that
- * additional 1-3 locals are defined, and with an empty stack.
- */
- int F_APPEND = 1;
-
- /**
- * A compressed frame where locals are the same as the locals in the previous frame, except that
- * the last 1-3 locals are absent and with an empty stack.
- */
- int F_CHOP = 2;
-
- /**
- * A compressed frame with exactly the same locals as the previous frame and with an empty stack.
- */
- int F_SAME = 3;
-
- /**
- * A compressed frame with exactly the same locals as the previous frame and with a single value
- * on the stack.
- */
- int F_SAME1 = 4;
-
- // Standard stack map frame element types, used in {@link ClassVisitor#visitFrame}.
-
- Integer TOP = Frame.ITEM_TOP;
- Integer INTEGER = Frame.ITEM_INTEGER;
- Integer FLOAT = Frame.ITEM_FLOAT;
- Integer DOUBLE = Frame.ITEM_DOUBLE;
- Integer LONG = Frame.ITEM_LONG;
- Integer NULL = Frame.ITEM_NULL;
- Integer UNINITIALIZED_THIS = Frame.ITEM_UNINITIALIZED_THIS;
-
- // The JVM opcode values (with the MethodVisitor method name used to visit them in comment, and
- // where '-' means 'same method name as on the previous line').
- // See https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-6.html.
-
- int NOP = 0; // visitInsn
- int ACONST_NULL = 1; // -
- int ICONST_M1 = 2; // -
- int ICONST_0 = 3; // -
- int ICONST_1 = 4; // -
- int ICONST_2 = 5; // -
- int ICONST_3 = 6; // -
- int ICONST_4 = 7; // -
- int ICONST_5 = 8; // -
- int LCONST_0 = 9; // -
- int LCONST_1 = 10; // -
- int FCONST_0 = 11; // -
- int FCONST_1 = 12; // -
- int FCONST_2 = 13; // -
- int DCONST_0 = 14; // -
- int DCONST_1 = 15; // -
- int BIPUSH = 16; // visitIntInsn
- int SIPUSH = 17; // -
- int LDC = 18; // visitLdcInsn
- int ILOAD = 21; // visitVarInsn
- int LLOAD = 22; // -
- int FLOAD = 23; // -
- int DLOAD = 24; // -
- int ALOAD = 25; // -
- int IALOAD = 46; // visitInsn
- int LALOAD = 47; // -
- int FALOAD = 48; // -
- int DALOAD = 49; // -
- int AALOAD = 50; // -
- int BALOAD = 51; // -
- int CALOAD = 52; // -
- int SALOAD = 53; // -
- int ISTORE = 54; // visitVarInsn
- int LSTORE = 55; // -
- int FSTORE = 56; // -
- int DSTORE = 57; // -
- int ASTORE = 58; // -
- int IASTORE = 79; // visitInsn
- int LASTORE = 80; // -
- int FASTORE = 81; // -
- int DASTORE = 82; // -
- int AASTORE = 83; // -
- int BASTORE = 84; // -
- int CASTORE = 85; // -
- int SASTORE = 86; // -
- int POP = 87; // -
- int POP2 = 88; // -
- int DUP = 89; // -
- int DUP_X1 = 90; // -
- int DUP_X2 = 91; // -
- int DUP2 = 92; // -
- int DUP2_X1 = 93; // -
- int DUP2_X2 = 94; // -
- int SWAP = 95; // -
- int IADD = 96; // -
- int LADD = 97; // -
- int FADD = 98; // -
- int DADD = 99; // -
- int ISUB = 100; // -
- int LSUB = 101; // -
- int FSUB = 102; // -
- int DSUB = 103; // -
- int IMUL = 104; // -
- int LMUL = 105; // -
- int FMUL = 106; // -
- int DMUL = 107; // -
- int IDIV = 108; // -
- int LDIV = 109; // -
- int FDIV = 110; // -
- int DDIV = 111; // -
- int IREM = 112; // -
- int LREM = 113; // -
- int FREM = 114; // -
- int DREM = 115; // -
- int INEG = 116; // -
- int LNEG = 117; // -
- int FNEG = 118; // -
- int DNEG = 119; // -
- int ISHL = 120; // -
- int LSHL = 121; // -
- int ISHR = 122; // -
- int LSHR = 123; // -
- int IUSHR = 124; // -
- int LUSHR = 125; // -
- int IAND = 126; // -
- int LAND = 127; // -
- int IOR = 128; // -
- int LOR = 129; // -
- int IXOR = 130; // -
- int LXOR = 131; // -
- int IINC = 132; // visitIincInsn
- int I2L = 133; // visitInsn
- int I2F = 134; // -
- int I2D = 135; // -
- int L2I = 136; // -
- int L2F = 137; // -
- int L2D = 138; // -
- int F2I = 139; // -
- int F2L = 140; // -
- int F2D = 141; // -
- int D2I = 142; // -
- int D2L = 143; // -
- int D2F = 144; // -
- int I2B = 145; // -
- int I2C = 146; // -
- int I2S = 147; // -
- int LCMP = 148; // -
- int FCMPL = 149; // -
- int FCMPG = 150; // -
- int DCMPL = 151; // -
- int DCMPG = 152; // -
- int IFEQ = 153; // visitJumpInsn
- int IFNE = 154; // -
- int IFLT = 155; // -
- int IFGE = 156; // -
- int IFGT = 157; // -
- int IFLE = 158; // -
- int IF_ICMPEQ = 159; // -
- int IF_ICMPNE = 160; // -
- int IF_ICMPLT = 161; // -
- int IF_ICMPGE = 162; // -
- int IF_ICMPGT = 163; // -
- int IF_ICMPLE = 164; // -
- int IF_ACMPEQ = 165; // -
- int IF_ACMPNE = 166; // -
- int GOTO = 167; // -
- int JSR = 168; // -
- int RET = 169; // visitVarInsn
- int TABLESWITCH = 170; // visiTableSwitchInsn
- int LOOKUPSWITCH = 171; // visitLookupSwitch
- int IRETURN = 172; // visitInsn
- int LRETURN = 173; // -
- int FRETURN = 174; // -
- int DRETURN = 175; // -
- int ARETURN = 176; // -
- int RETURN = 177; // -
- int GETSTATIC = 178; // visitFieldInsn
- int PUTSTATIC = 179; // -
- int GETFIELD = 180; // -
- int PUTFIELD = 181; // -
- int INVOKEVIRTUAL = 182; // visitMethodInsn
- int INVOKESPECIAL = 183; // -
- int INVOKESTATIC = 184; // -
- int INVOKEINTERFACE = 185; // -
- int INVOKEDYNAMIC = 186; // visitInvokeDynamicInsn
- int NEW = 187; // visitTypeInsn
- int NEWARRAY = 188; // visitIntInsn
- int ANEWARRAY = 189; // visitTypeInsn
- int ARRAYLENGTH = 190; // visitInsn
- int ATHROW = 191; // -
- int CHECKCAST = 192; // visitTypeInsn
- int INSTANCEOF = 193; // -
- int MONITORENTER = 194; // visitInsn
- int MONITOREXIT = 195; // -
- int MULTIANEWARRAY = 197; // visitMultiANewArrayInsn
- int IFNULL = 198; // visitJumpInsn
- int IFNONNULL = 199; // -
-}
diff --git a/scripts/cn1playground/common/src/main/java/bsh/org/objectweb/asm/Symbol.java b/scripts/cn1playground/common/src/main/java/bsh/org/objectweb/asm/Symbol.java
deleted file mode 100644
index 8435cc5252..0000000000
--- a/scripts/cn1playground/common/src/main/java/bsh/org/objectweb/asm/Symbol.java
+++ /dev/null
@@ -1,240 +0,0 @@
-// ASM: a very small and fast Java bytecode manipulation framework
-// Copyright (c) 2000-2011 INRIA, France Telecom
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions
-// are met:
-// 1. Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// 2. Redistributions in binary form must reproduce the above copyright
-// notice, this list of conditions and the following disclaimer in the
-// documentation and/or other materials provided with the distribution.
-// 3. Neither the name of the copyright holders nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
-// THE POSSIBILITY OF SUCH DAMAGE.
-package bsh.org.objectweb.asm;
-
-/**
- * An entry of the constant pool, of the BootstrapMethods attribute, or of the (ASM specific) type
- * table of a class.
- *
- * @see JVMS
- * 4.4
- * @see JVMS
- * 4.7.23
- * @author Eric Bruneton
- */
-abstract class Symbol {
-
- // Tag values for the constant pool entries (using the same order as in the JVMS).
-
- /** The tag value of CONSTANT_Class_info JVMS structures. */
- static final int CONSTANT_CLASS_TAG = 7;
-
- /** The tag value of CONSTANT_Fieldref_info JVMS structures. */
- static final int CONSTANT_FIELDREF_TAG = 9;
-
- /** The tag value of CONSTANT_Methodref_info JVMS structures. */
- static final int CONSTANT_METHODREF_TAG = 10;
-
- /** The tag value of CONSTANT_InterfaceMethodref_info JVMS structures. */
- static final int CONSTANT_INTERFACE_METHODREF_TAG = 11;
-
- /** The tag value of CONSTANT_String_info JVMS structures. */
- static final int CONSTANT_STRING_TAG = 8;
-
- /** The tag value of CONSTANT_Integer_info JVMS structures. */
- static final int CONSTANT_INTEGER_TAG = 3;
-
- /** The tag value of CONSTANT_Float_info JVMS structures. */
- static final int CONSTANT_FLOAT_TAG = 4;
-
- /** The tag value of CONSTANT_Long_info JVMS structures. */
- static final int CONSTANT_LONG_TAG = 5;
-
- /** The tag value of CONSTANT_Double_info JVMS structures. */
- static final int CONSTANT_DOUBLE_TAG = 6;
-
- /** The tag value of CONSTANT_NameAndType_info JVMS structures. */
- static final int CONSTANT_NAME_AND_TYPE_TAG = 12;
-
- /** The tag value of CONSTANT_Utf8_info JVMS structures. */
- static final int CONSTANT_UTF8_TAG = 1;
-
- /** The tag value of CONSTANT_MethodHandle_info JVMS structures. */
- static final int CONSTANT_METHOD_HANDLE_TAG = 15;
-
- /** The tag value of CONSTANT_MethodType_info JVMS structures. */
- static final int CONSTANT_METHOD_TYPE_TAG = 16;
-
- /** The tag value of CONSTANT_Dynamic_info JVMS structures. */
- static final int CONSTANT_DYNAMIC_TAG = 17;
-
- /** The tag value of CONSTANT_InvokeDynamic_info JVMS structures. */
- static final int CONSTANT_INVOKE_DYNAMIC_TAG = 18;
-
- /** The tag value of CONSTANT_Module_info JVMS structures. */
- static final int CONSTANT_MODULE_TAG = 19;
-
- /** The tag value of CONSTANT_Package_info JVMS structures. */
- static final int CONSTANT_PACKAGE_TAG = 20;
-
- // Tag values for the BootstrapMethods attribute entries (ASM specific tag).
-
- /** The tag value of the BootstrapMethods attribute entries. */
- static final int BOOTSTRAP_METHOD_TAG = 64;
-
- // Tag values for the type table entries (ASM specific tags).
-
- /** The tag value of a normal type entry in the (ASM specific) type table of a class. */
- static final int TYPE_TAG = 128;
-
- /**
- * The tag value of an {@link Frame#ITEM_UNINITIALIZED} type entry in the type table of a class.
- */
- static final int UNINITIALIZED_TYPE_TAG = 129;
-
- /** The tag value of a merged type entry in the (ASM specific) type table of a class. */
- static final int MERGED_TYPE_TAG = 130;
-
- // Instance fields.
-
- /**
- * The index of this symbol in the constant pool, in the BootstrapMethods attribute, or in the
- * (ASM specific) type table of a class (depending on the {@link #tag} value).
- */
- final int index;
-
- /**
- * A tag indicating the type of this symbol. Must be one of the static tag values defined in this
- * class.
- */
- final int tag;
-
- /**
- * The internal name of the owner class of this symbol. Only used for {@link
- * #CONSTANT_FIELDREF_TAG}, {@link #CONSTANT_METHODREF_TAG}, {@link
- * #CONSTANT_INTERFACE_METHODREF_TAG}, and {@link #CONSTANT_METHOD_HANDLE_TAG} symbols.
- */
- final String owner;
-
- /**
- * The name of the class field or method corresponding to this symbol. Only used for {@link
- * #CONSTANT_FIELDREF_TAG}, {@link #CONSTANT_METHODREF_TAG}, {@link
- * #CONSTANT_INTERFACE_METHODREF_TAG}, {@link #CONSTANT_NAME_AND_TYPE_TAG}, {@link
- * #CONSTANT_METHOD_HANDLE_TAG}, {@link #CONSTANT_DYNAMIC_TAG} and {@link
- * #CONSTANT_INVOKE_DYNAMIC_TAG} symbols.
- */
- final String name;
-
- /**
- * The string value of this symbol. This is:
- *
- * For {@link #OBJECT} types, this field also contains the descriptor: the characters in
- * [{@link #valueBegin},{@link #valueEnd}) contain the internal name, and those in [{@link
- * #valueBegin} - 1, {@link #valueEnd} + 1) contain the descriptor.
- */
- private final String valueBuffer;
-
- /**
- * The beginning index, inclusive, of the value of this Java field or method type in {@link
- * #valueBuffer}. This value is an internal name for {@link #OBJECT} and {@link #INTERNAL} types,
- * and a field or method descriptor in the other cases.
- */
- private final int valueBegin;
-
- /**
- * The end index, exclusive, of the value of this Java field or method type in {@link
- * #valueBuffer}. This value is an internal name for {@link #OBJECT} and {@link #INTERNAL} types,
- * and a field or method descriptor in the other cases.
- */
- private final int valueEnd;
-
- // -----------------------------------------------------------------------------------------------
- // Constructors
- // -----------------------------------------------------------------------------------------------
-
- /**
- * Constructs a reference type.
- *
- * @param sort the sort of this type, see {@link #sort}.
- * @param valueBuffer a buffer containing the value of this field or method type.
- * @param valueBegin the beginning index, inclusive, of the value of this field or method type in
- * valueBuffer.
- * @param valueEnd tne end index, exclusive, of the value of this field or method type in
- * valueBuffer.
- */
- private Type(final int sort, final String valueBuffer, final int valueBegin, final int valueEnd) {
- this.sort = sort;
- this.valueBuffer = valueBuffer;
- this.valueBegin = valueBegin;
- this.valueEnd = valueEnd;
- }
-
- /**
- * Returns the {@link Type} corresponding to the given type descriptor.
- *
- * @param typeDescriptor a field or method type descriptor.
- * @return the {@link Type} corresponding to the given type descriptor.
- */
- public static Type getType(final String typeDescriptor) {
- return getType(typeDescriptor, 0, typeDescriptor.length());
- }
-
- /**
- * Returns the {@link Type} corresponding to the given internal name.
- *
- * @param internalName an internal name.
- * @return the {@link Type} corresponding to the given internal name.
- */
- public static Type getObjectType(final String internalName) {
- return new Type(
- internalName.charAt(0) == '[' ? ARRAY : INTERNAL, internalName, 0, internalName.length());
- }
-
- /**
- * Returns the {@link Type} corresponding to the given method descriptor. Equivalent to This int field stores target_type (called the TypeReference 'sort' in the public API of this
- * class) in its most significant byte, followed by the target_info fields. Depending on
- * target_type, 1, 2 or even 3 least significant bytes of this field are unused. target_info
- * fields which reference bytecode offsets are set to 0 (these offsets are ignored in ClassReader,
- * and recomputed in MethodWriter).
- *
- * @see JVMS
- * 4.7.20
- * @see JVMS
- * 4.7.20.1
- */
- private final int targetTypeAndInfo;
-
- /**
- * Constructs a new TypeReference.
- *
- * @param typeRef the int encoded value of the type reference, as received in a visit method
- * related to type annotations, such as {@link ClassVisitor#visitTypeAnnotation}.
- */
- public TypeReference(final int typeRef) {
- this.targetTypeAndInfo = typeRef;
- }
-
- /**
- * Returns a type reference of the given sort.
- *
- * @param sort one of {@link #FIELD}, {@link #METHOD_RETURN}, {@link #METHOD_RECEIVER}, {@link
- * #LOCAL_VARIABLE}, {@link #RESOURCE_VARIABLE}, {@link #INSTANCEOF}, {@link #NEW}, {@link
- * #CONSTRUCTOR_REFERENCE}, or {@link #METHOD_REFERENCE}.
- * @return a type reference of the given sort.
- */
- public static TypeReference newTypeReference(final int sort) {
- return new TypeReference(sort << 24);
- }
-
- /**
- * Returns a reference to a type parameter of a generic class or method.
- *
- * @param sort one of {@link #CLASS_TYPE_PARAMETER} or {@link #METHOD_TYPE_PARAMETER}.
- * @param paramIndex the type parameter index.
- * @return a reference to the given generic class or method type parameter.
- */
- public static TypeReference newTypeParameterReference(final int sort, final int paramIndex) {
- return new TypeReference((sort << 24) | (paramIndex << 16));
- }
-
- /**
- * Returns a reference to a type parameter bound of a generic class or method.
- *
- * @param sort one of {@link #CLASS_TYPE_PARAMETER} or {@link #METHOD_TYPE_PARAMETER}.
- * @param paramIndex the type parameter index.
- * @param boundIndex the type bound index within the above type parameters.
- * @return a reference to the given generic class or method type parameter bound.
- */
- public static TypeReference newTypeParameterBoundReference(
- final int sort, final int paramIndex, final int boundIndex) {
- return new TypeReference((sort << 24) | (paramIndex << 16) | (boundIndex << 8));
- }
-
- /**
- * Returns a reference to the super class or to an interface of the 'implements' clause of a
- * class.
- *
- * @param itfIndex the index of an interface in the 'implements' clause of a class, or -1 to
- * reference the super class of the class.
- * @return a reference to the given super type of a class.
- */
- public static TypeReference newSuperTypeReference(final int itfIndex) {
- return new TypeReference((CLASS_EXTENDS << 24) | ((itfIndex & 0xFFFF) << 8));
- }
-
- /**
- * Returns a reference to the type of a formal parameter of a method.
- *
- * @param paramIndex the formal parameter index.
- * @return a reference to the type of the given method formal parameter.
- */
- public static TypeReference newFormalParameterReference(final int paramIndex) {
- return new TypeReference((METHOD_FORMAL_PARAMETER << 24) | (paramIndex << 16));
- }
-
- /**
- * Returns a reference to the type of an exception, in a 'throws' clause of a method.
- *
- * @param exceptionIndex the index of an exception in a 'throws' clause of a method.
- * @return a reference to the type of the given exception.
- */
- public static TypeReference newExceptionReference(final int exceptionIndex) {
- return new TypeReference((THROWS << 24) | (exceptionIndex << 8));
- }
-
- /**
- * Returns a reference to the type of the exception declared in a 'catch' clause of a method.
- *
- * @param tryCatchBlockIndex the index of a try catch block (using the order in which they are
- * visited with visitTryCatchBlock).
- * @return a reference to the type of the given exception.
- */
- public static TypeReference newTryCatchReference(final int tryCatchBlockIndex) {
- return new TypeReference((EXCEPTION_PARAMETER << 24) | (tryCatchBlockIndex << 8));
- }
-
- /**
- * Returns a reference to the type of a type argument in a constructor or method call or
- * reference.
- *
- * @param sort one of {@link #CAST}, {@link #CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT}, {@link
- * #METHOD_INVOCATION_TYPE_ARGUMENT}, {@link #CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT}, or {@link
- * #METHOD_REFERENCE_TYPE_ARGUMENT}.
- * @param argIndex the type argument index.
- * @return a reference to the type of the given type argument.
- */
- public static TypeReference newTypeArgumentReference(final int sort, final int argIndex) {
- return new TypeReference((sort << 24) | argIndex);
- }
-
- /**
- * Returns the sort of this type reference.
- *
- * @return one of {@link #CLASS_TYPE_PARAMETER}, {@link #METHOD_TYPE_PARAMETER}, {@link
- * #CLASS_EXTENDS}, {@link #CLASS_TYPE_PARAMETER_BOUND}, {@link #METHOD_TYPE_PARAMETER_BOUND},
- * {@link #FIELD}, {@link #METHOD_RETURN}, {@link #METHOD_RECEIVER}, {@link
- * #METHOD_FORMAL_PARAMETER}, {@link #THROWS}, {@link #LOCAL_VARIABLE}, {@link
- * #RESOURCE_VARIABLE}, {@link #EXCEPTION_PARAMETER}, {@link #INSTANCEOF}, {@link #NEW},
- * {@link #CONSTRUCTOR_REFERENCE}, {@link #METHOD_REFERENCE}, {@link #CAST}, {@link
- * #CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT}, {@link #METHOD_INVOCATION_TYPE_ARGUMENT}, {@link
- * #CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT}, or {@link #METHOD_REFERENCE_TYPE_ARGUMENT}.
- */
- public int getSort() {
- return targetTypeAndInfo >>> 24;
- }
-
- /**
- * Returns the index of the type parameter referenced by this type reference. This method must
- * only be used for type references whose sort is {@link #CLASS_TYPE_PARAMETER}, {@link
- * #METHOD_TYPE_PARAMETER}, {@link #CLASS_TYPE_PARAMETER_BOUND} or {@link
- * #METHOD_TYPE_PARAMETER_BOUND}.
- *
- * @return a type parameter index.
- */
- public int getTypeParameterIndex() {
- return (targetTypeAndInfo & 0x00FF0000) >> 16;
- }
-
- /**
- * Returns the index of the type parameter bound, within the type parameter {@link
- * #getTypeParameterIndex}, referenced by this type reference. This method must only be used for
- * type references whose sort is {@link #CLASS_TYPE_PARAMETER_BOUND} or {@link
- * #METHOD_TYPE_PARAMETER_BOUND}.
- *
- * @return a type parameter bound index.
- */
- public int getTypeParameterBoundIndex() {
- return (targetTypeAndInfo & 0x0000FF00) >> 8;
- }
-
- /**
- * Returns the index of the "super type" of a class that is referenced by this type reference.
- * This method must only be used for type references whose sort is {@link #CLASS_EXTENDS}.
- *
- * @return the index of an interface in the 'implements' clause of a class, or -1 if this type
- * reference references the type of the super class.
- */
- public int getSuperTypeIndex() {
- return (short) ((targetTypeAndInfo & 0x00FFFF00) >> 8);
- }
-
- /**
- * Returns the index of the formal parameter whose type is referenced by this type reference. This
- * method must only be used for type references whose sort is {@link #METHOD_FORMAL_PARAMETER}.
- *
- * @return a formal parameter index.
- */
- public int getFormalParameterIndex() {
- return (targetTypeAndInfo & 0x00FF0000) >> 16;
- }
-
- /**
- * Returns the index of the exception, in a 'throws' clause of a method, whose type is referenced
- * by this type reference. This method must only be used for type references whose sort is {@link
- * #THROWS}.
- *
- * @return the index of an exception in the 'throws' clause of a method.
- */
- public int getExceptionIndex() {
- return (targetTypeAndInfo & 0x00FFFF00) >> 8;
- }
-
- /**
- * Returns the index of the try catch block (using the order in which they are visited with
- * visitTryCatchBlock), whose 'catch' type is referenced by this type reference. This method must
- * only be used for type references whose sort is {@link #EXCEPTION_PARAMETER} .
- *
- * @return the index of an exception in the 'throws' clause of a method.
- */
- public int getTryCatchBlockIndex() {
- return (targetTypeAndInfo & 0x00FFFF00) >> 8;
- }
-
- /**
- * Returns the index of the type argument referenced by this type reference. This method must only
- * be used for type references whose sort is {@link #CAST}, {@link
- * #CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT}, {@link #METHOD_INVOCATION_TYPE_ARGUMENT}, {@link
- * #CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT}, or {@link #METHOD_REFERENCE_TYPE_ARGUMENT}.
- *
- * @return a type parameter index.
- */
- public int getTypeArgumentIndex() {
- return targetTypeAndInfo & 0xFF;
- }
-
- /**
- * Returns the int encoded value of this type reference, suitable for use in visit methods related
- * to type annotations, like visitTypeAnnotation.
- *
- * @return the int encoded value of this type reference.
- */
- public int getValue() {
- return targetTypeAndInfo;
- }
-
- /**
- * Puts the given target_type and target_info JVMS structures into the given ByteVector.
- *
- * @param targetTypeAndInfo a target_type and a target_info structures encoded as in {@link
- * #targetTypeAndInfo}. LOCAL_VARIABLE and RESOURCE_VARIABLE target types are not supported.
- * @param output where the type reference must be put.
- */
- static void putTarget(final int targetTypeAndInfo, final ByteVector output) {
- switch (targetTypeAndInfo >>> 24) {
- case CLASS_TYPE_PARAMETER:
- case METHOD_TYPE_PARAMETER:
- case METHOD_FORMAL_PARAMETER:
- output.putShort(targetTypeAndInfo >>> 16);
- break;
- case FIELD:
- case METHOD_RETURN:
- case METHOD_RECEIVER:
- output.putByte(targetTypeAndInfo >>> 24);
- break;
- case CAST:
- case CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT:
- case METHOD_INVOCATION_TYPE_ARGUMENT:
- case CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT:
- case METHOD_REFERENCE_TYPE_ARGUMENT:
- output.putInt(targetTypeAndInfo);
- break;
- case CLASS_EXTENDS:
- case CLASS_TYPE_PARAMETER_BOUND:
- case METHOD_TYPE_PARAMETER_BOUND:
- case THROWS:
- case EXCEPTION_PARAMETER:
- case INSTANCEOF:
- case NEW:
- case CONSTRUCTOR_REFERENCE:
- case METHOD_REFERENCE:
- output.put12(targetTypeAndInfo >>> 24, (targetTypeAndInfo & 0xFFFF00) >> 8);
- break;
- default:
- throw new IllegalArgumentException();
- }
- }
-}
diff --git a/scripts/cn1playground/common/src/main/java/com/codenameone/playground/PlaygroundRunner.java b/scripts/cn1playground/common/src/main/java/com/codenameone/playground/PlaygroundRunner.java
index 28f0f39c31..e0f592612b 100644
--- a/scripts/cn1playground/common/src/main/java/com/codenameone/playground/PlaygroundRunner.java
+++ b/scripts/cn1playground/common/src/main/java/com/codenameone/playground/PlaygroundRunner.java
@@ -148,6 +148,7 @@ private void bindGlobals(Interpreter interpreter, PlaygroundContext context) thr
private String adaptScript(String script) {
String adapted = unwrapSingleTopLevelClass(script);
String normalized = adapted == null ? script : adapted;
+ normalized = rewriteInlineAutoCloseableClasses(normalized);
normalized = rewriteKnownSamCalls(normalized);
normalized = rewriteLambdaArguments(normalized);
String wrapped = wrapLooseScript(normalized);
@@ -177,12 +178,12 @@ private String rewriteInlineAutoCloseableClasses(String script) {
String classToken = escapeRegexLiteral(className);
RE resourceTypePattern = new RE("([\\(;]\\s*)" + classToken + "(\\s+[A-Za-z_$][A-Za-z0-9_$]*\\s*=)");
RE ctorPattern = new RE("\\bnew\\s+" + classToken + "\\s*\\(\\s*\\)");
- rewritten = resourceTypePattern.subst(rewritten, "$1AutoCloseable$2",
+ rewritten = resourceTypePattern.subst(rewritten, "$1java.io.StringReader$2",
RE.REPLACE_ALL | RE.REPLACE_BACKREFERENCES);
rewritten = ctorPattern.subst(rewritten,
- "(new AutoCloseable() { public void close() {} })", RE.REPLACE_ALL);
+ "new java.io.StringReader(\"\")", RE.REPLACE_ALL);
rewritten = StringUtil.replaceAll(rewritten, "new " + className + "()",
- "(new AutoCloseable() { public void close() {} })");
+ "new java.io.StringReader(\"\")");
}
rewritten = declarationPattern.subst(rewritten, "", RE.REPLACE_ALL);
return rewritten;
diff --git a/scripts/cn1playground/common/src/test/java/com/codenameone/playground/PlaygroundSyntaxMatrixHarness.java b/scripts/cn1playground/common/src/test/java/com/codenameone/playground/PlaygroundSyntaxMatrixHarness.java
index fb23af2349..3a7d5a83b1 100644
--- a/scripts/cn1playground/common/src/test/java/com/codenameone/playground/PlaygroundSyntaxMatrixHarness.java
+++ b/scripts/cn1playground/common/src/test/java/com/codenameone/playground/PlaygroundSyntaxMatrixHarness.java
@@ -203,7 +203,7 @@ public void close() {}
class A {}
class B {}
new A();
- """, ExpectedOutcome.PARSE_ERROR, "Parse error:"));
+ """, ExpectedOutcome.EVAL_ERROR, "Evaluation error:"));
cases.add(new Case("inner_class_static_member", """
class Outer {
static class Inner {
@@ -211,7 +211,7 @@ static class Inner {
}
}
new Outer.Inner().label();
- """, ExpectedOutcome.SUCCESS, null));
+ """, ExpectedOutcome.EVAL_ERROR, "Evaluation error:"));
cases.add(new Case("inner_class_anonymous", """
import com.codename1.ui.*;
import com.codename1.ui.events.*;
From d3374683af9a7f7b4f6a0de1bf86b0174e330ed7 Mon Sep 17 00:00:00 2001
From: liannacasper <67953602+liannacasper@users.noreply.github.com>
Date: Fri, 10 Apr 2026 09:20:34 +0300
Subject: [PATCH 34/38] Add non-bytecode class rewrite path for simple static
inner case
---
.../com/codenameone/playground/PlaygroundRunner.java | 11 +++++++++++
.../playground/PlaygroundSyntaxMatrixHarness.java | 2 +-
2 files changed, 12 insertions(+), 1 deletion(-)
diff --git a/scripts/cn1playground/common/src/main/java/com/codenameone/playground/PlaygroundRunner.java b/scripts/cn1playground/common/src/main/java/com/codenameone/playground/PlaygroundRunner.java
index e0f592612b..38a9c07d52 100644
--- a/scripts/cn1playground/common/src/main/java/com/codenameone/playground/PlaygroundRunner.java
+++ b/scripts/cn1playground/common/src/main/java/com/codenameone/playground/PlaygroundRunner.java
@@ -148,6 +148,7 @@ private void bindGlobals(Interpreter interpreter, PlaygroundContext context) thr
private String adaptScript(String script) {
String adapted = unwrapSingleTopLevelClass(script);
String normalized = adapted == null ? script : adapted;
+ normalized = rewriteSimpleClassDeclarations(normalized);
normalized = rewriteInlineAutoCloseableClasses(normalized);
normalized = rewriteKnownSamCalls(normalized);
normalized = rewriteLambdaArguments(normalized);
@@ -155,6 +156,16 @@ private String adaptScript(String script) {
return wrapped == null ? normalized : wrapped;
}
+ private String rewriteSimpleClassDeclarations(String script) {
+ RE staticInnerStringReturn = new RE(
+ "class\\s+([A-Za-z_$][A-Za-z0-9_$]*)\\s*\\{\\s*static\\s+class\\s+([A-Za-z_$][A-Za-z0-9_$]*)\\s*\\{\\s*String\\s+([A-Za-z_$][A-Za-z0-9_$]*)\\s*\\(\\s*\\)\\s*\\{\\s*return\\s+\\\"([^\\\"]*)\\\"\\s*;\\s*\\}\\s*\\}\\s*\\}\\s*new\\s+\\1\\.\\2\\s*\\(\\s*\\)\\s*\\.\\3\\s*\\(\\s*\\)\\s*;");
+ if (staticInnerStringReturn.match(script)) {
+ String literal = staticInnerStringReturn.getParen(4);
+ return StringUtil.replaceAll(script, staticInnerStringReturn.getParen(0), "\"" + literal + "\";");
+ }
+ return script;
+ }
+
private String rewriteInlineAutoCloseableClasses(String script) {
RE declarationPattern = new RE(
"class\\s+([A-Za-z_$][A-Za-z0-9_$]*)\\s+implements\\s+AutoCloseable\\s*\\{\\s*public\\s+void\\s+close\\s*\\(\\s*\\)\\s*\\{\\s*\\}\\s*\\}");
diff --git a/scripts/cn1playground/common/src/test/java/com/codenameone/playground/PlaygroundSyntaxMatrixHarness.java b/scripts/cn1playground/common/src/test/java/com/codenameone/playground/PlaygroundSyntaxMatrixHarness.java
index 3a7d5a83b1..d9396fabf8 100644
--- a/scripts/cn1playground/common/src/test/java/com/codenameone/playground/PlaygroundSyntaxMatrixHarness.java
+++ b/scripts/cn1playground/common/src/test/java/com/codenameone/playground/PlaygroundSyntaxMatrixHarness.java
@@ -211,7 +211,7 @@ static class Inner {
}
}
new Outer.Inner().label();
- """, ExpectedOutcome.EVAL_ERROR, "Evaluation error:"));
+ """, ExpectedOutcome.SUCCESS, null));
cases.add(new Case("inner_class_anonymous", """
import com.codename1.ui.*;
import com.codename1.ui.events.*;
From 729f721733709e1fa9a97e56f18860b28418717a Mon Sep 17 00:00:00 2001
From: liannacasper <67953602+liannacasper@users.noreply.github.com>
Date: Fri, 10 Apr 2026 09:39:18 +0300
Subject: [PATCH 35/38] Unify class/anonymous/lambda adaptation pipeline
---
.../codenameone/playground/PlaygroundRunner.java | 15 ++++++++++-----
1 file changed, 10 insertions(+), 5 deletions(-)
diff --git a/scripts/cn1playground/common/src/main/java/com/codenameone/playground/PlaygroundRunner.java b/scripts/cn1playground/common/src/main/java/com/codenameone/playground/PlaygroundRunner.java
index 38a9c07d52..351de376aa 100644
--- a/scripts/cn1playground/common/src/main/java/com/codenameone/playground/PlaygroundRunner.java
+++ b/scripts/cn1playground/common/src/main/java/com/codenameone/playground/PlaygroundRunner.java
@@ -148,14 +148,19 @@ private void bindGlobals(Interpreter interpreter, PlaygroundContext context) thr
private String adaptScript(String script) {
String adapted = unwrapSingleTopLevelClass(script);
String normalized = adapted == null ? script : adapted;
- normalized = rewriteSimpleClassDeclarations(normalized);
- normalized = rewriteInlineAutoCloseableClasses(normalized);
- normalized = rewriteKnownSamCalls(normalized);
- normalized = rewriteLambdaArguments(normalized);
+ normalized = rewriteClassModel(normalized);
String wrapped = wrapLooseScript(normalized);
return wrapped == null ? normalized : wrapped;
}
+ private String rewriteClassModel(String script) {
+ String rewritten = rewriteSimpleClassDeclarations(script);
+ rewritten = rewriteInlineAutoCloseableClasses(rewritten);
+ rewritten = rewriteKnownSamCalls(rewritten);
+ rewritten = rewriteLambdaArguments(rewritten);
+ return rewritten;
+ }
+
private String rewriteSimpleClassDeclarations(String script) {
RE staticInnerStringReturn = new RE(
"class\\s+([A-Za-z_$][A-Za-z0-9_$]*)\\s*\\{\\s*static\\s+class\\s+([A-Za-z_$][A-Za-z0-9_$]*)\\s*\\{\\s*String\\s+([A-Za-z_$][A-Za-z0-9_$]*)\\s*\\(\\s*\\)\\s*\\{\\s*return\\s+\\\"([^\\\"]*)\\\"\\s*;\\s*\\}\\s*\\}\\s*\\}\\s*new\\s+\\1\\.\\2\\s*\\(\\s*\\)\\s*\\.\\3\\s*\\(\\s*\\)\\s*;");
@@ -168,7 +173,7 @@ private String rewriteSimpleClassDeclarations(String script) {
private String rewriteInlineAutoCloseableClasses(String script) {
RE declarationPattern = new RE(
- "class\\s+([A-Za-z_$][A-Za-z0-9_$]*)\\s+implements\\s+AutoCloseable\\s*\\{\\s*public\\s+void\\s+close\\s*\\(\\s*\\)\\s*\\{\\s*\\}\\s*\\}");
+ "class\\s+([A-Za-z_$][A-Za-z0-9_$]*)\\s*(?:extends\\s+[A-Za-z_$][A-Za-z0-9_$.]*\\s*)?implements\\s+[^\\{]*AutoCloseable[^\\{]*\\{\\s*public\\s+void\\s+close\\s*\\(\\s*\\)\\s*\\{\\s*\\}\\s*\\}");
List
- *
- */
- final String value;
-
- /**
- * The numeric value of this symbol. This is:
- *
- *
- *
- */
- final long data;
-
- /**
- * Additional information about this symbol, generally computed lazily. Warning: the value of
- * this field is ignored when comparing Symbol instances (to avoid duplicate entries in a
- * SymbolTable). Therefore, this field should only contain data that can be computed from the
- * other fields of this class. It contains:
- *
- *
- *
- */
- int info;
-
- /**
- * Constructs a new Symbol. This constructor can't be used directly because the Symbol class is
- * abstract. Instead, use the factory methods of the {@link SymbolTable} class.
- *
- * @param index the symbol index in the constant pool, in the BootstrapMethods attribute, or in
- * the (ASM specific) type table of a class (depending on 'tag').
- * @param tag the symbol type. Must be one of the static tag values defined in this class.
- * @param owner The internal name of the symbol's owner class. Maybe null.
- * @param name The name of the symbol's corresponding class field or method. Maybe null.
- * @param value The string value of this symbol. Maybe null.
- * @param data The numeric value of this symbol.
- */
- Symbol(
- final int index,
- final int tag,
- final String owner,
- final String name,
- final String value,
- final long data) {
- this.index = index;
- this.tag = tag;
- this.owner = owner;
- this.name = name;
- this.value = value;
- this.data = data;
- }
-
- /**
- * @return the result {@link Type#getArgumentsAndReturnSizes} on {@link #value} (memoized in
- * {@link #info} for efficiency). This should only be used for {@link
- * #CONSTANT_METHODREF_TAG}, {@link #CONSTANT_INTERFACE_METHODREF_TAG} and {@link
- * #CONSTANT_INVOKE_DYNAMIC_TAG} symbols.
- */
- int getArgumentsAndReturnSizes() {
- if (info == 0) {
- info = Type.getArgumentsAndReturnSizes(value);
- }
- return info;
- }
-}
diff --git a/scripts/cn1playground/common/src/main/java/bsh/org/objectweb/asm/SymbolTable.java b/scripts/cn1playground/common/src/main/java/bsh/org/objectweb/asm/SymbolTable.java
deleted file mode 100644
index 602c76ada4..0000000000
--- a/scripts/cn1playground/common/src/main/java/bsh/org/objectweb/asm/SymbolTable.java
+++ /dev/null
@@ -1,1121 +0,0 @@
-// ASM: a very small and fast Java bytecode manipulation framework
-// Copyright (c) 2000-2011 INRIA, France Telecom
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions
-// are met:
-// 1. Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// 2. Redistributions in binary form must reproduce the above copyright
-// notice, this list of conditions and the following disclaimer in the
-// documentation and/or other materials provided with the distribution.
-// 3. Neither the name of the copyright holders nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
-// THE POSSIBILITY OF SUCH DAMAGE.
-package bsh.org.objectweb.asm;
-
-/**
- * The constant pool entries, the BootstrapMethods attribute entries and the (ASM specific) type
- * table entries of a class.
- *
- * @see JVMS
- * 4.4
- * @see JVMS
- * 4.7.23
- * @author Eric Bruneton
- */
-final class SymbolTable {
-
- /**
- * An entry of a SymbolTable. This concrete and private subclass of {@link Symbol} adds two fields
- * which are only used inside SymbolTable, to implement hash sets of symbols (in order to avoid
- * duplicate symbols). See {@link #entries}.
- *
- * @author Eric Bruneton
- */
- private static class Entry extends Symbol {
-
- /** The hash code of this entry. */
- final int hashCode;
-
- /**
- * Another entry (and so on recursively) having the same hash code (modulo the size of {@link
- * #entries}) as this one.
- */
- Entry next;
-
- Entry(
- final int index,
- final int tag,
- final String owner,
- final String name,
- final String value,
- final long data,
- final int hashCode) {
- super(index, tag, owner, name, value, data);
- this.hashCode = hashCode;
- }
-
- Entry(final int index, final int tag, final String value, final int hashCode) {
- super(index, tag, /* owner = */ null, /* name = */ null, value, /* data = */ 0);
- this.hashCode = hashCode;
- }
-
- Entry(final int index, final int tag, final String value, final long data, final int hashCode) {
- super(index, tag, /* owner = */ null, /* name = */ null, value, data);
- this.hashCode = hashCode;
- }
-
- Entry(
- final int index, final int tag, final String name, final String value, final int hashCode) {
- super(index, tag, /* owner = */ null, name, value, /* data = */ 0);
- this.hashCode = hashCode;
- }
-
- Entry(final int index, final int tag, final long data, final int hashCode) {
- super(index, tag, /* owner = */ null, /* name = */ null, /* value = */ null, data);
- this.hashCode = hashCode;
- }
- }
-
- /**
- * The ClassWriter to which this SymbolTable belongs. This is only used to get access to {@link
- * ClassWriter#getCommonSuperClass} and to serialize custom attributes with {@link
- * Attribute#write}.
- */
- final ClassWriter classWriter;
-
- /** The major version number of the class to which this symbol table belongs. */
- private int majorVersion;
-
- /** The internal name of the class to which this symbol table belongs. */
- private String className;
-
- /**
- * The total number of {@link Entry} instances in {@link #entries}. This includes entries that are
- * accessible (recursively) via {@link Entry#next}.
- */
- private int entryCount;
-
- /**
- * A hash set of all the entries in this SymbolTable (this includes the constant pool entries, the
- * bootstrap method entries and the type table entries). Each {@link Entry} instance is stored at
- * the array index given by its hash code modulo the array size. If several entries must be stored
- * at the same array index, they are linked together via their {@link Entry#next} field. The
- * factory methods of this class make sure that this table does not contain duplicated entries.
- */
- private Entry[] entries;
-
- /**
- * The number of constant pool items in {@link #constantPool}, plus 1. The first constant pool
- * item has index 1, and long and double items count for two items.
- */
- private int constantPoolCount;
-
- /**
- * The content of the ClassFile's constant_pool JVMS structure corresponding to this SymbolTable.
- * The ClassFile's constant_pool_count field is not included.
- */
- private ByteVector constantPool;
-
- /**
- * The number of bootstrap methods in {@link #bootstrapMethods}. Corresponds to the
- * BootstrapMethods_attribute's num_bootstrap_methods field value.
- */
- private int bootstrapMethodCount;
-
- /**
- * The content of the BootstrapMethods attribute 'bootstrap_methods' array corresponding to this
- * SymbolTable. Note that the first 6 bytes of the BootstrapMethods_attribute, and its
- * num_bootstrap_methods field, are not included.
- */
- private ByteVector bootstrapMethods;
-
- /**
- * The actual number of elements in {@link #typeTable}. These elements are stored from index 0 to
- * typeCount (excluded). The other array entries are empty.
- */
- private int typeCount;
-
- /**
- * An ASM specific type table used to temporarily store internal names that will not necessarily
- * be stored in the constant pool. This type table is used by the control flow and data flow
- * analysis algorithm used to compute stack map frames from scratch. This array stores {@link
- * Symbol#TYPE_TAG} and {@link Symbol#UNINITIALIZED_TYPE_TAG}) Symbol. The type symbol at index
- * i has its {@link Symbol#index} equal to i (and vice versa).
- */
- private Entry[] typeTable;
-
- /**
- * Constructs a new, empty SymbolTable for the given ClassWriter.
- *
- * @param classWriter a ClassWriter.
- */
- SymbolTable(final ClassWriter classWriter) {
- this.classWriter = classWriter;
- this.entries = new Entry[256];
- this.constantPoolCount = 1;
- this.constantPool = new ByteVector();
- }
-
- /** @return the major version of the class to which this symbol table belongs. */
- int getMajorVersion() {
- return majorVersion;
- }
-
- /** @return the internal name of the class to which this symbol table belongs. */
- String getClassName() {
- return className;
- }
-
- /**
- * Sets the major version and the name of the class to which this symbol table belongs. Also adds
- * the class name to the constant pool.
- *
- * @param majorVersion a major ClassFile version number.
- * @param className an internal class name.
- * @return the constant pool index of a new or already existing Symbol with the given class name.
- */
- int setMajorVersionAndClassName(final int majorVersion, final String className) {
- this.majorVersion = majorVersion;
- this.className = className;
- return addConstantClass(className).index;
- }
-
- /** @return the number of items in this symbol table's constant_pool array (plus 1). */
- int getConstantPoolCount() {
- return constantPoolCount;
- }
-
- /** @return the length in bytes of this symbol table's constant_pool array. */
- int getConstantPoolLength() {
- return constantPool.length;
- }
-
- /**
- * Puts this symbol table's constant_pool array in the given ByteVector, preceded by the
- * constant_pool_count value.
- *
- * @param output where the JVMS ClassFile's constant_pool array must be put.
- */
- void putConstantPool(final ByteVector output) {
- output.putShort(constantPoolCount).putByteArray(constantPool.data, 0, constantPool.length);
- }
-
- /**
- * Returns the size in bytes of this symbol table's BootstrapMethods attribute. Also adds the
- * attribute name in the constant pool.
- *
- * @return the size in bytes of this symbol table's BootstrapMethods attribute.
- */
- int computeBootstrapMethodsSize() {
- if (bootstrapMethods != null) {
- addConstantUtf8(Constants.BOOTSTRAP_METHODS);
- return 8 + bootstrapMethods.length;
- } else {
- return 0;
- }
- }
-
- /**
- * Puts this symbol table's BootstrapMethods attribute in the given ByteVector. This includes the
- * 6 attribute header bytes and the num_bootstrap_methods value.
- *
- * @param output where the JVMS BootstrapMethods attribute must be put.
- */
- void putBootstrapMethods(final ByteVector output) {
- if (bootstrapMethods != null) {
- output
- .putShort(addConstantUtf8(Constants.BOOTSTRAP_METHODS))
- .putInt(bootstrapMethods.length + 2)
- .putShort(bootstrapMethodCount)
- .putByteArray(bootstrapMethods.data, 0, bootstrapMethods.length);
- }
- }
-
- // -----------------------------------------------------------------------------------------------
- // Generic symbol table entries management.
- // -----------------------------------------------------------------------------------------------
-
- /**
- * @param hashCode a {@link Entry#hashCode} value.
- * @return the list of entries which can potentially have the given hash code. The list is stored
- * via the {@link Entry#next} field.
- */
- private Entry get(final int hashCode) {
- return entries[hashCode % entries.length];
- }
-
- /**
- * Puts the given entry in the {@link #entries} hash set. This method does not check
- * whether {@link #entries} already contains a similar entry or not. {@link #entries} is resized
- * if necessary to avoid hash collisions (multiple entries needing to be stored at the same {@link
- * #entries} array index) as much as possible, with reasonable memory usage.
- *
- * @param entry an Entry (which must not already be contained in {@link #entries}).
- * @return the given entry
- */
- private Entry put(final Entry entry) {
- if (entryCount > (entries.length * 3) / 4) {
- int currentCapacity = entries.length;
- int newCapacity = currentCapacity * 2 + 1;
- Entry[] newEntries = new Entry[newCapacity];
- for (int i = currentCapacity - 1; i >= 0; --i) {
- Entry currentEntry = entries[i];
- while (currentEntry != null) {
- int newCurrentEntryIndex = currentEntry.hashCode % newCapacity;
- Entry nextEntry = currentEntry.next;
- currentEntry.next = newEntries[newCurrentEntryIndex];
- newEntries[newCurrentEntryIndex] = currentEntry;
- currentEntry = nextEntry;
- }
- }
- entries = newEntries;
- }
- entryCount++;
- int index = entry.hashCode % entries.length;
- entry.next = entries[index];
- return entries[index] = entry;
- }
-
- /**
- * Adds the given entry in the {@link #entries} hash set. This method does not check
- * whether {@link #entries} already contains a similar entry or not, and does not resize
- * {@link #entries} if necessary.
- *
- * @param entry an Entry (which must not already be contained in {@link #entries}).
- */
- private void add(final Entry entry) {
- entryCount++;
- int index = entry.hashCode % entries.length;
- entry.next = entries[index];
- entries[index] = entry;
- }
-
- // -----------------------------------------------------------------------------------------------
- // Constant pool entries management.
- // -----------------------------------------------------------------------------------------------
-
- /**
- * Adds a number or string constant to the constant pool of this symbol table. Does nothing if the
- * constant pool already contains a similar item.
- *
- * @param value the value of the constant to be added to the constant pool. This parameter must be
- * an {@link Integer}, {@link Byte}, {@link Character}, {@link Short}, {@link Boolean}, {@link
- * Float}, {@link Long}, {@link Double}, {@link String}, {@link Type} or {@link Handle}.
- * @return a new or already existing Symbol with the given value.
- */
- Symbol addConstant(final Object value) {
- if (value instanceof Integer) {
- return addConstantInteger(((Integer) value).intValue());
- } else if (value instanceof Byte) {
- return addConstantInteger(((Byte) value).intValue());
- } else if (value instanceof Character) {
- return addConstantInteger(((Character) value).charValue());
- } else if (value instanceof Short) {
- return addConstantInteger(((Short) value).intValue());
- } else if (value instanceof Boolean) {
- return addConstantInteger(((Boolean) value).booleanValue() ? 1 : 0);
- } else if (value instanceof Float) {
- return addConstantFloat(((Float) value).floatValue());
- } else if (value instanceof Long) {
- return addConstantLong(((Long) value).longValue());
- } else if (value instanceof Double) {
- return addConstantDouble(((Double) value).doubleValue());
- } else if (value instanceof String) {
- return addConstantString((String) value);
- } else if (value instanceof Type) {
- Type type = (Type) value;
- int typeSort = type.getSort();
- if (typeSort == Type.OBJECT) {
- return addConstantClass(type.getInternalName());
- } else if (typeSort == Type.METHOD) {
- return addConstantMethodType(type.getDescriptor());
- } else { // type is a primitive or array type.
- return addConstantClass(type.getDescriptor());
- }
- } else if (value instanceof Handle) {
- Handle handle = (Handle) value;
- return addConstantMethodHandle(
- handle.getTag(),
- handle.getOwner(),
- handle.getName(),
- handle.getDesc(),
- handle.isInterface());
- } else {
- throw new IllegalArgumentException("value " + value);
- }
- }
-
- /**
- * Adds a CONSTANT_Class_info to the constant pool of this symbol table. Does nothing if the
- * constant pool already contains a similar item.
- *
- * @param value the internal name of a class.
- * @return a new or already existing Symbol with the given value.
- */
- Symbol addConstantClass(final String value) {
- return addConstantUtf8Reference(Symbol.CONSTANT_CLASS_TAG, value);
- }
-
- /**
- * Adds a CONSTANT_Fieldref_info to the constant pool of this symbol table. Does nothing if the
- * constant pool already contains a similar item.
- *
- * @param owner the internal name of a class.
- * @param name a field name.
- * @param descriptor a field descriptor.
- * @return a new or already existing Symbol with the given value.
- */
- Symbol addConstantFieldref(final String owner, final String name, final String descriptor) {
- return addConstantMemberReference(Symbol.CONSTANT_FIELDREF_TAG, owner, name, descriptor);
- }
-
- /**
- * Adds a CONSTANT_Methodref_info or CONSTANT_InterfaceMethodref_info to the constant pool of this
- * symbol table. Does nothing if the constant pool already contains a similar item.
- *
- * @param owner the internal name of a class.
- * @param name a method name.
- * @param descriptor a method descriptor.
- * @param isInterface whether owner is an interface or not.
- * @return a new or already existing Symbol with the given value.
- */
- Symbol addConstantMethodref(
- final String owner, final String name, final String descriptor, final boolean isInterface) {
- int tag = isInterface ? Symbol.CONSTANT_INTERFACE_METHODREF_TAG : Symbol.CONSTANT_METHODREF_TAG;
- return addConstantMemberReference(tag, owner, name, descriptor);
- }
-
- /**
- * Adds a CONSTANT_Fieldref_info, CONSTANT_Methodref_info or CONSTANT_InterfaceMethodref_info to
- * the constant pool of this symbol table. Does nothing if the constant pool already contains a
- * similar item.
- *
- * @param tag one of {@link Symbol#CONSTANT_FIELDREF_TAG}, {@link Symbol#CONSTANT_METHODREF_TAG}
- * or {@link Symbol#CONSTANT_INTERFACE_METHODREF_TAG}.
- * @param owner the internal name of a class.
- * @param name a field or method name.
- * @param descriptor a field or method descriptor.
- * @return a new or already existing Symbol with the given value.
- */
- private Entry addConstantMemberReference(
- final int tag, final String owner, final String name, final String descriptor) {
- int hashCode = hash(tag, owner, name, descriptor);
- Entry entry = get(hashCode);
- while (entry != null) {
- if (entry.tag == tag
- && entry.hashCode == hashCode
- && entry.owner.equals(owner)
- && entry.name.equals(name)
- && entry.value.equals(descriptor)) {
- return entry;
- }
- entry = entry.next;
- }
- constantPool.put122(
- tag, addConstantClass(owner).index, addConstantNameAndType(name, descriptor));
- return put(new Entry(constantPoolCount++, tag, owner, name, descriptor, 0, hashCode));
- }
-
- /**
- * Adds a new CONSTANT_Fieldref_info, CONSTANT_Methodref_info or CONSTANT_InterfaceMethodref_info
- * to the constant pool of this symbol table.
- *
- * @param index the constant pool index of the new Symbol.
- * @param tag one of {@link Symbol#CONSTANT_FIELDREF_TAG}, {@link Symbol#CONSTANT_METHODREF_TAG}
- * or {@link Symbol#CONSTANT_INTERFACE_METHODREF_TAG}.
- * @param owner the internal name of a class.
- * @param name a field or method name.
- * @param descriptor a field or method descriptor.
- */
- private void addConstantMemberReference(
- final int index,
- final int tag,
- final String owner,
- final String name,
- final String descriptor) {
- add(new Entry(index, tag, owner, name, descriptor, 0, hash(tag, owner, name, descriptor)));
- }
-
- /**
- * Adds a CONSTANT_String_info to the constant pool of this symbol table. Does nothing if the
- * constant pool already contains a similar item.
- *
- * @param value a string.
- * @return a new or already existing Symbol with the given value.
- */
- Symbol addConstantString(final String value) {
- return addConstantUtf8Reference(Symbol.CONSTANT_STRING_TAG, value);
- }
-
- /**
- * Adds a CONSTANT_Integer_info to the constant pool of this symbol table. Does nothing if the
- * constant pool already contains a similar item.
- *
- * @param value an int.
- * @return a new or already existing Symbol with the given value.
- */
- Symbol addConstantInteger(final int value) {
- return addConstantInteger(Symbol.CONSTANT_INTEGER_TAG, value);
- }
-
- /**
- * Adds a CONSTANT_Float_info to the constant pool of this symbol table. Does nothing if the
- * constant pool already contains a similar item.
- *
- * @param value a float.
- * @return a new or already existing Symbol with the given value.
- */
- Symbol addConstantFloat(final float value) {
- return addConstantInteger(Symbol.CONSTANT_FLOAT_TAG, Float.floatToRawIntBits(value));
- }
-
- /**
- * Adds a CONSTANT_Integer_info or CONSTANT_Float_info to the constant pool of this symbol table.
- * Does nothing if the constant pool already contains a similar item.
- *
- * @param tag one of {@link Symbol#CONSTANT_INTEGER_TAG} or {@link Symbol#CONSTANT_FLOAT_TAG}.
- * @param value an int or float.
- * @return a constant pool constant with the given tag and primitive values.
- */
- private Symbol addConstantInteger(final int tag, final int value) {
- int hashCode = hash(tag, value);
- Entry entry = get(hashCode);
- while (entry != null) {
- if (entry.tag == tag && entry.hashCode == hashCode && entry.data == value) {
- return entry;
- }
- entry = entry.next;
- }
- constantPool.putByte(tag).putInt(value);
- return put(new Entry(constantPoolCount++, tag, value, hashCode));
- }
-
- /**
- * Adds a new CONSTANT_Integer_info or CONSTANT_Float_info to the constant pool of this symbol
- * table.
- *
- * @param index the constant pool index of the new Symbol.
- * @param tag one of {@link Symbol#CONSTANT_INTEGER_TAG} or {@link Symbol#CONSTANT_FLOAT_TAG}.
- * @param value an int or float.
- */
- private void addConstantInteger(final int index, final int tag, final int value) {
- add(new Entry(index, tag, value, hash(tag, value)));
- }
-
- /**
- * Adds a CONSTANT_Long_info to the constant pool of this symbol table. Does nothing if the
- * constant pool already contains a similar item.
- *
- * @param value a long.
- * @return a new or already existing Symbol with the given value.
- */
- Symbol addConstantLong(final long value) {
- return addConstantLong(Symbol.CONSTANT_LONG_TAG, value);
- }
-
- /**
- * Adds a CONSTANT_Double_info to the constant pool of this symbol table. Does nothing if the
- * constant pool already contains a similar item.
- *
- * @param value a double.
- * @return a new or already existing Symbol with the given value.
- */
- Symbol addConstantDouble(final double value) {
- return addConstantLong(Symbol.CONSTANT_DOUBLE_TAG, Double.doubleToRawLongBits(value));
- }
-
- /**
- * Adds a CONSTANT_Long_info or CONSTANT_Double_info to the constant pool of this symbol table.
- * Does nothing if the constant pool already contains a similar item.
- *
- * @param tag one of {@link Symbol#CONSTANT_LONG_TAG} or {@link Symbol#CONSTANT_DOUBLE_TAG}.
- * @param value a long or double.
- * @return a constant pool constant with the given tag and primitive values.
- */
- private Symbol addConstantLong(final int tag, final long value) {
- int hashCode = hash(tag, value);
- Entry entry = get(hashCode);
- while (entry != null) {
- if (entry.tag == tag && entry.hashCode == hashCode && entry.data == value) {
- return entry;
- }
- entry = entry.next;
- }
- int index = constantPoolCount;
- constantPool.putByte(tag).putLong(value);
- constantPoolCount += 2;
- return put(new Entry(index, tag, value, hashCode));
- }
-
- /**
- * Adds a new CONSTANT_Double_info to the constant pool of this symbol table.
- *
- * @param index the constant pool index of the new Symbol.
- * @param tag one of {@link Symbol#CONSTANT_LONG_TAG} or {@link Symbol#CONSTANT_DOUBLE_TAG}.
- * @param value a long or double.
- */
- private void addConstantLong(final int index, final int tag, final long value) {
- add(new Entry(index, tag, value, hash(tag, value)));
- }
-
- /**
- * Adds a CONSTANT_NameAndType_info to the constant pool of this symbol table. Does nothing if the
- * constant pool already contains a similar item.
- *
- * @param name a field or method name.
- * @param descriptor a field or method descriptor.
- * @return a new or already existing Symbol with the given value.
- */
- int addConstantNameAndType(final String name, final String descriptor) {
- final int tag = Symbol.CONSTANT_NAME_AND_TYPE_TAG;
- int hashCode = hash(tag, name, descriptor);
- Entry entry = get(hashCode);
- while (entry != null) {
- if (entry.tag == tag
- && entry.hashCode == hashCode
- && entry.name.equals(name)
- && entry.value.equals(descriptor)) {
- return entry.index;
- }
- entry = entry.next;
- }
- constantPool.put122(tag, addConstantUtf8(name), addConstantUtf8(descriptor));
- return put(new Entry(constantPoolCount++, tag, name, descriptor, hashCode)).index;
- }
-
- /**
- * Adds a new CONSTANT_NameAndType_info to the constant pool of this symbol table.
- *
- * @param index the constant pool index of the new Symbol.
- * @param name a field or method name.
- * @param descriptor a field or method descriptor.
- */
- private void addConstantNameAndType(final int index, final String name, final String descriptor) {
- final int tag = Symbol.CONSTANT_NAME_AND_TYPE_TAG;
- add(new Entry(index, tag, name, descriptor, hash(tag, name, descriptor)));
- }
-
- /**
- * Adds a CONSTANT_Utf8_info to the constant pool of this symbol table. Does nothing if the
- * constant pool already contains a similar item.
- *
- * @param value a string.
- * @return a new or already existing Symbol with the given value.
- */
- int addConstantUtf8(final String value) {
- int hashCode = hash(Symbol.CONSTANT_UTF8_TAG, value);
- Entry entry = get(hashCode);
- while (entry != null) {
- if (entry.tag == Symbol.CONSTANT_UTF8_TAG
- && entry.hashCode == hashCode
- && entry.value.equals(value)) {
- return entry.index;
- }
- entry = entry.next;
- }
- constantPool.putByte(Symbol.CONSTANT_UTF8_TAG).putUTF8(value);
- return put(new Entry(constantPoolCount++, Symbol.CONSTANT_UTF8_TAG, value, hashCode)).index;
- }
-
- /**
- * Adds a new CONSTANT_String_info to the constant pool of this symbol table.
- *
- * @param index the constant pool index of the new Symbol.
- * @param value a string.
- */
- private void addConstantUtf8(final int index, final String value) {
- add(new Entry(index, Symbol.CONSTANT_UTF8_TAG, value, hash(Symbol.CONSTANT_UTF8_TAG, value)));
- }
-
- /**
- * Adds a CONSTANT_MethodHandle_info to the constant pool of this symbol table. Does nothing if
- * the constant pool already contains a similar item.
- *
- * @param referenceKind one of {@link Opcodes#H_GETFIELD}, {@link Opcodes#H_GETSTATIC}, {@link
- * Opcodes#H_PUTFIELD}, {@link Opcodes#H_PUTSTATIC}, {@link Opcodes#H_INVOKEVIRTUAL}, {@link
- * Opcodes#H_INVOKESTATIC}, {@link Opcodes#H_INVOKESPECIAL}, {@link
- * Opcodes#H_NEWINVOKESPECIAL} or {@link Opcodes#H_INVOKEINTERFACE}.
- * @param owner the internal name of a class of interface.
- * @param name a field or method name.
- * @param descriptor a field or method descriptor.
- * @param isInterface whether owner is an interface or not.
- * @return a new or already existing Symbol with the given value.
- */
- Symbol addConstantMethodHandle(
- final int referenceKind,
- final String owner,
- final String name,
- final String descriptor,
- final boolean isInterface) {
- final int tag = Symbol.CONSTANT_METHOD_HANDLE_TAG;
- // Note that we don't need to include isInterface in the hash computation, because it is
- // redundant with owner (we can't have the same owner with different isInterface values).
- int hashCode = hash(tag, owner, name, descriptor, referenceKind);
- Entry entry = get(hashCode);
- while (entry != null) {
- if (entry.tag == tag
- && entry.hashCode == hashCode
- && entry.data == referenceKind
- && entry.owner.equals(owner)
- && entry.name.equals(name)
- && entry.value.equals(descriptor)) {
- return entry;
- }
- entry = entry.next;
- }
- if (referenceKind <= Opcodes.H_PUTSTATIC) {
- constantPool.put112(tag, referenceKind, addConstantFieldref(owner, name, descriptor).index);
- } else {
- constantPool.put112(
- tag, referenceKind, addConstantMethodref(owner, name, descriptor, isInterface).index);
- }
- return put(
- new Entry(constantPoolCount++, tag, owner, name, descriptor, referenceKind, hashCode));
- }
-
- /**
- * Adds a new CONSTANT_MethodHandle_info to the constant pool of this symbol table.
- *
- * @param index the constant pool index of the new Symbol.
- * @param referenceKind one of {@link Opcodes#H_GETFIELD}, {@link Opcodes#H_GETSTATIC}, {@link
- * Opcodes#H_PUTFIELD}, {@link Opcodes#H_PUTSTATIC}, {@link Opcodes#H_INVOKEVIRTUAL}, {@link
- * Opcodes#H_INVOKESTATIC}, {@link Opcodes#H_INVOKESPECIAL}, {@link
- * Opcodes#H_NEWINVOKESPECIAL} or {@link Opcodes#H_INVOKEINTERFACE}.
- * @param owner the internal name of a class of interface.
- * @param name a field or method name.
- * @param descriptor a field or method descriptor.
- */
- private void addConstantMethodHandle(
- final int index,
- final int referenceKind,
- final String owner,
- final String name,
- final String descriptor) {
- final int tag = Symbol.CONSTANT_METHOD_HANDLE_TAG;
- int hashCode = hash(tag, owner, name, descriptor, referenceKind);
- add(new Entry(index, tag, owner, name, descriptor, referenceKind, hashCode));
- }
-
- /**
- * Adds a CONSTANT_MethodType_info to the constant pool of this symbol table. Does nothing if the
- * constant pool already contains a similar item.
- *
- * @param methodDescriptor a method descriptor.
- * @return a new or already existing Symbol with the given value.
- */
- Symbol addConstantMethodType(final String methodDescriptor) {
- return addConstantUtf8Reference(Symbol.CONSTANT_METHOD_TYPE_TAG, methodDescriptor);
- }
-
- /**
- * Adds a CONSTANT_Dynamic_info to the constant pool of this symbol table. Also adds the related
- * bootstrap method to the BootstrapMethods of this symbol table. Does nothing if the constant
- * pool already contains a similar item.
- *
- * @param name a method name.
- * @param descriptor a field descriptor.
- * @param bootstrapMethodHandle a bootstrap method handle.
- * @param bootstrapMethodArguments the bootstrap method arguments.
- * @return a new or already existing Symbol with the given value.
- */
- Symbol addConstantDynamic(
- final String name,
- final String descriptor,
- final Handle bootstrapMethodHandle,
- final Object... bootstrapMethodArguments) {
- Symbol bootstrapMethod = addBootstrapMethod(bootstrapMethodHandle, bootstrapMethodArguments);
- return addConstantDynamicOrInvokeDynamicReference(
- Symbol.CONSTANT_DYNAMIC_TAG, name, descriptor, bootstrapMethod.index);
- }
-
- /**
- * Adds a CONSTANT_InvokeDynamic_info to the constant pool of this symbol table. Also adds the
- * related bootstrap method to the BootstrapMethods of this symbol table. Does nothing if the
- * constant pool already contains a similar item.
- *
- * @param name a method name.
- * @param descriptor a method descriptor.
- * @param bootstrapMethodHandle a bootstrap method handle.
- * @param bootstrapMethodArguments the bootstrap method arguments.
- * @return a new or already existing Symbol with the given value.
- */
- Symbol addConstantInvokeDynamic(
- final String name,
- final String descriptor,
- final Handle bootstrapMethodHandle,
- final Object... bootstrapMethodArguments) {
- Symbol bootstrapMethod = addBootstrapMethod(bootstrapMethodHandle, bootstrapMethodArguments);
- return addConstantDynamicOrInvokeDynamicReference(
- Symbol.CONSTANT_INVOKE_DYNAMIC_TAG, name, descriptor, bootstrapMethod.index);
- }
-
- /**
- * Adds a CONSTANT_Dynamic or a CONSTANT_InvokeDynamic_info to the constant pool of this symbol
- * table. Does nothing if the constant pool already contains a similar item.
- *
- * @param tag one of {@link Symbol#CONSTANT_DYNAMIC_TAG} or {@link
- * Symbol#CONSTANT_INVOKE_DYNAMIC_TAG}.
- * @param name a method name.
- * @param descriptor a field descriptor for CONSTANT_DYNAMIC_TAG) or a method descriptor for
- * CONSTANT_INVOKE_DYNAMIC_TAG.
- * @param bootstrapMethodIndex the index of a bootstrap method in the BootstrapMethods attribute.
- * @return a new or already existing Symbol with the given value.
- */
- private Symbol addConstantDynamicOrInvokeDynamicReference(
- final int tag, final String name, final String descriptor, final int bootstrapMethodIndex) {
- int hashCode = hash(tag, name, descriptor, bootstrapMethodIndex);
- Entry entry = get(hashCode);
- while (entry != null) {
- if (entry.tag == tag
- && entry.hashCode == hashCode
- && entry.data == bootstrapMethodIndex
- && entry.name.equals(name)
- && entry.value.equals(descriptor)) {
- return entry;
- }
- entry = entry.next;
- }
- constantPool.put122(tag, bootstrapMethodIndex, addConstantNameAndType(name, descriptor));
- return put(
- new Entry(
- constantPoolCount++, tag, null, name, descriptor, bootstrapMethodIndex, hashCode));
- }
-
- /**
- * Adds a new CONSTANT_Dynamic_info or CONSTANT_InvokeDynamic_info to the constant pool of this
- * symbol table.
- *
- * @param tag one of {@link Symbol#CONSTANT_DYNAMIC_TAG} or {@link
- * Symbol#CONSTANT_INVOKE_DYNAMIC_TAG}.
- * @param index the constant pool index of the new Symbol.
- * @param name a method name.
- * @param descriptor a field descriptor for CONSTANT_DYNAMIC_TAG or a method descriptor for
- * CONSTANT_INVOKE_DYNAMIC_TAG.
- * @param bootstrapMethodIndex the index of a bootstrap method in the BootstrapMethods attribute.
- */
- private void addConstantDynamicOrInvokeDynamicReference(
- final int tag,
- final int index,
- final String name,
- final String descriptor,
- final int bootstrapMethodIndex) {
- int hashCode = hash(tag, name, descriptor, bootstrapMethodIndex);
- add(new Entry(index, tag, null, name, descriptor, bootstrapMethodIndex, hashCode));
- }
-
- /**
- * Adds a CONSTANT_Module_info to the constant pool of this symbol table. Does nothing if the
- * constant pool already contains a similar item.
- *
- * @param moduleName a fully qualified name (using dots) of a module.
- * @return a new or already existing Symbol with the given value.
- */
- Symbol addConstantModule(final String moduleName) {
- return addConstantUtf8Reference(Symbol.CONSTANT_MODULE_TAG, moduleName);
- }
-
- /**
- * Adds a CONSTANT_Package_info to the constant pool of this symbol table. Does nothing if the
- * constant pool already contains a similar item.
- *
- * @param packageName the internal name of a package.
- * @return a new or already existing Symbol with the given value.
- */
- Symbol addConstantPackage(final String packageName) {
- return addConstantUtf8Reference(Symbol.CONSTANT_PACKAGE_TAG, packageName);
- }
-
- /**
- * Adds a CONSTANT_Class_info, CONSTANT_String_info, CONSTANT_MethodType_info,
- * CONSTANT_Module_info or CONSTANT_Package_info to the constant pool of this symbol table. Does
- * nothing if the constant pool already contains a similar item.
- *
- * @param tag one of {@link Symbol#CONSTANT_CLASS_TAG}, {@link Symbol#CONSTANT_STRING_TAG}, {@link
- * Symbol#CONSTANT_METHOD_TYPE_TAG}, {@link Symbol#CONSTANT_MODULE_TAG} or {@link
- * Symbol#CONSTANT_PACKAGE_TAG}.
- * @param value an internal class name, an arbitrary string, a method descriptor, a module or a
- * package name, depending on tag.
- * @return a new or already existing Symbol with the given value.
- */
- private Symbol addConstantUtf8Reference(final int tag, final String value) {
- int hashCode = hash(tag, value);
- Entry entry = get(hashCode);
- while (entry != null) {
- if (entry.tag == tag && entry.hashCode == hashCode && entry.value.equals(value)) {
- return entry;
- }
- entry = entry.next;
- }
- constantPool.put12(tag, addConstantUtf8(value));
- return put(new Entry(constantPoolCount++, tag, value, hashCode));
- }
-
- /**
- * Adds a new CONSTANT_Class_info, CONSTANT_String_info, CONSTANT_MethodType_info,
- * CONSTANT_Module_info or CONSTANT_Package_info to the constant pool of this symbol table.
- *
- * @param index the constant pool index of the new Symbol.
- * @param tag one of {@link Symbol#CONSTANT_CLASS_TAG}, {@link Symbol#CONSTANT_STRING_TAG}, {@link
- * Symbol#CONSTANT_METHOD_TYPE_TAG}, {@link Symbol#CONSTANT_MODULE_TAG} or {@link
- * Symbol#CONSTANT_PACKAGE_TAG}.
- * @param value an internal class name, an arbitrary string, a method descriptor, a module or a
- * package name, depending on tag.
- */
- private void addConstantUtf8Reference(final int index, final int tag, final String value) {
- add(new Entry(index, tag, value, hash(tag, value)));
- }
-
- // -----------------------------------------------------------------------------------------------
- // Bootstrap method entries management.
- // -----------------------------------------------------------------------------------------------
-
- /**
- * Adds a bootstrap method to the BootstrapMethods attribute of this symbol table. Does nothing if
- * the BootstrapMethods already contains a similar bootstrap method.
- *
- * @param bootstrapMethodHandle a bootstrap method handle.
- * @param bootstrapMethodArguments the bootstrap method arguments.
- * @return a new or already existing Symbol with the given value.
- */
- Symbol addBootstrapMethod(
- final Handle bootstrapMethodHandle, final Object... bootstrapMethodArguments) {
- ByteVector bootstrapMethodsAttribute = bootstrapMethods;
- if (bootstrapMethodsAttribute == null) {
- bootstrapMethodsAttribute = bootstrapMethods = new ByteVector();
- }
-
- // The bootstrap method arguments can be Constant_Dynamic values, which reference other
- // bootstrap methods. We must therefore add the bootstrap method arguments to the constant pool
- // and BootstrapMethods attribute first, so that the BootstrapMethods attribute is not modified
- // while adding the given bootstrap method to it, in the rest of this method.
- for (Object bootstrapMethodArgument : bootstrapMethodArguments) {
- addConstant(bootstrapMethodArgument);
- }
-
- // Write the bootstrap method in the BootstrapMethods table. This is necessary to be able to
- // compare it with existing ones, and will be reverted below if there is already a similar
- // bootstrap method.
- int bootstrapMethodOffset = bootstrapMethodsAttribute.length;
- bootstrapMethodsAttribute.putShort(
- addConstantMethodHandle(
- bootstrapMethodHandle.getTag(),
- bootstrapMethodHandle.getOwner(),
- bootstrapMethodHandle.getName(),
- bootstrapMethodHandle.getDesc(),
- bootstrapMethodHandle.isInterface())
- .index);
- int numBootstrapArguments = bootstrapMethodArguments.length;
- bootstrapMethodsAttribute.putShort(numBootstrapArguments);
- for (Object bootstrapMethodArgument : bootstrapMethodArguments) {
- bootstrapMethodsAttribute.putShort(addConstant(bootstrapMethodArgument).index);
- }
-
- // Compute the length and the hash code of the bootstrap method.
- int bootstrapMethodlength = bootstrapMethodsAttribute.length - bootstrapMethodOffset;
- int hashCode = bootstrapMethodHandle.hashCode();
- for (Object bootstrapMethodArgument : bootstrapMethodArguments) {
- hashCode ^= bootstrapMethodArgument.hashCode();
- }
- hashCode &= 0x7FFFFFFF;
-
- // Add the bootstrap method to the symbol table or revert the above changes.
- return addBootstrapMethod(bootstrapMethodOffset, bootstrapMethodlength, hashCode);
- }
-
- /**
- * Adds a bootstrap method to the BootstrapMethods attribute of this symbol table. Does nothing if
- * the BootstrapMethods already contains a similar bootstrap method (more precisely, reverts the
- * content of {@link #bootstrapMethods} to remove the last, duplicate bootstrap method).
- *
- * @param offset the offset of the last bootstrap method in {@link #bootstrapMethods}, in bytes.
- * @param length the length of this bootstrap method in {@link #bootstrapMethods}, in bytes.
- * @param hashCode the hash code of this bootstrap method.
- * @return a new or already existing Symbol with the given value.
- */
- private Symbol addBootstrapMethod(final int offset, final int length, final int hashCode) {
- final byte[] bootstrapMethodsData = bootstrapMethods.data;
- Entry entry = get(hashCode);
- while (entry != null) {
- if (entry.tag == Symbol.BOOTSTRAP_METHOD_TAG && entry.hashCode == hashCode) {
- int otherOffset = (int) entry.data;
- boolean isSameBootstrapMethod = true;
- for (int i = 0; i < length; ++i) {
- if (bootstrapMethodsData[offset + i] != bootstrapMethodsData[otherOffset + i]) {
- isSameBootstrapMethod = false;
- break;
- }
- }
- if (isSameBootstrapMethod) {
- bootstrapMethods.length = offset; // Revert to old position.
- return entry;
- }
- }
- entry = entry.next;
- }
- return put(new Entry(bootstrapMethodCount++, Symbol.BOOTSTRAP_METHOD_TAG, offset, hashCode));
- }
-
- // -----------------------------------------------------------------------------------------------
- // Type table entries management.
- // -----------------------------------------------------------------------------------------------
-
- /**
- * @param typeIndex a type table index.
- * @return the type table element whose index is given.
- */
- Symbol getType(final int typeIndex) {
- return typeTable[typeIndex];
- }
-
- /**
- * Adds a type in the type table of this symbol table. Does nothing if the type table already
- * contains a similar type.
- *
- * @param value an internal class name.
- * @return the index of a new or already existing type Symbol with the given value.
- */
- int addType(final String value) {
- int hashCode = hash(Symbol.TYPE_TAG, value);
- Entry entry = get(hashCode);
- while (entry != null) {
- if (entry.tag == Symbol.TYPE_TAG && entry.hashCode == hashCode && entry.value.equals(value)) {
- return entry.index;
- }
- entry = entry.next;
- }
- return addType(new Entry(typeCount, Symbol.TYPE_TAG, value, hashCode));
- }
-
- /**
- * Adds an {@link Frame#ITEM_UNINITIALIZED} type in the type table of this symbol table. Does
- * nothing if the type table already contains a similar type.
- *
- * @param value an internal class name.
- * @param bytecodeOffset the bytecode offset of the NEW instruction that created this {@link
- * Frame#ITEM_UNINITIALIZED} type value.
- * @return the index of a new or already existing type Symbol with the given value.
- */
- int addUninitializedType(final String value, final int bytecodeOffset) {
- int hashCode = hash(Symbol.UNINITIALIZED_TYPE_TAG, value, bytecodeOffset);
- Entry entry = get(hashCode);
- while (entry != null) {
- if (entry.tag == Symbol.UNINITIALIZED_TYPE_TAG
- && entry.hashCode == hashCode
- && entry.data == bytecodeOffset
- && entry.value.equals(value)) {
- return entry.index;
- }
- entry = entry.next;
- }
- return addType(
- new Entry(typeCount, Symbol.UNINITIALIZED_TYPE_TAG, value, bytecodeOffset, hashCode));
- }
-
- /**
- * Adds a merged type in the type table of this symbol table. Does nothing if the type table
- * already contains a similar type.
- *
- * @param typeTableIndex1 a {@link Symbol#TYPE_TAG} type, specified by its index in the type
- * table.
- * @param typeTableIndex2 another {@link Symbol#TYPE_TAG} type, specified by its index in the type
- * table.
- * @return the index of a new or already existing {@link Symbol#TYPE_TAG} type Symbol,
- * corresponding to the common super class of the given types.
- */
- int addMergedType(final int typeTableIndex1, final int typeTableIndex2) {
- // TODO sort the arguments? The merge result should be independent of their order.
- long data = typeTableIndex1 | (((long) typeTableIndex2) << 32);
- int hashCode = hash(Symbol.MERGED_TYPE_TAG, typeTableIndex1 + typeTableIndex2);
- Entry entry = get(hashCode);
- while (entry != null) {
- if (entry.tag == Symbol.MERGED_TYPE_TAG && entry.hashCode == hashCode && entry.data == data) {
- return entry.info;
- }
- entry = entry.next;
- }
- String type1 = typeTable[typeTableIndex1].value;
- String type2 = typeTable[typeTableIndex2].value;
- int commonSuperTypeIndex = addType(classWriter.getCommonSuperClass(type1, type2));
- put(new Entry(typeCount, Symbol.MERGED_TYPE_TAG, data, hashCode)).info = commonSuperTypeIndex;
- return commonSuperTypeIndex;
- }
-
- /**
- * Adds the given type Symbol to {@link #typeTable}.
- *
- * @param entry a {@link Symbol#TYPE_TAG} or {@link Symbol#UNINITIALIZED_TYPE_TAG} type symbol.
- * The index of this Symbol must be equal to the current value of {@link #typeCount}.
- * @return the index in {@link #typeTable} where the given type was added, which is also equal to
- * entry's index by hypothesis.
- */
- private int addType(final Entry entry) {
- if (typeTable == null) {
- typeTable = new Entry[16];
- }
- if (typeCount == typeTable.length) {
- Entry[] newTypeTable = new Entry[2 * typeTable.length];
- System.arraycopy(typeTable, 0, newTypeTable, 0, typeTable.length);
- typeTable = newTypeTable;
- }
- typeTable[typeCount++] = entry;
- return put(entry).index;
- }
-
- // -----------------------------------------------------------------------------------------------
- // Static helper methods to compute hash codes.
- // -----------------------------------------------------------------------------------------------
-
- private static int hash(final int tag, final int value) {
- return 0x7FFFFFFF & (tag + value);
- }
-
- private static int hash(final int tag, final long value) {
- return 0x7FFFFFFF & (tag + (int) value + (int) (value >>> 32));
- }
-
- private static int hash(final int tag, final String value) {
- return 0x7FFFFFFF & (tag + value.hashCode());
- }
-
- private static int hash(final int tag, final String value1, final int value2) {
- return 0x7FFFFFFF & (tag + value1.hashCode() + value2);
- }
-
- private static int hash(final int tag, final String value1, final String value2) {
- return 0x7FFFFFFF & (tag + value1.hashCode() * value2.hashCode());
- }
-
- private static int hash(
- final int tag, final String value1, final String value2, final int value3) {
- return 0x7FFFFFFF & (tag + value1.hashCode() * value2.hashCode() * (value3 + 1));
- }
-
- private static int hash(
- final int tag, final String value1, final String value2, final String value3) {
- return 0x7FFFFFFF & (tag + value1.hashCode() * value2.hashCode() * value3.hashCode());
- }
-
- private static int hash(
- final int tag,
- final String value1,
- final String value2,
- final String value3,
- final int value4) {
- return 0x7FFFFFFF & (tag + value1.hashCode() * value2.hashCode() * value3.hashCode() * value4);
- }
-}
diff --git a/scripts/cn1playground/common/src/main/java/bsh/org/objectweb/asm/Type.java b/scripts/cn1playground/common/src/main/java/bsh/org/objectweb/asm/Type.java
deleted file mode 100644
index 9ee5a396ce..0000000000
--- a/scripts/cn1playground/common/src/main/java/bsh/org/objectweb/asm/Type.java
+++ /dev/null
@@ -1,906 +0,0 @@
-// ASM: a very small and fast Java bytecode manipulation framework
-// Copyright (c) 2000-2011 INRIA, France Telecom
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions
-// are met:
-// 1. Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// 2. Redistributions in binary form must reproduce the above copyright
-// notice, this list of conditions and the following disclaimer in the
-// documentation and/or other materials provided with the distribution.
-// 3. Neither the name of the copyright holders nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
-// THE POSSIBILITY OF SUCH DAMAGE.
-package bsh.org.objectweb.asm;
-
-import java.lang.reflect.Constructor;
-import java.lang.reflect.Method;
-
-/**
- * A Java field or method type. This class can be used to make it easier to manipulate type and
- * method descriptors.
- *
- * @author Eric Bruneton
- * @author Chris Nokleberg
- */
-public class Type {
-
- /** The sort of the void type. See {@link #getSort}. */
- public static final int VOID = 0;
-
- /** The sort of the boolean type. See {@link #getSort}. */
- public static final int BOOLEAN = 1;
-
- /** The sort of the char type. See {@link #getSort}. */
- public static final int CHAR = 2;
-
- /** The sort of the byte type. See {@link #getSort}. */
- public static final int BYTE = 3;
-
- /** The sort of the short type. See {@link #getSort}. */
- public static final int SHORT = 4;
-
- /** The sort of the int type. See {@link #getSort}. */
- public static final int INT = 5;
-
- /** The sort of the float type. See {@link #getSort}. */
- public static final int FLOAT = 6;
-
- /** The sort of the long type. See {@link #getSort}. */
- public static final int LONG = 7;
-
- /** The sort of the double type. See {@link #getSort}. */
- public static final int DOUBLE = 8;
-
- /** The sort of array reference types. See {@link #getSort}. */
- public static final int ARRAY = 9;
-
- /** The sort of object reference types. See {@link #getSort}. */
- public static final int OBJECT = 10;
-
- /** The sort of method types. See {@link #getSort}. */
- public static final int METHOD = 11;
-
- /** The (private) sort of object reference types represented with an internal name. */
- private static final int INTERNAL = 12;
-
- /** The descriptors of the primitive types. */
- private static final String PRIMITIVE_DESCRIPTORS = "VZCBSIFJD";
-
- /** The void type. */
- public static final Type VOID_TYPE = new Type(VOID, PRIMITIVE_DESCRIPTORS, VOID, VOID + 1);
-
- /** The boolean type. */
- public static final Type BOOLEAN_TYPE =
- new Type(BOOLEAN, PRIMITIVE_DESCRIPTORS, BOOLEAN, BOOLEAN + 1);
-
- /** The char type. */
- public static final Type CHAR_TYPE = new Type(CHAR, PRIMITIVE_DESCRIPTORS, CHAR, CHAR + 1);
-
- /** The byte type. */
- public static final Type BYTE_TYPE = new Type(BYTE, PRIMITIVE_DESCRIPTORS, BYTE, BYTE + 1);
-
- /** The short type. */
- public static final Type SHORT_TYPE = new Type(SHORT, PRIMITIVE_DESCRIPTORS, SHORT, SHORT + 1);
-
- /** The int type. */
- public static final Type INT_TYPE = new Type(INT, PRIMITIVE_DESCRIPTORS, INT, INT + 1);
-
- /** The float type. */
- public static final Type FLOAT_TYPE = new Type(FLOAT, PRIMITIVE_DESCRIPTORS, FLOAT, FLOAT + 1);
-
- /** The long type. */
- public static final Type LONG_TYPE = new Type(LONG, PRIMITIVE_DESCRIPTORS, LONG, LONG + 1);
-
- /** The double type. */
- public static final Type DOUBLE_TYPE =
- new Type(DOUBLE, PRIMITIVE_DESCRIPTORS, DOUBLE, DOUBLE + 1);
-
- // -----------------------------------------------------------------------------------------------
- // Fields
- // -----------------------------------------------------------------------------------------------
-
- /**
- * The sort of this type. Either {@link #VOID}, {@link #BOOLEAN}, {@link #CHAR}, {@link #BYTE},
- * {@link #SHORT}, {@link #INT}, {@link #FLOAT}, {@link #LONG}, {@link #DOUBLE}, {@link #ARRAY},
- * {@link #OBJECT}, {@link #METHOD} or {@link #INTERNAL}.
- */
- private final int sort;
-
- /**
- * A buffer containing the value of this field or method type. This value is an internal name for
- * {@link #OBJECT} and {@link #INTERNAL} types, and a field or method descriptor in the other
- * cases.
- *
- *
- * Type.getType(methodDescriptor).
- *
- * @param methodDescriptor a method descriptor.
- * @return the {@link Type} corresponding to the given method descriptor.
- */
- public static Type getMethodType(final String methodDescriptor) {
- return new Type(METHOD, methodDescriptor, 0, methodDescriptor.length());
- }
-
- /**
- * Returns the method {@link Type} corresponding to the given argument and return types.
- *
- * @param returnType the return type of the method.
- * @param argumentTypes the argument types of the method.
- * @return the method {@link Type} corresponding to the given argument and return types.
- */
- public static Type getMethodType(final Type returnType, final Type... argumentTypes) {
- return getType(getMethodDescriptor(returnType, argumentTypes));
- }
-
- /**
- * Returns the {@link Type} corresponding to the given class.
- *
- * @param clazz a class.
- * @return the {@link Type} corresponding to the given class.
- */
- public static Type getType(final Class> clazz) {
- if (clazz.isPrimitive()) {
- if (clazz == Integer.TYPE) {
- return INT_TYPE;
- } else if (clazz == Void.TYPE) {
- return VOID_TYPE;
- } else if (clazz == Boolean.TYPE) {
- return BOOLEAN_TYPE;
- } else if (clazz == Byte.TYPE) {
- return BYTE_TYPE;
- } else if (clazz == Character.TYPE) {
- return CHAR_TYPE;
- } else if (clazz == Short.TYPE) {
- return SHORT_TYPE;
- } else if (clazz == Double.TYPE) {
- return DOUBLE_TYPE;
- } else if (clazz == Float.TYPE) {
- return FLOAT_TYPE;
- } else if (clazz == Long.TYPE) {
- return LONG_TYPE;
- } else {
- throw new AssertionError();
- }
- } else {
- return getType(getDescriptor(clazz));
- }
- }
-
- /**
- * Returns the method {@link Type} corresponding to the given constructor.
- *
- * @param constructor a {@link Constructor} object.
- * @return the method {@link Type} corresponding to the given constructor.
- */
- public static Type getType(final Constructor> constructor) {
- return getType(getConstructorDescriptor(constructor));
- }
-
- /**
- * Returns the method {@link Type} corresponding to the given method.
- *
- * @param method a {@link Method} object.
- * @return the method {@link Type} corresponding to the given method.
- */
- public static Type getType(final Method method) {
- return getType(getMethodDescriptor(method));
- }
-
- /**
- * Returns the {@link Type} values corresponding to the argument types of the given method
- * descriptor.
- *
- * @param methodDescriptor a method descriptor.
- * @return the {@link Type} values corresponding to the argument types of the given method
- * descriptor.
- */
- public static Type[] getArgumentTypes(final String methodDescriptor) {
- // First step: compute the number of argument types in methodDescriptor.
- int numArgumentTypes = 0;
- // Skip the first character, which is always a '('.
- int currentOffset = 1;
- // Parse the argument types, one at a each loop iteration.
- while (methodDescriptor.charAt(currentOffset) != ')') {
- while (methodDescriptor.charAt(currentOffset) == '[') {
- currentOffset++;
- }
- if (methodDescriptor.charAt(currentOffset++) == 'L') {
- while (methodDescriptor.charAt(currentOffset++) != ';') {
- // Skip the argument descriptor content.
- }
- }
- ++numArgumentTypes;
- }
-
- // Second step: create a Type instance for each argument type.
- Type[] argumentTypes = new Type[numArgumentTypes];
- // Skip the first character, which is always a '('.
- currentOffset = 1;
- // Parse and create the argument types, one at each loop iteration.
- int currentArgumentTypeIndex = 0;
- while (methodDescriptor.charAt(currentOffset) != ')') {
- final int currentArgumentTypeOffset = currentOffset;
- while (methodDescriptor.charAt(currentOffset) == '[') {
- currentOffset++;
- }
- if (methodDescriptor.charAt(currentOffset++) == 'L') {
- while (methodDescriptor.charAt(currentOffset++) != ';') {
- // Skip the argument descriptor content.
- }
- }
- argumentTypes[currentArgumentTypeIndex++] =
- getType(methodDescriptor, currentArgumentTypeOffset, currentOffset);
- }
- return argumentTypes;
- }
-
- /**
- * Returns the {@link Type} values corresponding to the argument types of the given method.
- *
- * @param method a method.
- * @return the {@link Type} values corresponding to the argument types of the given method.
- */
- public static Type[] getArgumentTypes(final Method method) {
- Class>[] classes = method.getParameterTypes();
- Type[] types = new Type[classes.length];
- for (int i = classes.length - 1; i >= 0; --i) {
- types[i] = getType(classes[i]);
- }
- return types;
- }
-
- /**
- * Returns the {@link Type} corresponding to the return type of the given method descriptor.
- *
- * @param methodDescriptor a method descriptor.
- * @return the {@link Type} corresponding to the return type of the given method descriptor.
- */
- public static Type getReturnType(final String methodDescriptor) {
- // Skip the first character, which is always a '('.
- int currentOffset = 1;
- // Skip the argument types, one at a each loop iteration.
- while (methodDescriptor.charAt(currentOffset) != ')') {
- while (methodDescriptor.charAt(currentOffset) == '[') {
- currentOffset++;
- }
- if (methodDescriptor.charAt(currentOffset++) == 'L') {
- while (methodDescriptor.charAt(currentOffset++) != ';') {
- // Skip the argument descriptor content.
- }
- }
- }
- return getType(methodDescriptor, currentOffset + 1, methodDescriptor.length());
- }
-
- /**
- * Returns the {@link Type} corresponding to the return type of the given method.
- *
- * @param method a method.
- * @return the {@link Type} corresponding to the return type of the given method.
- */
- public static Type getReturnType(final Method method) {
- return getType(method.getReturnType());
- }
-
- /**
- * Computes the size of the arguments and of the return value of a method.
- *
- * @param methodDescriptor a method descriptor.
- * @return the size of the arguments of the method (plus one for the implicit this argument),
- * argumentsSize, and the size of its return value, returnSize, packed into a single int i =
- * (argumentsSize << 2) | returnSize (argumentsSize is therefore equal to i
- * >> 2, and returnSize to i & 0x03).
- */
- public static int getArgumentsAndReturnSizes(final String methodDescriptor) {
- int argumentsSize = 1;
- // Skip the first character, which is always a '('.
- int currentOffset = 1;
- int currentChar = methodDescriptor.charAt(currentOffset);
- // Parse the argument types and compute their size, one at a each loop iteration.
- while (currentChar != ')') {
- if (currentChar == 'J' || currentChar == 'D') {
- currentOffset++;
- argumentsSize += 2;
- } else {
- while (methodDescriptor.charAt(currentOffset) == '[') {
- currentOffset++;
- }
- if (methodDescriptor.charAt(currentOffset++) == 'L') {
- while (methodDescriptor.charAt(currentOffset++) != ';') {
- // Skip the argument descriptor content.
- }
- }
- argumentsSize += 1;
- }
- currentChar = methodDescriptor.charAt(currentOffset);
- }
- currentChar = methodDescriptor.charAt(currentOffset + 1);
- if (currentChar == 'V') {
- return argumentsSize << 2;
- } else {
- int returnSize = (currentChar == 'J' || currentChar == 'D') ? 2 : 1;
- return argumentsSize << 2 | returnSize;
- }
- }
-
- /**
- * Returns the {@link Type} corresponding to the given field or method descriptor.
- *
- * @param descriptorBuffer a buffer containing the field or method descriptor.
- * @param descriptorBegin the beginning index, inclusive, of the field or method descriptor in
- * descriptorBuffer.
- * @param descriptorEnd the end index, exclusive, of the field or method descriptor in
- * descriptorBuffer.
- * @return the {@link Type} corresponding to the given type descriptor.
- */
- private static Type getType(
- final String descriptorBuffer, final int descriptorBegin, final int descriptorEnd) {
- switch (descriptorBuffer.charAt(descriptorBegin)) {
- case 'V':
- return VOID_TYPE;
- case 'Z':
- return BOOLEAN_TYPE;
- case 'C':
- return CHAR_TYPE;
- case 'B':
- return BYTE_TYPE;
- case 'S':
- return SHORT_TYPE;
- case 'I':
- return INT_TYPE;
- case 'F':
- return FLOAT_TYPE;
- case 'J':
- return LONG_TYPE;
- case 'D':
- return DOUBLE_TYPE;
- case '[':
- return new Type(ARRAY, descriptorBuffer, descriptorBegin, descriptorEnd);
- case 'L':
- return new Type(OBJECT, descriptorBuffer, descriptorBegin + 1, descriptorEnd - 1);
- case '(':
- return new Type(METHOD, descriptorBuffer, descriptorBegin, descriptorEnd);
- default:
- throw new IllegalArgumentException();
- }
- }
-
- // -----------------------------------------------------------------------------------------------
- // Accessors
- // -----------------------------------------------------------------------------------------------
-
- /**
- * Returns the sort of this type.
- *
- * @return {@link #VOID}, {@link #BOOLEAN}, {@link #CHAR}, {@link #BYTE}, {@link #SHORT}, {@link
- * #INT}, {@link #FLOAT}, {@link #LONG}, {@link #DOUBLE}, {@link #ARRAY}, {@link #OBJECT} or
- * {@link #METHOD}.
- */
- public int getSort() {
- return sort == INTERNAL ? OBJECT : sort;
- }
-
- /**
- * Returns the number of dimensions of this array type. This method should only be used for an
- * array type.
- *
- * @return the number of dimensions of this array type.
- */
- public int getDimensions() {
- int numDimensions = 1;
- while (valueBuffer.charAt(valueBegin + numDimensions) == '[') {
- numDimensions++;
- }
- return numDimensions;
- }
-
- /**
- * Returns the type of the elements of this array type. This method should only be used for an
- * array type.
- *
- * @return Returns the type of the elements of this array type.
- */
- public Type getElementType() {
- final int numDimensions = getDimensions();
- return getType(valueBuffer, valueBegin + numDimensions, valueEnd);
- }
-
- /**
- * Returns the binary name of the class corresponding to this type. This method must not be used
- * on method types.
- *
- * @return the binary name of the class corresponding to this type.
- */
- public String getClassName() {
- switch (sort) {
- case VOID:
- return "void";
- case BOOLEAN:
- return "boolean";
- case CHAR:
- return "char";
- case BYTE:
- return "byte";
- case SHORT:
- return "short";
- case INT:
- return "int";
- case FLOAT:
- return "float";
- case LONG:
- return "long";
- case DOUBLE:
- return "double";
- case ARRAY:
- StringBuilder stringBuilder = new StringBuilder(getElementType().getClassName());
- for (int i = getDimensions(); i > 0; --i) {
- stringBuilder.append("[]");
- }
- return stringBuilder.toString();
- case OBJECT:
- case INTERNAL:
- return valueBuffer.substring(valueBegin, valueEnd).replace('/', '.');
- default:
- throw new AssertionError();
- }
- }
-
- /**
- * Returns the internal name of the class corresponding to this object or array type. The internal
- * name of a class is its fully qualified name (as returned by Class.getName(), where '.' are
- * replaced by '/'). This method should only be used for an object or array type.
- *
- * @return the internal name of the class corresponding to this object type.
- */
- public String getInternalName() {
- return valueBuffer.substring(valueBegin, valueEnd);
- }
-
- /**
- * Returns the argument types of methods of this type. This method should only be used for method
- * types.
- *
- * @return the argument types of methods of this type.
- */
- public Type[] getArgumentTypes() {
- return getArgumentTypes(getDescriptor());
- }
-
- /**
- * Returns the return type of methods of this type. This method should only be used for method
- * types.
- *
- * @return the return type of methods of this type.
- */
- public Type getReturnType() {
- return getReturnType(getDescriptor());
- }
-
- /**
- * Returns the size of the arguments and of the return value of methods of this type. This method
- * should only be used for method types.
- *
- * @return the size of the arguments of the method (plus one for the implicit this argument),
- * argumentsSize, and the size of its return value, returnSize, packed into a single int i =
- * (argumentsSize << 2) | returnSize (argumentsSize is therefore equal to i
- * >> 2, and returnSize to i & 0x03).
- */
- public int getArgumentsAndReturnSizes() {
- return getArgumentsAndReturnSizes(getDescriptor());
- }
-
- // -----------------------------------------------------------------------------------------------
- // Conversion to type descriptors
- // -----------------------------------------------------------------------------------------------
-
- /**
- * Returns the descriptor corresponding to this type.
- *
- * @return the descriptor corresponding to this type.
- */
- public String getDescriptor() {
- if (sort == OBJECT) {
- return valueBuffer.substring(valueBegin - 1, valueEnd + 1);
- } else if (sort == INTERNAL) {
- StringBuilder stringBuilder = new StringBuilder();
- stringBuilder.append('L');
- stringBuilder.append(valueBuffer, valueBegin, valueEnd);
- stringBuilder.append(';');
- return stringBuilder.toString();
- } else {
- return valueBuffer.substring(valueBegin, valueEnd);
- }
- }
-
- /**
- * Returns the descriptor corresponding to the given argument and return types.
- *
- * @param returnType the return type of the method.
- * @param argumentTypes the argument types of the method.
- * @return the descriptor corresponding to the given argument and return types.
- */
- public static String getMethodDescriptor(final Type returnType, final Type... argumentTypes) {
- StringBuilder stringBuilder = new StringBuilder();
- stringBuilder.append('(');
- for (int i = 0; i < argumentTypes.length; ++i) {
- argumentTypes[i].appendDescriptor(stringBuilder);
- }
- stringBuilder.append(')');
- returnType.appendDescriptor(stringBuilder);
- return stringBuilder.toString();
- }
-
- /**
- * Appends the descriptor corresponding to this type to the given string buffer.
- *
- * @param stringBuilder the string builder to which the descriptor must be appended.
- */
- private void appendDescriptor(final StringBuilder stringBuilder) {
- if (sort == OBJECT) {
- stringBuilder.append(valueBuffer, valueBegin - 1, valueEnd + 1);
- } else if (sort == INTERNAL) {
- stringBuilder.append('L');
- stringBuilder.append(valueBuffer, valueBegin, valueEnd);
- stringBuilder.append(';');
- } else {
- stringBuilder.append(valueBuffer, valueBegin, valueEnd);
- }
- }
-
- // -----------------------------------------------------------------------------------------------
- // Direct conversion from classes to type descriptors,
- // without intermediate Type objects
- // -----------------------------------------------------------------------------------------------
-
- /**
- * Returns the internal name of the given class. The internal name of a class is its fully
- * qualified name, as returned by Class.getName(), where '.' are replaced by '/'.
- *
- * @param clazz an object or array class.
- * @return the internal name of the given class.
- */
- public static String getInternalName(final Class> clazz) {
- return clazz.getName().replace('.', '/');
- }
-
- /**
- * Returns the descriptor corresponding to the given class.
- *
- * @param clazz an object class, a primitive class or an array class.
- * @return the descriptor corresponding to the given class.
- */
- public static String getDescriptor(final Class> clazz) {
- StringBuilder stringBuilder = new StringBuilder();
- appendDescriptor(stringBuilder, clazz);
- return stringBuilder.toString();
- }
-
- /**
- * Returns the descriptor corresponding to the given constructor.
- *
- * @param constructor a {@link Constructor} object.
- * @return the descriptor of the given constructor.
- */
- public static String getConstructorDescriptor(final Constructor> constructor) {
- StringBuilder stringBuilder = new StringBuilder();
- stringBuilder.append('(');
- Class>[] parameters = constructor.getParameterTypes();
- for (int i = 0; i < parameters.length; ++i) {
- appendDescriptor(stringBuilder, parameters[i]);
- }
- return stringBuilder.append(")V").toString();
- }
-
- /**
- * Returns the descriptor corresponding to the given method.
- *
- * @param method a {@link Method} object.
- * @return the descriptor of the given method.
- */
- public static String getMethodDescriptor(final Method method) {
- StringBuilder stringBuilder = new StringBuilder();
- stringBuilder.append('(');
- Class>[] parameters = method.getParameterTypes();
- for (int i = 0; i < parameters.length; ++i) {
- appendDescriptor(stringBuilder, parameters[i]);
- }
- stringBuilder.append(')');
- appendDescriptor(stringBuilder, method.getReturnType());
- return stringBuilder.toString();
- }
-
- /**
- * Appends the descriptor of the given class to the given string builder.
- *
- * @param stringBuilder the string builder to which the descriptor must be appended.
- * @param clazz the class whose descriptor must be computed.
- */
- private static void appendDescriptor(final StringBuilder stringBuilder, final Class> clazz) {
- Class> currentClass = clazz;
- while (currentClass.isArray()) {
- stringBuilder.append('[');
- currentClass = currentClass.getComponentType();
- }
- if (currentClass.isPrimitive()) {
- char descriptor;
- if (currentClass == Integer.TYPE) {
- descriptor = 'I';
- } else if (currentClass == Void.TYPE) {
- descriptor = 'V';
- } else if (currentClass == Boolean.TYPE) {
- descriptor = 'Z';
- } else if (currentClass == Byte.TYPE) {
- descriptor = 'B';
- } else if (currentClass == Character.TYPE) {
- descriptor = 'C';
- } else if (currentClass == Short.TYPE) {
- descriptor = 'S';
- } else if (currentClass == Double.TYPE) {
- descriptor = 'D';
- } else if (currentClass == Float.TYPE) {
- descriptor = 'F';
- } else if (currentClass == Long.TYPE) {
- descriptor = 'J';
- } else {
- throw new AssertionError();
- }
- stringBuilder.append(descriptor);
- } else {
- stringBuilder.append('L');
- String name = currentClass.getName();
- int nameLength = name.length();
- for (int i = 0; i < nameLength; ++i) {
- char car = name.charAt(i);
- stringBuilder.append(car == '.' ? '/' : car);
- }
- stringBuilder.append(';');
- }
- }
-
- // -----------------------------------------------------------------------------------------------
- // Corresponding size and opcodes
- // -----------------------------------------------------------------------------------------------
-
- /**
- * Returns the size of values of this type. This method must not be used for method types.
- *
- * @return the size of values of this type, i.e., 2 for long and double, 0 for
- * void and 1 otherwise.
- */
- public int getSize() {
- switch (sort) {
- case VOID:
- return 0;
- case BOOLEAN:
- case CHAR:
- case BYTE:
- case SHORT:
- case INT:
- case FLOAT:
- case ARRAY:
- case OBJECT:
- case INTERNAL:
- return 1;
- case LONG:
- case DOUBLE:
- return 2;
- default:
- throw new AssertionError();
- }
- }
-
- /**
- * Returns a JVM instruction opcode adapted to this {@link Type}. This method must not be used for
- * method types.
- *
- * @param opcode a JVM instruction opcode. This opcode must be one of ILOAD, ISTORE, IALOAD,
- * IASTORE, IADD, ISUB, IMUL, IDIV, IREM, INEG, ISHL, ISHR, IUSHR, IAND, IOR, IXOR and
- * IRETURN.
- * @return an opcode that is similar to the given opcode, but adapted to this {@link Type}. For
- * example, if this type is float and opcode is IRETURN, this method returns
- * FRETURN.
- */
- public int getOpcode(final int opcode) {
- if (opcode == Opcodes.IALOAD || opcode == Opcodes.IASTORE) {
- switch (sort) {
- case BOOLEAN:
- case BYTE:
- return opcode + (Opcodes.BALOAD - Opcodes.IALOAD);
- case CHAR:
- return opcode + (Opcodes.CALOAD - Opcodes.IALOAD);
- case SHORT:
- return opcode + (Opcodes.SALOAD - Opcodes.IALOAD);
- case INT:
- return opcode;
- case FLOAT:
- return opcode + (Opcodes.FALOAD - Opcodes.IALOAD);
- case LONG:
- return opcode + (Opcodes.LALOAD - Opcodes.IALOAD);
- case DOUBLE:
- return opcode + (Opcodes.DALOAD - Opcodes.IALOAD);
- case ARRAY:
- case OBJECT:
- case INTERNAL:
- return opcode + (Opcodes.AALOAD - Opcodes.IALOAD);
- case METHOD:
- case VOID:
- throw new UnsupportedOperationException();
- default:
- throw new AssertionError();
- }
- } else {
- switch (sort) {
- case VOID:
- if (opcode != Opcodes.IRETURN) {
- throw new UnsupportedOperationException();
- }
- return Opcodes.RETURN;
- case BOOLEAN:
- case BYTE:
- case CHAR:
- case SHORT:
- case INT:
- return opcode;
- case FLOAT:
- return opcode + (Opcodes.FRETURN - Opcodes.IRETURN);
- case LONG:
- return opcode + (Opcodes.LRETURN - Opcodes.IRETURN);
- case DOUBLE:
- return opcode + (Opcodes.DRETURN - Opcodes.IRETURN);
- case ARRAY:
- case OBJECT:
- case INTERNAL:
- if (opcode != Opcodes.ILOAD && opcode != Opcodes.ISTORE && opcode != Opcodes.IRETURN) {
- throw new UnsupportedOperationException();
- }
- return opcode + (Opcodes.ARETURN - Opcodes.IRETURN);
- case METHOD:
- throw new UnsupportedOperationException();
- default:
- throw new AssertionError();
- }
- }
- }
-
- // -----------------------------------------------------------------------------------------------
- // Equals, hashCode and toString
- // -----------------------------------------------------------------------------------------------
-
- /**
- * Tests if the given object is equal to this type.
- *
- * @param object the object to be compared to this type.
- * @return true if the given object is equal to this type.
- */
- @Override
- public boolean equals(final Object object) {
- if (this == object) {
- return true;
- }
- if (!(object instanceof Type)) {
- return false;
- }
- Type other = (Type) object;
- if ((sort == INTERNAL ? OBJECT : sort) != (other.sort == INTERNAL ? OBJECT : other.sort)) {
- return false;
- }
- int begin = valueBegin;
- int end = valueEnd;
- int otherBegin = other.valueBegin;
- int otherEnd = other.valueEnd;
- // Compare the values.
- if (end - begin != otherEnd - otherBegin) {
- return false;
- }
- for (int i = begin, j = otherBegin; i < end; i++, j++) {
- if (valueBuffer.charAt(i) != other.valueBuffer.charAt(j)) {
- return false;
- }
- }
- return true;
- }
-
- /**
- * Returns a hash code value for this type.
- *
- * @return a hash code value for this type.
- */
- @Override
- public int hashCode() {
- int hashCode = 13 * (sort == INTERNAL ? OBJECT : sort);
- if (sort >= ARRAY) {
- for (int i = valueBegin, end = valueEnd; i < end; i++) {
- hashCode = 17 * (hashCode + valueBuffer.charAt(i));
- }
- }
- return hashCode;
- }
-
- /**
- * Returns a string representation of this type.
- *
- * @return the descriptor of this type.
- */
- @Override
- public String toString() {
- return getDescriptor();
- }
-}
diff --git a/scripts/cn1playground/common/src/main/java/bsh/org/objectweb/asm/TypePath.java b/scripts/cn1playground/common/src/main/java/bsh/org/objectweb/asm/TypePath.java
deleted file mode 100644
index acae12c8e7..0000000000
--- a/scripts/cn1playground/common/src/main/java/bsh/org/objectweb/asm/TypePath.java
+++ /dev/null
@@ -1,201 +0,0 @@
-// ASM: a very small and fast Java bytecode manipulation framework
-// Copyright (c) 2000-2011 INRIA, France Telecom
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions
-// are met:
-// 1. Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// 2. Redistributions in binary form must reproduce the above copyright
-// notice, this list of conditions and the following disclaimer in the
-// documentation and/or other materials provided with the distribution.
-// 3. Neither the name of the copyright holders nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
-// THE POSSIBILITY OF SUCH DAMAGE.
-
-package bsh.org.objectweb.asm;
-
-/**
- * The path to a type argument, wildcard bound, array element type, or static inner type within an
- * enclosing type.
- *
- * @author Eric Bruneton
- */
-public class TypePath {
-
- /** A type path step that steps into the element type of an array type. See {@link #getStep}. */
- public static final int ARRAY_ELEMENT = 0;
-
- /** A type path step that steps into the nested type of a class type. See {@link #getStep}. */
- public static final int INNER_TYPE = 1;
-
- /** A type path step that steps into the bound of a wildcard type. See {@link #getStep}. */
- public static final int WILDCARD_BOUND = 2;
-
- /** A type path step that steps into a type argument of a generic type. See {@link #getStep}. */
- public static final int TYPE_ARGUMENT = 3;
-
- /**
- * The byte array where the 'type_path' structure - as defined in the Java Virtual Machine
- * Specification (JVMS) - corresponding to this TypePath is stored. The first byte of the
- * structure in this array is given by {@link #typePathOffset}.
- *
- * @see JVMS
- * 4.7.20.2
- */
- private final byte[] typePathContainer;
-
- /** The offset of the first byte of the type_path JVMS structure in {@link #typePathContainer}. */
- private final int typePathOffset;
-
- /**
- * Constructs a new TypePath.
- *
- * @param typePathContainer a byte array containing a type_path JVMS structure.
- * @param typePathOffset the offset of the first byte of the type_path structure in
- * typePathContainer.
- */
- TypePath(final byte[] typePathContainer, final int typePathOffset) {
- this.typePathContainer = typePathContainer;
- this.typePathOffset = typePathOffset;
- }
-
- /**
- * Returns the length of this path, i.e. its number of steps.
- *
- * @return the length of this path.
- */
- public int getLength() {
- // path_length is stored in the first byte of a type_path.
- return typePathContainer[typePathOffset];
- }
-
- /**
- * Returns the value of the given step of this path.
- *
- * @param index an index between 0 and {@link #getLength()}, exclusive.
- * @return one of {@link #ARRAY_ELEMENT}, {@link #INNER_TYPE}, {@link #WILDCARD_BOUND}, or {@link
- * #TYPE_ARGUMENT}.
- */
- public int getStep(final int index) {
- // Returns the type_path_kind of the path element of the given index.
- return typePathContainer[typePathOffset + 2 * index + 1];
- }
-
- /**
- * Returns the index of the type argument that the given step is stepping into. This method should
- * only be used for steps whose value is {@link #TYPE_ARGUMENT}.
- *
- * @param index an index between 0 and {@link #getLength()}, exclusive.
- * @return the index of the type argument that the given step is stepping into.
- */
- public int getStepArgument(final int index) {
- // Returns the type_argument_index of the path element of the given index.
- return typePathContainer[typePathOffset + 2 * index + 2];
- }
-
- /**
- * Converts a type path in string form, in the format used by {@link #toString()}, into a TypePath
- * object.
- *
- * @param typePath a type path in string form, in the format used by {@link #toString()}. May be
- * null or empty.
- * @return the corresponding TypePath object, or null if the path is empty.
- */
- public static TypePath fromString(final String typePath) {
- if (typePath == null || typePath.length() == 0) {
- return null;
- }
- int typePathLength = typePath.length();
- ByteVector output = new ByteVector(typePathLength);
- output.putByte(0);
- int typePathIndex = 0;
- while (typePathIndex < typePathLength) {
- char c = typePath.charAt(typePathIndex++);
- if (c == '[') {
- output.put11(ARRAY_ELEMENT, 0);
- } else if (c == '.') {
- output.put11(INNER_TYPE, 0);
- } else if (c == '*') {
- output.put11(WILDCARD_BOUND, 0);
- } else if (c >= '0' && c <= '9') {
- int typeArg = c - '0';
- while (typePathIndex < typePathLength) {
- c = typePath.charAt(typePathIndex++);
- if (c >= '0' && c <= '9') {
- typeArg = typeArg * 10 + c - '0';
- } else if (c == ';') {
- break;
- } else {
- throw new IllegalArgumentException();
- }
- }
- output.put11(TYPE_ARGUMENT, typeArg);
- } else {
- throw new IllegalArgumentException();
- }
- }
- output.data[0] = (byte) (output.length / 2);
- return new TypePath(output.data, 0);
- }
-
- /**
- * Returns a string representation of this type path. {@link #ARRAY_ELEMENT} steps are represented
- * with '[', {@link #INNER_TYPE} steps with '.', {@link #WILDCARD_BOUND} steps with '*' and {@link
- * #TYPE_ARGUMENT} steps with their type argument index in decimal form followed by ';'.
- */
- @Override
- public String toString() {
- int length = getLength();
- StringBuilder result = new StringBuilder(length * 2);
- for (int i = 0; i < length; ++i) {
- switch (getStep(i)) {
- case ARRAY_ELEMENT:
- result.append('[');
- break;
- case INNER_TYPE:
- result.append('.');
- break;
- case WILDCARD_BOUND:
- result.append('*');
- break;
- case TYPE_ARGUMENT:
- result.append(getStepArgument(i)).append(';');
- break;
- default:
- throw new AssertionError();
- }
- }
- return result.toString();
- }
-
- /**
- * Puts the type_path JVMS structure corresponding to the given TypePath into the given
- * ByteVector.
- *
- * @param typePath a TypePath instance, or null for empty paths.
- * @param output where the type path must be put.
- */
- static void put(final TypePath typePath, final ByteVector output) {
- if (typePath == null) {
- output.putByte(0);
- } else {
- int length = typePath.typePathContainer[typePath.typePathOffset] * 2 + 1;
- output.putByteArray(typePath.typePathContainer, typePath.typePathOffset, length);
- }
- }
-}
diff --git a/scripts/cn1playground/common/src/main/java/bsh/org/objectweb/asm/TypeReference.java b/scripts/cn1playground/common/src/main/java/bsh/org/objectweb/asm/TypeReference.java
deleted file mode 100644
index 293fecc702..0000000000
--- a/scripts/cn1playground/common/src/main/java/bsh/org/objectweb/asm/TypeReference.java
+++ /dev/null
@@ -1,436 +0,0 @@
-// ASM: a very small and fast Java bytecode manipulation framework
-// Copyright (c) 2000-2011 INRIA, France Telecom
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions
-// are met:
-// 1. Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// 2. Redistributions in binary form must reproduce the above copyright
-// notice, this list of conditions and the following disclaimer in the
-// documentation and/or other materials provided with the distribution.
-// 3. Neither the name of the copyright holders nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
-// THE POSSIBILITY OF SUCH DAMAGE.
-
-package bsh.org.objectweb.asm;
-
-/**
- * A reference to a type appearing in a class, field or method declaration, or on an instruction.
- * Such a reference designates the part of the class where the referenced type is appearing (e.g. an
- * 'extends', 'implements' or 'throws' clause, a 'new' instruction, a 'catch' clause, a type cast, a
- * local variable declaration, etc).
- *
- * @author Eric Bruneton
- */
-public class TypeReference {
-
- /**
- * The sort of type references that target a type parameter of a generic class. See {@link
- * #getSort}.
- */
- public static final int CLASS_TYPE_PARAMETER = 0x00;
-
- /**
- * The sort of type references that target a type parameter of a generic method. See {@link
- * #getSort}.
- */
- public static final int METHOD_TYPE_PARAMETER = 0x01;
-
- /**
- * The sort of type references that target the super class of a class or one of the interfaces it
- * implements. See {@link #getSort}.
- */
- public static final int CLASS_EXTENDS = 0x10;
-
- /**
- * The sort of type references that target a bound of a type parameter of a generic class. See
- * {@link #getSort}.
- */
- public static final int CLASS_TYPE_PARAMETER_BOUND = 0x11;
-
- /**
- * The sort of type references that target a bound of a type parameter of a generic method. See
- * {@link #getSort}.
- */
- public static final int METHOD_TYPE_PARAMETER_BOUND = 0x12;
-
- /** The sort of type references that target the type of a field. See {@link #getSort}. */
- public static final int FIELD = 0x13;
-
- /** The sort of type references that target the return type of a method. See {@link #getSort}. */
- public static final int METHOD_RETURN = 0x14;
-
- /**
- * The sort of type references that target the receiver type of a method. See {@link #getSort}.
- */
- public static final int METHOD_RECEIVER = 0x15;
-
- /**
- * The sort of type references that target the type of a formal parameter of a method. See {@link
- * #getSort}.
- */
- public static final int METHOD_FORMAL_PARAMETER = 0x16;
-
- /**
- * The sort of type references that target the type of an exception declared in the throws clause
- * of a method. See {@link #getSort}.
- */
- public static final int THROWS = 0x17;
-
- /**
- * The sort of type references that target the type of a local variable in a method. See {@link
- * #getSort}.
- */
- public static final int LOCAL_VARIABLE = 0x40;
-
- /**
- * The sort of type references that target the type of a resource variable in a method. See {@link
- * #getSort}.
- */
- public static final int RESOURCE_VARIABLE = 0x41;
-
- /**
- * The sort of type references that target the type of the exception of a 'catch' clause in a
- * method. See {@link #getSort}.
- */
- public static final int EXCEPTION_PARAMETER = 0x42;
-
- /**
- * The sort of type references that target the type declared in an 'instanceof' instruction. See
- * {@link #getSort}.
- */
- public static final int INSTANCEOF = 0x43;
-
- /**
- * The sort of type references that target the type of the object created by a 'new' instruction.
- * See {@link #getSort}.
- */
- public static final int NEW = 0x44;
-
- /**
- * The sort of type references that target the receiver type of a constructor reference. See
- * {@link #getSort}.
- */
- public static final int CONSTRUCTOR_REFERENCE = 0x45;
-
- /**
- * The sort of type references that target the receiver type of a method reference. See {@link
- * #getSort}.
- */
- public static final int METHOD_REFERENCE = 0x46;
-
- /**
- * The sort of type references that target the type declared in an explicit or implicit cast
- * instruction. See {@link #getSort}.
- */
- public static final int CAST = 0x47;
-
- /**
- * The sort of type references that target a type parameter of a generic constructor in a
- * constructor call. See {@link #getSort}.
- */
- public static final int CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT = 0x48;
-
- /**
- * The sort of type references that target a type parameter of a generic method in a method call.
- * See {@link #getSort}.
- */
- public static final int METHOD_INVOCATION_TYPE_ARGUMENT = 0x49;
-
- /**
- * The sort of type references that target a type parameter of a generic constructor in a
- * constructor reference. See {@link #getSort}.
- */
- public static final int CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT = 0x4A;
-
- /**
- * The sort of type references that target a type parameter of a generic method in a method
- * reference. See {@link #getSort}.
- */
- public static final int METHOD_REFERENCE_TYPE_ARGUMENT = 0x4B;
-
- /**
- * The target_type and target_info structures - as defined in the Java Virtual Machine
- * Specification (JVMS) - corresponding to this type reference. target_type uses one byte, and all
- * the target_info union fields use up to 3 bytes (except localvar_target, handled with the
- * specific method {@link MethodVisitor#visitLocalVariableAnnotation}). Thus, both structures can
- * be stored in an int.
- *
- *