Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
asm
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Packages
Packages
Container Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Talia McCormick
asm
Commits
6e219625
Commit
6e219625
authored
Jan 20, 2018
by
Eric Bruneton
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch '317748-non-regression' into 'master'
Add a non-regression test for issue
#317748
. See merge request
!97
parents
adad7843
6fada1f7
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
160 additions
and
7 deletions
+160
-7
asm/src/main/java/org/objectweb/asm/Attribute.java
asm/src/main/java/org/objectweb/asm/Attribute.java
+43
-0
asm/src/main/java/org/objectweb/asm/ClassWriter.java
asm/src/main/java/org/objectweb/asm/ClassWriter.java
+26
-1
asm/src/main/java/org/objectweb/asm/FieldWriter.java
asm/src/main/java/org/objectweb/asm/FieldWriter.java
+9
-0
asm/src/main/java/org/objectweb/asm/MethodWriter.java
asm/src/main/java/org/objectweb/asm/MethodWriter.java
+10
-0
asm/src/test/java/org/objectweb/asm/ClassWriterTest.java
asm/src/test/java/org/objectweb/asm/ClassWriterTest.java
+72
-6
No files found.
asm/src/main/java/org/objectweb/asm/Attribute.java
View file @
6e219625
...
...
@@ -277,4 +277,47 @@ public class Attribute {
attribute
=
attribute
.
nextAttribute
;
}
}
/** A set of attribute prototypes (attributes with the same type are considered equal). */
static
final
class
Set
{
private
static
final
int
SIZE_INCREMENT
=
6
;
private
int
size
;
private
Attribute
[]
data
=
new
Attribute
[
SIZE_INCREMENT
];
void
addAttributes
(
final
Attribute
attributeList
)
{
Attribute
attribute
=
attributeList
;
while
(
attribute
!=
null
)
{
if
(!
contains
(
attribute
))
{
add
(
attribute
);
}
attribute
=
attribute
.
nextAttribute
;
}
}
Attribute
[]
toArray
()
{
Attribute
[]
result
=
new
Attribute
[
size
];
System
.
arraycopy
(
data
,
0
,
result
,
0
,
size
);
return
result
;
}
private
boolean
contains
(
final
Attribute
attribute
)
{
for
(
int
i
=
0
;
i
<
size
;
++
i
)
{
if
(
data
[
i
].
type
.
equals
(
attribute
.
type
))
{
return
true
;
}
}
return
false
;
}
private
void
add
(
final
Attribute
attribute
)
{
if
(
size
>=
data
.
length
)
{
Attribute
[]
newData
=
new
Attribute
[
data
.
length
+
SIZE_INCREMENT
];
System
.
arraycopy
(
data
,
0
,
newData
,
0
,
size
);
data
=
newData
;
}
data
[
size
++]
=
attribute
;
}
}
}
asm/src/main/java/org/objectweb/asm/ClassWriter.java
View file @
6e219625
...
...
@@ -601,6 +601,7 @@ public class ClassWriter extends ClassVisitor {
// Third step: do a ClassReader->ClassWriter round trip if the generated class contains ASM
// specific instructions due to large forward jumps.
if
(
hasAsmInstructions
)
{
Attribute
[]
attributes
=
getAttributePrototypes
();
firstField
=
null
;
lastField
=
null
;
firstMethod
=
null
;
...
...
@@ -613,13 +614,37 @@ public class ClassWriter extends ClassVisitor {
firstAttribute
=
null
;
compute
=
hasFrames
?
MethodWriter
.
COMPUTE_INSERTED_FRAMES
:
MethodWriter
.
COMPUTE_NOTHING
;
new
ClassReader
(
result
.
data
,
0
,
/* checkClassVersion = */
false
)
.
accept
(
this
,
(
hasFrames
?
ClassReader
.
EXPAND_FRAMES
:
0
)
|
ClassReader
.
EXPAND_ASM_INSNS
);
.
accept
(
this
,
attributes
,
(
hasFrames
?
ClassReader
.
EXPAND_FRAMES
:
0
)
|
ClassReader
.
EXPAND_ASM_INSNS
);
return
toByteArray
();
}
else
{
return
result
.
data
;
}
}
/**
* Returns the prototypes of the attributes used by this class, its fields and its methods.
*
* @return the prototypes of the attributes used by this class, its fields and its methods.
*/
private
Attribute
[]
getAttributePrototypes
()
{
Attribute
.
Set
attributePrototypes
=
new
Attribute
.
Set
();
attributePrototypes
.
addAttributes
(
firstAttribute
);
FieldWriter
fieldWriter
=
firstField
;
while
(
fieldWriter
!=
null
)
{
fieldWriter
.
collectAttributePrototypes
(
attributePrototypes
);
fieldWriter
=
(
FieldWriter
)
fieldWriter
.
fv
;
}
MethodWriter
methodWriter
=
firstMethod
;
while
(
methodWriter
!=
null
)
{
methodWriter
.
collectAttributePrototypes
(
attributePrototypes
);
methodWriter
=
(
MethodWriter
)
methodWriter
.
mv
;
}
return
attributePrototypes
.
toArray
();
}
// -----------------------------------------------------------------------------------------------
// Utility methods: constant pool management for Attribute sub classes
// -----------------------------------------------------------------------------------------------
...
...
asm/src/main/java/org/objectweb/asm/FieldWriter.java
View file @
6e219625
...
...
@@ -334,4 +334,13 @@ final class FieldWriter extends FieldVisitor {
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
);
}
}
asm/src/main/java/org/objectweb/asm/MethodWriter.java
View file @
6e219625
...
...
@@ -2303,4 +2303,14 @@ final class MethodWriter extends MethodVisitor {
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
);
}
}
asm/src/test/java/org/objectweb/asm/ClassWriterTest.java
View file @
6e219625
...
...
@@ -325,13 +325,21 @@ public class ClassWriterTest extends AsmTest {
ClassReader
classReader
=
new
ClassReader
(
classFile
);
ClassWriter
classWriter
=
new
ClassWriter
(
0
);
ClassVisitor
classVisitor
=
new
NopInserter
(
apiParameter
.
value
(),
classWriter
);
ForwardJumpNopInserter
forwardJumpNopInserter
=
new
ForwardJumpNopInserter
(
apiParameter
.
value
(),
classWriter
);
if
(
classParameter
.
isMoreRecentThan
(
apiParameter
))
{
assertThrows
(
RuntimeException
.
class
,
()
->
classReader
.
accept
(
classVisitor
,
attributes
(),
0
));
assertThrows
(
RuntimeException
.
class
,
()
->
classReader
.
accept
(
forwardJumpNopInserter
,
attributes
(),
0
));
return
;
}
classReader
.
accept
(
classVisitor
,
attributes
(),
0
);
classReader
.
accept
(
forwardJumpNopInserter
,
attributes
(),
0
);
if
(!
forwardJumpNopInserter
.
transformed
)
{
classWriter
=
new
ClassWriter
(
0
);
classReader
.
accept
(
new
WideForwardJumpInserter
(
apiParameter
.
value
(),
classWriter
),
attributes
(),
0
);
}
byte
[]
transformedClass
=
classWriter
.
toByteArray
();
assertThat
(()
->
loadAndInstantiate
(
classParameter
.
getName
(),
transformedClass
))
...
...
@@ -559,11 +567,12 @@ public class ClassWriterTest extends AsmTest {
}
}
private
static
class
NopInserter
extends
ClassVisitor
{
/** Inserts NOP instructions after the first forward jump found, to get a wide jump. */
private
static
class
ForwardJumpNopInserter
extends
ClassVisitor
{
boolean
transformed
=
false
;
boolean
transformed
;
NopInserter
(
final
int
api
,
final
ClassVisitor
classVisitor
)
{
ForwardJump
NopInserter
(
final
int
api
,
final
ClassVisitor
classVisitor
)
{
super
(
api
,
classVisitor
);
}
...
...
@@ -597,4 +606,61 @@ public class ClassWriterTest extends AsmTest {
};
}
}
/** Inserts a wide forward jump in the first non-abstract method that is found. */
private
static
class
WideForwardJumpInserter
extends
ClassVisitor
{
private
boolean
needFrames
;
private
boolean
transformed
;
WideForwardJumpInserter
(
final
int
api
,
final
ClassVisitor
classVisitor
)
{
super
(
api
,
classVisitor
);
}
@Override
public
void
visit
(
final
int
version
,
final
int
access
,
final
String
name
,
final
String
signature
,
final
String
superName
,
final
String
[]
interfaces
)
{
needFrames
=
(
version
&
0xFFFF
)
>=
Opcodes
.
V1_7
;
super
.
visit
(
version
,
access
,
name
,
signature
,
superName
,
interfaces
);
}
@Override
public
MethodVisitor
visitMethod
(
final
int
access
,
final
String
name
,
final
String
descriptor
,
final
String
signature
,
final
String
[]
exceptions
)
{
return
new
MethodVisitor
(
api
,
super
.
visitMethod
(
access
,
name
,
descriptor
,
signature
,
exceptions
))
{
@Override
public
void
visitCode
()
{
super
.
visitCode
();
if
(!
transformed
)
{
Label
startLabel
=
new
Label
();
visitJumpInsn
(
Opcodes
.
GOTO
,
startLabel
);
if
(
needFrames
)
{
visitLabel
(
new
Label
());
visitFrame
(
Opcodes
.
F_SAME
,
0
,
null
,
0
,
null
);
}
for
(
int
i
=
0
;
i
<=
Short
.
MAX_VALUE
;
++
i
)
{
visitInsn
(
Opcodes
.
NOP
);
}
visitLabel
(
startLabel
);
if
(
needFrames
)
{
visitFrame
(
Opcodes
.
F_SAME
,
0
,
null
,
0
,
null
);
visitInsn
(
Opcodes
.
NOP
);
}
transformed
=
true
;
}
}
};
}
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment