Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
raphw
asm
Commits
6673a08b
Commit
6673a08b
authored
Oct 14, 2012
by
ebruneton
Browse files
Fixed bug #316360.
parent
5d18119f
Changes
5
Hide whitespace changes
Inline
Side-by-side
src/org/objectweb/asm/ClassReader.java
View file @
6673a08b
...
...
@@ -1142,7 +1142,7 @@ public class ClassReader {
u
+=
2
;
// generates the first (implicit) stack map frame
if
(
FRAMES
&&
(
stackMap
!=
0
||
unzip
)
)
{
if
(
FRAMES
&&
stackMap
!=
0
)
{
/*
* for the first explicit frame the offset is not offset_delta + 1
* but only offset_delta; setting the implicit frame offset to -1
...
...
@@ -1159,8 +1159,6 @@ public class ClassReader {
if
(
unzip
)
{
getImplicitFrame
(
context
);
}
}
if
(
FRAMES
&&
stackMap
!=
0
)
{
/*
* Finds labels for UNINITIALIZED frame types. Instead of decoding
* each element of the stack map table, we look for 3 consecutive
...
...
@@ -1198,17 +1196,19 @@ public class ClassReader {
}
}
// visits the frame
(s)
for this offset, if any
// visits the frame for this offset, if any
while
(
FRAMES
&&
frame
!=
null
&&
(
frame
.
offset
==
offset
||
frame
.
offset
==
-
1
))
{
// if there is a frame for this offset, makes the visitor visit
// it, and reads the next frame if there is one.
if
(!
zip
||
unzip
)
{
mv
.
visitFrame
(
Opcodes
.
F_NEW
,
frame
.
localCount
,
frame
.
local
,
frame
.
stackCount
,
frame
.
stack
);
}
else
if
(
frame
.
offset
!=
-
1
)
{
mv
.
visitFrame
(
frame
.
mode
,
frame
.
localDiff
,
frame
.
local
,
frame
.
stackCount
,
frame
.
stack
);
if
(
frame
.
offset
!=
-
1
)
{
if
(!
zip
||
unzip
)
{
mv
.
visitFrame
(
Opcodes
.
F_NEW
,
frame
.
localCount
,
frame
.
local
,
frame
.
stackCount
,
frame
.
stack
);
}
else
{
mv
.
visitFrame
(
frame
.
mode
,
frame
.
localDiff
,
frame
.
local
,
frame
.
stackCount
,
frame
.
stack
);
}
}
if
(
frameCount
>
0
)
{
stackMap
=
readFrame
(
stackMap
,
zip
,
unzip
,
labels
,
frame
);
...
...
src/org/objectweb/asm/MethodVisitor.java
View file @
6673a08b
...
...
@@ -184,13 +184,9 @@ public abstract class MethodVisitor {
* compressed form (all frames must use the same format, i.e. you must not
* mix expanded and compressed frames within a single method):
* <ul>
* <li>In expanded form, all frames must have the F_NEW type, and a first
* frame corresponding to the method signature must be explicitly visited
* before the first instruction.</li>
* <li>In expanded form, all frames must have the F_NEW type.</li>
* <li>In compressed form, frames are basically "deltas" from the state of
* the previous frame (the first frame, corresponding to the method's
* parameters and access flags, is implicit in this form, and must not be
* visited):
* the previous frame:
* <ul>
* <li>{@link Opcodes#F_SAME} representing frame with exactly the same
* locals as the previous frame and with the empty stack.</li>
...
...
@@ -207,7 +203,11 @@ public abstract class MethodVisitor {
* are absent and with the empty stack (<code>nLocals</code> is 1, 2 or 3).</li>
* <li>{@link Opcodes#F_FULL} representing complete frame data.</li></li>
* </ul>
* </ul>
* </ul> <br>
* In both cases the first frame, corresponding to the method's parameters
* and access flags, is implicit and must not be visited. Also, it is
* illegal to visit two or more frames for the same code location (i.e., at
* least one instruction must be visited between two calls to visitFrame).
*
* @param type
* the type of this stack map frame. Must be
...
...
src/org/objectweb/asm/MethodWriter.java
View file @
6673a08b
...
...
@@ -42,8 +42,8 @@ class MethodWriter extends MethodVisitor {
/**
* Pseudo access flag used to denote constructors.
*/
static
final
int
ACC_CONSTRUCTOR
=
262144
;
static
final
int
ACC_CONSTRUCTOR
=
0x80000
;
/**
* Frame has exactly the same locals as the previous stack map frame and
* number of stack items is zero.
...
...
@@ -256,11 +256,6 @@ class MethodWriter extends MethodVisitor {
*/
private
int
[]
previousFrame
;
/**
* Index of the next element to be added in {@link #frame}.
*/
private
int
frameIndex
;
/**
* The current stack map frame. The first element contains the offset of the
* instruction to which the frame corresponds, the second element is the
...
...
@@ -430,6 +425,9 @@ class MethodWriter extends MethodVisitor {
cw
.
lastMethod
=
this
;
this
.
cw
=
cw
;
this
.
access
=
access
;
if
(
"<init>"
.
equals
(
name
))
{
this
.
access
|=
ACC_CONSTRUCTOR
;
}
this
.
name
=
cw
.
newUTF8
(
name
);
this
.
desc
=
cw
.
newUTF8
(
desc
);
this
.
descriptor
=
desc
;
...
...
@@ -445,9 +443,6 @@ class MethodWriter extends MethodVisitor {
}
this
.
compute
=
computeFrames
?
FRAMES
:
(
computeMaxs
?
MAXS
:
NOTHING
);
if
(
computeMaxs
||
computeFrames
)
{
if
(
computeFrames
&&
"<init>"
.
equals
(
name
))
{
this
.
access
|=
ACC_CONSTRUCTOR
;
}
// updates maxLocals
int
size
=
Type
.
getArgumentsAndReturnSizes
(
descriptor
)
>>
2
;
if
((
access
&
Opcodes
.
ACC_STATIC
)
!=
0
)
{
...
...
@@ -550,8 +545,11 @@ class MethodWriter extends MethodVisitor {
}
if
(
type
==
Opcodes
.
F_NEW
)
{
if
(
previousFrame
==
null
)
{
visitImplicitFirstFrame
();
}
currentLocals
=
nLocal
;
startFrame
(
code
.
length
,
nLocal
,
nStack
);
int
frameIndex
=
startFrame
(
code
.
length
,
nLocal
,
nStack
);
for
(
int
i
=
0
;
i
<
nLocal
;
++
i
)
{
if
(
local
[
i
]
instanceof
String
)
{
frame
[
frameIndex
++]
=
Frame
.
OBJECT
...
...
@@ -1334,8 +1332,8 @@ class MethodWriter extends MethodVisitor {
}
code
.
data
[
end
]
=
(
byte
)
Opcodes
.
ATHROW
;
// emits a frame for this unreachable block
startFrame
(
start
,
0
,
1
);
frame
[
frameIndex
++
]
=
Frame
.
OBJECT
int
frameIndex
=
startFrame
(
start
,
0
,
1
);
frame
[
frameIndex
]
=
Frame
.
OBJECT
|
cw
.
addType
(
"java/lang/Throwable"
);
endFrame
();
// removes the start-end range from the exception
...
...
@@ -1562,7 +1560,7 @@ class MethodWriter extends MethodVisitor {
}
}
// visits the frame and its content
startFrame
(
f
.
owner
.
position
,
nLocal
,
nStack
);
int
frameIndex
=
startFrame
(
f
.
owner
.
position
,
nLocal
,
nStack
);
for
(
i
=
0
;
nLocal
>
0
;
++
i
,
--
nLocal
)
{
t
=
locals
[
i
];
frame
[
frameIndex
++]
=
t
;
...
...
@@ -1580,6 +1578,67 @@ class MethodWriter extends MethodVisitor {
endFrame
();
}
/**
* Visit the implicit first frame of this method.
*/
private
void
visitImplicitFirstFrame
()
{
// There can be at most descriptor.length() + 1 locals
int
frameIndex
=
startFrame
(
0
,
descriptor
.
length
()
+
1
,
0
);
if
((
access
&
Opcodes
.
ACC_STATIC
)
==
0
)
{
if
((
access
&
ACC_CONSTRUCTOR
)
==
0
)
{
frame
[
frameIndex
++]
=
Frame
.
OBJECT
|
cw
.
addType
(
cw
.
thisName
);
}
else
{
frame
[
frameIndex
++]
=
6
;
// Opcodes.UNINITIALIZED_THIS;
}
}
int
i
=
1
;
loop:
while
(
true
)
{
int
j
=
i
;
switch
(
descriptor
.
charAt
(
i
++))
{
case
'Z'
:
case
'C'
:
case
'B'
:
case
'S'
:
case
'I'
:
frame
[
frameIndex
++]
=
1
;
// Opcodes.INTEGER;
break
;
case
'F'
:
frame
[
frameIndex
++]
=
2
;
// Opcodes.FLOAT;
break
;
case
'J'
:
frame
[
frameIndex
++]
=
4
;
// Opcodes.LONG;
break
;
case
'D'
:
frame
[
frameIndex
++]
=
3
;
// Opcodes.DOUBLE;
break
;
case
'['
:
while
(
descriptor
.
charAt
(
i
)
==
'['
)
{
++
i
;
}
if
(
descriptor
.
charAt
(
i
)
==
'L'
)
{
++
i
;
while
(
descriptor
.
charAt
(
i
)
!=
';'
)
{
++
i
;
}
}
frame
[
frameIndex
++]
=
Frame
.
OBJECT
|
cw
.
addType
(
descriptor
.
substring
(
j
,
++
i
));
break
;
case
'L'
:
while
(
descriptor
.
charAt
(
i
)
!=
';'
)
{
++
i
;
}
frame
[
frameIndex
++]
=
Frame
.
OBJECT
|
cw
.
addType
(
descriptor
.
substring
(
j
+
1
,
i
++));
break
;
default
:
break
loop
;
}
}
frame
[
1
]
=
frameIndex
-
3
;
endFrame
();
}
/**
* Starts the visit of a stack map frame.
*
...
...
@@ -1589,8 +1648,9 @@ class MethodWriter extends MethodVisitor {
* 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.
*/
private
void
startFrame
(
final
int
offset
,
final
int
nLocal
,
final
int
nStack
)
{
private
int
startFrame
(
final
int
offset
,
final
int
nLocal
,
final
int
nStack
)
{
int
n
=
3
+
nLocal
+
nStack
;
if
(
frame
==
null
||
frame
.
length
<
n
)
{
frame
=
new
int
[
n
];
...
...
@@ -1598,7 +1658,7 @@ class MethodWriter extends MethodVisitor {
frame
[
0
]
=
offset
;
frame
[
1
]
=
nLocal
;
frame
[
2
]
=
nStack
;
frameIndex
=
3
;
return
3
;
}
/**
...
...
@@ -1896,7 +1956,8 @@ class MethodWriter extends MethodVisitor {
*/
final
void
put
(
final
ByteVector
out
)
{
final
int
FACTOR
=
ClassWriter
.
TO_ACC_SYNTHETIC
;
int
mask
=
Opcodes
.
ACC_DEPRECATED
|
ClassWriter
.
ACC_SYNTHETIC_ATTRIBUTE
int
mask
=
ACC_CONSTRUCTOR
|
Opcodes
.
ACC_DEPRECATED
|
ClassWriter
.
ACC_SYNTHETIC_ATTRIBUTE
|
((
access
&
ClassWriter
.
ACC_SYNTHETIC_ATTRIBUTE
)
/
FACTOR
);
out
.
putShort
(
access
&
~
mask
).
putShort
(
name
).
putShort
(
desc
);
if
(
classReaderOffset
!=
0
)
{
...
...
src/org/objectweb/asm/optimizer/shrink.properties
View file @
6673a08b
...
...
@@ -194,7 +194,7 @@ org/objectweb/asm/MethodWriter.frameCount=u
org/objectweb/asm/
MethodWriter.stackMap
=
v
org/objectweb/asm/
MethodWriter.previousFrameOffset
=
w
org/objectweb/asm/
MethodWriter.previousFrame
=
x
org/objectweb/asm/
MethodWriter.frameIndex
=
y
#
org/objectweb/asm/MethodWriter.frameIndex=y
org/objectweb/asm/
MethodWriter.frame
=
z
org/objectweb/asm/
MethodWriter.handlerCount
=
A
org/objectweb/asm/
MethodWriter.firstHandler
=
B
...
...
@@ -333,7 +333,8 @@ org/objectweb/asm/MethodWriter.readShort([BI)S=b
org/objectweb/asm/MethodWriter.readUnsignedShort([BI)
I
=
c
org/objectweb/asm/MethodWriter.writeShort([BII)
V
=
a
org/objectweb/asm/MethodWriter.visitFrame(Lorg/objectweb/asm/Frame;)
V
=
b
org/objectweb/asm/MethodWriter.startFrame(III)
V
=
a
org/objectweb/asm/MethodWriter.visitImplicitFirstFrame()
V
=
f
org/objectweb/asm/MethodWriter.startFrame(III)
I
=
a
org/objectweb/asm/MethodWriter.endFrame()
V
=
b
org/objectweb/asm/MethodWriter.writeFrame()
V
=
c
org/objectweb/asm/MethodWriter.resizeInstructions()
V
=
d
...
...
src/org/objectweb/asm/util/CheckMethodAdapter.java
View file @
6673a08b
...
...
@@ -111,11 +111,6 @@ public class CheckMethodAdapter extends MethodVisitor {
*/
private
Set
<
Label
>
usedLabels
;
/**
* If an explicit first frame has been visited before the first instruction.
*/
private
boolean
hasExplicitFirstFrame
;
/**
* Number of visited frames in expanded form.
*/
...
...
@@ -126,6 +121,11 @@ public class CheckMethodAdapter extends MethodVisitor {
*/
private
int
compressedFrames
;
/**
* Number of instructions before the last visited frame.
*/
private
int
lastFrame
=
-
1
;
/**
* The exception handler ranges. Each pair of list element contains the
* start and end labels of an exception handler block.
...
...
@@ -506,6 +506,11 @@ public class CheckMethodAdapter extends MethodVisitor {
@Override
public
void
visitFrame
(
final
int
type
,
final
int
nLocal
,
final
Object
[]
local
,
final
int
nStack
,
final
Object
[]
stack
)
{
if
(
insnCount
==
lastFrame
)
{
throw
new
IllegalStateException
(
"At most one frame can be visited at a given code location."
);
}
lastFrame
=
insnCount
;
int
mLocal
;
int
mStack
;
switch
(
type
)
{
...
...
@@ -561,13 +566,6 @@ public class CheckMethodAdapter extends MethodVisitor {
checkFrameValue
(
stack
[
i
]);
}
if
(
type
==
Opcodes
.
F_NEW
)
{
if
(
insnCount
==
0
)
{
hasExplicitFirstFrame
=
true
;
}
else
if
(!
hasExplicitFirstFrame
)
{
throw
new
RuntimeException
(
"In expanded form, a first frame must be explicitly "
+
"visited before the first instruction."
);
}
++
expandedFrames
;
}
else
{
++
compressedFrames
;
...
...
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