test: Add support for jasmin
Adding .j files in a jasmin directory will place those classes into
the same jar as src/src2 source files.
Adding .j files in a jasmin-multidex directory will place those classes
into the same jar as src-multidex source files.
Jasmin classes have medium priority and will overwrite any .java
classes.
Smali classes have the highest priority and smali classes
will overwrite any jasmin classes.
Using jasmin is preferred for tests that can run cross-platform.
(Also convert two of the tests to use jasmin instead of smali).
Test: art/test/run-test --host --optimizing --build-with-jack 064-field-access
Test: DESUGAR=false art/test/run-test --host --optimizing --build-with-javac-dx 064-field-access
Test: DESUGAR=false art/test/run-test --host --optimizing --build-with-javac-dx 606-erroneous-class
Test: art/test/run-test --host --optimizing --build-with-jack 606-erroneous-class
Test: #(manual) run-test --jvm and check that .class is there as a build artifact
Bug: 62855082
Change-Id: I5966d37f603bb5b93f75a842e7d597721afafacd
diff --git a/test/064-field-access/jasmin/SubClassUsingInaccessibleField.j b/test/064-field-access/jasmin/SubClassUsingInaccessibleField.j
new file mode 100644
index 0000000..3422f85
--- /dev/null
+++ b/test/064-field-access/jasmin/SubClassUsingInaccessibleField.j
@@ -0,0 +1,36 @@
+; Copyright (C) 2017 The Android Open Source Project
+;
+; Licensed under the Apache License, Version 2.0 (the "License");
+; you may not use this file except in compliance with the License.
+; You may obtain a copy of the License at
+;
+; http://www.apache.org/licenses/LICENSE-2.0
+;
+; Unless required by applicable law or agreed to in writing, software
+; distributed under the License is distributed on an "AS IS" BASIS,
+; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+; See the License for the specific language governing permissions and
+; limitations under the License.
+
+.class public SubClassUsingInaccessibleField
+.super other/PublicClass
+
+.method public <init>()V
+ .limit stack 1
+ .limit locals 1
+ aload_0
+ invokespecial other/PublicClass/<init>()V
+ return
+.end method
+
+; Regression test for compiler DCHECK() failure (bogus check) when referencing
+; a package-private field from an indirectly inherited package-private class,
+; using this very class as the declaring class in the FieldId, bug: 27684368 .
+.method public test()I
+ .limit stack 1
+ .limit locals 1
+ aload_0
+ getfield SubClassUsingInaccessibleField/otherProtectedClassPackageIntInstanceField I
+ ireturn
+.end method
+
diff --git a/test/064-field-access/smali/SubClassUsingInaccessibleField.smali b/test/064-field-access/smali/SubClassUsingInaccessibleField.smali
deleted file mode 100644
index 224b431..0000000
--- a/test/064-field-access/smali/SubClassUsingInaccessibleField.smali
+++ /dev/null
@@ -1,32 +0,0 @@
-# Copyright (C) 2016 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-.class public LSubClassUsingInaccessibleField;
-
-.super Lother/PublicClass;
-
-.method public constructor <init>()V
- .registers 1
- invoke-direct {p0}, Lother/PublicClass;-><init>()V
- return-void
-.end method
-
-# Regression test for compiler DCHECK() failure (bogus check) when referencing
-# a package-private field from an indirectly inherited package-private class,
-# using this very class as the declaring class in the FieldId, bug: 27684368 .
-.method public test()I
- .registers 2
- iget v0, p0, LSubClassUsingInaccessibleField;->otherProtectedClassPackageIntInstanceField:I
- return v0
-.end method
diff --git a/test/606-erroneous-class/jasmin-multidex/ClassA.j b/test/606-erroneous-class/jasmin-multidex/ClassA.j
new file mode 100644
index 0000000..50c6755
--- /dev/null
+++ b/test/606-erroneous-class/jasmin-multidex/ClassA.j
@@ -0,0 +1,30 @@
+; Copyright (C) 2017 The Android Open Source Project
+;
+; Licensed under the Apache License, Version 2.0 (the "License");
+; you may not use this file except in compliance with the License.
+; You may obtain a copy of the License at
+;
+; http://www.apache.org/licenses/LICENSE-2.0
+;
+; Unless required by applicable law or agreed to in writing, software
+; distributed under the License is distributed on an "AS IS" BASIS,
+; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+; See the License for the specific language governing permissions and
+; limitations under the License.
+
+.class public final ClassA
+.super java/lang/Object
+
+.method public static foo()V
+ .limit stack 1
+ .limit locals 0
+ ; Obtain the ErrClass type from Dex cache of the first Dex file. Note that
+ ; because the first Dex file has already been verified, we know the class
+ ; is erroneous at this point.
+ getstatic ClassB/g LErrClass;
+ ; Use the object in a way that will try to store the ErrClass type in
+ ; the Dex cache of the second Dex file.
+ invokevirtual ErrClass/foo()V
+ return
+.end method
+
diff --git a/test/606-erroneous-class/smali-multidex/ClassA.smali b/test/606-erroneous-class/smali-multidex/ClassA.smali
deleted file mode 100644
index f87fcb2..0000000
--- a/test/606-erroneous-class/smali-multidex/ClassA.smali
+++ /dev/null
@@ -1,27 +0,0 @@
-# Copyright (C) 2016 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-.class public final LClassA;
-.super Ljava/lang/Object;
-
-.method public static foo()V
- .registers 1
- # Obtain the ErrClass type from Dex cache of the first Dex file. Note that
- # because the first Dex file has already been verified, we know the class
- # is erroneous at this point.
- sget-object v0, LClassB;->g:LErrClass;
- # Use the object in a way that will try to store the ErrClass type in
- # the Dex cache of the second Dex file.
- invoke-virtual {v0}, LErrClass;->foo()V
-.end method
diff --git a/test/etc/default-build b/test/etc/default-build
index 13f4301..bafd415 100755
--- a/test/etc/default-build
+++ b/test/etc/default-build
@@ -24,6 +24,13 @@
HAS_SMALI=false
fi
+# .j files in jasmin get compiled into classes.jar
+if [ -d jasmin ]; then
+ HAS_JASMIN=true
+else
+ HAS_JASMIN=false
+fi
+
if [ -d src ]; then
HAS_SRC=true
else
@@ -55,6 +62,13 @@
HAS_SMALI_MULTIDEX=false
fi
+# .j files in jasmin-multidex get compiled into classes2.jar
+if [ -d jasmin-multidex ]; then
+ HAS_JASMIN_MULTIDEX=true
+else
+ HAS_JASMIN_MULTIDEX=false
+fi
+
if [ -d src-ex ]; then
HAS_SRC_EX=true
else
@@ -80,7 +94,6 @@
DX_FLAGS="--min-sdk-version=24"
DX_VM_FLAGS=""
-SKIP_DX_MERGER="false"
EXPERIMENTAL=""
BUILD_MODE="target"
@@ -219,6 +232,21 @@
fi
}
+function make_jasmin() {
+ local out_directory="$1"
+ shift
+ local jasmin_sources=("$@")
+
+ mkdir -p "$out_directory"
+
+ if [[ $DEV_MODE == yes ]]; then
+ echo ${JASMIN} -d "$out_directory" "${jasmin_sources[@]}"
+ ${JASMIN} -d "$out_directory" "${jasmin_sources[@]}"
+ else
+ ${JASMIN} -d "$out_directory" "${jasmin_sources[@]}" >/dev/null
+ fi
+}
+
function desugar() {
local desugar_args=--mode=host
if [[ $BUILD_MODE == target ]]; then
@@ -268,6 +296,26 @@
${DX} -JXmx256m ${DX_VM_FLAGS} --debug --dex --dump-to=${name}.lst --output=${name}.dex --dump-width=1000 ${DX_FLAGS} "${dx_input}"
}
+# Merge all the dex files in $1..$N into $1. Skip non-existing files, but at least 1 file must exist.
+function make_dexmerge() {
+ # Dex file that acts as the destination.
+ local dst_file="$1"
+
+ # Dex files that act as the source.
+ local dex_files_to_merge=()
+
+ # Skip any non-existing files.
+ while [[ $# -gt 0 ]]; do
+ if [[ -e "$1" ]]; then
+ dex_files_to_merge+=("$1")
+ fi
+ shift
+ done
+
+ # Should have at least 1 dex_files_to_merge here, otherwise dxmerger will print the help.
+ ${DXMERGER} "$dst_file" "${dex_files_to_merge[@]}"
+}
+
# Print the directory name only if it exists.
function maybe_dir() {
local dirname="$1"
@@ -281,11 +329,6 @@
exit 0
fi
-if ! [ "${HAS_SRC}" = "true" ] && ! [ "${HAS_SRC2}" = "true" ] && ! [ "${HAS_SRC_ART}" = "true" ]; then
- # No src directory? Then forget about trying to run dx.
- SKIP_DX_MERGER="true"
-fi
-
if [ ${HAS_SRC_DEX2OAT_UNRESOLVED} = "true" ]; then
mkdir classes
mkdir classes-ex
@@ -332,7 +375,7 @@
fi
# Compile jack files into a DEX file.
- if [ "${HAS_SRC}" = "true" ] || [ "${HAS_SRC2}" = "true" ] || [ "${HAS_SRC_ART}" ]; then
+ if [ "${HAS_SRC}" = "true" ] || [ "${HAS_SRC2}" = "true" ] || [ "${HAS_SRC_ART}" = "true" ]; then
${JACK} ${JACK_ARGS} ${jack_extra_args} --output-dex .
fi
else
@@ -361,22 +404,49 @@
fi
if [[ "${HAS_SRC}" == "true" || "${HAS_SRC2}" == "true" || "${HAS_SRC_ART}" == "true" ]]; then
- if [ ${NEED_DEX} = "true" -a ${SKIP_DX_MERGER} = "false" ]; then
+ if [ ${NEED_DEX} = "true" ]; then
make_dex classes
fi
fi
fi
fi
+if [[ "${HAS_JASMIN}" == true ]]; then
+ # Compile Jasmin classes as if they were part of the classes.dex file.
+ make_jasmin jasmin_classes $(find 'jasmin' -name '*.j')
+ if [[ "${NEED_DEX}" == "true" ]]; then
+ # Disable desugar because it won't handle intentional linkage errors.
+ USE_DESUGAR=false make_dex jasmin_classes
+ make_dexmerge classes.dex jasmin_classes.dex
+ else
+ # Move jasmin classes into classes directory so that they are picked up with -cp classes.
+ mkdir -p classes
+ mv jasmin_classes/* classes
+ fi
+fi
+
if [ "${HAS_SMALI}" = "true" -a ${NEED_DEX} = "true" ]; then
# Compile Smali classes
${SMALI} -JXmx512m assemble ${SMALI_ARGS} --output smali_classes.dex `find smali -name '*.smali'`
- # Don't bother with dexmerger if we provide our own main function in a smali file.
- if [ ${SKIP_DX_MERGER} = "false" ]; then
- ${DXMERGER} classes.dex classes.dex smali_classes.dex
+ # Merge smali files into classes.dex, this takes priority over any jasmin files.
+ make_dexmerge classes.dex smali_classes.dex
+fi
+
+# Compile Jasmin classes in jasmin-multidex as if they were part of the classes2.jar
+if [[ "$HAS_JASMIN_MULTIDEX" == true ]]; then
+ make_jasmin jasmin_classes2 $(find 'jasmin-multidex' -name '*.j')
+
+ if [[ "${NEED_DEX}" == "true" ]]; then
+ # Disable desugar because it won't handle intentional linkage errors.
+ USE_DESUGAR=false make_dex jasmin_classes2
+
+ # Merge jasmin_classes2.dex into classes2.dex
+ make_dexmerge classes2.dex jasmin_classes2.dex
else
- mv smali_classes.dex classes.dex
+ # Move jasmin classes into classes2 directory so that they are picked up with -cp classes2.
+ mkdir -p classes2
+ mv jasmin_classes2/* classes2
fi
fi
@@ -384,12 +454,8 @@
# Compile Smali classes
${SMALI} -JXmx512m assemble ${SMALI_ARGS} --output smali_classes2.dex `find smali-multidex -name '*.smali'`
- # Don't bother with dexmerger if we provide our own main function in a smali file.
- if [ ${HAS_SRC_MULTIDEX} = "true" ]; then
- ${DXMERGER} classes2.dex classes2.dex smali_classes2.dex
- else
- mv smali_classes2.dex classes2.dex
- fi
+ # Merge smali_classes2.dex into classes2.dex
+ make_dexmerge classes2.dex smali_classes2.dex
fi
@@ -430,9 +496,9 @@
fi
fi
-# Create a single jar with two dex files for multidex.
+# Create a single dex jar with two dex files for multidex.
if [ ${NEED_DEX} = "true" ]; then
- if [ ${HAS_SRC_MULTIDEX} = "true" ] || [ ${HAS_SMALI_MULTIDEX} = "true" ]; then
+ if [ ${HAS_SRC_MULTIDEX} = "true" ] || [ ${HAS_JASMIN_MULTIDEX} = "true" ] || [ ${HAS_SMALI_MULTIDEX} = "true" ]; then
zip $TEST_NAME.jar classes.dex classes2.dex
else
zip $TEST_NAME.jar classes.dex