Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
爱吃血肠
spring-framework
提交
ccabff6b
S
spring-framework
项目概览
爱吃血肠
/
spring-framework
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
S
spring-framework
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
ccabff6b
编写于
12月 30, 2016
作者:
J
Juergen Hoeller
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Upgrade to ASM 5.2
Issue: SPR-15071
上级
311522bc
变更
11
展开全部
隐藏空白更改
内联
并排
Showing
11 changed file
with
436 addition
and
708 deletion
+436
-708
spring-core/src/main/java/org/springframework/asm/AnnotationVisitor.java
.../main/java/org/springframework/asm/AnnotationVisitor.java
+1
-1
spring-core/src/main/java/org/springframework/asm/ClassReader.java
...re/src/main/java/org/springframework/asm/ClassReader.java
+71
-2
spring-core/src/main/java/org/springframework/asm/ClassWriter.java
...re/src/main/java/org/springframework/asm/ClassWriter.java
+41
-32
spring-core/src/main/java/org/springframework/asm/CurrentFrame.java
...e/src/main/java/org/springframework/asm/CurrentFrame.java
+56
-0
spring-core/src/main/java/org/springframework/asm/Frame.java
spring-core/src/main/java/org/springframework/asm/Frame.java
+109
-5
spring-core/src/main/java/org/springframework/asm/Item.java
spring-core/src/main/java/org/springframework/asm/Item.java
+1
-2
spring-core/src/main/java/org/springframework/asm/Label.java
spring-core/src/main/java/org/springframework/asm/Label.java
+2
-3
spring-core/src/main/java/org/springframework/asm/MethodVisitor.java
.../src/main/java/org/springframework/asm/MethodVisitor.java
+10
-9
spring-core/src/main/java/org/springframework/asm/MethodWriter.java
...e/src/main/java/org/springframework/asm/MethodWriter.java
+85
-607
spring-core/src/main/java/org/springframework/asm/Opcodes.java
...g-core/src/main/java/org/springframework/asm/Opcodes.java
+11
-7
spring-core/src/main/java/org/springframework/asm/Type.java
spring-core/src/main/java/org/springframework/asm/Type.java
+49
-40
未找到文件。
spring-core/src/main/java/org/springframework/asm/AnnotationVisitor.java
浏览文件 @
ccabff6b
...
...
@@ -89,7 +89,7 @@ public abstract class AnnotationVisitor {
* the actual value, whose type must be {@link Byte},
* {@link Boolean}, {@link Character}, {@link Short},
* {@link Integer} , {@link Long}, {@link Float}, {@link Double},
* {@link String} or {@link Type} o
r
OBJECT or ARRAY sort. This
* {@link String} or {@link Type} o
f
OBJECT or ARRAY sort. This
* value can also be an array of byte, boolean, short, char, int,
* long, float or double values (this is equivalent to using
* {@link #visitArray visitArray} and visiting each array element
...
...
spring-core/src/main/java/org/springframework/asm/ClassReader.java
浏览文件 @
ccabff6b
...
...
@@ -104,6 +104,21 @@ public class ClassReader {
*/
public
static
final
int
EXPAND_FRAMES
=
8
;
/**
* Flag to expand the ASM pseudo instructions into an equivalent sequence of
* standard bytecode instructions. When resolving a forward jump it may
* happen that the signed 2 bytes offset reserved for it is not sufficient
* to store the bytecode offset. In this case the jump instruction is
* replaced with a temporary ASM pseudo instruction using an unsigned 2
* bytes offset (see Label#resolve). This internal flag is used to re-read
* classes containing such instructions, in order to replace them with
* standard instructions. In addition, when this flag is used, GOTO_W and
* JSR_W are <i>not</i> converted into GOTO and JSR, to make sure that
* infinite loops where a GOTO_W is replaced with a GOTO in ClassReader and
* converted back to a GOTO_W in ClassWriter cannot occur.
*/
static
final
int
EXPAND_ASM_INSNS
=
256
;
/**
* The class to be parsed. <i>The content of this array must not be
* modified. This field is intended for {@link Attribute} sub classes, and
...
...
@@ -1062,6 +1077,10 @@ public class ClassReader {
readLabel
(
offset
+
readShort
(
u
+
1
),
labels
);
u
+=
3
;
break
;
case
ClassWriter
.
ASM_LABEL_INSN
:
readLabel
(
offset
+
readUnsignedShort
(
u
+
1
),
labels
);
u
+=
3
;
break
;
case
ClassWriter
.
LABELW_INSN
:
readLabel
(
offset
+
readInt
(
u
+
1
),
labels
);
u
+=
5
;
...
...
@@ -1286,8 +1305,23 @@ public class ClassReader {
}
}
}
if
((
context
.
flags
&
EXPAND_ASM_INSNS
)
!=
0
)
{
// Expanding the ASM pseudo instructions can introduce F_INSERT
// frames, even if the method does not currently have any frame.
// Also these inserted frames must be computed by simulating the
// effect of the bytecode instructions one by one, starting from the
// first one and the last existing frame (or the implicit first
// one). Finally, due to the way MethodWriter computes this (with
// the compute = INSERTED_FRAMES option), MethodWriter needs to know
// maxLocals before the first instruction is visited. For all these
// reasons we always visit the implicit first frame in this case
// (passing only maxLocals - the rest can be and is computed in
// MethodWriter).
mv
.
visitFrame
(
Opcodes
.
F_NEW
,
maxLocals
,
null
,
0
,
null
);
}
// visits the instructions
int
opcodeDelta
=
(
context
.
flags
&
EXPAND_ASM_INSNS
)
==
0
?
-
33
:
0
;
u
=
codeStart
;
while
(
u
<
codeEnd
)
{
int
offset
=
u
-
codeStart
;
...
...
@@ -1352,9 +1386,42 @@ public class ClassReader {
u
+=
3
;
break
;
case
ClassWriter
.
LABELW_INSN
:
mv
.
visitJumpInsn
(
opcode
-
33
,
labels
[
offset
+
readInt
(
u
+
1
)]);
mv
.
visitJumpInsn
(
opcode
+
opcodeDelta
,
labels
[
offset
+
readInt
(
u
+
1
)]);
u
+=
5
;
break
;
case
ClassWriter
.
ASM_LABEL_INSN
:
{
// changes temporary opcodes 202 to 217 (inclusive), 218
// and 219 to IFEQ ... JSR (inclusive), IFNULL and
// IFNONNULL
opcode
=
opcode
<
218
?
opcode
-
49
:
opcode
-
20
;
Label
target
=
labels
[
offset
+
readUnsignedShort
(
u
+
1
)];
// replaces GOTO with GOTO_W, JSR with JSR_W and IFxxx
// <l> with IFNOTxxx <l'> GOTO_W <l>, where IFNOTxxx is
// the "opposite" opcode of IFxxx (i.e., IFNE for IFEQ)
// and where <l'> designates the instruction just after
// the GOTO_W.
if
(
opcode
==
Opcodes
.
GOTO
||
opcode
==
Opcodes
.
JSR
)
{
mv
.
visitJumpInsn
(
opcode
+
33
,
target
);
}
else
{
opcode
=
opcode
<=
166
?
((
opcode
+
1
)
^
1
)
-
1
:
opcode
^
1
;
Label
endif
=
new
Label
();
mv
.
visitJumpInsn
(
opcode
,
endif
);
mv
.
visitJumpInsn
(
200
,
target
);
// GOTO_W
mv
.
visitLabel
(
endif
);
// since we introduced an unconditional jump instruction we
// also need to insert a stack map frame here, unless there
// is already one. The actual frame content will be computed
// in MethodWriter.
if
(
FRAMES
&&
stackMap
!=
0
&&
(
frame
==
null
||
frame
.
offset
!=
offset
+
3
))
{
mv
.
visitFrame
(
ClassWriter
.
F_INSERT
,
0
,
null
,
0
,
null
);
}
}
u
+=
3
;
break
;
}
case
ClassWriter
.
WIDE_INSN
:
opcode
=
b
[
u
+
1
]
&
0xFF
;
if
(
opcode
==
Opcodes
.
IINC
)
{
...
...
@@ -1848,7 +1915,9 @@ public class ClassReader {
v
+=
2
;
break
;
case
'Z'
:
// pointer to CONSTANT_Boolean
av
.
visit
(
name
,
readInt
(
items
[
readUnsignedShort
(
v
)])
==
0
?
Boolean
.
FALSE
:
Boolean
.
TRUE
);
av
.
visit
(
name
,
readInt
(
items
[
readUnsignedShort
(
v
)])
==
0
?
Boolean
.
FALSE
:
Boolean
.
TRUE
);
v
+=
2
;
break
;
case
'S'
:
// pointer to CONSTANT_Short
...
...
spring-core/src/main/java/org/springframework/asm/ClassWriter.java
浏览文件 @
ccabff6b
...
...
@@ -58,8 +58,8 @@ public class ClassWriter extends ClassVisitor {
* {@link MethodVisitor#visitFrame} method are ignored, and the stack map
* frames are recomputed from the methods bytecode. The arguments of the
* {@link MethodVisitor#visitMaxs visitMaxs} method are also ignored and
* recomputed from the bytecode. In other words,
computeFrames
implies
*
computeMaxs
.
* recomputed from the bytecode. In other words,
COMPUTE_FRAMES
implies
*
COMPUTE_MAXS
.
*
* @see #ClassWriter(int)
*/
...
...
@@ -167,6 +167,22 @@ public class ClassWriter extends ClassVisitor {
*/
static
final
int
WIDE_INSN
=
17
;
/**
* The type of the ASM pseudo instructions with an unsigned 2 bytes offset
* label (see Label#resolve).
*/
static
final
int
ASM_LABEL_INSN
=
18
;
/**
* Represents a frame inserted between already existing frames. This kind of
* frame can only be used if the frame content can be computed from the
* previous existing frame and from the instructions between this existing
* frame and the inserted one, without any knowledge of the type hierarchy.
* This kind of frame is only used when an unconditional jump is inserted in
* a method while expanding an ASM pseudo instruction (see ClassReader).
*/
static
final
int
F_INSERT
=
256
;
/**
* The instruction types of all JVM opcodes.
*/
...
...
@@ -484,25 +500,19 @@ public class ClassWriter extends ClassVisitor {
MethodWriter
lastMethod
;
/**
* <tt>true</tt> if the maximum stack size and number of local variables
* must be automatically computed.
*/
private
boolean
computeMaxs
;
/**
* <tt>true</tt> if the stack map frames must be recomputed from scratch.
* Indicates what must be automatically computed.
*
* @see MethodWriter#compute
*/
private
boolean
computeFrames
;
private
int
compute
;
/**
* <tt>true</tt> if the stack map tables of this class are invalid. The
* {@link MethodWriter#resizeInstructions} method cannot transform existing
* stack map tables, and so produces potentially invalid classes when it is
* executed. In this case the class is reread and rewritten with the
* {@link #COMPUTE_FRAMES} option (the resizeInstructions method can resize
* stack map tables when this option is used).
* <tt>true</tt> if some methods have wide forward jumps using ASM pseudo
* instructions, which need to be expanded into sequences of standard
* bytecode instructions. In this case the class is re-read and re-written
* with a ClassReader -> ClassWriter chain to perform this transformation.
*/
boolean
invalidFrame
s
;
boolean
hasAsmInsn
s
;
// ------------------------------------------------------------------------
// Static initializer
...
...
@@ -517,7 +527,7 @@ public class ClassWriter extends ClassVisitor {
String
s
=
"AAAAAAAAAAAAAAAABCLMMDDDDDEEEEEEEEEEEEEEEEEEEEAAAAAAAADD"
+
"DDDEEEEEEEEEEEEEEEEEEEEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
+
"AAAAAAAAAAAAAAAAANAAAAAAAAAAAAAAAAAAAAJJJJJJJJJJJJJJJJDOPAA"
+
"AAAAGGGGGGGHIFBFAAFFAARQJJKK
JJJJJJJJJJJJJJJJJJ
"
;
+
"AAAAGGGGGGGHIFBFAAFFAARQJJKK
SSSSSSSSSSSSSSSSSS
"
;
for
(
i
=
0
;
i
<
b
.
length
;
++
i
)
{
b
[
i
]
=
(
byte
)
(
s
.
charAt
(
i
)
-
'A'
);
}
...
...
@@ -571,7 +581,7 @@ public class ClassWriter extends ClassVisitor {
// // temporary opcodes used internally by ASM - see Label and
// MethodWriter
// for (i = 202; i < 220; ++i) {
// b[i] = LABEL_INSN;
// b[i] =
ASM_
LABEL_INSN;
// }
//
// // LDC(_W) instructions
...
...
@@ -614,8 +624,9 @@ public class ClassWriter extends ClassVisitor {
key2
=
new
Item
();
key3
=
new
Item
();
key4
=
new
Item
();
this
.
computeMaxs
=
(
flags
&
COMPUTE_MAXS
)
!=
0
;
this
.
computeFrames
=
(
flags
&
COMPUTE_FRAMES
)
!=
0
;
this
.
compute
=
(
flags
&
COMPUTE_FRAMES
)
!=
0
?
MethodWriter
.
FRAMES
:
((
flags
&
COMPUTE_MAXS
)
!=
0
?
MethodWriter
.
MAXS
:
MethodWriter
.
NOTHING
);
}
/**
...
...
@@ -645,9 +656,9 @@ public class ClassWriter extends ClassVisitor {
* @param flags
* option flags that can be used to modify the default behavior
* of this class. <i>These option flags do not affect methods
* that are copied as is in the new class. This means that
the
*
maximum stack size nor the stack frames will be computed for
* these methods</i>. See {@link #COMPUTE_MAXS},
* that are copied as is in the new class. This means that
*
neither the maximum stack size nor the stack frames will be
*
computed for
these methods</i>. See {@link #COMPUTE_MAXS},
* {@link #COMPUTE_FRAMES}.
*/
public
ClassWriter
(
final
ClassReader
classReader
,
final
int
flags
)
{
...
...
@@ -791,7 +802,7 @@ public class ClassWriter extends ClassVisitor {
public
final
MethodVisitor
visitMethod
(
final
int
access
,
final
String
name
,
final
String
desc
,
final
String
signature
,
final
String
[]
exceptions
)
{
return
new
MethodWriter
(
this
,
access
,
name
,
desc
,
signature
,
exceptions
,
compute
Maxs
,
computeFrames
);
exceptions
,
compute
);
}
@Override
...
...
@@ -977,22 +988,20 @@ public class ClassWriter extends ClassVisitor {
if
(
attrs
!=
null
)
{
attrs
.
put
(
this
,
null
,
0
,
-
1
,
-
1
,
out
);
}
if
(
invalidFrame
s
)
{
if
(
hasAsmInsn
s
)
{
anns
=
null
;
ianns
=
null
;
attrs
=
null
;
innerClassesCount
=
0
;
innerClasses
=
null
;
bootstrapMethodsCount
=
0
;
bootstrapMethods
=
null
;
firstField
=
null
;
lastField
=
null
;
firstMethod
=
null
;
lastMethod
=
null
;
compute
Maxs
=
false
;
computeFrames
=
tru
e
;
invalidFrames
=
false
;
new
ClassReader
(
out
.
data
).
accept
(
this
,
ClassReader
.
SKIP_FRAME
S
);
compute
=
MethodWriter
.
INSERTED_FRAMES
;
hasAsmInsns
=
fals
e
;
new
ClassReader
(
out
.
data
).
accept
(
this
,
ClassReader
.
EXPAND_FRAMES
|
ClassReader
.
EXPAND_ASM_INSN
S
);
return
toByteArray
();
}
return
out
.
data
;
...
...
spring-core/src/main/java/org/springframework/asm/CurrentFrame.java
0 → 100644
浏览文件 @
ccabff6b
/***
* 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
org.springframework.asm
;
/**
* Information about the input stack map frame at the "current" instruction of a
* method. This is implemented as a Frame subclass for a "basic block"
* containing only one instruction.
*
* @author Eric Bruneton
*/
class
CurrentFrame
extends
Frame
{
/**
* Sets this CurrentFrame to the input stack map frame of the next "current"
* instruction, i.e. the instruction just after the given one. It is assumed
* that the value of this object when this method is called is the stack map
* frame status just before the given instruction is executed.
*/
@Override
void
execute
(
int
opcode
,
int
arg
,
ClassWriter
cw
,
Item
item
)
{
super
.
execute
(
opcode
,
arg
,
cw
,
item
);
Frame
successor
=
new
Frame
();
merge
(
cw
,
successor
,
0
);
set
(
successor
);
owner
.
inputStackTop
=
0
;
}
}
spring-core/src/main/java/org/springframework/asm/Frame.java
浏览文件 @
ccabff6b
...
...
@@ -34,7 +34,7 @@ package org.springframework.asm;
*
* @author Eric Bruneton
*/
final
class
Frame
{
class
Frame
{
/*
* Frames are computed in a two steps process: during the visit of each
...
...
@@ -496,7 +496,7 @@ final class Frame {
* When the stack map frames are completely computed, this field is the
* actual number of types in {@link #outputStack}.
*/
private
int
outputStackTop
;
int
outputStackTop
;
/**
* Number of types that are initialized in the basic block.
...
...
@@ -520,6 +520,110 @@ final class Frame {
*/
private
int
[]
initializations
;
/**
* Sets this frame to the given value.
*
* @param cw
* the ClassWriter to which this label belongs.
* @param nLocal
* the number of local variables.
* @param local
* the local variable types. Primitive types are represented by
* {@link Opcodes#TOP}, {@link Opcodes#INTEGER},
* {@link Opcodes#FLOAT}, {@link Opcodes#LONG},
* {@link Opcodes#DOUBLE},{@link Opcodes#NULL} or
* {@link Opcodes#UNINITIALIZED_THIS} (long and double are
* represented by a single element). Reference types are
* represented by String objects (representing internal names),
* and uninitialized types by Label objects (this label
* designates the NEW instruction that created this uninitialized
* value).
* @param nStack
* the number of operand stack elements.
* @param stack
* the operand stack types (same format as the "local" array).
*/
final
void
set
(
ClassWriter
cw
,
final
int
nLocal
,
final
Object
[]
local
,
final
int
nStack
,
final
Object
[]
stack
)
{
int
i
=
convert
(
cw
,
nLocal
,
local
,
inputLocals
);
while
(
i
<
local
.
length
)
{
inputLocals
[
i
++]
=
TOP
;
}
int
nStackTop
=
0
;
for
(
int
j
=
0
;
j
<
nStack
;
++
j
)
{
if
(
stack
[
j
]
==
Opcodes
.
LONG
||
stack
[
j
]
==
Opcodes
.
DOUBLE
)
{
++
nStackTop
;
}
}
inputStack
=
new
int
[
nStack
+
nStackTop
];
convert
(
cw
,
nStack
,
stack
,
inputStack
);
outputStackTop
=
0
;
initializationCount
=
0
;
}
/**
* Converts types from the MethodWriter.visitFrame() format to the Frame
* format.
*
* @param cw
* the ClassWriter to which this label belongs.
* @param nInput
* the number of types to convert.
* @param input
* the types to convert. Primitive types are represented by
* {@link Opcodes#TOP}, {@link Opcodes#INTEGER},
* {@link Opcodes#FLOAT}, {@link Opcodes#LONG},
* {@link Opcodes#DOUBLE},{@link Opcodes#NULL} or
* {@link Opcodes#UNINITIALIZED_THIS} (long and double are
* represented by a single element). Reference types are
* represented by String objects (representing internal names),
* and uninitialized types by Label objects (this label
* designates the NEW instruction that created this uninitialized
* value).
* @param output
* where to store the converted types.
* @return the number of output elements.
*/
private
static
int
convert
(
ClassWriter
cw
,
int
nInput
,
Object
[]
input
,
int
[]
output
)
{
int
i
=
0
;
for
(
int
j
=
0
;
j
<
nInput
;
++
j
)
{
if
(
input
[
j
]
instanceof
Integer
)
{
output
[
i
++]
=
BASE
|
((
Integer
)
input
[
j
]).
intValue
();
if
(
input
[
j
]
==
Opcodes
.
LONG
||
input
[
j
]
==
Opcodes
.
DOUBLE
)
{
output
[
i
++]
=
TOP
;
}
}
else
if
(
input
[
j
]
instanceof
String
)
{
output
[
i
++]
=
type
(
cw
,
Type
.
getObjectType
((
String
)
input
[
j
])
.
getDescriptor
());
}
else
{
output
[
i
++]
=
UNINITIALIZED
|
cw
.
addUninitializedType
(
""
,
((
Label
)
input
[
j
]).
position
);
}
}
return
i
;
}
/**
* 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 f to avoid unexpected side
* effects.
*
* @param f
* The new frame value.
*/
final
void
set
(
final
Frame
f
)
{
inputLocals
=
f
.
inputLocals
;
inputStack
=
f
.
inputStack
;
outputLocals
=
f
.
outputLocals
;
outputStack
=
f
.
outputStack
;
outputStackTop
=
f
.
outputStackTop
;
initializationCount
=
f
.
initializationCount
;
initializations
=
f
.
initializations
;
}
/**
* Returns the output frame local variable type at the given index.
*
...
...
@@ -585,7 +689,7 @@ final class Frame {
}
// pushes the type on the output stack
outputStack
[
outputStackTop
++]
=
type
;
// updates the maximu
n
height reached by the output stack, if needed
// updates the maximu
m
height reached by the output stack, if needed
int
top
=
owner
.
inputStackTop
+
outputStackTop
;
if
(
top
>
owner
.
outputStackMax
)
{
owner
.
outputStackMax
=
top
;
...
...
@@ -809,7 +913,7 @@ final class Frame {
* @param maxLocals
* the maximum number of local variables of this method.
*/
void
initInputFrame
(
final
ClassWriter
cw
,
final
int
access
,
final
void
initInputFrame
(
final
ClassWriter
cw
,
final
int
access
,
final
Type
[]
args
,
final
int
maxLocals
)
{
inputLocals
=
new
int
[
maxLocals
];
inputStack
=
new
int
[
0
];
...
...
@@ -1283,7 +1387,7 @@ final class Frame {
* @return <tt>true</tt> if the input frame of the given label has been
* changed by this operation.
*/
boolean
merge
(
final
ClassWriter
cw
,
final
Frame
frame
,
final
int
edge
)
{
final
boolean
merge
(
final
ClassWriter
cw
,
final
Frame
frame
,
final
int
edge
)
{
boolean
changed
=
false
;
int
i
,
s
,
dim
,
kind
,
t
;
...
...
spring-core/src/main/java/org/springframework/asm/Item.java
浏览文件 @
ccabff6b
...
...
@@ -201,6 +201,7 @@ final class Item {
* @param strVal3
* third part of the value of this item.
*/
@SuppressWarnings
(
"fallthrough"
)
void
set
(
final
int
type
,
final
String
strVal1
,
final
String
strVal2
,
final
String
strVal3
)
{
this
.
type
=
type
;
...
...
@@ -210,8 +211,6 @@ final class Item {
switch
(
type
)
{
case
ClassWriter
.
CLASS
:
this
.
intVal
=
0
;
// intVal of a class must be zero, see visitInnerClass
hashCode
=
0x7FFFFFFF
&
(
type
+
strVal1
.
hashCode
());
return
;
case
ClassWriter
.
UTF8
:
case
ClassWriter
.
STR
:
case
ClassWriter
.
MTYPE
:
...
...
spring-core/src/main/java/org/springframework/asm/Label.java
浏览文件 @
ccabff6b
...
...
@@ -364,9 +364,8 @@ public class Label {
* small to store the offset. In such a case the corresponding jump
* instruction is replaced with a pseudo instruction (using unused
* opcodes) using an unsigned two bytes offset. These pseudo
* instructions will need to be replaced with true instructions with
* wider offsets (4 bytes instead of 2). This is done in
* {@link MethodWriter#resizeInstructions}.
* instructions will be replaced with standard bytecode instructions
* with wider offsets (4 bytes instead of 2), in ClassReader.
* @throws IllegalArgumentException
* if this label has already been resolved, or if it has not
* been created by the given code writer.
...
...
spring-core/src/main/java/org/springframework/asm/MethodVisitor.java
浏览文件 @
ccabff6b
...
...
@@ -33,15 +33,16 @@ package org.springframework.asm;
* A visitor to visit a Java method. The methods of this class must be called in
* the following order: ( <tt>visitParameter</tt> )* [
* <tt>visitAnnotationDefault</tt> ] ( <tt>visitAnnotation</tt> |
* <tt>visitTypeAnnotation</tt> | <tt>visitAttribute</tt> )* [
* <tt>visitCode</tt> ( <tt>visitFrame</tt> | <tt>visit<i>X</i>Insn</tt> |
* <tt>visitLabel</tt> | <tt>visitInsnAnnotation</tt> |
* <tt>visitTryCatchBlock</tt> | <tt>visitTryCatchBlockAnnotation</tt> |
* <tt>visitLocalVariable</tt> | <tt>visitLocalVariableAnnotation</tt> |
* <tt>visitLineNumber</tt> )* <tt>visitMaxs</tt> ] <tt>visitEnd</tt>. In
* addition, the <tt>visit<i>X</i>Insn</tt> and <tt>visitLabel</tt> methods must
* be called in the sequential order of the bytecode instructions of the visited
* code, <tt>visitInsnAnnotation</tt> must be called <i>after</i> the annotated
* <tt>visitParameterAnnotation</tt> <tt>visitTypeAnnotation</tt> |
* <tt>visitAttribute</tt> )* [ <tt>visitCode</tt> ( <tt>visitFrame</tt> |
* <tt>visit<i>X</i>Insn</tt> | <tt>visitLabel</tt> |
* <tt>visitInsnAnnotation</tt> | <tt>visitTryCatchBlock</tt> |
* <tt>visitTryCatchAnnotation</tt> | <tt>visitLocalVariable</tt> |
* <tt>visitLocalVariableAnnotation</tt> | <tt>visitLineNumber</tt> )*
* <tt>visitMaxs</tt> ] <tt>visitEnd</tt>. In addition, the
* <tt>visit<i>X</i>Insn</tt> and <tt>visitLabel</tt> methods must be called in
* the sequential order of the bytecode instructions of the visited code,
* <tt>visitInsnAnnotation</tt> must be called <i>after</i> the annotated
* instruction, <tt>visitTryCatchBlock</tt> must be called <i>before</i> the
* labels passed as arguments have been visited,
* <tt>visitTryCatchBlockAnnotation</tt> must be called <i>after</i> the
...
...
spring-core/src/main/java/org/springframework/asm/MethodWriter.java
浏览文件 @
ccabff6b
此差异已折叠。
点击以展开。
spring-core/src/main/java/org/springframework/asm/Opcodes.java
浏览文件 @
ccabff6b
...
...
@@ -146,13 +146,17 @@ public interface Opcodes {
*/
int
F_SAME1
=
4
;
Integer
TOP
=
0
;
Integer
INTEGER
=
1
;
Integer
FLOAT
=
2
;
Integer
DOUBLE
=
3
;
Integer
LONG
=
4
;
Integer
NULL
=
5
;
Integer
UNINITIALIZED_THIS
=
6
;
// Do not try to change the following code to use auto-boxing,
// these values are compared by reference and not by value
// The constructor of Integer was deprecated in 9
// but we are stuck with it by backward compatibility
@SuppressWarnings
(
"deprecation"
)
Integer
TOP
=
new
Integer
(
0
);
@SuppressWarnings
(
"deprecation"
)
Integer
INTEGER
=
new
Integer
(
1
);
@SuppressWarnings
(
"deprecation"
)
Integer
FLOAT
=
new
Integer
(
2
);
@SuppressWarnings
(
"deprecation"
)
Integer
DOUBLE
=
new
Integer
(
3
);
@SuppressWarnings
(
"deprecation"
)
Integer
LONG
=
new
Integer
(
4
);
@SuppressWarnings
(
"deprecation"
)
Integer
NULL
=
new
Integer
(
5
);
@SuppressWarnings
(
"deprecation"
)
Integer
UNINITIALIZED_THIS
=
new
Integer
(
6
);
// opcodes // visit method (- = idem)
...
...
spring-core/src/main/java/org/springframework/asm/Type.java
浏览文件 @
ccabff6b
...
...
@@ -377,7 +377,16 @@ public class Type {
*/
public
static
Type
getReturnType
(
final
String
methodDescriptor
)
{
char
[]
buf
=
methodDescriptor
.
toCharArray
();
return
getType
(
buf
,
methodDescriptor
.
indexOf
(
')'
)
+
1
);
int
off
=
1
;
while
(
true
)
{
char
car
=
buf
[
off
++];
if
(
car
==
')'
)
{
return
getType
(
buf
,
off
);
}
else
if
(
car
==
'L'
)
{
while
(
buf
[
off
++]
!=
';'
)
{
}
}
}
}
/**
...
...
@@ -625,9 +634,9 @@ public class Type {
* @return the descriptor corresponding to this Java type.
*/
public
String
getDescriptor
()
{
StringBuilder
sb
=
new
StringBuilder
();
getDescriptor
(
sb
);
return
sb
.
toString
();
StringBuilder
buf
=
new
StringBuilder
();
getDescriptor
(
buf
);
return
buf
.
toString
();
}
/**
...
...
@@ -643,34 +652,34 @@ public class Type {
*/
public
static
String
getMethodDescriptor
(
final
Type
returnType
,
final
Type
...
argumentTypes
)
{
StringBuilder
sb
=
new
StringBuilder
();
sb
.
append
(
'('
);
StringBuilder
buf
=
new
StringBuilder
();
buf
.
append
(
'('
);
for
(
int
i
=
0
;
i
<
argumentTypes
.
length
;
++
i
)
{
argumentTypes
[
i
].
getDescriptor
(
sb
);
argumentTypes
[
i
].
getDescriptor
(
buf
);
}
sb
.
append
(
')'
);
returnType
.
getDescriptor
(
sb
);
return
sb
.
toString
();
buf
.
append
(
')'
);
returnType
.
getDescriptor
(
buf
);
return
buf
.
toString
();
}
/**
* Appends the descriptor corresponding to this Java type to the given
* string bu
ild
er.
* string bu
ff
er.
*
* @param
sb
* the string bu
ild
er to which the descriptor must be appended.
* @param
buf
* the string bu
ff
er to which the descriptor must be appended.
*/
private
void
getDescriptor
(
final
StringBuilder
sb
)
{
private
void
getDescriptor
(
final
StringBuilder
buf
)
{
if
(
this
.
buf
==
null
)
{
// descriptor is in byte 3 of 'off' for primitive types (buf ==
// null)
sb
.
append
((
char
)
((
off
&
0xFF000000
)
>>>
24
));
buf
.
append
((
char
)
((
off
&
0xFF000000
)
>>>
24
));
}
else
if
(
sort
==
OBJECT
)
{
sb
.
append
(
'L'
);
sb
.
append
(
this
.
buf
,
off
,
len
);
sb
.
append
(
';'
);
buf
.
append
(
'L'
);
buf
.
append
(
this
.
buf
,
off
,
len
);
buf
.
append
(
';'
);
}
else
{
// sort == ARRAY || sort == METHOD
sb
.
append
(
this
.
buf
,
off
,
len
);
buf
.
append
(
this
.
buf
,
off
,
len
);
}
}
...
...
@@ -700,9 +709,9 @@ public class Type {
* @return the descriptor corresponding to the given class.
*/
public
static
String
getDescriptor
(
final
Class
<?>
c
)
{
StringBuilder
sb
=
new
StringBuilder
();
getDescriptor
(
sb
,
c
);
return
sb
.
toString
();
StringBuilder
buf
=
new
StringBuilder
();
getDescriptor
(
buf
,
c
);
return
buf
.
toString
();
}
/**
...
...
@@ -714,12 +723,12 @@ public class Type {
*/
public
static
String
getConstructorDescriptor
(
final
Constructor
<?>
c
)
{
Class
<?>[]
parameters
=
c
.
getParameterTypes
();
StringBuilder
sb
=
new
StringBuilder
();
sb
.
append
(
'('
);
StringBuilder
buf
=
new
StringBuilder
();
buf
.
append
(
'('
);
for
(
int
i
=
0
;
i
<
parameters
.
length
;
++
i
)
{
getDescriptor
(
sb
,
parameters
[
i
]);
getDescriptor
(
buf
,
parameters
[
i
]);
}
return
sb
.
append
(
")V"
).
toString
();
return
buf
.
append
(
")V"
).
toString
();
}
/**
...
...
@@ -731,25 +740,25 @@ public class Type {
*/
public
static
String
getMethodDescriptor
(
final
Method
m
)
{
Class
<?>[]
parameters
=
m
.
getParameterTypes
();
StringBuilder
sb
=
new
StringBuilder
();
sb
.
append
(
'('
);
StringBuilder
buf
=
new
StringBuilder
();
buf
.
append
(
'('
);
for
(
int
i
=
0
;
i
<
parameters
.
length
;
++
i
)
{
getDescriptor
(
sb
,
parameters
[
i
]);
getDescriptor
(
buf
,
parameters
[
i
]);
}
sb
.
append
(
')'
);
getDescriptor
(
sb
,
m
.
getReturnType
());
return
sb
.
toString
();
buf
.
append
(
')'
);
getDescriptor
(
buf
,
m
.
getReturnType
());
return
buf
.
toString
();
}
/**
* Appends the descriptor of the given class to the given string bu
ild
er.
* Appends the descriptor of the given class to the given string bu
ff
er.
*
* @param
sb
* @param
buf
* the string buffer to which the descriptor must be appended.
* @param c
* the class whose descriptor must be computed.
*/
private
static
void
getDescriptor
(
final
StringBuilder
sb
,
final
Class
<?>
c
)
{
private
static
void
getDescriptor
(
final
StringBuilder
buf
,
final
Class
<?>
c
)
{
Class
<?>
d
=
c
;
while
(
true
)
{
if
(
d
.
isPrimitive
())
{
...
...
@@ -773,20 +782,20 @@ public class Type {
}
else
/* if (d == Long.TYPE) */
{
car
=
'J'
;
}
sb
.
append
(
car
);
buf
.
append
(
car
);
return
;
}
else
if
(
d
.
isArray
())
{
sb
.
append
(
'['
);
buf
.
append
(
'['
);
d
=
d
.
getComponentType
();
}
else
{
sb
.
append
(
'L'
);
buf
.
append
(
'L'
);
String
name
=
d
.
getName
();
int
len
=
name
.
length
();
for
(
int
i
=
0
;
i
<
len
;
++
i
)
{
char
car
=
name
.
charAt
(
i
);
sb
.
append
(
car
==
'.'
?
'/'
:
car
);
buf
.
append
(
car
==
'.'
?
'/'
:
car
);
}
sb
.
append
(
';'
);
buf
.
append
(
';'
);
return
;
}
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录