Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
dragonwell8_jdk
提交
7118adb7
D
dragonwell8_jdk
项目概览
openanolis
/
dragonwell8_jdk
通知
3
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看板
体验新版 GitCode,发现更多精彩内容 >>
提交
7118adb7
编写于
1月 20, 2012
作者:
A
amurillo
浏览文件
操作
浏览文件
下载
差异文件
Merge
上级
f79720f2
4050f67e
变更
19
展开全部
隐藏空白更改
内联
并排
Showing
19 changed file
with
740 addition
and
204 deletion
+740
-204
src/share/classes/java/lang/Class.java
src/share/classes/java/lang/Class.java
+5
-0
src/share/classes/java/lang/ClassValue.java
src/share/classes/java/lang/ClassValue.java
+576
-64
src/share/classes/java/lang/invoke/AdapterMethodHandle.java
src/share/classes/java/lang/invoke/AdapterMethodHandle.java
+4
-0
src/share/classes/java/lang/invoke/MemberName.java
src/share/classes/java/lang/invoke/MemberName.java
+1
-1
src/share/classes/java/lang/invoke/MethodHandleImpl.java
src/share/classes/java/lang/invoke/MethodHandleImpl.java
+30
-31
src/share/classes/java/lang/invoke/MethodHandleProxies.java
src/share/classes/java/lang/invoke/MethodHandleProxies.java
+1
-1
src/share/classes/java/lang/invoke/MethodHandles.java
src/share/classes/java/lang/invoke/MethodHandles.java
+13
-6
src/share/classes/sun/invoke/util/ValueConversions.java
src/share/classes/sun/invoke/util/ValueConversions.java
+4
-4
src/share/classes/sun/invoke/util/Wrapper.java
src/share/classes/sun/invoke/util/Wrapper.java
+2
-2
test/java/lang/invoke/CallSiteTest.java
test/java/lang/invoke/CallSiteTest.java
+1
-1
test/java/lang/invoke/ClassValueTest.java
test/java/lang/invoke/ClassValueTest.java
+10
-12
test/java/lang/invoke/InvokeGenericTest.java
test/java/lang/invoke/InvokeGenericTest.java
+18
-16
test/java/lang/invoke/JavaDocExamplesTest.java
test/java/lang/invoke/JavaDocExamplesTest.java
+2
-0
test/java/lang/invoke/MethodHandlesTest.java
test/java/lang/invoke/MethodHandlesTest.java
+48
-41
test/java/lang/invoke/MethodTypeTest.java
test/java/lang/invoke/MethodTypeTest.java
+3
-2
test/java/lang/invoke/PermuteArgsTest.java
test/java/lang/invoke/PermuteArgsTest.java
+7
-7
test/java/lang/invoke/RicochetTest.java
test/java/lang/invoke/RicochetTest.java
+9
-9
test/java/lang/invoke/ThrowExceptionsTest.java
test/java/lang/invoke/ThrowExceptionsTest.java
+3
-3
test/sun/invoke/util/ValueConversionsTest.java
test/sun/invoke/util/ValueConversionsTest.java
+3
-4
未找到文件。
src/share/classes/java/lang/Class.java
浏览文件 @
7118adb7
...
...
@@ -3118,4 +3118,9 @@ public final
AnnotationType
getAnnotationType
()
{
return
annotationType
;
}
/* Backing store of user-defined values pertaining to this class.
* Maintained by the ClassValue class.
*/
transient
ClassValue
.
ClassValueMap
classValueMap
;
}
src/share/classes/java/lang/ClassValue.java
浏览文件 @
7118adb7
此差异已折叠。
点击以展开。
src/share/classes/java/lang/invoke/AdapterMethodHandle.java
浏览文件 @
7118adb7
...
...
@@ -378,6 +378,7 @@ class AdapterMethodHandle extends BoundMethodHandle {
}
/** Construct an adapter conversion descriptor for a single-argument conversion. */
@SuppressWarnings
(
"cast"
)
// some (int) casts below provide clarity but trigger warnings
private
static
long
makeConv
(
int
convOp
,
int
argnum
,
int
src
,
int
dest
)
{
assert
(
src
==
(
src
&
CONV_TYPE_MASK
));
assert
(
dest
==
(
dest
&
CONV_TYPE_MASK
));
...
...
@@ -390,6 +391,7 @@ class AdapterMethodHandle extends BoundMethodHandle {
insertStackMove
(
stackMove
)
);
}
@SuppressWarnings
(
"cast"
)
// some (int) casts below provide clarity but trigger warnings
private
static
long
makeDupConv
(
int
convOp
,
int
argnum
,
int
stackMove
)
{
// simple argument motion, requiring one slot to specify
assert
(
convOp
==
OP_DUP_ARGS
||
convOp
==
OP_DROP_ARGS
);
...
...
@@ -401,6 +403,7 @@ class AdapterMethodHandle extends BoundMethodHandle {
insertStackMove
(
stackMove
)
);
}
@SuppressWarnings
(
"cast"
)
// some (int) casts below provide clarity but trigger warnings
private
static
long
makeSwapConv
(
int
convOp
,
int
srcArg
,
byte
srcType
,
int
destSlot
,
byte
destType
)
{
// more complex argument motion, requiring two slots to specify
assert
(
convOp
==
OP_SWAP_ARGS
||
convOp
==
OP_ROT_ARGS
);
...
...
@@ -411,6 +414,7 @@ class AdapterMethodHandle extends BoundMethodHandle {
(
int
)
destSlot
<<
CONV_VMINFO_SHIFT
);
}
@SuppressWarnings
(
"cast"
)
// some (int) casts below provide clarity but trigger warnings
private
static
long
makeSpreadConv
(
int
convOp
,
int
argnum
,
int
src
,
int
dest
,
int
stackMove
)
{
// spreading or collecting, at a particular slot location
assert
(
convOp
==
OP_SPREAD_ARGS
||
convOp
==
OP_COLLECT_ARGS
||
convOp
==
OP_FOLD_ARGS
);
...
...
src/share/classes/java/lang/invoke/MemberName.java
浏览文件 @
7118adb7
...
...
@@ -353,7 +353,7 @@ import static java.lang.invoke.MethodHandleStatics.*;
assert
(
isResolved
());
}
/** Create a name for the given reflected constructor. The resulting name will be in a resolved state. */
public
MemberName
(
Constructor
ctor
)
{
public
MemberName
(
Constructor
<?>
ctor
)
{
Object
[]
typeInfo
=
{
void
.
class
,
ctor
.
getParameterTypes
()
};
init
(
ctor
.
getDeclaringClass
(),
CONSTRUCTOR_NAME
,
typeInfo
,
flagsMods
(
IS_CONSTRUCTOR
,
ctor
.
getModifiers
()));
// fill in vmtarget, vmindex while we have ctor in hand:
...
...
src/share/classes/java/lang/invoke/MethodHandleImpl.java
浏览文件 @
7118adb7
...
...
@@ -112,7 +112,7 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
assert
(
cookedConstructor
.
type
().
equals
(
ctype
));
ctype
=
ctype
.
dropParameterTypes
(
0
,
1
);
cookedConstructor
=
AdapterMethodHandle
.
makeCollectArguments
(
cookedConstructor
,
returner
,
0
,
true
);
MethodHandle
allocator
=
new
AllocateObject
(
allocateClass
);
AllocateObject
allocator
=
new
AllocateObject
(
allocateClass
);
// allocate() => new C(void)
assert
(
allocator
.
type
().
equals
(
MethodType
.
methodType
(
allocateClass
)));
ctype
=
ctype
.
dropParameterTypes
(
0
,
1
);
...
...
@@ -120,19 +120,19 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
return
fold
;
}
static
final
class
AllocateObject
<
C
>
extends
BoundMethodHandle
{
static
final
class
AllocateObject
/*<C>*/
extends
BoundMethodHandle
{
private
static
final
Unsafe
unsafe
=
Unsafe
.
getUnsafe
();
private
final
Class
<
C
>
allocateClass
;
private
final
Class
<
?>
/*<C>*/
allocateClass
;
// for allocation only:
private
AllocateObject
(
Class
<
C
>
allocateClass
)
{
private
AllocateObject
(
Class
<
?>
/*<C>*/
allocateClass
)
{
super
(
ALLOCATE
.
asType
(
MethodType
.
methodType
(
allocateClass
,
AllocateObject
.
class
)));
this
.
allocateClass
=
allocateClass
;
}
@SuppressWarnings
(
"unchecked"
)
private
C
allocate
()
throws
InstantiationException
{
return
(
C
)
unsafe
.
allocateInstance
(
allocateClass
);
private
Object
/*C*/
allocate
()
throws
InstantiationException
{
return
unsafe
.
allocateInstance
(
allocateClass
);
}
static
final
MethodHandle
ALLOCATE
;
static
{
...
...
@@ -148,8 +148,8 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
MethodHandle
accessField
(
MemberName
member
,
boolean
isSetter
,
Class
<?>
lookupClass
)
{
// Use sun. misc.Unsafe to dig up the dirt on the field.
MethodHandle
mh
=
new
FieldAccessor
(
member
,
isSetter
);
return
mh
;
FieldAccessor
accessor
=
new
FieldAccessor
(
member
,
isSetter
);
return
accessor
;
}
static
...
...
@@ -175,7 +175,7 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
return
mhs
[
isSetter
?
1
:
0
];
}
static
final
class
FieldAccessor
<
C
,
V
>
extends
BoundMethodHandle
{
static
final
class
FieldAccessor
/*<C,V>*/
extends
BoundMethodHandle
{
private
static
final
Unsafe
unsafe
=
Unsafe
.
getUnsafe
();
final
Object
base
;
// for static refs only
final
long
offset
;
...
...
@@ -190,26 +190,24 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
@Override
String
debugString
()
{
return
addTypeString
(
name
,
this
);
}
int
getFieldI
(
C
obj
)
{
return
unsafe
.
getInt
(
obj
,
offset
);
}
void
setFieldI
(
C
obj
,
int
x
)
{
unsafe
.
putInt
(
obj
,
offset
,
x
);
}
long
getFieldJ
(
C
obj
)
{
return
unsafe
.
getLong
(
obj
,
offset
);
}
void
setFieldJ
(
C
obj
,
long
x
)
{
unsafe
.
putLong
(
obj
,
offset
,
x
);
}
float
getFieldF
(
C
obj
)
{
return
unsafe
.
getFloat
(
obj
,
offset
);
}
void
setFieldF
(
C
obj
,
float
x
)
{
unsafe
.
putFloat
(
obj
,
offset
,
x
);
}
double
getFieldD
(
C
obj
)
{
return
unsafe
.
getDouble
(
obj
,
offset
);
}
void
setFieldD
(
C
obj
,
double
x
)
{
unsafe
.
putDouble
(
obj
,
offset
,
x
);
}
boolean
getFieldZ
(
C
obj
)
{
return
unsafe
.
getBoolean
(
obj
,
offset
);
}
void
setFieldZ
(
C
obj
,
boolean
x
)
{
unsafe
.
putBoolean
(
obj
,
offset
,
x
);
}
byte
getFieldB
(
C
obj
)
{
return
unsafe
.
getByte
(
obj
,
offset
);
}
void
setFieldB
(
C
obj
,
byte
x
)
{
unsafe
.
putByte
(
obj
,
offset
,
x
);
}
short
getFieldS
(
C
obj
)
{
return
unsafe
.
getShort
(
obj
,
offset
);
}
void
setFieldS
(
C
obj
,
short
x
)
{
unsafe
.
putShort
(
obj
,
offset
,
x
);
}
char
getFieldC
(
C
obj
)
{
return
unsafe
.
getChar
(
obj
,
offset
);
}
void
setFieldC
(
C
obj
,
char
x
)
{
unsafe
.
putChar
(
obj
,
offset
,
x
);
}
@SuppressWarnings
(
"unchecked"
)
V
getFieldL
(
C
obj
)
{
return
(
V
)
unsafe
.
getObject
(
obj
,
offset
);
}
@SuppressWarnings
(
"unchecked"
)
void
setFieldL
(
C
obj
,
V
x
)
{
unsafe
.
putObject
(
obj
,
offset
,
x
);
}
int
getFieldI
(
Object
/*C*/
obj
)
{
return
unsafe
.
getInt
(
obj
,
offset
);
}
void
setFieldI
(
Object
/*C*/
obj
,
int
x
)
{
unsafe
.
putInt
(
obj
,
offset
,
x
);
}
long
getFieldJ
(
Object
/*C*/
obj
)
{
return
unsafe
.
getLong
(
obj
,
offset
);
}
void
setFieldJ
(
Object
/*C*/
obj
,
long
x
)
{
unsafe
.
putLong
(
obj
,
offset
,
x
);
}
float
getFieldF
(
Object
/*C*/
obj
)
{
return
unsafe
.
getFloat
(
obj
,
offset
);
}
void
setFieldF
(
Object
/*C*/
obj
,
float
x
)
{
unsafe
.
putFloat
(
obj
,
offset
,
x
);
}
double
getFieldD
(
Object
/*C*/
obj
)
{
return
unsafe
.
getDouble
(
obj
,
offset
);
}
void
setFieldD
(
Object
/*C*/
obj
,
double
x
)
{
unsafe
.
putDouble
(
obj
,
offset
,
x
);
}
boolean
getFieldZ
(
Object
/*C*/
obj
)
{
return
unsafe
.
getBoolean
(
obj
,
offset
);
}
void
setFieldZ
(
Object
/*C*/
obj
,
boolean
x
)
{
unsafe
.
putBoolean
(
obj
,
offset
,
x
);
}
byte
getFieldB
(
Object
/*C*/
obj
)
{
return
unsafe
.
getByte
(
obj
,
offset
);
}
void
setFieldB
(
Object
/*C*/
obj
,
byte
x
)
{
unsafe
.
putByte
(
obj
,
offset
,
x
);
}
short
getFieldS
(
Object
/*C*/
obj
)
{
return
unsafe
.
getShort
(
obj
,
offset
);
}
void
setFieldS
(
Object
/*C*/
obj
,
short
x
)
{
unsafe
.
putShort
(
obj
,
offset
,
x
);
}
char
getFieldC
(
Object
/*C*/
obj
)
{
return
unsafe
.
getChar
(
obj
,
offset
);
}
void
setFieldC
(
Object
/*C*/
obj
,
char
x
)
{
unsafe
.
putChar
(
obj
,
offset
,
x
);
}
Object
/*V*/
getFieldL
(
Object
/*C*/
obj
)
{
return
unsafe
.
getObject
(
obj
,
offset
);
}
void
setFieldL
(
Object
/*C*/
obj
,
Object
/*V*/
x
)
{
unsafe
.
putObject
(
obj
,
offset
,
x
);
}
// cast (V) is OK here, since we wrap convertArguments around the MH.
static
Object
staticBase
(
final
MemberName
field
)
{
...
...
@@ -244,8 +242,9 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
void
setStaticS
(
short
x
)
{
unsafe
.
putShort
(
base
,
offset
,
x
);
}
char
getStaticC
()
{
return
unsafe
.
getChar
(
base
,
offset
);
}
void
setStaticC
(
char
x
)
{
unsafe
.
putChar
(
base
,
offset
,
x
);
}
V
getStaticL
()
{
return
(
V
)
unsafe
.
getObject
(
base
,
offset
);
}
void
setStaticL
(
V
x
)
{
unsafe
.
putObject
(
base
,
offset
,
x
);
}
@SuppressWarnings
(
"unchecked"
)
// (V) is for internal clarity but triggers warning
Object
/*V*/
getStaticL
()
{
return
unsafe
.
getObject
(
base
,
offset
);
}
void
setStaticL
(
Object
/*V*/
x
)
{
unsafe
.
putObject
(
base
,
offset
,
x
);
}
static
String
fname
(
Class
<?>
vclass
,
boolean
isSetter
,
boolean
isStatic
)
{
String
stem
;
...
...
src/share/classes/java/lang/invoke/MethodHandleProxies.java
浏览文件 @
7118adb7
...
...
@@ -150,7 +150,7 @@ public class MethodHandleProxies {
}
return
intfc
.
cast
(
Proxy
.
newProxyInstance
(
intfc
.
getClassLoader
(),
new
Class
[]{
intfc
,
WrapperInstance
.
class
},
new
Class
<?>
[]{
intfc
,
WrapperInstance
.
class
},
new
InvocationHandler
()
{
private
Object
getArg
(
String
name
)
{
if
((
Object
)
name
==
"getWrapperInstanceTarget"
)
return
target
;
...
...
src/share/classes/java/lang/invoke/MethodHandles.java
浏览文件 @
7118adb7
...
...
@@ -948,10 +948,11 @@ return mh1;
public
MethodHandle
unreflect
(
Method
m
)
throws
IllegalAccessException
{
MemberName
method
=
new
MemberName
(
m
);
assert
(
method
.
isMethod
());
if
(!
m
.
isAccessible
())
checkMethod
(
method
.
getDeclaringClass
(),
method
,
method
.
isStatic
());
if
(
m
.
isAccessible
())
return
MethodHandleImpl
.
findMethod
(
method
,
true
,
/*no lookupClass*/
null
);
checkMethod
(
method
.
getDeclaringClass
(),
method
,
method
.
isStatic
());
MethodHandle
mh
=
MethodHandleImpl
.
findMethod
(
method
,
true
,
lookupClassOrNull
());
if
(!
m
.
isAccessible
())
mh
=
restrictProtectedReceiver
(
method
,
mh
);
return
mh
;
return
restrictProtectedReceiver
(
method
,
mh
);
}
/**
...
...
@@ -1006,11 +1007,17 @@ return mh1;
* is set and {@code asVarargsCollector} fails
* @throws NullPointerException if the argument is null
*/
@SuppressWarnings
(
"rawtypes"
)
// Will be Constructor<?> after JSR 292 MR
public
MethodHandle
unreflectConstructor
(
Constructor
c
)
throws
IllegalAccessException
{
MemberName
ctor
=
new
MemberName
(
c
);
assert
(
ctor
.
isConstructor
());
if
(!
c
.
isAccessible
())
checkAccess
(
c
.
getDeclaringClass
(),
ctor
);
MethodHandle
rawCtor
=
MethodHandleImpl
.
findMethod
(
ctor
,
false
,
lookupClassOrNull
());
MethodHandle
rawCtor
;
if
(
c
.
isAccessible
())
{
rawCtor
=
MethodHandleImpl
.
findMethod
(
ctor
,
false
,
/*no lookupClass*/
null
);
}
else
{
checkAccess
(
c
.
getDeclaringClass
(),
ctor
);
rawCtor
=
MethodHandleImpl
.
findMethod
(
ctor
,
false
,
lookupClassOrNull
());
}
MethodHandle
allocator
=
MethodHandleImpl
.
makeAllocator
(
rawCtor
);
return
fixVarargs
(
allocator
,
rawCtor
);
}
...
...
@@ -1225,7 +1232,7 @@ return mh1;
?
"expected a static field"
:
"expected a non-static field"
,
this
);
if
(
trusted
)
return
MethodHandleImpl
.
accessField
(
field
,
isSetter
,
lookupClassOrNull
()
);
return
MethodHandleImpl
.
accessField
(
field
,
isSetter
,
/*no lookupClass*/
null
);
checkAccess
(
refc
,
field
);
MethodHandle
mh
=
MethodHandleImpl
.
accessField
(
field
,
isSetter
,
lookupClassOrNull
());
return
restrictProtectedReceiver
(
field
,
mh
);
...
...
src/share/classes/sun/invoke/util/ValueConversions.java
浏览文件 @
7118adb7
...
...
@@ -55,9 +55,9 @@ public class ValueConversions {
private
static
final
Lookup
IMPL_LOOKUP
=
MethodHandles
.
lookup
();
private
static
EnumMap
<
Wrapper
,
MethodHandle
>[]
newWrapperCaches
(
int
n
)
{
@SuppressWarnings
(
"unchecked"
)
@SuppressWarnings
(
"unchecked"
)
// generic array creation
EnumMap
<
Wrapper
,
MethodHandle
>[]
caches
=
(
EnumMap
<
Wrapper
,
MethodHandle
>[])
new
EnumMap
[
n
];
// unchecked warning expected here
=
(
EnumMap
<
Wrapper
,
MethodHandle
>[])
new
EnumMap
<?,?>[
n
];
for
(
int
i
=
0
;
i
<
n
;
i
++)
caches
[
i
]
=
new
EnumMap
<>(
Wrapper
.
class
);
return
caches
;
...
...
@@ -1097,7 +1097,7 @@ public class ValueConversions {
}
private
static
MethodHandle
buildNewArray
(
int
nargs
)
{
return
MethodHandles
.
insertArguments
(
NEW_ARRAY
,
0
,
(
int
)
nargs
);
return
MethodHandles
.
insertArguments
(
NEW_ARRAY
,
0
,
nargs
);
}
private
static
final
MethodHandle
[]
FILLERS
=
new
MethodHandle
[
MAX_ARITY
+
1
];
...
...
@@ -1122,7 +1122,7 @@ public class ValueConversions {
}
MethodHandle
leftFill
=
filler
(
leftLen
);
// recursive fill
MethodHandle
rightFill
=
FILL_ARRAYS
[
rightLen
];
rightFill
=
MethodHandles
.
insertArguments
(
rightFill
,
1
,
(
int
)
leftLen
);
// [leftLen..nargs-1]
rightFill
=
MethodHandles
.
insertArguments
(
rightFill
,
1
,
leftLen
);
// [leftLen..nargs-1]
// Combine the two fills: right(left(newArray(nargs), x1..x20), x21..x23)
MethodHandle
mh
=
filler
(
0
);
// identity function produces result
...
...
src/share/classes/sun/invoke/util/Wrapper.java
浏览文件 @
7118adb7
...
...
@@ -31,7 +31,7 @@ public enum Wrapper {
BYTE
(
Byte
.
class
,
byte
.
class
,
'B'
,
(
Byte
)(
byte
)
0
,
new
byte
[
0
],
Format
.
signed
(
8
)),
SHORT
(
Short
.
class
,
short
.
class
,
'S'
,
(
Short
)(
short
)
0
,
new
short
[
0
],
Format
.
signed
(
16
)),
CHAR
(
Character
.
class
,
char
.
class
,
'C'
,
(
Character
)(
char
)
0
,
new
char
[
0
],
Format
.
unsigned
(
16
)),
INT
(
Integer
.
class
,
int
.
class
,
'I'
,
(
Integer
)
(
int
)
0
,
new
int
[
0
],
Format
.
signed
(
32
)),
INT
(
Integer
.
class
,
int
.
class
,
'I'
,
(
Integer
)
/*(int)*/
0
,
new
int
[
0
],
Format
.
signed
(
32
)),
LONG
(
Long
.
class
,
long
.
class
,
'J'
,
(
Long
)(
long
)
0
,
new
long
[
0
],
Format
.
signed
(
64
)),
FLOAT
(
Float
.
class
,
float
.
class
,
'F'
,
(
Float
)(
float
)
0
,
new
float
[
0
],
Format
.
floating
(
32
)),
DOUBLE
(
Double
.
class
,
double
.
class
,
'D'
,
(
Double
)(
double
)
0
,
new
double
[
0
],
Format
.
floating
(
64
)),
...
...
@@ -539,7 +539,7 @@ public enum Wrapper {
switch
(
basicTypeChar
)
{
case
'L'
:
throw
newIllegalArgumentException
(
"cannot wrap to object type"
);
case
'V'
:
return
null
;
case
'I'
:
return
Integer
.
valueOf
(
(
int
)
x
);
case
'I'
:
return
Integer
.
valueOf
(
x
);
case
'J'
:
return
Long
.
valueOf
(
x
);
case
'F'
:
return
Float
.
valueOf
(
x
);
case
'D'
:
return
Double
.
valueOf
(
x
);
...
...
test/java/lang/invoke/CallSiteTest.java
浏览文件 @
7118adb7
...
...
@@ -43,7 +43,7 @@ import static java.lang.invoke.MethodHandles.*;
import
static
java
.
lang
.
invoke
.
MethodType
.*;
public
class
CallSiteTest
{
private
final
static
Class
CLASS
=
CallSiteTest
.
class
;
private
final
static
Class
<?>
CLASS
=
CallSiteTest
.
class
;
private
static
CallSite
mcs
;
private
static
CallSite
vcs
;
...
...
test/java/lang/invoke/ClassValueTest.java
浏览文件 @
7118adb7
...
...
@@ -38,10 +38,6 @@
package
test.java.lang.invoke
;
import
java.util.*
;
import
java.lang.invoke.*
;
import
org.junit.*
;
import
static
org
.
junit
.
Assert
.*;
...
...
@@ -61,7 +57,7 @@ public class ClassValueTest {
}
}
static
final
Class
[]
CLASSES
=
{
static
final
Class
<?>
[]
CLASSES
=
{
String
.
class
,
Integer
.
class
,
int
.
class
,
...
...
@@ -73,11 +69,11 @@ public class ClassValueTest {
@Test
public
void
testGet
()
{
countForCV1
=
0
;
for
(
Class
c
:
CLASSES
)
{
for
(
Class
<?>
c
:
CLASSES
)
{
assertEquals
(
nameForCV1
(
c
),
CV1
.
get
(
c
));
}
assertEquals
(
CLASSES
.
length
,
countForCV1
);
for
(
Class
c
:
CLASSES
)
{
for
(
Class
<?>
c
:
CLASSES
)
{
assertEquals
(
nameForCV1
(
c
),
CV1
.
get
(
c
));
}
assertEquals
(
CLASSES
.
length
,
countForCV1
);
...
...
@@ -85,7 +81,7 @@ public class ClassValueTest {
@Test
public
void
testRemove
()
{
for
(
Class
c
:
CLASSES
)
{
for
(
Class
<?>
c
:
CLASSES
)
{
CV1
.
get
(
c
);
}
countForCV1
=
0
;
...
...
@@ -94,7 +90,7 @@ public class ClassValueTest {
CV1
.
remove
(
CLASSES
[
i
]);
}
assertEquals
(
0
,
countForCV1
);
// no change
for
(
Class
c
:
CLASSES
)
{
for
(
Class
<?>
c
:
CLASSES
)
{
assertEquals
(
nameForCV1
(
c
),
CV1
.
get
(
c
));
}
assertEquals
(
REMCOUNT
,
countForCV1
);
...
...
@@ -124,7 +120,7 @@ public class ClassValueTest {
for
(
int
pass
=
0
;
pass
<=
2
;
pass
++)
{
for
(
int
i1
=
0
;
i1
<
CVN_COUNT1
;
i1
++)
{
eachClass:
for
(
Class
c
:
CLASSES
)
{
for
(
Class
<?>
c
:
CLASSES
)
{
for
(
int
i2
=
0
;
i2
<
CVN_COUNT2
;
i2
++)
{
int
n
=
i1
*
CVN_COUNT2
+
i2
;
assertEquals
(
0
,
countForCVN
);
...
...
@@ -156,8 +152,10 @@ public class ClassValueTest {
}
}
assertEquals
(
countForCVN
,
0
);
for
(
int
n
=
0
;
n
<
cvns
.
length
;
n
++)
{
for
(
Class
c
:
CLASSES
)
{
System
.
out
.
println
(
"[rechecking values]"
);
for
(
int
i
=
0
;
i
<
cvns
.
length
*
10
;
i
++)
{
int
n
=
i
%
cvns
.
length
;
for
(
Class
<?>
c
:
CLASSES
)
{
assertEquals
(
nameForCVN
(
c
,
n
),
cvns
[
n
].
get
(
c
));
}
}
...
...
test/java/lang/invoke/InvokeGenericTest.java
浏览文件 @
7118adb7
...
...
@@ -45,6 +45,7 @@ import static org.junit.Assume.*;
*
* @author jrose
*/
@SuppressWarnings
(
"cast"
)
// various casts help emphasize arguments to invokeExact
public
class
InvokeGenericTest
{
// How much output?
static
int
verbosity
=
0
;
...
...
@@ -129,7 +130,7 @@ public class InvokeGenericTest {
}
}
static
List
<
Object
>
calledLog
=
new
ArrayList
<
Object
>();
static
List
<
Object
>
calledLog
=
new
ArrayList
<>();
static
Object
logEntry
(
String
name
,
Object
...
args
)
{
return
Arrays
.
asList
(
name
,
Arrays
.
asList
(
args
));
}
...
...
@@ -237,8 +238,7 @@ public class InvokeGenericTest {
else
try
{
return
param
.
newInstance
();
}
catch
(
InstantiationException
ex
)
{
}
catch
(
IllegalAccessException
ex
)
{
}
catch
(
InstantiationException
|
IllegalAccessException
ex
)
{
}
return
null
;
// random class not Object, String, Integer, etc.
}
...
...
@@ -274,9 +274,11 @@ public class InvokeGenericTest {
return
zeroArgs
(
params
.
toArray
(
new
Class
<?>[
0
]));
}
@SafeVarargs
@SuppressWarnings
(
"varargs"
)
static
<
T
,
E
extends
T
>
T
[]
array
(
Class
<
T
[]>
atype
,
E
...
a
)
{
return
Arrays
.
copyOf
(
a
,
a
.
length
,
atype
);
}
@SafeVarargs
@SuppressWarnings
(
"varargs"
)
static
<
T
>
T
[]
cat
(
T
[]
a
,
T
...
b
)
{
int
alen
=
a
.
length
,
blen
=
b
.
length
;
if
(
blen
==
0
)
return
a
;
...
...
@@ -311,7 +313,7 @@ public class InvokeGenericTest {
int
beg
,
int
end
,
Class
<?>
argType
)
{
MethodType
targetType
=
target
.
type
();
end
=
Math
.
min
(
end
,
targetType
.
parameterCount
());
ArrayList
<
Class
<?>>
argTypes
=
new
ArrayList
<
Class
<?>
>(
targetType
.
parameterList
());
ArrayList
<
Class
<?>>
argTypes
=
new
ArrayList
<>(
targetType
.
parameterList
());
Collections
.
fill
(
argTypes
.
subList
(
beg
,
end
),
argType
);
MethodType
ttype2
=
MethodType
.
methodType
(
targetType
.
returnType
(),
argTypes
);
return
target
.
asType
(
ttype2
);
...
...
@@ -320,7 +322,7 @@ public class InvokeGenericTest {
// This lookup is good for all members in and under InvokeGenericTest.
static
final
Lookup
LOOKUP
=
MethodHandles
.
lookup
();
Map
<
List
<
Class
<?>>,
MethodHandle
>
CALLABLES
=
new
HashMap
<
List
<
Class
<?>>,
MethodHandle
>();
Map
<
List
<
Class
<?>>,
MethodHandle
>
CALLABLES
=
new
HashMap
<>();
MethodHandle
callable
(
List
<
Class
<?>>
params
)
{
MethodHandle
mh
=
CALLABLES
.
get
(
params
);
if
(
mh
==
null
)
{
...
...
@@ -353,8 +355,8 @@ public class InvokeGenericTest {
countTest
();
String
[]
args
=
{
"one"
,
"two"
};
MethodHandle
mh
=
callable
(
Object
.
class
,
String
.
class
);
Object
res
;
List
resl
;
res
=
resl
=
(
List
)
mh
.
invoke
((
String
)
args
[
0
],
(
Object
)
args
[
1
]);
Object
res
;
List
<?>
resl
;
res
=
resl
=
(
List
<?>
)
mh
.
invoke
((
String
)
args
[
0
],
(
Object
)
args
[
1
]);
//System.out.println(res);
assertEquals
(
Arrays
.
asList
(
args
),
res
);
}
...
...
@@ -365,8 +367,8 @@ public class InvokeGenericTest {
countTest
();
int
[]
args
=
{
1
,
2
};
MethodHandle
mh
=
callable
(
Object
.
class
,
Object
.
class
);
Object
res
;
List
resl
;
res
=
resl
=
(
List
)
mh
.
invoke
(
args
[
0
],
args
[
1
]);
Object
res
;
List
<?>
resl
;
res
=
resl
=
(
List
<?>
)
mh
.
invoke
(
args
[
0
],
args
[
1
]);
//System.out.println(res);
assertEquals
(
Arrays
.
toString
(
args
),
res
.
toString
());
}
...
...
@@ -377,8 +379,8 @@ public class InvokeGenericTest {
countTest
();
String
[]
args
=
{
"one"
,
"two"
};
MethodHandle
mh
=
callable
(
Object
.
class
,
String
.
class
);
Object
res
;
List
resl
;
res
=
resl
=
(
List
)
mh
.
invoke
((
String
)
args
[
0
],
(
Object
)
args
[
1
]);
Object
res
;
List
<?>
resl
;
res
=
resl
=
(
List
<?>
)
mh
.
invoke
((
String
)
args
[
0
],
(
Object
)
args
[
1
]);
//System.out.println(res);
assertEquals
(
Arrays
.
asList
(
args
),
res
);
}
...
...
@@ -440,9 +442,9 @@ public class InvokeGenericTest {
* A void return type is possible iff the first type is void.class.
*/
static
List
<
MethodType
>
allMethodTypes
(
int
minargc
,
int
maxargc
,
Class
<?>...
types
)
{
ArrayList
<
MethodType
>
result
=
new
ArrayList
<
MethodType
>();
ArrayList
<
MethodType
>
result
=
new
ArrayList
<>();
if
(
types
.
length
>
0
)
{
ArrayList
<
MethodType
>
argcTypes
=
new
ArrayList
<
MethodType
>();
ArrayList
<
MethodType
>
argcTypes
=
new
ArrayList
<>();
// build arity-zero types first
for
(
Class
<?>
rtype
:
types
)
{
argcTypes
.
add
(
MethodType
.
methodType
(
rtype
));
...
...
@@ -456,7 +458,7 @@ public class InvokeGenericTest {
if
(
argc
>=
maxargc
)
break
;
ArrayList
<
MethodType
>
prevTypes
=
argcTypes
;
argcTypes
=
new
ArrayList
<
MethodType
>();
argcTypes
=
new
ArrayList
<>();
for
(
MethodType
prevType
:
prevTypes
)
{
for
(
Class
<?>
ptype
:
types
)
{
argcTypes
.
add
(
prevType
.
insertParameterTypes
(
argc
,
ptype
));
...
...
@@ -524,8 +526,8 @@ public class InvokeGenericTest {
countTest
();
Object
[]
args
=
{
1
,
2
};
MethodHandle
mh
=
callable
(
Object
.
class
,
int
.
class
);
Object
res
;
List
resl
;
int
resi
;
res
=
resl
=
(
List
)
mh
.
invoke
((
int
)
args
[
0
],
(
Object
)
args
[
1
]);
Object
res
;
List
<?>
resl
;
int
resi
;
res
=
resl
=
(
List
<?>
)
mh
.
invoke
((
int
)
args
[
0
],
(
Object
)
args
[
1
]);
//System.out.println(res);
assertEquals
(
Arrays
.
asList
(
args
),
res
);
mh
=
MethodHandles
.
identity
(
int
.
class
);
...
...
test/java/lang/invoke/JavaDocExamplesTest.java
浏览文件 @
7118adb7
...
...
@@ -54,6 +54,7 @@ import static org.junit.Assert.*;
/**
* @author jrose
*/
@SuppressWarnings
(
"LocalVariableHidesMemberVariable"
)
public
class
JavaDocExamplesTest
{
/** Wrapper for running the JUnit tests in this module.
* Put JUnit on the classpath!
...
...
@@ -336,6 +337,7 @@ assertEquals("[123]", (String) longsToString.invokeExact((long)123));
}}
}
@SuppressWarnings
(
"rawtypes"
)
@Test
public
void
testAsVarargsCollector
()
throws
Throwable
{
{{
{}
/// JAVADOC
...
...
test/java/lang/invoke/MethodHandlesTest.java
浏览文件 @
7118adb7
...
...
@@ -176,7 +176,7 @@ public class MethodHandlesTest {
}
}
static
List
<
Object
>
calledLog
=
new
ArrayList
<
Object
>();
static
List
<
Object
>
calledLog
=
new
ArrayList
<>();
static
Object
logEntry
(
String
name
,
Object
...
args
)
{
return
Arrays
.
asList
(
name
,
Arrays
.
asList
(
args
));
}
...
...
@@ -211,6 +211,7 @@ public class MethodHandlesTest {
return
dst
.
cast
(
value
);
}
@SuppressWarnings
(
"cast"
)
// primitive cast to (long) is part of the pattern
static
Object
castToWrapperOrNull
(
long
value
,
Class
<?>
dst
)
{
if
(
dst
==
int
.
class
||
dst
==
Integer
.
class
)
return
(
int
)(
value
);
...
...
@@ -284,8 +285,7 @@ public class MethodHandlesTest {
else
try
{
return
param
.
newInstance
();
}
catch
(
InstantiationException
ex
)
{
}
catch
(
IllegalAccessException
ex
)
{
}
catch
(
InstantiationException
|
IllegalAccessException
ex
)
{
}
return
null
;
// random class not Object, String, Integer, etc.
}
...
...
@@ -302,9 +302,11 @@ public class MethodHandlesTest {
return
args
;
}
@SafeVarargs
@SuppressWarnings
(
"varargs"
)
static
<
T
,
E
extends
T
>
T
[]
array
(
Class
<
T
[]>
atype
,
E
...
a
)
{
return
Arrays
.
copyOf
(
a
,
a
.
length
,
atype
);
}
@SafeVarargs
@SuppressWarnings
(
"varargs"
)
static
<
T
>
T
[]
cat
(
T
[]
a
,
T
...
b
)
{
int
alen
=
a
.
length
,
blen
=
b
.
length
;
if
(
blen
==
0
)
return
a
;
...
...
@@ -354,14 +356,14 @@ public class MethodHandlesTest {
try
{
LIST_TO_STRING
=
PRIVATE
.
findStatic
(
PRIVATE
.
lookupClass
(),
"listToString"
,
MethodType
.
methodType
(
String
.
class
,
List
.
class
));
}
catch
(
Exception
ex
)
{
throw
new
RuntimeException
(
ex
);
}
}
catch
(
NoSuchMethodException
|
IllegalAccess
Exception
ex
)
{
throw
new
RuntimeException
(
ex
);
}
list
=
MethodHandles
.
filterReturnValue
(
list
,
LIST_TO_STRING
);
}
else
if
(
rtype
.
isPrimitive
())
{
if
(
LIST_TO_INT
==
null
)
try
{
LIST_TO_INT
=
PRIVATE
.
findStatic
(
PRIVATE
.
lookupClass
(),
"listToInt"
,
MethodType
.
methodType
(
int
.
class
,
List
.
class
));
}
catch
(
Exception
ex
)
{
throw
new
RuntimeException
(
ex
);
}
}
catch
(
NoSuchMethodException
|
IllegalAccess
Exception
ex
)
{
throw
new
RuntimeException
(
ex
);
}
list
=
MethodHandles
.
filterReturnValue
(
list
,
LIST_TO_INT
);
list
=
MethodHandles
.
explicitCastArguments
(
list
,
listType
);
}
else
{
...
...
@@ -370,8 +372,8 @@ public class MethodHandlesTest {
return
list
.
asType
(
listType
);
}
private
static
MethodHandle
LIST_TO_STRING
,
LIST_TO_INT
;
private
static
String
listToString
(
List
x
)
{
return
x
.
toString
();
}
private
static
int
listToInt
(
List
x
)
{
return
x
.
toString
().
hashCode
();
}
private
static
String
listToString
(
List
<?>
x
)
{
return
x
.
toString
();
}
private
static
int
listToInt
(
List
<?>
x
)
{
return
x
.
toString
().
hashCode
();
}
static
MethodHandle
changeArgTypes
(
MethodHandle
target
,
Class
<?>
argType
)
{
return
changeArgTypes
(
target
,
0
,
999
,
argType
);
...
...
@@ -380,7 +382,7 @@ public class MethodHandlesTest {
int
beg
,
int
end
,
Class
<?>
argType
)
{
MethodType
targetType
=
target
.
type
();
end
=
Math
.
min
(
end
,
targetType
.
parameterCount
());
ArrayList
<
Class
<?>>
argTypes
=
new
ArrayList
<
Class
<?>
>(
targetType
.
parameterList
());
ArrayList
<
Class
<?>>
argTypes
=
new
ArrayList
<>(
targetType
.
parameterList
());
Collections
.
fill
(
argTypes
.
subList
(
beg
,
end
),
argType
);
MethodType
ttype2
=
MethodType
.
methodType
(
targetType
.
returnType
(),
argTypes
);
return
target
.
asType
(
ttype2
);
...
...
@@ -405,6 +407,7 @@ public class MethodHandlesTest {
final
String
name
;
public
Example
()
{
name
=
"Example#"
+
nextArg
();
}
protected
Example
(
String
name
)
{
this
.
name
=
name
;
}
@SuppressWarnings
(
"LeakingThisInConstructor"
)
protected
Example
(
int
x
)
{
this
();
called
(
"protected <init>"
,
this
,
x
);
}
@Override
public
String
toString
()
{
return
name
;
}
...
...
@@ -441,6 +444,7 @@ public class MethodHandlesTest {
static
class
SubExample
extends
Example
{
@Override
public
void
v0
()
{
called
(
"Sub/v0"
,
this
);
}
@Override
void
pkg_v0
()
{
called
(
"Sub/pkg_v0"
,
this
);
}
@SuppressWarnings
(
"LeakingThisInConstructor"
)
private
SubExample
(
int
x
)
{
called
(
"<init>"
,
this
,
x
);
}
public
SubExample
()
{
super
(
"SubExample#"
+
nextArg
());
}
}
...
...
@@ -912,7 +916,7 @@ public class MethodHandlesTest {
static
final
Object
[][]
CASES
;
static
{
ArrayList
<
Object
[]>
cases
=
new
ArrayList
<
Object
[]
>();
ArrayList
<
Object
[]>
cases
=
new
ArrayList
<>();
Object
types
[][]
=
{
{
'L'
,
Object
.
class
},
{
'R'
,
String
.
class
},
{
'I'
,
int
.
class
},
{
'J'
,
long
.
class
},
...
...
@@ -931,12 +935,12 @@ public class MethodHandlesTest {
Field
field
;
try
{
field
=
HasFields
.
class
.
getDeclaredField
(
name
);
}
catch
(
Exception
ex
)
{
}
catch
(
NoSuchFieldException
|
Security
Exception
ex
)
{
throw
new
InternalError
(
"no field HasFields."
+
name
);
}
try
{
value
=
field
.
get
(
fields
);
}
catch
(
Exception
ex
)
{
}
catch
(
IllegalArgumentException
|
IllegalAccess
Exception
ex
)
{
throw
new
InternalError
(
"cannot fetch field HasFields."
+
name
);
}
if
(
type
==
float
.
class
)
{
...
...
@@ -1257,7 +1261,7 @@ public class MethodHandlesTest {
List
<
Object
>
array2list
(
Object
array
)
{
int
length
=
Array
.
getLength
(
array
);
ArrayList
<
Object
>
model
=
new
ArrayList
<
Object
>(
length
);
ArrayList
<
Object
>
model
=
new
ArrayList
<>(
length
);
for
(
int
i
=
0
;
i
<
length
;
i
++)
model
.
add
(
Array
.
get
(
array
,
i
));
return
model
;
...
...
@@ -1288,7 +1292,7 @@ public class MethodHandlesTest {
String
name
=
pfx
+
"id"
;
try
{
return
PRIVATE
.
findStatic
(
Callee
.
class
,
name
,
type
);
}
catch
(
Exception
ex
)
{
}
catch
(
NoSuchMethodException
|
IllegalAccess
Exception
ex
)
{
throw
new
RuntimeException
(
ex
);
}
}
...
...
@@ -1365,7 +1369,7 @@ public class MethodHandlesTest {
MethodHandle
vac
=
vac0
.
asVarargsCollector
(
Object
[].
class
);
testConvert
(
true
,
vac
.
asType
(
MethodType
.
genericMethodType
(
0
)),
null
,
"vac"
);
testConvert
(
true
,
vac
.
asType
(
MethodType
.
genericMethodType
(
0
)),
null
,
"vac"
);
for
(
Class
<?>
at
:
new
Class
[]
{
Object
.
class
,
String
.
class
,
Integer
.
class
})
{
for
(
Class
<?>
at
:
new
Class
<?>
[]
{
Object
.
class
,
String
.
class
,
Integer
.
class
})
{
testConvert
(
true
,
vac
.
asType
(
MethodType
.
genericMethodType
(
1
)),
null
,
"vac"
,
at
);
testConvert
(
true
,
vac
.
asType
(
MethodType
.
genericMethodType
(
2
)),
null
,
"vac"
,
at
,
at
);
}
...
...
@@ -1514,7 +1518,7 @@ public class MethodHandlesTest {
public
void
testSpreadArguments
()
throws
Throwable
{
if
(
CAN_SKIP_WORKING
)
return
;
startTest
(
"spreadArguments"
);
for
(
Class
<?>
argType
:
new
Class
[]{
Object
.
class
,
Integer
.
class
,
int
.
class
})
{
for
(
Class
<?>
argType
:
new
Class
<?>
[]{
Object
.
class
,
Integer
.
class
,
int
.
class
})
{
if
(
verbosity
>=
3
)
System
.
out
.
println
(
"spreadArguments "
+
argType
);
for
(
int
nargs
=
0
;
nargs
<
50
;
nargs
++)
{
...
...
@@ -1538,7 +1542,7 @@ public class MethodHandlesTest {
Object
[]
args
=
randomArgs
(
target2
.
type
().
parameterArray
());
// make sure the target does what we think it does:
if
(
pos
==
0
&&
nargs
<
5
&&
!
argType
.
isPrimitive
())
{
Object
[]
check
=
(
Object
[])
(
Object
)
target
.
invokeWithArguments
(
args
);
Object
[]
check
=
(
Object
[])
target
.
invokeWithArguments
(
args
);
assertArrayEquals
(
args
,
check
);
switch
(
nargs
)
{
case
0
:
...
...
@@ -1555,7 +1559,7 @@ public class MethodHandlesTest {
break
;
}
}
List
<
Class
<?>>
newParams
=
new
ArrayList
<
Class
<?>
>(
target2
.
type
().
parameterList
());
List
<
Class
<?>>
newParams
=
new
ArrayList
<>(
target2
.
type
().
parameterList
());
{
// modify newParams in place
List
<
Class
<?>>
spreadParams
=
newParams
.
subList
(
pos
,
nargs
);
spreadParams
.
clear
();
spreadParams
.
add
(
arrayType
);
...
...
@@ -1608,7 +1612,7 @@ public class MethodHandlesTest {
public
void
testCollectArguments
()
throws
Throwable
{
if
(
CAN_SKIP_WORKING
)
return
;
startTest
(
"collectArguments"
);
for
(
Class
<?>
argType
:
new
Class
[]{
Object
.
class
,
Integer
.
class
,
int
.
class
})
{
for
(
Class
<?>
argType
:
new
Class
<?>
[]{
Object
.
class
,
Integer
.
class
,
int
.
class
})
{
if
(
verbosity
>=
3
)
System
.
out
.
println
(
"collectArguments "
+
argType
);
for
(
int
nargs
=
0
;
nargs
<
50
;
nargs
++)
{
...
...
@@ -1670,12 +1674,13 @@ public class MethodHandlesTest {
MethodHandle
target
=
varargsArray
(
nargs
+
ins
);
Object
[]
args
=
randomArgs
(
target
.
type
().
parameterArray
());
List
<
Object
>
resList
=
Arrays
.
asList
(
args
);
List
<
Object
>
argsToPass
=
new
ArrayList
<
Object
>(
resList
);
List
<
Object
>
argsToPass
=
new
ArrayList
<>(
resList
);
List
<
Object
>
argsToInsert
=
argsToPass
.
subList
(
pos
,
pos
+
ins
);
if
(
verbosity
>=
3
)
System
.
out
.
println
(
"insert: "
+
argsToInsert
+
" into "
+
target
);
@SuppressWarnings
(
"cast"
)
// cast to spread Object... is helpful
MethodHandle
target2
=
MethodHandles
.
insertArguments
(
target
,
pos
,
(
Object
[])
argsToInsert
.
toArray
());
(
Object
[]
/*...*/
)
argsToInsert
.
toArray
());
argsToInsert
.
clear
();
// remove from argsToInsert
Object
res2
=
target2
.
invokeWithArguments
(
argsToPass
);
Object
res2List
=
Arrays
.
asList
((
Object
[])
res2
);
...
...
@@ -1693,7 +1698,7 @@ public class MethodHandlesTest {
Class
<?>
classOfVCList
=
varargsList
(
1
).
invokeWithArguments
(
0
).
getClass
();
assertTrue
(
List
.
class
.
isAssignableFrom
(
classOfVCList
));
for
(
int
nargs
=
0
;
nargs
<=
3
;
nargs
++)
{
for
(
Class
<?>
rtype
:
new
Class
[]
{
Object
.
class
,
for
(
Class
<?>
rtype
:
new
Class
<?>
[]
{
Object
.
class
,
List
.
class
,
int
.
class
,
byte
.
class
,
...
...
@@ -1790,7 +1795,7 @@ public class MethodHandlesTest {
System
.
out
.
println
(
"fold "
+
target
+
" with "
+
combine
);
MethodHandle
target2
=
MethodHandles
.
foldArguments
(
target
,
combine
);
// Simulate expected effect of combiner on arglist:
List
<
Object
>
expected
=
new
ArrayList
<
Object
>(
argsToPass
);
List
<
Object
>
expected
=
new
ArrayList
<>(
argsToPass
);
List
<
Object
>
argsToFold
=
expected
.
subList
(
pos
,
pos
+
fold
);
if
(
verbosity
>=
3
)
System
.
out
.
println
(
"fold: "
+
argsToFold
+
" into "
+
target2
);
...
...
@@ -1822,9 +1827,9 @@ public class MethodHandlesTest {
MethodHandle
target
=
varargsArray
(
nargs
);
Object
[]
args
=
randomArgs
(
target
.
type
().
parameterArray
());
MethodHandle
target2
=
MethodHandles
.
dropArguments
(
target
,
pos
,
Collections
.
nCopies
(
drop
,
Object
.
class
).
toArray
(
new
Class
[
0
]));
Collections
.
nCopies
(
drop
,
Object
.
class
).
toArray
(
new
Class
<?>
[
0
]));
List
<
Object
>
resList
=
Arrays
.
asList
(
args
);
List
<
Object
>
argsToDrop
=
new
ArrayList
<
Object
>(
resList
);
List
<
Object
>
argsToDrop
=
new
ArrayList
<>(
resList
);
for
(
int
i
=
drop
;
i
>
0
;
i
--)
{
argsToDrop
.
add
(
pos
,
"blort#"
+
i
);
}
...
...
@@ -1840,11 +1845,11 @@ public class MethodHandlesTest {
if
(
CAN_SKIP_WORKING
)
return
;
startTest
(
"exactInvoker, genericInvoker, varargsInvoker, dynamicInvoker"
);
// exactInvoker, genericInvoker, varargsInvoker[0..N], dynamicInvoker
Set
<
MethodType
>
done
=
new
HashSet
<
MethodType
>();
Set
<
MethodType
>
done
=
new
HashSet
<>();
for
(
int
i
=
0
;
i
<=
6
;
i
++)
{
if
(
CAN_TEST_LIGHTLY
&&
i
>
3
)
break
;
MethodType
gtype
=
MethodType
.
genericMethodType
(
i
);
for
(
Class
<?>
argType
:
new
Class
[]{
Object
.
class
,
Integer
.
class
,
int
.
class
})
{
for
(
Class
<?>
argType
:
new
Class
<?>
[]{
Object
.
class
,
Integer
.
class
,
int
.
class
})
{
for
(
int
j
=
-
1
;
j
<
i
;
j
++)
{
MethodType
type
=
gtype
;
if
(
j
<
0
)
...
...
@@ -1873,7 +1878,7 @@ public class MethodHandlesTest {
assertTrue
(
target
.
isVarargsCollector
());
target
=
target
.
asType
(
type
);
Object
[]
args
=
randomArgs
(
type
.
parameterArray
());
List
<
Object
>
targetPlusArgs
=
new
ArrayList
<
Object
>(
Arrays
.
asList
(
args
));
List
<
Object
>
targetPlusArgs
=
new
ArrayList
<>(
Arrays
.
asList
(
args
));
targetPlusArgs
.
add
(
0
,
target
);
int
code
=
(
Integer
)
invokee
(
args
);
Object
log
=
logEntry
(
"invokee"
,
args
);
...
...
@@ -1960,7 +1965,7 @@ public class MethodHandlesTest {
.
appendParameterTypes
(
Object
[].
class
)
.
insertParameterTypes
(
0
,
MethodHandle
.
class
));
assertEquals
(
expType
,
inv
.
type
());
List
<
Object
>
targetPlusVarArgs
=
new
ArrayList
<
Object
>(
targetPlusArgs
);
List
<
Object
>
targetPlusVarArgs
=
new
ArrayList
<>(
targetPlusArgs
);
List
<
Object
>
tailList
=
targetPlusVarArgs
.
subList
(
1
+
k
,
1
+
nargs
);
Object
[]
tail
=
tailList
.
toArray
();
tailList
.
clear
();
tailList
.
add
(
tail
);
...
...
@@ -2191,7 +2196,7 @@ public class MethodHandlesTest {
if
(
throwMode
==
THROW_NOTHING
)
{
assertSame
(
arg0
,
returned
);
}
else
if
(
throwMode
==
THROW_CAUGHT
)
{
List
<
Object
>
catchArgs
=
new
ArrayList
<
Object
>(
Arrays
.
asList
(
args
));
List
<
Object
>
catchArgs
=
new
ArrayList
<>(
Arrays
.
asList
(
args
));
// catcher receives an initial subsequence of target arguments:
catchArgs
.
subList
(
nargs
-
catchDrops
,
nargs
).
clear
();
// catcher also receives the exception, prepended:
...
...
@@ -2317,12 +2322,13 @@ public class MethodHandlesTest {
INT_IDENTITY
=
PRIVATE
.
findStatic
(
Surprise
.
class
,
"intIdentity"
,
MethodType
.
methodType
(
int
.
class
,
int
.
class
));
}
catch
(
Exception
ex
)
{
}
catch
(
NoSuchMethodException
|
IllegalAccess
Exception
ex
)
{
throw
new
RuntimeException
(
ex
);
}
}
}
@SuppressWarnings
(
"ConvertToStringSwitch"
)
void
testCastFailure
(
String
mode
,
int
okCount
)
throws
Throwable
{
countTest
(
false
);
if
(
verbosity
>
2
)
System
.
out
.
println
(
"mode="
+
mode
);
...
...
@@ -2418,13 +2424,14 @@ public class MethodHandlesTest {
}
public
interface
Fooable
{
// overloads:
Object
foo
(
Object
x
,
String
y
);
List
foo
(
String
x
,
int
y
);
Object
foo
(
String
x
);
Object
foo
(
Object
x
,
String
y
);
List
<?>
foo
(
String
x
,
int
y
);
Object
foo
(
String
x
);
}
static
Object
fooForFooable
(
String
x
,
Object
...
y
)
{
return
called
(
"fooForFooable/"
+
x
,
y
);
}
@SuppressWarnings
(
"serial"
)
// not really a public API, just a test case
public
static
class
MyCheckedException
extends
Exception
{
}
public
interface
WillThrow
{
...
...
@@ -2453,7 +2460,7 @@ public class MethodHandlesTest {
{
countTest
();
if
(
verbosity
>=
2
)
System
.
out
.
println
(
"Appendable"
);
ArrayList
<
List
>
appendResults
=
new
ArrayList
<
List
>();
ArrayList
<
List
<?>>
appendResults
=
new
ArrayList
<
>();
MethodHandle
append
=
lookup
.
bind
(
appendResults
,
"add"
,
MethodType
.
methodType
(
boolean
.
class
,
Object
.
class
));
append
=
append
.
asType
(
MethodType
.
methodType
(
void
.
class
,
List
.
class
));
// specialize the type
MethodHandle
asList
=
lookup
.
findStatic
(
Arrays
.
class
,
"asList"
,
MethodType
.
methodType
(
List
.
class
,
Object
[].
class
));
...
...
@@ -2475,11 +2482,11 @@ public class MethodHandlesTest {
formatter
.
format
(
fmt
,
fmtArgs
);
String
actual
=
""
;
if
(
verbosity
>=
3
)
System
.
out
.
println
(
"appendResults="
+
appendResults
);
for
(
List
l
:
appendResults
)
{
for
(
List
<?>
l
:
appendResults
)
{
Object
x
=
l
.
get
(
0
);
switch
(
l
.
size
())
{
case
1
:
actual
+=
x
;
continue
;
case
3
:
actual
+=
((
String
)
x
).
substring
((
int
)
l
.
get
(
1
),
(
in
t
)
l
.
get
(
2
));
continue
;
case
3
:
actual
+=
((
String
)
x
).
substring
((
int
)
(
Object
)
l
.
get
(
1
),
(
int
)(
Objec
t
)
l
.
get
(
2
));
continue
;
}
actual
+=
l
;
}
...
...
@@ -2551,7 +2558,7 @@ public class MethodHandlesTest {
}
}
// Test error checking on bad interfaces:
for
(
Class
<?>
nonSMI
:
new
Class
[]
{
Object
.
class
,
for
(
Class
<?>
nonSMI
:
new
Class
<?>
[]
{
Object
.
class
,
String
.
class
,
CharSequence
.
class
,
java
.
io
.
Serializable
.
class
,
...
...
@@ -2579,7 +2586,7 @@ public class MethodHandlesTest {
}
}
// Test error checking on interfaces with the wrong method type:
for
(
Class
<?>
intfc
:
new
Class
[]
{
Runnable
.
class
/*arity 0*/
,
for
(
Class
<?>
intfc
:
new
Class
<?>
[]
{
Runnable
.
class
/*arity 0*/
,
Fooable
.
class
/*arity 1 & 2*/
})
{
int
badArity
=
1
;
// known to be incompatible
if
(
verbosity
>
2
)
System
.
out
.
println
(
intfc
.
getName
());
...
...
@@ -2657,7 +2664,7 @@ class ValueConversions {
Object
a8
,
Object
a9
)
{
return
makeArray
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
,
a9
);
}
static
MethodHandle
[]
makeArrays
()
{
ArrayList
<
MethodHandle
>
arrays
=
new
ArrayList
<
MethodHandle
>();
ArrayList
<
MethodHandle
>
arrays
=
new
ArrayList
<>();
MethodHandles
.
Lookup
lookup
=
IMPL_LOOKUP
;
for
(;;)
{
int
nargs
=
arrays
.
size
();
...
...
@@ -2746,7 +2753,7 @@ class ValueConversions {
Object
a8
,
Object
a9
)
{
return
makeList
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
,
a9
);
}
static
MethodHandle
[]
makeLists
()
{
ArrayList
<
MethodHandle
>
lists
=
new
ArrayList
<
MethodHandle
>();
ArrayList
<
MethodHandle
>
lists
=
new
ArrayList
<>();
MethodHandles
.
Lookup
lookup
=
IMPL_LOOKUP
;
for
(;;)
{
int
nargs
=
lists
.
size
();
...
...
@@ -2769,7 +2776,7 @@ class ValueConversions {
static
{
try
{
AS_LIST
=
IMPL_LOOKUP
.
findStatic
(
Arrays
.
class
,
"asList"
,
MethodType
.
methodType
(
List
.
class
,
Object
[].
class
));
}
catch
(
Exception
ex
)
{
throw
new
RuntimeException
(
ex
);
}
}
catch
(
NoSuchMethodException
|
IllegalAccess
Exception
ex
)
{
throw
new
RuntimeException
(
ex
);
}
}
/** Return a method handle that takes the indicated number of Object
...
...
test/java/lang/invoke/MethodTypeTest.java
浏览文件 @
7118adb7
...
...
@@ -29,6 +29,7 @@
package
test.java.lang.invoke
;
import
java.io.IOException
;
import
java.lang.invoke.MethodType
;
import
java.lang.reflect.Method
;
...
...
@@ -378,7 +379,7 @@ public class MethodTypeTest {
public
void
testHashCode
()
{
System
.
out
.
println
(
"hashCode"
);
MethodType
instance
=
mt_viS
;
ArrayList
<
Class
<?>>
types
=
new
ArrayList
<
Class
<?>
>();
ArrayList
<
Class
<?>>
types
=
new
ArrayList
<>();
types
.
add
(
instance
.
returnType
());
types
.
addAll
(
instance
.
parameterList
());
int
expResult
=
types
.
hashCode
();
...
...
@@ -556,7 +557,7 @@ public class MethodTypeTest {
Object
decode
;
try
{
decode
=
readSerial
(
wire
);
}
catch
(
Exception
ex
)
{
}
catch
(
IOException
|
ClassNotFound
Exception
ex
)
{
decode
=
ex
;
// oops!
}
assertEquals
(
mt
,
decode
);
...
...
test/java/lang/invoke/PermuteArgsTest.java
浏览文件 @
7118adb7
...
...
@@ -45,7 +45,7 @@ import static java.lang.invoke.MethodHandles.*;
import
static
java
.
lang
.
invoke
.
MethodType
.*;
public
class
PermuteArgsTest
{
private
static
final
Class
CLASS
=
PermuteArgsTest
.
class
;
private
static
final
Class
<?>
CLASS
=
PermuteArgsTest
.
class
;
private
static
final
int
MAX_ARITY
=
Integer
.
getInteger
(
CLASS
.
getSimpleName
()+
".MAX_ARITY"
,
8
);
private
static
final
boolean
DRY_RUN
=
Boolean
.
getBoolean
(
CLASS
.
getSimpleName
()+
".DRY_RUN"
);
private
static
final
boolean
VERBOSE
=
Boolean
.
getBoolean
(
CLASS
.
getSimpleName
()+
".VERBOSE"
)
||
DRY_RUN
;
...
...
@@ -99,12 +99,12 @@ public class PermuteArgsTest {
return
Arrays
.
asList
(
w
,
x
,
y
,
z
);
}
static
Object
listI_etc
(
int
...
va
)
{
ArrayList
<
Object
>
res
=
new
ArrayList
<
Object
>();
ArrayList
<
Object
>
res
=
new
ArrayList
<>();
for
(
int
x
:
va
)
res
.
add
(
x
);
return
res
;
}
static
Object
listIJL_etc
(
int
x
,
long
y
,
Object
z
,
Object
...
va
)
{
ArrayList
<
Object
>
res
=
new
ArrayList
<
Object
>();
ArrayList
<
Object
>
res
=
new
ArrayList
<>();
res
.
addAll
(
Arrays
.
asList
(
x
,
y
,
z
));
res
.
addAll
(
Arrays
.
asList
(
va
));
return
res
;
...
...
@@ -168,7 +168,7 @@ public class PermuteArgsTest {
mh1
=
adjustArity
(
mh
,
arity
);
}
catch
(
IllegalArgumentException
ex
)
{
System
.
out
.
println
(
"*** mh = "
+
name
+
" : "
+
mh
+
"; arity = "
+
arity
+
" => "
+
ex
);
ex
.
printStackTrace
();
ex
.
printStackTrace
(
System
.
out
);
break
;
// cannot get this arity for this type
}
test
(
"("
+
arity
+
")"
+
name
,
mh1
);
...
...
@@ -213,7 +213,7 @@ public class PermuteArgsTest {
}
static
void
testPermutations
(
MethodHandle
mh
)
throws
Throwable
{
HashSet
<
String
>
done
=
new
HashSet
<
String
>();
HashSet
<
String
>
done
=
new
HashSet
<>();
MethodType
mt
=
mh
.
type
();
int
[]
perm
=
nullPerm
(
mt
.
parameterCount
());
final
int
MARGIN
=
(
perm
.
length
<=
10
?
2
:
0
);
...
...
@@ -326,8 +326,8 @@ public class PermuteArgsTest {
Class
<?>
pt
=
ptypes
[
i
];
Object
arg
;
if
(
pt
==
Void
.
class
)
arg
=
null
;
else
if
(
pt
==
int
.
class
)
arg
=
(
int
)
i
+
101
;
else
if
(
pt
==
long
.
class
)
arg
=
(
long
)
i
+
10_000_000_001L
;
else
if
(
pt
==
int
.
class
)
arg
=
i
+
101
;
else
if
(
pt
==
long
.
class
)
arg
=
i
+
10_000_000_001L
;
else
arg
=
"#"
+
(
i
+
1
);
args
[
i
]
=
arg
;
}
...
...
test/java/lang/invoke/RicochetTest.java
浏览文件 @
7118adb7
...
...
@@ -40,7 +40,6 @@ import org.junit.*;
import
static
java
.
lang
.
invoke
.
MethodType
.*;
import
static
java
.
lang
.
invoke
.
MethodHandles
.*;
import
static
org
.
junit
.
Assert
.*;
import
static
org
.
junit
.
Assume
.*;
/**
...
...
@@ -48,7 +47,7 @@ import static org.junit.Assume.*;
* @author jrose
*/
public
class
RicochetTest
{
private
static
final
Class
CLASS
=
RicochetTest
.
class
;
private
static
final
Class
<?>
CLASS
=
RicochetTest
.
class
;
private
static
final
int
MAX_ARITY
=
Integer
.
getInteger
(
CLASS
.
getSimpleName
()+
".MAX_ARITY"
,
40
);
public
static
void
main
(
String
...
av
)
throws
Throwable
{
...
...
@@ -148,7 +147,7 @@ public class RicochetTest {
for
(
int
nargs
=
0
;
nargs
<=
MAX
;
nargs
++)
{
if
(
nargs
>
30
&&
nargs
<
MAX
-
20
)
nargs
+=
10
;
int
[]
args
=
new
int
[
nargs
];
for
(
int
j
=
0
;
j
<
args
.
length
;
j
++)
args
[
j
]
=
(
int
)(
j
+
11
)
;
for
(
int
j
=
0
;
j
<
args
.
length
;
j
++)
args
[
j
]
=
j
+
11
;
//System.out.println("testIntSpreads "+Arrays.toString(args));
int
[]
args1
=
(
int
[])
id
.
invokeExact
(
args
);
assertArrayEquals
(
args
,
args1
);
...
...
@@ -388,6 +387,7 @@ public class RicochetTest {
java
.
util
.
Random
random
;
final
MethodHandle
[]
fns
;
int
depth
;
@SuppressWarnings
(
"LeakingThisInConstructor"
)
RFCB
(
int
seed
)
throws
Throwable
{
this
.
random
=
new
java
.
util
.
Random
(
seed
);
this
.
fns
=
new
MethodHandle
[
Math
.
max
(
29
,
(
1
<<
MAX_DEPTH
-
2
)/
3
)];
...
...
@@ -408,7 +408,7 @@ public class RicochetTest {
case
1
:
Throwable
ex
=
new
RuntimeException
();
ex
.
fillInStackTrace
();
if
(
VERBOSITY
>=
2
)
ex
.
printStackTrace
();
if
(
VERBOSITY
>=
2
)
ex
.
printStackTrace
(
System
.
out
);
x
=
"ST; "
+
x
;
break
;
case
2
:
...
...
@@ -467,7 +467,7 @@ public class RicochetTest {
return
mh
.
invokeWithArguments
(
args
);
}
catch
(
Throwable
ex
)
{
System
.
out
.
println
(
"threw: "
+
mh
+
Arrays
.
asList
(
args
));
ex
.
printStackTrace
();
ex
.
printStackTrace
(
System
.
out
);
return
ex
;
}
}
...
...
@@ -515,8 +515,8 @@ public class RicochetTest {
private
static
long
opJ
(
long
x
)
{
return
(
long
)
opI
((
int
)
x
);
}
private
static
Object
opL2
(
Object
x
,
Object
y
)
{
return
(
Object
)
opI2
((
int
)
x
,
(
int
)
y
);
}
private
static
Object
opL
(
Object
x
)
{
return
(
Object
)
opI
((
int
)
x
);
}
private
static
int
opL2_I
(
Object
x
,
Object
y
)
{
return
(
int
)
opI2
((
int
)
x
,
(
int
)
y
);
}
private
static
int
opL_I
(
Object
x
)
{
return
(
int
)
opI
((
int
)
x
);
}
private
static
int
opL2_I
(
Object
x
,
Object
y
)
{
return
opI2
((
int
)
x
,
(
int
)
y
);
}
private
static
int
opL_I
(
Object
x
)
{
return
opI
((
int
)
x
);
}
private
static
long
opL_J
(
Object
x
)
{
return
(
long
)
opI
((
int
)
x
);
}
private
static
final
MethodHandle
opI
,
opI2
,
opI3
,
opI4
,
opI_L
,
opJ
,
opJ2
,
opJ3
,
opL2
,
opL
,
opL2_I
,
opL_I
,
opL_J
;
static
{
...
...
@@ -570,8 +570,8 @@ public class RicochetTest {
INT_LISTERS
[
i
]
=
lister
;
LONG_LISTERS
[
i
]
=
llister
;
if
(
i
==
0
)
break
;
lister
=
insertArguments
(
lister
,
i
-
1
,
(
int
)
0
);
llister
=
insertArguments
(
llister
,
i
-
1
,
(
long
)
0
);
lister
=
insertArguments
(
lister
,
i
-
1
,
0
);
llister
=
insertArguments
(
llister
,
i
-
1
,
0L
);
}
}
...
...
test/java/lang/invoke/ThrowExceptionsTest.java
浏览文件 @
7118adb7
...
...
@@ -40,7 +40,7 @@ import static java.lang.invoke.MethodHandles.*;
import
static
java
.
lang
.
invoke
.
MethodType
.*;
public
class
ThrowExceptionsTest
{
private
static
final
Class
CLASS
=
ThrowExceptionsTest
.
class
;
private
static
final
Class
<?>
CLASS
=
ThrowExceptionsTest
.
class
;
private
static
final
Lookup
LOOKUP
=
lookup
();
public
static
void
main
(
String
argv
[])
throws
Throwable
{
...
...
@@ -132,9 +132,9 @@ public class ThrowExceptionsTest {
int
tc
=
testCases
;
try
{
m
.
invoke
(
this
);
}
catch
(
Throwable
ex
)
{
}
catch
(
IllegalAccessException
|
IllegalArgumentException
|
InvocationTargetException
ex
)
{
System
.
out
.
println
(
"*** "
+
ex
);
ex
.
printStackTrace
();
ex
.
printStackTrace
(
System
.
out
);
}
if
(
testCases
==
tc
)
testCases
++;
}
...
...
test/sun/invoke/util/ValueConversionsTest.java
浏览文件 @
7118adb7
...
...
@@ -27,11 +27,9 @@ import sun.invoke.util.ValueConversions;
import
sun.invoke.util.Wrapper
;
import
java.lang.invoke.MethodType
;
import
java.lang.invoke.MethodHandle
;
import
java.lang.invoke.MethodHandles
;
import
java.io.Serializable
;
import
java.util.Arrays
;
import
java.util.Collections
;
import
org.junit.Ignore
;
import
org.junit.Test
;
import
static
org
.
junit
.
Assert
.*;
...
...
@@ -52,7 +50,7 @@ import static org.junit.Assert.*;
* @author jrose
*/
public
class
ValueConversionsTest
{
private
static
final
Class
CLASS
=
ValueConversionsTest
.
class
;
private
static
final
Class
<?>
CLASS
=
ValueConversionsTest
.
class
;
private
static
final
int
MAX_ARITY
=
Integer
.
getInteger
(
CLASS
.
getSimpleName
()+
".MAX_ARITY"
,
40
);
private
static
final
int
START_ARITY
=
Integer
.
getInteger
(
CLASS
.
getSimpleName
()+
".START_ARITY"
,
0
);
private
static
final
boolean
EXHAUSTIVE
=
Boolean
.
getBoolean
(
CLASS
.
getSimpleName
()+
".EXHAUSTIVE"
);
...
...
@@ -165,7 +163,7 @@ public class ValueConversionsTest {
Object
expResult
=
box
;
Object
result
=
null
;
switch
(
w
)
{
case
INT:
result
=
boxer
.
invokeExact
(
(
int
)
n
);
break
;
case
INT:
result
=
boxer
.
invokeExact
(
/*int*/
n
);
break
;
case
LONG:
result
=
boxer
.
invokeExact
((
long
)
n
);
break
;
case
FLOAT:
result
=
boxer
.
invokeExact
((
float
)
n
);
break
;
case
DOUBLE:
result
=
boxer
.
invokeExact
((
double
)
n
);
break
;
...
...
@@ -361,6 +359,7 @@ public class ValueConversionsTest {
assert
(
stype
==
MethodType
.
methodType
(
arrayType
,
arrayType
));
if
(
nargs
<=
5
)
{
// invoke target as a spreader also:
@SuppressWarnings
(
"cast"
)
Object
res2
=
spreader
.
invokeWithArguments
((
Object
)
res
);
String
res2String
=
toArrayString
(
res2
);
assertEquals
(
Arrays
.
toString
(
args
),
res2String
);
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录