Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
dragonwell8_jdk
提交
6f00077f
D
dragonwell8_jdk
项目概览
openanolis
/
dragonwell8_jdk
通知
4
Star
2
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
D
dragonwell8_jdk
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
6f00077f
编写于
4月 20, 2016
作者:
M
mhaupt
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
8081512: Remove sun.invoke.anon classes, or move / co-locate them with tests
Reviewed-by: mchung, sundar
上级
5e449602
变更
5
显示空白变更内容
内联
并排
Showing
5 changed file
with
0 addition
and
1338 deletion
+0
-1338
src/share/classes/sun/invoke/anon/AnonymousClassLoader.java
src/share/classes/sun/invoke/anon/AnonymousClassLoader.java
+0
-230
src/share/classes/sun/invoke/anon/ConstantPoolParser.java
src/share/classes/sun/invoke/anon/ConstantPoolParser.java
+0
-368
src/share/classes/sun/invoke/anon/ConstantPoolPatch.java
src/share/classes/sun/invoke/anon/ConstantPoolPatch.java
+0
-503
src/share/classes/sun/invoke/anon/ConstantPoolVisitor.java
src/share/classes/sun/invoke/anon/ConstantPoolVisitor.java
+0
-192
src/share/classes/sun/invoke/anon/InvalidConstantPoolFormatException.java
...s/sun/invoke/anon/InvalidConstantPoolFormatException.java
+0
-45
未找到文件。
src/share/classes/sun/invoke/anon/AnonymousClassLoader.java
已删除
100644 → 0
浏览文件 @
5e449602
/*
* Copyright (c) 2008, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package
sun.invoke.anon
;
import
java.io.IOException
;
import
java.lang.reflect.InvocationTargetException
;
import
java.lang.reflect.Method
;
import
sun.misc.IOUtils
;
/**
* Anonymous class loader. Will load any valid classfile, producing
* a {@link Class} metaobject, without installing that class in the
* system dictionary. Therefore, {@link Class#forName(String)} will never
* produce a reference to an anonymous class.
* <p>
* The access permissions of the anonymous class are borrowed from
* a <em>host class</em>. The new class behaves as if it were an
* inner class of the host class. It can access the host's private
* members, if the creator of the class loader has permission to
* do so (or to create accessible reflective objects).
* <p>
* When the anonymous class is loaded, elements of its constant pool
* can be patched to new values. This provides a hook to pre-resolve
* named classes in the constant pool to other classes, including
* anonymous ones. Also, string constants can be pre-resolved to
* any reference. (The verifier treats non-string, non-class reference
* constants as plain objects.)
* <p>
* Why include the patching function? It makes some use cases much easier.
* Second, the constant pool needed some internal patching anyway,
* to anonymize the loaded class itself. Finally, if you are going
* to use this seriously, you'll want to build anonymous classes
* on top of pre-existing anonymous classes, and that requires patching.
*
* <p>%%% TO-DO:
* <ul>
* <li>needs better documentation</li>
* <li>needs more security work (for safe delegation)</li>
* <li>needs a clearer story about error processing</li>
* <li>patch member references also (use ';' as delimiter char)</li>
* <li>patch method references to (conforming) method handles</li>
* </ul>
*
* @author jrose
* @author Remi Forax
* @see <a href="http://blogs.sun.com/jrose/entry/anonymous_classes_in_the_vm">
* http://blogs.sun.com/jrose/entry/anonymous_classes_in_the_vm</a>
*/
public
class
AnonymousClassLoader
{
final
Class
<?>
hostClass
;
// Privileged constructor.
private
AnonymousClassLoader
(
Class
<?>
hostClass
)
{
this
.
hostClass
=
hostClass
;
}
public
static
AnonymousClassLoader
make
(
sun
.
misc
.
Unsafe
unsafe
,
Class
<?>
hostClass
)
{
if
(
unsafe
==
null
)
throw
new
NullPointerException
();
return
new
AnonymousClassLoader
(
hostClass
);
}
public
Class
<?>
loadClass
(
byte
[]
classFile
)
{
if
(
defineAnonymousClass
==
null
)
{
// no JVM support; try to fake an approximation
try
{
return
fakeLoadClass
(
new
ConstantPoolParser
(
classFile
).
createPatch
());
}
catch
(
InvalidConstantPoolFormatException
ee
)
{
throw
new
IllegalArgumentException
(
ee
);
}
}
return
loadClass
(
classFile
,
null
);
}
public
Class
<?>
loadClass
(
ConstantPoolPatch
classPatch
)
{
if
(
defineAnonymousClass
==
null
)
{
// no JVM support; try to fake an approximation
return
fakeLoadClass
(
classPatch
);
}
Object
[]
patches
=
classPatch
.
patchArray
;
// Convert class names (this late in the game)
// to use slash '/' instead of dot '.'.
// Java likes dots, but the JVM likes slashes.
for
(
int
i
=
0
;
i
<
patches
.
length
;
i
++)
{
Object
value
=
patches
[
i
];
if
(
value
!=
null
)
{
byte
tag
=
classPatch
.
getTag
(
i
);
switch
(
tag
)
{
case
ConstantPoolVisitor
.
CONSTANT_Class
:
if
(
value
instanceof
String
)
{
if
(
patches
==
classPatch
.
patchArray
)
patches
=
patches
.
clone
();
patches
[
i
]
=
((
String
)
value
).
replace
(
'.'
,
'/'
);
}
break
;
case
ConstantPoolVisitor
.
CONSTANT_Fieldref
:
case
ConstantPoolVisitor
.
CONSTANT_Methodref
:
case
ConstantPoolVisitor
.
CONSTANT_InterfaceMethodref
:
case
ConstantPoolVisitor
.
CONSTANT_NameAndType
:
// When/if the JVM supports these patches,
// we'll probably need to reformat them also.
// Meanwhile, let the class loader create the error.
break
;
}
}
}
return
loadClass
(
classPatch
.
outer
.
classFile
,
classPatch
.
patchArray
);
}
private
Class
<?>
loadClass
(
byte
[]
classFile
,
Object
[]
patchArray
)
{
try
{
return
(
Class
<?>)
defineAnonymousClass
.
invoke
(
unsafe
,
hostClass
,
classFile
,
patchArray
);
}
catch
(
Exception
ex
)
{
throwReflectedException
(
ex
);
throw
new
RuntimeException
(
"error loading into "
+
hostClass
,
ex
);
}
}
private
static
void
throwReflectedException
(
Exception
ex
)
{
if
(
ex
instanceof
InvocationTargetException
)
{
Throwable
tex
=
((
InvocationTargetException
)
ex
).
getTargetException
();
if
(
tex
instanceof
Error
)
throw
(
Error
)
tex
;
ex
=
(
Exception
)
tex
;
}
if
(
ex
instanceof
RuntimeException
)
{
throw
(
RuntimeException
)
ex
;
}
}
private
Class
<?>
fakeLoadClass
(
ConstantPoolPatch
classPatch
)
{
// Implementation:
// 1. Make up a new name nobody has used yet.
// 2. Inspect the tail-header of the class to find the this_class index.
// 3. Patch the CONSTANT_Class for this_class to the new name.
// 4. Add other CP entries required by (e.g.) string patches.
// 5. Flatten Class constants down to their names, making sure that
// the host class loader can pick them up again accurately.
// 6. Generate the edited class file bytes.
//
// Potential limitations:
// * The class won't be truly anonymous, and may interfere with others.
// * Flattened class constants might not work, because of loader issues.
// * Pseudo-string constants will not flatten down to real strings.
// * Method handles will (of course) fail to flatten to linkage strings.
if
(
true
)
throw
new
UnsupportedOperationException
(
"NYI"
);
Object
[]
cpArray
;
try
{
cpArray
=
classPatch
.
getOriginalCP
();
}
catch
(
InvalidConstantPoolFormatException
ex
)
{
throw
new
RuntimeException
(
ex
);
}
int
thisClassIndex
=
classPatch
.
getParser
().
getThisClassIndex
();
String
thisClassName
=
(
String
)
cpArray
[
thisClassIndex
];
synchronized
(
AnonymousClassLoader
.
class
)
{
thisClassName
=
thisClassName
+
"\\|"
+(++
fakeNameCounter
);
}
classPatch
.
putUTF8
(
thisClassIndex
,
thisClassName
);
byte
[]
classFile
=
null
;
return
unsafe
.
defineClass
(
null
,
classFile
,
0
,
classFile
.
length
,
hostClass
.
getClassLoader
(),
hostClass
.
getProtectionDomain
());
}
private
static
int
fakeNameCounter
=
99999
;
// ignore two warnings on this line:
private
static
sun
.
misc
.
Unsafe
unsafe
=
sun
.
misc
.
Unsafe
.
getUnsafe
();
// preceding line requires that this class be on the boot class path
static
private
final
Method
defineAnonymousClass
;
static
{
Method
dac
=
null
;
Class
<?
extends
sun
.
misc
.
Unsafe
>
unsafeClass
=
unsafe
.
getClass
();
try
{
dac
=
unsafeClass
.
getMethod
(
"defineAnonymousClass"
,
Class
.
class
,
byte
[].
class
,
Object
[].
class
);
}
catch
(
Exception
ee
)
{
dac
=
null
;
}
defineAnonymousClass
=
dac
;
}
private
static
void
noJVMSupport
()
{
throw
new
UnsupportedOperationException
(
"no JVM support for anonymous classes"
);
}
private
static
native
Class
<?>
loadClassInternal
(
Class
<?>
hostClass
,
byte
[]
classFile
,
Object
[]
patchArray
);
public
static
byte
[]
readClassFile
(
Class
<?>
templateClass
)
throws
IOException
{
String
templateName
=
templateClass
.
getName
();
int
lastDot
=
templateName
.
lastIndexOf
(
'.'
);
java
.
net
.
URL
url
=
templateClass
.
getResource
(
templateName
.
substring
(
lastDot
+
1
)+
".class"
);
java
.
net
.
URLConnection
connection
=
url
.
openConnection
();
int
contentLength
=
connection
.
getContentLength
();
if
(
contentLength
<
0
)
throw
new
IOException
(
"invalid content length "
+
contentLength
);
return
IOUtils
.
readFully
(
connection
.
getInputStream
(),
contentLength
,
true
);
}
}
src/share/classes/sun/invoke/anon/ConstantPoolParser.java
已删除
100644 → 0
浏览文件 @
5e449602
/*
* Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package
sun.invoke.anon
;
import
java.io.IOException
;
import
java.io.OutputStream
;
import
java.nio.BufferUnderflowException
;
import
java.nio.ByteBuffer
;
import
static
sun
.
invoke
.
anon
.
ConstantPoolVisitor
.*;
/** A constant pool parser.
*/
public
class
ConstantPoolParser
{
final
byte
[]
classFile
;
final
byte
[]
tags
;
final
char
[]
firstHeader
;
// maghi, maglo, minor, major, cplen
// these are filled in on first parse:
int
endOffset
;
char
[]
secondHeader
;
// flags, this_class, super_class, intlen
// used to decode UTF8 array
private
char
[]
charArray
=
new
char
[
80
];
/** Creates a constant pool parser.
* @param classFile an array of bytes containing a class.
* @throws InvalidConstantPoolFormatException if the header of the class has errors.
*/
public
ConstantPoolParser
(
byte
[]
classFile
)
throws
InvalidConstantPoolFormatException
{
this
.
classFile
=
classFile
;
this
.
firstHeader
=
parseHeader
(
classFile
);
this
.
tags
=
new
byte
[
firstHeader
[
4
]];
}
/** Create a constant pool parser by loading the bytecodes of the
* class taken as argument.
*
* @param templateClass the class to parse.
*
* @throws IOException raised if an I/O occurs when loading
* the bytecode of the template class.
* @throws InvalidConstantPoolFormatException if the header of the class has errors.
*
* @see #ConstantPoolParser(byte[])
* @see AnonymousClassLoader#readClassFile(Class)
*/
public
ConstantPoolParser
(
Class
<?>
templateClass
)
throws
IOException
,
InvalidConstantPoolFormatException
{
this
(
AnonymousClassLoader
.
readClassFile
(
templateClass
));
}
/** Creates an empty patch to patch the class file
* used by the current parser.
* @return a new class patch.
*/
public
ConstantPoolPatch
createPatch
()
{
return
new
ConstantPoolPatch
(
this
);
}
/** Report the tag of the indicated CP entry.
* @param index
* @return one of {@link ConstantPoolVisitor#CONSTANT_Utf8}, etc.
*/
public
byte
getTag
(
int
index
)
{
getEndOffset
();
// trigger an exception if we haven't parsed yet
return
tags
[
index
];
}
/** Report the length of the constant pool. */
public
int
getLength
()
{
return
firstHeader
[
4
];
}
/** Report the offset, within the class file, of the start of the constant pool. */
public
int
getStartOffset
()
{
return
firstHeader
.
length
*
2
;
}
/** Report the offset, within the class file, of the end of the constant pool. */
public
int
getEndOffset
()
{
if
(
endOffset
==
0
)
throw
new
IllegalStateException
(
"class file has not yet been parsed"
);
return
endOffset
;
}
/** Report the CP index of this class's own name. */
public
int
getThisClassIndex
()
{
getEndOffset
();
// provoke exception if not yet parsed
return
secondHeader
[
1
];
}
/** Report the total size of the class file. */
public
int
getTailLength
()
{
return
classFile
.
length
-
getEndOffset
();
}
/** Write the head (header plus constant pool)
* of the class file to the indicated stream.
*/
public
void
writeHead
(
OutputStream
out
)
throws
IOException
{
out
.
write
(
classFile
,
0
,
getEndOffset
());
}
/** Write the head (header plus constant pool)
* of the class file to the indicated stream,
* incorporating the non-null entries of the given array
* as patches.
*/
void
writePatchedHead
(
OutputStream
out
,
Object
[]
patchArray
)
{
// this will be useful to partially emulate the class loader on old JVMs
throw
new
UnsupportedOperationException
(
"Not yet implemented"
);
}
/** Write the tail (everything after the constant pool)
* of the class file to the indicated stream.
*/
public
void
writeTail
(
OutputStream
out
)
throws
IOException
{
out
.
write
(
classFile
,
getEndOffset
(),
getTailLength
());
}
private
static
char
[]
parseHeader
(
byte
[]
classFile
)
throws
InvalidConstantPoolFormatException
{
char
[]
result
=
new
char
[
5
];
ByteBuffer
buffer
=
ByteBuffer
.
wrap
(
classFile
);
for
(
int
i
=
0
;
i
<
result
.
length
;
i
++)
result
[
i
]
=
(
char
)
getUnsignedShort
(
buffer
);
int
magic
=
result
[
0
]
<<
16
|
result
[
1
]
<<
0
;
if
(
magic
!=
0xCAFEBABE
)
throw
new
InvalidConstantPoolFormatException
(
"invalid magic number "
+
magic
);
// skip major, minor version
int
len
=
result
[
4
];
if
(
len
<
1
)
throw
new
InvalidConstantPoolFormatException
(
"constant pool length < 1"
);
return
result
;
}
/** Parse the constant pool of the class
* calling a method visit* each time a constant pool entry is parsed.
*
* The order of the calls to visit* is not guaranteed to be the same
* than the order of the constant pool entry in the bytecode array.
*
* @param visitor
* @throws InvalidConstantPoolFormatException
*/
public
void
parse
(
ConstantPoolVisitor
visitor
)
throws
InvalidConstantPoolFormatException
{
ByteBuffer
buffer
=
ByteBuffer
.
wrap
(
classFile
);
buffer
.
position
(
getStartOffset
());
//skip header
Object
[]
values
=
new
Object
[
getLength
()];
try
{
parseConstantPool
(
buffer
,
values
,
visitor
);
}
catch
(
BufferUnderflowException
e
)
{
throw
new
InvalidConstantPoolFormatException
(
e
);
}
if
(
endOffset
==
0
)
{
endOffset
=
buffer
.
position
();
secondHeader
=
new
char
[
4
];
for
(
int
i
=
0
;
i
<
secondHeader
.
length
;
i
++)
{
secondHeader
[
i
]
=
(
char
)
getUnsignedShort
(
buffer
);
}
}
resolveConstantPool
(
values
,
visitor
);
}
private
char
[]
getCharArray
(
int
utfLength
)
{
if
(
utfLength
<=
charArray
.
length
)
return
charArray
;
return
charArray
=
new
char
[
utfLength
];
}
private
void
parseConstantPool
(
ByteBuffer
buffer
,
Object
[]
values
,
ConstantPoolVisitor
visitor
)
throws
InvalidConstantPoolFormatException
{
for
(
int
i
=
1
;
i
<
tags
.
length
;
)
{
byte
tag
=
(
byte
)
getUnsignedByte
(
buffer
);
assert
(
tags
[
i
]
==
0
||
tags
[
i
]
==
tag
);
tags
[
i
]
=
tag
;
switch
(
tag
)
{
case
CONSTANT_Utf8:
int
utfLen
=
getUnsignedShort
(
buffer
);
String
value
=
getUTF8
(
buffer
,
utfLen
,
getCharArray
(
utfLen
));
visitor
.
visitUTF8
(
i
,
CONSTANT_Utf8
,
value
);
tags
[
i
]
=
tag
;
values
[
i
++]
=
value
;
break
;
case
CONSTANT_Integer:
visitor
.
visitConstantValue
(
i
,
tag
,
buffer
.
getInt
());
i
++;
break
;
case
CONSTANT_Float:
visitor
.
visitConstantValue
(
i
,
tag
,
buffer
.
getFloat
());
i
++;
break
;
case
CONSTANT_Long:
visitor
.
visitConstantValue
(
i
,
tag
,
buffer
.
getLong
());
i
+=
2
;
break
;
case
CONSTANT_Double:
visitor
.
visitConstantValue
(
i
,
tag
,
buffer
.
getDouble
());
i
+=
2
;
break
;
case
CONSTANT_Class:
// fall through:
case
CONSTANT_String:
tags
[
i
]
=
tag
;
values
[
i
++]
=
new
int
[]
{
getUnsignedShort
(
buffer
)
};
break
;
case
CONSTANT_Fieldref:
// fall through:
case
CONSTANT_Methodref:
// fall through:
case
CONSTANT_InterfaceMethodref:
// fall through:
case
CONSTANT_NameAndType:
tags
[
i
]
=
tag
;
values
[
i
++]
=
new
int
[]
{
getUnsignedShort
(
buffer
),
getUnsignedShort
(
buffer
)
};
break
;
default
:
throw
new
AssertionError
(
"invalid constant "
+
tag
);
}
}
}
private
void
resolveConstantPool
(
Object
[]
values
,
ConstantPoolVisitor
visitor
)
{
// clean out the int[] values, which are temporary
for
(
int
beg
=
1
,
end
=
values
.
length
-
1
,
beg2
,
end2
;
beg
<=
end
;
beg
=
beg2
,
end
=
end2
)
{
beg2
=
end
;
end2
=
beg
-
1
;
//System.out.println("CP resolve pass: "+beg+".."+end);
for
(
int
i
=
beg
;
i
<=
end
;
i
++)
{
Object
value
=
values
[
i
];
if
(!(
value
instanceof
int
[]))
continue
;
int
[]
array
=
(
int
[])
value
;
byte
tag
=
tags
[
i
];
switch
(
tag
)
{
case
CONSTANT_String:
String
stringBody
=
(
String
)
values
[
array
[
0
]];
visitor
.
visitConstantString
(
i
,
tag
,
stringBody
,
array
[
0
]);
values
[
i
]
=
null
;
break
;
case
CONSTANT_Class:
{
String
className
=
(
String
)
values
[
array
[
0
]];
// use the external form favored by Class.forName:
className
=
className
.
replace
(
'/'
,
'.'
);
visitor
.
visitConstantString
(
i
,
tag
,
className
,
array
[
0
]);
values
[
i
]
=
className
;
break
;
}
case
CONSTANT_NameAndType:
{
String
memberName
=
(
String
)
values
[
array
[
0
]];
String
signature
=
(
String
)
values
[
array
[
1
]];
visitor
.
visitDescriptor
(
i
,
tag
,
memberName
,
signature
,
array
[
0
],
array
[
1
]);
values
[
i
]
=
new
String
[]
{
memberName
,
signature
};
break
;
}
case
CONSTANT_Fieldref:
// fall through:
case
CONSTANT_Methodref:
// fall through:
case
CONSTANT_InterfaceMethodref:
{
Object
className
=
values
[
array
[
0
]];
Object
nameAndType
=
values
[
array
[
1
]];
if
(!(
className
instanceof
String
)
||
!(
nameAndType
instanceof
String
[]))
{
// one more pass is needed
if
(
beg2
>
i
)
beg2
=
i
;
if
(
end2
<
i
)
end2
=
i
;
continue
;
}
String
[]
nameAndTypeArray
=
(
String
[])
nameAndType
;
visitor
.
visitMemberRef
(
i
,
tag
,
(
String
)
className
,
nameAndTypeArray
[
0
],
nameAndTypeArray
[
1
],
array
[
0
],
array
[
1
]);
values
[
i
]
=
null
;
}
break
;
default
:
continue
;
}
}
}
}
private
static
int
getUnsignedByte
(
ByteBuffer
buffer
)
{
return
buffer
.
get
()
&
0xFF
;
}
private
static
int
getUnsignedShort
(
ByteBuffer
buffer
)
{
int
b1
=
getUnsignedByte
(
buffer
);
int
b2
=
getUnsignedByte
(
buffer
);
return
(
b1
<<
8
)
+
(
b2
<<
0
);
}
private
static
String
getUTF8
(
ByteBuffer
buffer
,
int
utfLen
,
char
[]
charArray
)
throws
InvalidConstantPoolFormatException
{
int
utfLimit
=
buffer
.
position
()
+
utfLen
;
int
index
=
0
;
while
(
buffer
.
position
()
<
utfLimit
)
{
int
c
=
buffer
.
get
()
&
0xff
;
if
(
c
>
127
)
{
buffer
.
position
(
buffer
.
position
()
-
1
);
return
getUTF8Extended
(
buffer
,
utfLimit
,
charArray
,
index
);
}
charArray
[
index
++]
=
(
char
)
c
;
}
return
new
String
(
charArray
,
0
,
index
);
}
private
static
String
getUTF8Extended
(
ByteBuffer
buffer
,
int
utfLimit
,
char
[]
charArray
,
int
index
)
throws
InvalidConstantPoolFormatException
{
int
c
,
c2
,
c3
;
while
(
buffer
.
position
()
<
utfLimit
)
{
c
=
buffer
.
get
()
&
0xff
;
switch
(
c
>>
4
)
{
case
0
:
case
1
:
case
2
:
case
3
:
case
4
:
case
5
:
case
6
:
case
7
:
/* 0xxxxxxx*/
charArray
[
index
++]
=
(
char
)
c
;
break
;
case
12
:
case
13
:
/* 110x xxxx 10xx xxxx*/
c2
=
buffer
.
get
();
if
((
c2
&
0xC0
)
!=
0x80
)
throw
new
InvalidConstantPoolFormatException
(
"malformed input around byte "
+
buffer
.
position
());
charArray
[
index
++]
=
(
char
)(((
c
&
0x1F
)
<<
6
)
|
(
c2
&
0x3F
));
break
;
case
14
:
/* 1110 xxxx 10xx xxxx 10xx xxxx */
c2
=
buffer
.
get
();
c3
=
buffer
.
get
();
if
(((
c2
&
0xC0
)
!=
0x80
)
||
((
c3
&
0xC0
)
!=
0x80
))
throw
new
InvalidConstantPoolFormatException
(
"malformed input around byte "
+
(
buffer
.
position
()));
charArray
[
index
++]
=
(
char
)(((
c
&
0x0F
)
<<
12
)
|
((
c2
&
0x3F
)
<<
6
)
|
((
c3
&
0x3F
)
<<
0
));
break
;
default
:
/* 10xx xxxx, 1111 xxxx */
throw
new
InvalidConstantPoolFormatException
(
"malformed input around byte "
+
buffer
.
position
());
}
}
// The number of chars produced may be less than utflen
return
new
String
(
charArray
,
0
,
index
);
}
}
src/share/classes/sun/invoke/anon/ConstantPoolPatch.java
已删除
100644 → 0
浏览文件 @
5e449602
/*
* Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package
sun.invoke.anon
;
import
java.io.IOException
;
import
java.io.OutputStream
;
import
java.util.Arrays
;
import
java.util.HashSet
;
import
java.util.IdentityHashMap
;
import
java.util.Map
;
import
static
sun
.
invoke
.
anon
.
ConstantPoolVisitor
.*;
/** A class and its patched constant pool.
*
* This class allow to modify (patch) a constant pool
* by changing the value of its entry.
* Entry are referenced using index that can be get
* by parsing the constant pool using
* {@link ConstantPoolParser#parse(ConstantPoolVisitor)}.
*
* @see ConstantPoolVisitor
* @see ConstantPoolParser#createPatch()
*/
public
class
ConstantPoolPatch
{
final
ConstantPoolParser
outer
;
final
Object
[]
patchArray
;
ConstantPoolPatch
(
ConstantPoolParser
outer
)
{
this
.
outer
=
outer
;
this
.
patchArray
=
new
Object
[
outer
.
getLength
()];
}
/** Create a {@link ConstantPoolParser} and
* a {@link ConstantPoolPatch} in one step.
* Equivalent to {@code new ConstantPoolParser(classFile).createPatch()}.
*
* @param classFile an array of bytes containing a class.
* @see #ConstantPoolParser(Class)
*/
public
ConstantPoolPatch
(
byte
[]
classFile
)
throws
InvalidConstantPoolFormatException
{
this
(
new
ConstantPoolParser
(
classFile
));
}
/** Create a {@link ConstantPoolParser} and
* a {@link ConstantPoolPatch} in one step.
* Equivalent to {@code new ConstantPoolParser(templateClass).createPatch()}.
*
* @param templateClass the class to parse.
* @see #ConstantPoolParser(Class)
*/
public
ConstantPoolPatch
(
Class
<?>
templateClass
)
throws
IOException
,
InvalidConstantPoolFormatException
{
this
(
new
ConstantPoolParser
(
templateClass
));
}
/** Creates a patch from an existing patch.
* All changes are copied from that patch.
* @param patch a patch
*
* @see ConstantPoolParser#createPatch()
*/
public
ConstantPoolPatch
(
ConstantPoolPatch
patch
)
{
outer
=
patch
.
outer
;
patchArray
=
patch
.
patchArray
.
clone
();
}
/** Which parser built this patch? */
public
ConstantPoolParser
getParser
()
{
return
outer
;
}
/** Report the tag at the given index in the constant pool. */
public
byte
getTag
(
int
index
)
{
return
outer
.
getTag
(
index
);
}
/** Report the current patch at the given index of the constant pool.
* Null means no patch will be made.
* To observe the unpatched entry at the given index, use
* {@link #getParser()}{@code .}@link ConstantPoolParser#parse(ConstantPoolVisitor)}
*/
public
Object
getPatch
(
int
index
)
{
Object
value
=
patchArray
[
index
];
if
(
value
==
null
)
return
null
;
switch
(
getTag
(
index
))
{
case
CONSTANT_Fieldref:
case
CONSTANT_Methodref:
case
CONSTANT_InterfaceMethodref:
if
(
value
instanceof
String
)
value
=
stripSemis
(
2
,
(
String
)
value
);
break
;
case
CONSTANT_NameAndType:
if
(
value
instanceof
String
)
value
=
stripSemis
(
1
,
(
String
)
value
);
break
;
}
return
value
;
}
/** Clear all patches. */
public
void
clear
()
{
Arrays
.
fill
(
patchArray
,
null
);
}
/** Clear one patch. */
public
void
clear
(
int
index
)
{
patchArray
[
index
]
=
null
;
}
/** Produce the patches as an array. */
public
Object
[]
getPatches
()
{
return
patchArray
.
clone
();
}
/** Produce the original constant pool as an array. */
public
Object
[]
getOriginalCP
()
throws
InvalidConstantPoolFormatException
{
return
getOriginalCP
(
0
,
patchArray
.
length
,
-
1
);
}
/** Walk the constant pool, applying patches using the given map.
*
* @param utf8Map Utf8 strings to modify, if encountered
* @param classMap Classes (or their names) to modify, if encountered
* @param valueMap Constant values to modify, if encountered
* @param deleteUsedEntries if true, delete map entries that are used
*/
public
void
putPatches
(
final
Map
<
String
,
String
>
utf8Map
,
final
Map
<
String
,
Object
>
classMap
,
final
Map
<
Object
,
Object
>
valueMap
,
boolean
deleteUsedEntries
)
throws
InvalidConstantPoolFormatException
{
final
HashSet
<
String
>
usedUtf8Keys
;
final
HashSet
<
String
>
usedClassKeys
;
final
HashSet
<
Object
>
usedValueKeys
;
if
(
deleteUsedEntries
)
{
usedUtf8Keys
=
(
utf8Map
==
null
)
?
null
:
new
HashSet
<
String
>();
usedClassKeys
=
(
classMap
==
null
)
?
null
:
new
HashSet
<
String
>();
usedValueKeys
=
(
valueMap
==
null
)
?
null
:
new
HashSet
<
Object
>();
}
else
{
usedUtf8Keys
=
null
;
usedClassKeys
=
null
;
usedValueKeys
=
null
;
}
outer
.
parse
(
new
ConstantPoolVisitor
()
{
@Override
public
void
visitUTF8
(
int
index
,
byte
tag
,
String
utf8
)
{
putUTF8
(
index
,
utf8Map
.
get
(
utf8
));
if
(
usedUtf8Keys
!=
null
)
usedUtf8Keys
.
add
(
utf8
);
}
@Override
public
void
visitConstantValue
(
int
index
,
byte
tag
,
Object
value
)
{
putConstantValue
(
index
,
tag
,
valueMap
.
get
(
value
));
if
(
usedValueKeys
!=
null
)
usedValueKeys
.
add
(
value
);
}
@Override
public
void
visitConstantString
(
int
index
,
byte
tag
,
String
name
,
int
nameIndex
)
{
if
(
tag
==
CONSTANT_Class
)
{
putConstantValue
(
index
,
tag
,
classMap
.
get
(
name
));
if
(
usedClassKeys
!=
null
)
usedClassKeys
.
add
(
name
);
}
else
{
assert
(
tag
==
CONSTANT_String
);
visitConstantValue
(
index
,
tag
,
name
);
}
}
});
if
(
usedUtf8Keys
!=
null
)
utf8Map
.
keySet
().
removeAll
(
usedUtf8Keys
);
if
(
usedClassKeys
!=
null
)
classMap
.
keySet
().
removeAll
(
usedClassKeys
);
if
(
usedValueKeys
!=
null
)
valueMap
.
keySet
().
removeAll
(
usedValueKeys
);
}
Object
[]
getOriginalCP
(
final
int
startIndex
,
final
int
endIndex
,
final
int
tagMask
)
throws
InvalidConstantPoolFormatException
{
final
Object
[]
cpArray
=
new
Object
[
endIndex
-
startIndex
];
outer
.
parse
(
new
ConstantPoolVisitor
()
{
void
show
(
int
index
,
byte
tag
,
Object
value
)
{
if
(
index
<
startIndex
||
index
>=
endIndex
)
return
;
if
(((
1
<<
tag
)
&
tagMask
)
==
0
)
return
;
cpArray
[
index
-
startIndex
]
=
value
;
}
@Override
public
void
visitUTF8
(
int
index
,
byte
tag
,
String
utf8
)
{
show
(
index
,
tag
,
utf8
);
}
@Override
public
void
visitConstantValue
(
int
index
,
byte
tag
,
Object
value
)
{
assert
(
tag
!=
CONSTANT_String
);
show
(
index
,
tag
,
value
);
}
@Override
public
void
visitConstantString
(
int
index
,
byte
tag
,
String
value
,
int
j
)
{
show
(
index
,
tag
,
value
);
}
@Override
public
void
visitMemberRef
(
int
index
,
byte
tag
,
String
className
,
String
memberName
,
String
signature
,
int
j
,
int
k
)
{
show
(
index
,
tag
,
new
String
[]{
className
,
memberName
,
signature
});
}
@Override
public
void
visitDescriptor
(
int
index
,
byte
tag
,
String
memberName
,
String
signature
,
int
j
,
int
k
)
{
show
(
index
,
tag
,
new
String
[]{
memberName
,
signature
});
}
});
return
cpArray
;
}
/** Write the head (header plus constant pool)
* of the patched class file to the indicated stream.
*/
void
writeHead
(
OutputStream
out
)
throws
IOException
{
outer
.
writePatchedHead
(
out
,
patchArray
);
}
/** Write the tail (everything after the constant pool)
* of the patched class file to the indicated stream.
*/
void
writeTail
(
OutputStream
out
)
throws
IOException
{
outer
.
writeTail
(
out
);
}
private
void
checkConstantTag
(
byte
tag
,
Object
value
)
{
if
(
value
==
null
)
throw
new
IllegalArgumentException
(
"invalid null constant value"
);
if
(
classForTag
(
tag
)
!=
value
.
getClass
())
throw
new
IllegalArgumentException
(
"invalid constant value"
+
(
tag
==
CONSTANT_None
?
""
:
" for tag "
+
tagName
(
tag
))
+
" of class "
+
value
.
getClass
());
}
private
void
checkTag
(
int
index
,
byte
putTag
)
{
byte
tag
=
outer
.
tags
[
index
];
if
(
tag
!=
putTag
)
throw
new
IllegalArgumentException
(
"invalid put operation"
+
" for "
+
tagName
(
putTag
)
+
" at index "
+
index
+
" found "
+
tagName
(
tag
));
}
private
void
checkTagMask
(
int
index
,
int
tagBitMask
)
{
byte
tag
=
outer
.
tags
[
index
];
int
tagBit
=
((
tag
&
0x1F
)
==
tag
)
?
(
1
<<
tag
)
:
0
;
if
((
tagBit
&
tagBitMask
)
==
0
)
throw
new
IllegalArgumentException
(
"invalid put operation"
+
" at index "
+
index
+
" found "
+
tagName
(
tag
));
}
private
static
void
checkMemberName
(
String
memberName
)
{
if
(
memberName
.
indexOf
(
';'
)
>=
0
)
throw
new
IllegalArgumentException
(
"memberName "
+
memberName
+
" contains a ';'"
);
}
/** Set the entry of the constant pool indexed by index to
* a new string.
*
* @param index an index to a constant pool entry containing a
* {@link ConstantPoolVisitor#CONSTANT_Utf8} value.
* @param utf8 a string
*
* @see ConstantPoolVisitor#visitUTF8(int, byte, String)
*/
public
void
putUTF8
(
int
index
,
String
utf8
)
{
if
(
utf8
==
null
)
{
clear
(
index
);
return
;
}
checkTag
(
index
,
CONSTANT_Utf8
);
patchArray
[
index
]
=
utf8
;
}
/** Set the entry of the constant pool indexed by index to
* a new value, depending on its dynamic type.
*
* @param index an index to a constant pool entry containing a
* one of the following structures:
* {@link ConstantPoolVisitor#CONSTANT_Integer},
* {@link ConstantPoolVisitor#CONSTANT_Float},
* {@link ConstantPoolVisitor#CONSTANT_Long},
* {@link ConstantPoolVisitor#CONSTANT_Double},
* {@link ConstantPoolVisitor#CONSTANT_String}, or
* {@link ConstantPoolVisitor#CONSTANT_Class}
* @param value a boxed int, float, long or double; or a string or class object
* @throws IllegalArgumentException if the type of the constant does not
* match the constant pool entry type,
* as reported by {@link #getTag(int)}
*
* @see #putConstantValue(int, byte, Object)
* @see ConstantPoolVisitor#visitConstantValue(int, byte, Object)
* @see ConstantPoolVisitor#visitConstantString(int, byte, String, int)
*/
public
void
putConstantValue
(
int
index
,
Object
value
)
{
if
(
value
==
null
)
{
clear
(
index
);
return
;
}
byte
tag
=
tagForConstant
(
value
.
getClass
());
checkConstantTag
(
tag
,
value
);
checkTag
(
index
,
tag
);
patchArray
[
index
]
=
value
;
}
/** Set the entry of the constant pool indexed by index to
* a new value.
*
* @param index an index to a constant pool entry matching the given tag
* @param tag one of the following values:
* {@link ConstantPoolVisitor#CONSTANT_Integer},
* {@link ConstantPoolVisitor#CONSTANT_Float},
* {@link ConstantPoolVisitor#CONSTANT_Long},
* {@link ConstantPoolVisitor#CONSTANT_Double},
* {@link ConstantPoolVisitor#CONSTANT_String}, or
* {@link ConstantPoolVisitor#CONSTANT_Class}
* @param value a boxed number, string, or class object
* @throws IllegalArgumentException if the type of the constant does not
* match the constant pool entry type, or if a class name contains
* '/' or ';'
*
* @see #putConstantValue(int, Object)
* @see ConstantPoolVisitor#visitConstantValue(int, byte, Object)
* @see ConstantPoolVisitor#visitConstantString(int, byte, String, int)
*/
public
void
putConstantValue
(
int
index
,
byte
tag
,
Object
value
)
{
if
(
value
==
null
)
{
clear
(
index
);
return
;
}
checkTag
(
index
,
tag
);
if
(
tag
==
CONSTANT_Class
&&
value
instanceof
String
)
{
checkClassName
((
String
)
value
);
}
else
if
(
tag
==
CONSTANT_String
)
{
// the JVM accepts any object as a patch for a string
}
else
{
// make sure the incoming value is the right type
checkConstantTag
(
tag
,
value
);
}
checkTag
(
index
,
tag
);
patchArray
[
index
]
=
value
;
}
/** Set the entry of the constant pool indexed by index to
* a new {@link ConstantPoolVisitor#CONSTANT_NameAndType} value.
*
* @param index an index to a constant pool entry containing a
* {@link ConstantPoolVisitor#CONSTANT_NameAndType} value.
* @param memberName a memberName
* @param signature a signature
* @throws IllegalArgumentException if memberName contains the character ';'
*
* @see ConstantPoolVisitor#visitDescriptor(int, byte, String, String, int, int)
*/
public
void
putDescriptor
(
int
index
,
String
memberName
,
String
signature
)
{
checkTag
(
index
,
CONSTANT_NameAndType
);
checkMemberName
(
memberName
);
patchArray
[
index
]
=
addSemis
(
memberName
,
signature
);
}
/** Set the entry of the constant pool indexed by index to
* a new {@link ConstantPoolVisitor#CONSTANT_Fieldref},
* {@link ConstantPoolVisitor#CONSTANT_Methodref}, or
* {@link ConstantPoolVisitor#CONSTANT_InterfaceMethodref} value.
*
* @param index an index to a constant pool entry containing a member reference
* @param className a class name
* @param memberName a field or method name
* @param signature a field or method signature
* @throws IllegalArgumentException if memberName contains the character ';'
* or signature is not a correct signature
*
* @see ConstantPoolVisitor#visitMemberRef(int, byte, String, String, String, int, int)
*/
public
void
putMemberRef
(
int
index
,
byte
tag
,
String
className
,
String
memberName
,
String
signature
)
{
checkTagMask
(
tag
,
CONSTANT_MemberRef_MASK
);
checkTag
(
index
,
tag
);
checkClassName
(
className
);
checkMemberName
(
memberName
);
if
(
signature
.
startsWith
(
"("
)
==
(
tag
==
CONSTANT_Fieldref
))
throw
new
IllegalArgumentException
(
"bad signature: "
+
signature
);
patchArray
[
index
]
=
addSemis
(
className
,
memberName
,
signature
);
}
static
private
final
int
CONSTANT_MemberRef_MASK
=
CONSTANT_Fieldref
|
CONSTANT_Methodref
|
CONSTANT_InterfaceMethodref
;
private
static
final
Map
<
Class
<?>,
Byte
>
CONSTANT_VALUE_CLASS_TAG
=
new
IdentityHashMap
<
Class
<?>,
Byte
>();
private
static
final
Class
<?>[]
CONSTANT_VALUE_CLASS
=
new
Class
<?>[
16
];
static
{
Object
[][]
values
=
{
{
Integer
.
class
,
CONSTANT_Integer
},
{
Long
.
class
,
CONSTANT_Long
},
{
Float
.
class
,
CONSTANT_Float
},
{
Double
.
class
,
CONSTANT_Double
},
{
String
.
class
,
CONSTANT_String
},
{
Class
.
class
,
CONSTANT_Class
}
};
for
(
Object
[]
value
:
values
)
{
Class
<?>
cls
=
(
Class
<?>)
value
[
0
];
Byte
tag
=
(
Byte
)
value
[
1
];
CONSTANT_VALUE_CLASS_TAG
.
put
(
cls
,
tag
);
CONSTANT_VALUE_CLASS
[(
byte
)
tag
]
=
cls
;
}
}
static
Class
<?>
classForTag
(
byte
tag
)
{
if
((
tag
&
0xFF
)
>=
CONSTANT_VALUE_CLASS
.
length
)
return
null
;
return
CONSTANT_VALUE_CLASS
[
tag
];
}
static
byte
tagForConstant
(
Class
<?>
cls
)
{
Byte
tag
=
CONSTANT_VALUE_CLASS_TAG
.
get
(
cls
);
return
(
tag
==
null
)
?
CONSTANT_None
:
(
byte
)
tag
;
}
private
static
void
checkClassName
(
String
className
)
{
if
(
className
.
indexOf
(
'/'
)
>=
0
||
className
.
indexOf
(
';'
)
>=
0
)
throw
new
IllegalArgumentException
(
"invalid class name "
+
className
);
}
static
String
addSemis
(
String
name
,
String
...
names
)
{
StringBuilder
buf
=
new
StringBuilder
(
name
.
length
()
*
5
);
buf
.
append
(
name
);
for
(
String
name2
:
names
)
{
buf
.
append
(
';'
).
append
(
name2
);
}
String
res
=
buf
.
toString
();
assert
(
stripSemis
(
names
.
length
,
res
)[
0
].
equals
(
name
));
assert
(
stripSemis
(
names
.
length
,
res
)[
1
].
equals
(
names
[
0
]));
assert
(
names
.
length
==
1
||
stripSemis
(
names
.
length
,
res
)[
2
].
equals
(
names
[
1
]));
return
res
;
}
static
String
[]
stripSemis
(
int
count
,
String
string
)
{
String
[]
res
=
new
String
[
count
+
1
];
int
pos
=
0
;
for
(
int
i
=
0
;
i
<
count
;
i
++)
{
int
pos2
=
string
.
indexOf
(
';'
,
pos
);
if
(
pos2
<
0
)
pos2
=
string
.
length
();
// yuck
res
[
i
]
=
string
.
substring
(
pos
,
pos2
);
pos
=
pos2
;
}
res
[
count
]
=
string
.
substring
(
pos
);
return
res
;
}
public
String
toString
()
{
StringBuilder
buf
=
new
StringBuilder
(
this
.
getClass
().
getName
());
buf
.
append
(
"{"
);
Object
[]
origCP
=
null
;
for
(
int
i
=
0
;
i
<
patchArray
.
length
;
i
++)
{
if
(
patchArray
[
i
]
==
null
)
continue
;
if
(
origCP
!=
null
)
{
buf
.
append
(
", "
);
}
else
{
try
{
origCP
=
getOriginalCP
();
}
catch
(
InvalidConstantPoolFormatException
ee
)
{
origCP
=
new
Object
[
0
];
}
}
Object
orig
=
(
i
<
origCP
.
length
)
?
origCP
[
i
]
:
"?"
;
buf
.
append
(
orig
).
append
(
"="
).
append
(
patchArray
[
i
]);
}
buf
.
append
(
"}"
);
return
buf
.
toString
();
}
}
src/share/classes/sun/invoke/anon/ConstantPoolVisitor.java
已删除
100644 → 0
浏览文件 @
5e449602
/*
* Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package
sun.invoke.anon
;
/**
* A visitor called by {@link ConstantPoolParser#parse(ConstantPoolVisitor)}
* when a constant pool entry is parsed.
* <p>
* A visit* method is called when a constant pool entry is parsed.
* The first argument is always the constant pool index.
* The second argument is always the constant pool tag,
* even for methods like {@link #visitUTF8(int, byte, String)} which only apply to one tag.
* String arguments refer to Utf8 or NameAndType entries declared elsewhere,
* and are always accompanied by the indexes of those entries.
* <p>
* The order of the calls to the visit* methods is not necessarily related
* to the order of the entries in the constant pool.
* If one entry has a reference to another entry, the latter (lower-level)
* entry will be visited first.
* <p>
* The following table shows the relation between constant pool entry
* types and the corresponding visit* methods:
*
* <table border=1 cellpadding=5 summary="constant pool visitor methods">
* <tr><th>Tag(s)</th><th>Method</th></tr>
* <tr>
* <td>{@link #CONSTANT_Utf8}</td>
* <td>{@link #visitUTF8(int, byte, String)}</td>
* </tr><tr>
* <td>{@link #CONSTANT_Integer}, {@link #CONSTANT_Float},
* {@link #CONSTANT_Long}, {@link #CONSTANT_Double}</td>
* <td>{@link #visitConstantValue(int, byte, Object)}</td>
* </tr><tr>
* <td>{@link #CONSTANT_String}, {@link #CONSTANT_Class}</td>
* <td>{@link #visitConstantString(int, byte, String, int)}</td>
* </tr><tr>
* <td>{@link #CONSTANT_NameAndType}</td>
* <td>{@link #visitDescriptor(int, byte, String, String, int, int)}</td>
* </tr><tr>
* <td>{@link #CONSTANT_Fieldref},
* {@link #CONSTANT_Methodref},
* {@link #CONSTANT_InterfaceMethodref}</td>
* <td>{@link #visitMemberRef(int, byte, String, String, String, int, int)}</td>
* </tr>
* </table>
*
* @see ConstantPoolPatch
* @author Remi Forax
* @author jrose
*/
public
class
ConstantPoolVisitor
{
/** Called each time an UTF8 constant pool entry is found.
* @param index the constant pool index
* @param tag always {@link #CONSTANT_Utf8}
* @param utf8 string encoded in modified UTF-8 format passed as a {@code String}
*
* @see ConstantPoolPatch#putUTF8(int, String)
*/
public
void
visitUTF8
(
int
index
,
byte
tag
,
String
utf8
)
{
// do nothing
}
/** Called for each constant pool entry that encodes an integer,
* a float, a long, or a double.
* Constant strings and classes are not managed by this method but
* by {@link #visitConstantString(int, byte, String, int)}.
*
* @param index the constant pool index
* @param tag one of {@link #CONSTANT_Integer},
* {@link #CONSTANT_Float},
* {@link #CONSTANT_Long},
* or {@link #CONSTANT_Double}
* @param value encoded value
*
* @see ConstantPoolPatch#putConstantValue(int, Object)
*/
public
void
visitConstantValue
(
int
index
,
byte
tag
,
Object
value
)
{
// do nothing
}
/** Called for each constant pool entry that encodes a string or a class.
* @param index the constant pool index
* @param tag one of {@link #CONSTANT_String},
* {@link #CONSTANT_Class},
* @param name string body or class name (using dot separator)
* @param nameIndex the index of the Utf8 string for the name
*
* @see ConstantPoolPatch#putConstantValue(int, byte, Object)
*/
public
void
visitConstantString
(
int
index
,
byte
tag
,
String
name
,
int
nameIndex
)
{
// do nothing
}
/** Called for each constant pool entry that encodes a name and type.
* @param index the constant pool index
* @param tag always {@link #CONSTANT_NameAndType}
* @param memberName a field or method name
* @param signature the member signature
* @param memberNameIndex index of the Utf8 string for the member name
* @param signatureIndex index of the Utf8 string for the signature
*
* @see ConstantPoolPatch#putDescriptor(int, String, String)
*/
public
void
visitDescriptor
(
int
index
,
byte
tag
,
String
memberName
,
String
signature
,
int
memberNameIndex
,
int
signatureIndex
)
{
// do nothing
}
/** Called for each constant pool entry that encodes a field or method.
* @param index the constant pool index
* @param tag one of {@link #CONSTANT_Fieldref},
* or {@link #CONSTANT_Methodref},
* or {@link #CONSTANT_InterfaceMethodref}
* @param className the class name (using dot separator)
* @param memberName name of the field or method
* @param signature the field or method signature
* @param classNameIndex index of the Utf8 string for the class name
* @param descriptorIndex index of the NameAndType descriptor constant
*
* @see ConstantPoolPatch#putMemberRef(int, byte, String, String, String)
*/
public
void
visitMemberRef
(
int
index
,
byte
tag
,
String
className
,
String
memberName
,
String
signature
,
int
classNameIndex
,
int
descriptorIndex
)
{
// do nothing
}
public
static
final
byte
CONSTANT_None
=
0
,
CONSTANT_Utf8
=
1
,
//CONSTANT_Unicode = 2, /* unused */
CONSTANT_Integer
=
3
,
CONSTANT_Float
=
4
,
CONSTANT_Long
=
5
,
CONSTANT_Double
=
6
,
CONSTANT_Class
=
7
,
CONSTANT_String
=
8
,
CONSTANT_Fieldref
=
9
,
CONSTANT_Methodref
=
10
,
CONSTANT_InterfaceMethodref
=
11
,
CONSTANT_NameAndType
=
12
;
private
static
String
[]
TAG_NAMES
=
{
"Empty"
,
"Utf8"
,
null
,
//"Unicode",
"Integer"
,
"Float"
,
"Long"
,
"Double"
,
"Class"
,
"String"
,
"Fieldref"
,
"Methodref"
,
"InterfaceMethodref"
,
"NameAndType"
};
public
static
String
tagName
(
byte
tag
)
{
String
name
=
null
;
if
((
tag
&
0xFF
)
<
TAG_NAMES
.
length
)
name
=
TAG_NAMES
[
tag
];
if
(
name
==
null
)
name
=
"Unknown#"
+(
tag
&
0xFF
);
return
name
;
}
}
src/share/classes/sun/invoke/anon/InvalidConstantPoolFormatException.java
已删除
100644 → 0
浏览文件 @
5e449602
/*
* Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package
sun.invoke.anon
;
/** Exception used when there is an error in the constant pool
* format.
*/
public
class
InvalidConstantPoolFormatException
extends
Exception
{
private
static
final
long
serialVersionUID
=-
6103888330523770949L
;
public
InvalidConstantPoolFormatException
(
String
message
,
Throwable
cause
)
{
super
(
message
,
cause
);
}
public
InvalidConstantPoolFormatException
(
String
message
)
{
super
(
message
);
}
public
InvalidConstantPoolFormatException
(
Throwable
cause
)
{
super
(
cause
);
}
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录