Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
dragonwell8_jdk
提交
a7fbe030
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看板
提交
a7fbe030
编写于
5月 24, 2011
作者:
T
trims
浏览文件
操作
浏览文件
下载
差异文件
Merge
上级
80977770
0431323c
变更
18
隐藏空白更改
内联
并排
Showing
18 changed file
with
259 addition
and
87 deletion
+259
-87
src/share/classes/java/lang/invoke/AdapterMethodHandle.java
src/share/classes/java/lang/invoke/AdapterMethodHandle.java
+28
-7
src/share/classes/java/lang/invoke/BoundMethodHandle.java
src/share/classes/java/lang/invoke/BoundMethodHandle.java
+1
-1
src/share/classes/java/lang/invoke/FilterGeneric.java
src/share/classes/java/lang/invoke/FilterGeneric.java
+1
-1
src/share/classes/java/lang/invoke/FilterOneArgument.java
src/share/classes/java/lang/invoke/FilterOneArgument.java
+1
-1
src/share/classes/java/lang/invoke/FromGeneric.java
src/share/classes/java/lang/invoke/FromGeneric.java
+1
-1
src/share/classes/java/lang/invoke/InvokeGeneric.java
src/share/classes/java/lang/invoke/InvokeGeneric.java
+6
-9
src/share/classes/java/lang/invoke/MethodHandle.java
src/share/classes/java/lang/invoke/MethodHandle.java
+51
-11
src/share/classes/java/lang/invoke/MethodHandleImpl.java
src/share/classes/java/lang/invoke/MethodHandleImpl.java
+88
-21
src/share/classes/java/lang/invoke/MethodHandleStatics.java
src/share/classes/java/lang/invoke/MethodHandleStatics.java
+2
-0
src/share/classes/java/lang/invoke/MethodHandles.java
src/share/classes/java/lang/invoke/MethodHandles.java
+6
-7
src/share/classes/java/lang/invoke/MethodType.java
src/share/classes/java/lang/invoke/MethodType.java
+17
-5
src/share/classes/java/lang/invoke/MethodTypeForm.java
src/share/classes/java/lang/invoke/MethodTypeForm.java
+2
-0
src/share/classes/java/lang/invoke/SpreadGeneric.java
src/share/classes/java/lang/invoke/SpreadGeneric.java
+2
-2
src/share/classes/java/lang/invoke/ToGeneric.java
src/share/classes/java/lang/invoke/ToGeneric.java
+2
-2
src/share/classes/sun/invoke/util/Wrapper.java
src/share/classes/sun/invoke/util/Wrapper.java
+1
-3
test/java/lang/invoke/6991596/Test6991596.java
test/java/lang/invoke/6991596/Test6991596.java
+2
-2
test/java/lang/invoke/InvokeGenericTest.java
test/java/lang/invoke/InvokeGenericTest.java
+40
-13
test/java/lang/invoke/MethodHandlesTest.java
test/java/lang/invoke/MethodHandlesTest.java
+8
-1
未找到文件。
src/share/classes/java/lang/invoke/AdapterMethodHandle.java
浏览文件 @
a7fbe030
...
...
@@ -141,7 +141,7 @@ class AdapterMethodHandle extends BoundMethodHandle {
while
(
lastConv
>=
0
)
{
Class
<?>
src
=
newType
.
parameterType
(
lastConv
);
// source type
Class
<?>
dst
=
oldType
.
parameterType
(
lastConv
);
// destination type
if
(
VerifyType
.
isNullConversion
(
src
,
dst
))
{
if
(
isTrivialConversion
(
src
,
dst
,
level
))
{
--
lastConv
;
}
else
{
break
;
...
...
@@ -150,7 +150,7 @@ class AdapterMethodHandle extends BoundMethodHandle {
Class
<?>
needReturn
=
newType
.
returnType
();
Class
<?>
haveReturn
=
oldType
.
returnType
();
boolean
retConv
=
!
VerifyType
.
isNullConversion
(
haveReturn
,
needReturn
);
boolean
retConv
=
!
isTrivialConversion
(
haveReturn
,
needReturn
,
level
);
// Now build a chain of one or more adapters.
MethodHandle
adapter
=
target
,
adapter2
;
...
...
@@ -158,7 +158,7 @@ class AdapterMethodHandle extends BoundMethodHandle {
for
(
int
i
=
0
;
i
<=
lastConv
;
i
++)
{
Class
<?>
src
=
newType
.
parameterType
(
i
);
// source type
Class
<?>
dst
=
midType
.
parameterType
(
i
);
// destination type
if
(
VerifyType
.
isNullConversion
(
src
,
dst
))
{
if
(
isTrivialConversion
(
src
,
dst
,
level
))
{
// do nothing: difference is trivial
continue
;
}
...
...
@@ -219,6 +219,22 @@ class AdapterMethodHandle extends BoundMethodHandle {
return
adapter
;
}
private
static
boolean
isTrivialConversion
(
Class
<?>
src
,
Class
<?>
dst
,
int
level
)
{
if
(
src
==
dst
||
dst
==
void
.
class
)
return
true
;
if
(!
VerifyType
.
isNullConversion
(
src
,
dst
))
return
false
;
if
(
level
>
1
)
return
true
;
// explicitCastArguments
boolean
sp
=
src
.
isPrimitive
();
boolean
dp
=
dst
.
isPrimitive
();
if
(
sp
!=
dp
)
return
false
;
if
(
sp
)
{
// in addition to being a null conversion, forbid boolean->int etc.
return
Wrapper
.
forPrimitiveType
(
dst
)
.
isConvertibleFrom
(
Wrapper
.
forPrimitiveType
(
src
));
}
else
{
return
dst
.
isAssignableFrom
(
src
);
}
}
private
static
MethodHandle
makeReturnConversion
(
MethodHandle
target
,
Class
<?>
haveReturn
,
Class
<?>
needReturn
)
{
MethodHandle
adjustReturn
;
if
(
haveReturn
==
void
.
class
)
{
...
...
@@ -530,6 +546,10 @@ class AdapterMethodHandle extends BoundMethodHandle {
}
static
MethodHandle
makeVarargsCollector
(
MethodHandle
target
,
Class
<?>
arrayType
)
{
MethodType
type
=
target
.
type
();
int
last
=
type
.
parameterCount
()
-
1
;
if
(
type
.
parameterType
(
last
)
!=
arrayType
)
target
=
target
.
asType
(
type
.
changeParameterType
(
last
,
arrayType
));
return
new
AsVarargsCollector
(
target
,
arrayType
);
}
...
...
@@ -596,7 +616,7 @@ class AdapterMethodHandle extends BoundMethodHandle {
||
!
VerifyType
.
isNullConversion
(
castType
,
dst
))
return
false
;
int
diff
=
diffTypes
(
newType
,
targetType
,
false
);
return
(
diff
==
arg
+
1
);
// arg is sole non-trivial diff
return
(
diff
==
arg
+
1
)
||
(
diff
==
0
)
;
// arg is sole non-trivial diff
}
/** Can an primitive conversion adapter validly convert src to dst? */
static
boolean
canCheckCast
(
Class
<?>
src
,
Class
<?>
dst
)
{
...
...
@@ -1033,8 +1053,9 @@ class AdapterMethodHandle extends BoundMethodHandle {
Class
<?>
spreadArgType
,
int
spreadArgPos
,
int
spreadArgCount
)
{
// FIXME: Get rid of newType; derive new arguments from structure of spreadArgType
MethodType
targetType
=
target
.
type
();
if
(!
canSpreadArguments
(
newType
,
targetType
,
spreadArgType
,
spreadArgPos
,
spreadArgCount
))
return
null
;
assert
(
canSpreadArguments
(
newType
,
targetType
,
spreadArgType
,
spreadArgPos
,
spreadArgCount
))
:
"[newType, targetType, spreadArgType, spreadArgPos, spreadArgCount] = "
+
Arrays
.
asList
(
newType
,
targetType
,
spreadArgType
,
spreadArgPos
,
spreadArgCount
);
// dest is not significant; remove?
int
dest
=
T_VOID
;
for
(
int
i
=
0
;
i
<
spreadArgCount
;
i
++)
{
...
...
@@ -1127,7 +1148,7 @@ class AdapterMethodHandle extends BoundMethodHandle {
}
@Override
public
String
to
String
()
{
String
debug
String
()
{
return
getNameString
(
nonAdapter
((
MethodHandle
)
vmtarget
),
this
);
}
...
...
src/share/classes/java/lang/invoke/BoundMethodHandle.java
浏览文件 @
a7fbe030
...
...
@@ -155,7 +155,7 @@ class BoundMethodHandle extends MethodHandle {
}
@Override
public
String
to
String
()
{
String
debug
String
()
{
return
addTypeString
(
baseName
(),
this
);
}
...
...
src/share/classes/java/lang/invoke/FilterGeneric.java
浏览文件 @
a7fbe030
...
...
@@ -234,7 +234,7 @@ class FilterGeneric {
protected
final
MethodHandle
target
;
// ultimate target
@Override
public
String
to
String
()
{
String
debug
String
()
{
return
addTypeString
(
target
,
this
);
}
...
...
src/share/classes/java/lang/invoke/FilterOneArgument.java
浏览文件 @
a7fbe030
...
...
@@ -41,7 +41,7 @@ class FilterOneArgument extends BoundMethodHandle {
protected
final
MethodHandle
target
;
// Object -> Object
@Override
public
String
to
String
()
{
String
debug
String
()
{
return
target
.
toString
();
}
...
...
src/share/classes/java/lang/invoke/FromGeneric.java
浏览文件 @
a7fbe030
...
...
@@ -260,7 +260,7 @@ class FromGeneric {
protected
final
MethodHandle
target
;
// (any**N) => R
@Override
public
String
to
String
()
{
String
debug
String
()
{
return
addTypeString
(
target
,
this
);
}
...
...
src/share/classes/java/lang/invoke/InvokeGeneric.java
浏览文件 @
a7fbe030
...
...
@@ -129,20 +129,17 @@ class InvokeGeneric {
if
(
needType
==
erasedCallerType
.
returnType
())
return
false
;
// no conversions possible, since must be primitive or Object
Class
<?>
haveType
=
target
.
type
().
returnType
();
if
(
VerifyType
.
isNullConversion
(
haveType
,
needType
))
if
(
VerifyType
.
isNullConversion
(
haveType
,
needType
)
&&
!
needType
.
isInterface
()
)
return
false
;
return
true
;
}
private
MethodHandle
addReturnConversion
(
MethodHandle
target
,
Class
<?>
type
)
{
if
(
true
)
throw
new
RuntimeException
(
"NYI"
);
private
MethodHandle
addReturnConversion
(
MethodHandle
finisher
,
Class
<?>
type
)
{
// FIXME: This is slow because it creates a closure node on every call that requires a return cast.
MethodType
targetType
=
target
.
type
();
MethodType
finisherType
=
finisher
.
type
();
MethodHandle
caster
=
ValueConversions
.
identity
(
type
);
caster
=
caster
.
asType
(
MethodType
.
methodType
(
type
,
targetType
.
returnType
()));
// Drop irrelevant arguments, because we only care about the return value:
caster
=
MethodHandles
.
dropArguments
(
caster
,
1
,
targetType
.
parameterList
());
MethodHandle
result
=
MethodHandles
.
foldArguments
(
caster
,
target
);
return
result
.
asType
(
target
.
type
());
caster
=
caster
.
asType
(
caster
.
type
().
changeParameterType
(
0
,
finisherType
.
returnType
()));
finisher
=
MethodHandles
.
filterReturnValue
(
finisher
,
caster
);
return
finisher
.
asType
(
finisherType
);
}
public
String
toString
()
{
...
...
src/share/classes/java/lang/invoke/MethodHandle.java
浏览文件 @
a7fbe030
...
...
@@ -26,6 +26,7 @@
package
java.lang.invoke
;
import
java.util.ArrayList
;
import
sun.invoke.util.ValueConversions
;
import
static
java
.
lang
.
invoke
.
MethodHandleStatics
.*;
...
...
@@ -708,9 +709,9 @@ public abstract class MethodHandle {
*/
public
MethodHandle
asType
(
MethodType
newType
)
{
if
(!
type
.
isConvertibleTo
(
newType
))
{
throw
new
WrongMethodTypeException
(
"cannot convert "
+
t
ype
+
" to "
+
newType
);
throw
new
WrongMethodTypeException
(
"cannot convert "
+
t
his
+
" to "
+
newType
);
}
return
MethodHandle
s
.
convertArguments
(
this
,
newType
);
return
MethodHandle
Impl
.
convertArguments
(
this
,
newType
,
1
);
}
/**
...
...
@@ -750,11 +751,46 @@ public abstract class MethodHandle {
* @see #asCollector
*/
public
MethodHandle
asSpreader
(
Class
<?>
arrayType
,
int
arrayLength
)
{
Class
<?>
arrayElement
=
arrayType
.
getComponentType
();
if
(
arrayElement
==
null
)
throw
newIllegalArgumentException
(
"not an array type"
);
asSpreaderChecks
(
arrayType
,
arrayLength
);
return
MethodHandleImpl
.
spreadArguments
(
this
,
arrayType
,
arrayLength
);
}
private
void
asSpreaderChecks
(
Class
<?>
arrayType
,
int
arrayLength
)
{
spreadArrayChecks
(
arrayType
,
arrayLength
);
int
nargs
=
type
().
parameterCount
();
if
(
nargs
<
arrayLength
)
throw
newIllegalArgumentException
(
"bad spread array length"
);
return
MethodHandleImpl
.
spreadArguments
(
this
,
arrayType
,
arrayLength
);
if
(
arrayType
!=
Object
[].
class
&&
arrayLength
!=
0
)
{
boolean
sawProblem
=
false
;
Class
<?>
arrayElement
=
arrayType
.
getComponentType
();
for
(
int
i
=
nargs
-
arrayLength
;
i
<
nargs
;
i
++)
{
if
(!
MethodType
.
canConvert
(
arrayElement
,
type
().
parameterType
(
i
)))
{
sawProblem
=
true
;
break
;
}
}
if
(
sawProblem
)
{
ArrayList
<
Class
<?>>
ptypes
=
new
ArrayList
<
Class
<?>>(
type
().
parameterList
());
for
(
int
i
=
nargs
-
arrayLength
;
i
<
nargs
;
i
++)
{
ptypes
.
set
(
i
,
arrayElement
);
}
// elicit an error:
this
.
asType
(
MethodType
.
methodType
(
type
().
returnType
(),
ptypes
));
}
}
}
private
void
spreadArrayChecks
(
Class
<?>
arrayType
,
int
arrayLength
)
{
Class
<?>
arrayElement
=
arrayType
.
getComponentType
();
if
(
arrayElement
==
null
)
throw
newIllegalArgumentException
(
"not an array type"
,
arrayType
);
if
((
arrayLength
&
0x7F
)
!=
arrayLength
)
{
if
((
arrayLength
&
0xFF
)
!=
arrayLength
)
throw
newIllegalArgumentException
(
"array length is not legal"
,
arrayLength
);
assert
(
arrayLength
>=
128
);
if
(
arrayElement
==
long
.
class
||
arrayElement
==
double
.
class
)
throw
newIllegalArgumentException
(
"array length is not legal for long[] or double[]"
,
arrayLength
);
}
}
/**
...
...
@@ -802,10 +838,8 @@ public abstract class MethodHandle {
return
MethodHandleImpl
.
collectArguments
(
this
,
type
.
parameterCount
()-
1
,
collector
);
}
private
void
asCollectorChecks
(
Class
<?>
arrayType
,
int
arrayLength
)
{
Class
<?>
arrayElement
=
arrayType
.
getComponentType
();
if
(
arrayElement
==
null
)
throw
newIllegalArgumentException
(
"not an array type"
,
arrayType
);
private
void
asCollectorChecks
(
Class
<?>
arrayType
,
int
arrayLength
)
{
spreadArrayChecks
(
arrayType
,
arrayLength
);
int
nargs
=
type
().
parameterCount
();
if
(
nargs
==
0
||
!
type
().
parameterType
(
nargs
-
1
).
isAssignableFrom
(
arrayType
))
throw
newIllegalArgumentException
(
"array type not assignable to trailing argument"
,
this
,
arrayType
);
...
...
@@ -965,8 +999,8 @@ assert(failed);
*/
public
MethodHandle
asVarargsCollector
(
Class
<?>
arrayType
)
{
Class
<?>
arrayElement
=
arrayType
.
getComponentType
();
if
(
arrayElement
==
null
)
throw
newIllegalArgumentException
(
"not an array type"
);
return
MethodHandles
.
as
VarargsCollector
(
this
,
arrayType
);
asCollectorChecks
(
arrayType
,
0
);
return
AdapterMethodHandle
.
make
VarargsCollector
(
this
,
arrayType
);
}
/**
...
...
@@ -1043,6 +1077,12 @@ assert(failed);
*/
@Override
public
String
toString
()
{
if
(
DEBUG_METHOD_HANDLE_NAMES
)
return
debugString
();
return
"MethodHandle"
+
type
;
}
/*non-public*/
String
debugString
()
{
return
getNameString
(
this
);
}
}
src/share/classes/java/lang/invoke/MethodHandleImpl.java
浏览文件 @
a7fbe030
...
...
@@ -93,9 +93,28 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
static
MethodHandle
makeAllocator
(
MethodHandle
rawConstructor
)
{
MethodType
rawConType
=
rawConstructor
.
type
();
Class
<?>
allocateClass
=
rawConType
.
parameterType
(
0
);
// Wrap the raw (unsafe) constructor with the allocation of a suitable object.
if
(
AdapterMethodHandle
.
canCollectArguments
(
rawConType
,
MethodType
.
methodType
(
allocateClass
),
0
,
true
))
{
// allocator(arg...)
// [fold]=> cookedConstructor(obj=allocate(C), arg...)
// [dup,collect]=> identity(obj, void=rawConstructor(obj, arg...))
MethodHandle
returner
=
MethodHandles
.
identity
(
allocateClass
);
MethodType
ctype
=
rawConType
.
insertParameterTypes
(
0
,
allocateClass
).
changeReturnType
(
allocateClass
);
MethodHandle
cookedConstructor
=
AdapterMethodHandle
.
makeCollectArguments
(
returner
,
rawConstructor
,
1
,
false
);
assert
(
cookedConstructor
.
type
().
equals
(
ctype
));
ctype
=
ctype
.
dropParameterTypes
(
0
,
1
);
cookedConstructor
=
AdapterMethodHandle
.
makeCollectArguments
(
cookedConstructor
,
returner
,
0
,
true
);
MethodHandle
allocator
=
new
AllocateObject
(
allocateClass
);
// allocate() => new C(void)
assert
(
allocator
.
type
().
equals
(
MethodType
.
methodType
(
allocateClass
)));
ctype
=
ctype
.
dropParameterTypes
(
0
,
1
);
MethodHandle
fold
=
foldArguments
(
cookedConstructor
,
ctype
,
0
,
allocator
);
return
fold
;
}
assert
(
MethodHandleNatives
.
workaroundWithoutRicochetFrames
());
// this code is deprecated
MethodHandle
allocator
=
AllocateObject
.
make
(
rawConType
.
parameterType
(
0
)
,
rawConstructor
);
=
AllocateObject
.
make
(
allocateClass
,
rawConstructor
);
assert
(
allocator
.
type
()
.
equals
(
rawConType
.
dropParameterTypes
(
0
,
1
).
changeReturnType
(
rawConType
.
parameterType
(
0
))));
return
allocator
;
...
...
@@ -112,8 +131,16 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
super
(
invoker
);
this
.
allocateClass
=
allocateClass
;
this
.
rawConstructor
=
rawConstructor
;
assert
(
MethodHandleNatives
.
workaroundWithoutRicochetFrames
());
// this code is deprecated
}
// for allocation only:
private
AllocateObject
(
Class
<
C
>
allocateClass
)
{
super
(
ALLOCATE
.
asType
(
MethodType
.
methodType
(
allocateClass
,
AllocateObject
.
class
)));
this
.
allocateClass
=
allocateClass
;
this
.
rawConstructor
=
null
;
}
static
MethodHandle
make
(
Class
<?>
allocateClass
,
MethodHandle
rawConstructor
)
{
assert
(
MethodHandleNatives
.
workaroundWithoutRicochetFrames
());
// this code is deprecated
MethodType
rawConType
=
rawConstructor
.
type
();
assert
(
rawConType
.
parameterType
(
0
)
==
allocateClass
);
MethodType
newType
=
rawConType
.
dropParameterTypes
(
0
,
1
).
changeReturnType
(
allocateClass
);
...
...
@@ -129,14 +156,14 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
}
else
{
MethodHandle
invoke
=
VARARGS_INVOKE
;
MethodType
conType
=
CON_TYPES
[
nargs
];
MethodHandle
gcon
=
spreadArguments
(
rawConstructor
,
conType
,
1
);
MethodHandle
gcon
=
spreadArguments
FromPos
(
rawConstructor
,
conType
,
1
);
if
(
gcon
==
null
)
return
null
;
MethodHandle
galloc
=
new
AllocateObject
(
invoke
,
allocateClass
,
gcon
);
return
collectArguments
(
galloc
,
newType
,
1
,
null
);
}
}
@Override
public
String
to
String
()
{
String
debug
String
()
{
return
addTypeString
(
allocateClass
.
getSimpleName
(),
this
);
}
@SuppressWarnings
(
"unchecked"
)
...
...
@@ -214,9 +241,11 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
// For testing use this:
//static final MethodHandle[] INVOKES = Arrays.copyOf(makeInvokes(), 2);
static
final
MethodHandle
VARARGS_INVOKE
;
static
final
MethodHandle
ALLOCATE
;
static
{
try
{
VARARGS_INVOKE
=
IMPL_LOOKUP
.
findVirtual
(
AllocateObject
.
class
,
"invoke_V"
,
MethodType
.
genericMethodType
(
0
,
true
));
ALLOCATE
=
IMPL_LOOKUP
.
findVirtual
(
AllocateObject
.
class
,
"allocate"
,
MethodType
.
genericMethodType
(
0
));
}
catch
(
ReflectiveOperationException
ex
)
{
throw
uncaughtException
(
ex
);
}
...
...
@@ -278,7 +307,7 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
this
.
base
=
staticBase
(
field
);
}
@Override
public
String
to
String
()
{
return
addTypeString
(
name
,
this
);
}
String
debug
String
()
{
return
addTypeString
(
name
,
this
);
}
int
getFieldI
(
C
obj
)
{
return
unsafe
.
getInt
(
obj
,
offset
);
}
void
setFieldI
(
C
obj
,
int
x
)
{
unsafe
.
putInt
(
obj
,
offset
,
x
);
}
...
...
@@ -309,8 +338,9 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
try
{
// FIXME: Should not have to create 'f' to get this value.
f
=
c
.
getDeclaredField
(
field
.
getName
());
// Note: Previous line might invalidly throw SecurityException (7042829)
return
unsafe
.
staticFieldBase
(
f
);
}
catch
(
Exception
ee
)
{
}
catch
(
NoSuchField
Exception
ee
)
{
throw
uncaughtException
(
ee
);
}
}
...
...
@@ -747,7 +777,7 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
.
insertParameterTypes
(
keepPosArgs
,
arrayType
);
return
spreadArguments
(
target
,
newType
,
keepPosArgs
,
arrayType
,
arrayLength
);
}
static
MethodHandle
spreadArguments
(
MethodHandle
target
,
MethodType
newType
,
int
spreadArgPos
)
{
static
MethodHandle
spreadArguments
FromPos
(
MethodHandle
target
,
MethodType
newType
,
int
spreadArgPos
)
{
int
arrayLength
=
target
.
type
().
parameterCount
()
-
spreadArgPos
;
return
spreadArguments
(
target
,
newType
,
spreadArgPos
,
Object
[].
class
,
arrayLength
);
}
...
...
@@ -761,9 +791,7 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
// spread the last argument of newType to oldType
assert
(
arrayLength
==
oldType
.
parameterCount
()
-
spreadArgPos
);
assert
(
newType
.
parameterType
(
spreadArgPos
)
==
arrayType
);
MethodHandle
res
=
AdapterMethodHandle
.
makeSpreadArguments
(
newType
,
target
,
arrayType
,
spreadArgPos
,
arrayLength
);
if
(
res
==
null
)
throw
new
IllegalArgumentException
(
"spread on "
+
target
+
" with "
+
arrayType
.
getSimpleName
());
return
res
;
return
AdapterMethodHandle
.
makeSpreadArguments
(
newType
,
target
,
arrayType
,
spreadArgPos
,
arrayLength
);
}
static
MethodHandle
collectArguments
(
MethodHandle
target
,
...
...
@@ -771,6 +799,7 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
MethodHandle
collector
)
{
MethodType
type
=
target
.
type
();
Class
<?>
collectType
=
collector
.
type
().
returnType
();
assert
(
collectType
!=
void
.
class
);
// else use foldArguments
if
(
collectType
!=
type
.
parameterType
(
collectArg
))
target
=
target
.
asType
(
type
.
changeParameterType
(
collectArg
,
collectType
));
MethodType
newType
=
type
...
...
@@ -878,9 +907,11 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
this
.
test
=
test
;
this
.
target
=
target
;
this
.
fallback
=
fallback
;
assert
(
MethodHandleNatives
.
workaroundWithoutRicochetFrames
());
// this code is deprecated
}
// FIXME: Build the control flow out of foldArguments.
static
MethodHandle
make
(
MethodHandle
test
,
MethodHandle
target
,
MethodHandle
fallback
)
{
assert
(
MethodHandleNatives
.
workaroundWithoutRicochetFrames
());
// this code is deprecated
MethodType
type
=
target
.
type
();
int
nargs
=
type
.
parameterCount
();
if
(
nargs
<
INVOKES
.
length
)
{
...
...
@@ -897,16 +928,16 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
MethodHandle
invoke
=
VARARGS_INVOKE
;
MethodType
gtype
=
MethodType
.
genericMethodType
(
1
);
assert
(
invoke
.
type
().
dropParameterTypes
(
0
,
1
)
==
gtype
);
MethodHandle
gtest
=
spreadArguments
(
test
,
gtype
.
changeReturnType
(
boolean
.
class
),
0
);
MethodHandle
gtarget
=
spreadArguments
(
target
,
gtype
,
0
);
MethodHandle
gfallback
=
spreadArguments
(
fallback
,
gtype
,
0
);
MethodHandle
gtest
=
spreadArguments
FromPos
(
test
,
gtype
.
changeReturnType
(
boolean
.
class
),
0
);
MethodHandle
gtarget
=
spreadArguments
FromPos
(
target
,
gtype
,
0
);
MethodHandle
gfallback
=
spreadArguments
FromPos
(
fallback
,
gtype
,
0
);
MethodHandle
gguard
=
new
GuardWithTest
(
invoke
,
gtest
,
gtarget
,
gfallback
);
if
(
gtest
==
null
||
gtarget
==
null
||
gfallback
==
null
)
return
null
;
return
collectArguments
(
gguard
,
type
,
0
,
null
);
}
}
@Override
public
String
to
String
()
{
String
debug
String
()
{
return
addTypeString
(
target
,
this
);
}
private
Object
invoke_V
(
Object
...
av
)
throws
Throwable
{
...
...
@@ -989,10 +1020,49 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
}
}
static
MethodHandle
selectAlternative
(
boolean
testResult
,
MethodHandle
target
,
MethodHandle
fallback
)
{
return
testResult
?
target
:
fallback
;
}
static
MethodHandle
SELECT_ALTERNATIVE
;
static
MethodHandle
selectAlternative
()
{
if
(
SELECT_ALTERNATIVE
!=
null
)
return
SELECT_ALTERNATIVE
;
try
{
SELECT_ALTERNATIVE
=
IMPL_LOOKUP
.
findStatic
(
MethodHandleImpl
.
class
,
"selectAlternative"
,
MethodType
.
methodType
(
MethodHandle
.
class
,
boolean
.
class
,
MethodHandle
.
class
,
MethodHandle
.
class
));
}
catch
(
ReflectiveOperationException
ex
)
{
throw
new
RuntimeException
(
ex
);
}
return
SELECT_ALTERNATIVE
;
}
static
MethodHandle
makeGuardWithTest
(
MethodHandle
test
,
MethodHandle
target
,
MethodHandle
fallback
)
{
// gwt(arg...)
// [fold]=> continueAfterTest(z=test(arg...), arg...)
// [filter]=> (tf=select(z))(arg...)
// where select(z) = select(z, t, f).bindTo(t, f) => z ? t f
// [tailcall]=> tf(arg...)
assert
(
test
.
type
().
returnType
()
==
boolean
.
class
);
MethodType
foldTargetType
=
target
.
type
().
insertParameterTypes
(
0
,
boolean
.
class
);
if
(
AdapterMethodHandle
.
canCollectArguments
(
foldTargetType
,
test
.
type
(),
0
,
true
))
{
// working backwards, as usual:
assert
(
target
.
type
().
equals
(
fallback
.
type
()));
MethodHandle
tailcall
=
MethodHandles
.
exactInvoker
(
target
.
type
());
MethodHandle
select
=
selectAlternative
();
select
=
bindArgument
(
select
,
2
,
fallback
);
select
=
bindArgument
(
select
,
1
,
target
);
// select(z: boolean) => (z ? target : fallback)
MethodHandle
filter
=
filterArgument
(
tailcall
,
0
,
select
);
assert
(
filter
.
type
().
parameterType
(
0
)
==
boolean
.
class
);
MethodHandle
fold
=
foldArguments
(
filter
,
filter
.
type
().
dropParameterTypes
(
0
,
1
),
0
,
test
);
return
fold
;
}
assert
(
MethodHandleNatives
.
workaroundWithoutRicochetFrames
());
// this code is deprecated
return
GuardWithTest
.
make
(
test
,
target
,
fallback
);
}
...
...
@@ -1012,7 +1082,7 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
this
.
catcher
=
catcher
;
}
@Override
public
String
to
String
()
{
String
debug
String
()
{
return
addTypeString
(
target
,
this
);
}
private
Object
invoke_V
(
Object
...
av
)
throws
Throwable
{
...
...
@@ -1144,11 +1214,12 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
}
else
{
MethodType
gtype
=
MethodType
.
genericMethodType
(
0
,
true
);
MethodType
gcatchType
=
gtype
.
insertParameterTypes
(
0
,
Throwable
.
class
);
MethodHandle
gtarget
=
spreadArguments
(
target
,
gtype
,
0
);
MethodHandle
gcatcher
=
spreadArguments
(
catcher
,
gcatchType
,
1
);
MethodHandle
gtarget
=
spreadArgumentsFromPos
(
target
,
gtype
,
0
);
catcher
=
catcher
.
asType
(
ctype
.
changeParameterType
(
0
,
Throwable
.
class
));
MethodHandle
gcatcher
=
spreadArgumentsFromPos
(
catcher
,
gcatchType
,
1
);
MethodHandle
gguard
=
new
GuardWithCatch
(
GuardWithCatch
.
VARARGS_INVOKE
,
gtarget
,
exType
,
gcatcher
);
if
(
gtarget
==
null
||
gcatcher
==
null
||
gguard
==
null
)
return
null
;
return
collectArguments
(
gguard
,
type
,
0
,
null
);
return
collectArguments
(
gguard
,
type
,
0
,
ValueConversions
.
varargsArray
(
nargs
)).
asType
(
type
);
}
}
...
...
@@ -1178,8 +1249,4 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
static
MethodHandle
getBootstrap
(
Class
<?>
callerClass
)
{
return
MethodHandleNatives
.
getBootstrap
(
callerClass
);
}
static
MethodHandle
asVarargsCollector
(
MethodHandle
target
,
Class
<?>
arrayType
)
{
return
AdapterMethodHandle
.
makeVarargsCollector
(
target
,
arrayType
);
}
}
src/share/classes/java/lang/invoke/MethodHandleStatics.java
浏览文件 @
a7fbe030
...
...
@@ -35,6 +35,8 @@ package java.lang.invoke;
private
MethodHandleStatics
()
{
}
// do not instantiate
static
final
boolean
DEBUG_METHOD_HANDLE_NAMES
=
Boolean
.
getBoolean
(
"java.lang.invoke.MethodHandle.DEBUG_NAMES"
);
/*non-public*/
static
String
getNameString
(
MethodHandle
target
,
MethodType
type
)
{
if
(
type
==
null
)
type
=
target
.
type
();
...
...
src/share/classes/java/lang/invoke/MethodHandles.java
浏览文件 @
a7fbe030
...
...
@@ -1065,6 +1065,7 @@ return mh1;
if
(!
method
.
isProtected
()
||
method
.
isStatic
()
||
allowedModes
==
TRUSTED
||
method
.
getDeclaringClass
()
==
lookupClass
()
||
VerifyAccess
.
isSamePackage
(
method
.
getDeclaringClass
(),
lookupClass
())
||
(
ALLOW_NESTMATE_ACCESS
&&
VerifyAccess
.
isSamePackageMember
(
method
.
getDeclaringClass
(),
lookupClass
())))
return
mh
;
...
...
@@ -1377,6 +1378,9 @@ publicLookup().findVirtual(MethodHandle.class, "invoke", type)
*/
public
static
MethodHandle
convertArguments
(
MethodHandle
target
,
MethodType
newType
)
{
if
(!
target
.
type
().
isConvertibleTo
(
newType
))
{
throw
new
WrongMethodTypeException
(
"cannot convert "
+
target
+
" to "
+
newType
);
}
return
MethodHandleImpl
.
convertArguments
(
target
,
newType
,
1
);
}
...
...
@@ -1567,7 +1571,7 @@ assert((int)twice.invokeExact(21) == 42);
int
numSpread
=
(
outargs
-
spreadPos
);
MethodHandle
res
=
null
;
if
(
spreadPos
>=
0
&&
numSpread
>=
0
)
{
res
=
MethodHandleImpl
.
spreadArguments
(
target
,
newType
,
spreadPos
);
res
=
MethodHandleImpl
.
spreadArguments
FromPos
(
target
,
newType
,
spreadPos
);
}
if
(
res
==
null
)
{
throw
newIllegalArgumentException
(
"cannot spread "
+
newType
+
" to "
+
oldType
);
...
...
@@ -2135,7 +2139,7 @@ System.out.println((int) f0.invokeExact("x", "y")); // 2
int
hpc
=
hargs
.
size
(),
tpc
=
targs
.
size
();
if
(
hpc
>=
tpc
||
!
targs
.
subList
(
0
,
hpc
).
equals
(
hargs
))
throw
misMatchedTypes
(
"target and handler types"
,
ttype
,
htype
);
handler
=
dropArguments
(
handler
,
hpc
,
h
args
.
subList
(
hpc
,
tpc
));
handler
=
dropArguments
(
handler
,
1
+
hpc
,
t
args
.
subList
(
hpc
,
tpc
));
htype
=
handler
.
type
();
}
return
MethodHandleImpl
.
makeGuardWithCatch
(
target
,
exType
,
handler
);
...
...
@@ -2380,9 +2384,4 @@ System.out.println((int) f0.invokeExact("x", "y")); // 2
}
return
null
;
}
/*non-public*/
static
MethodHandle
asVarargsCollector
(
MethodHandle
target
,
Class
<?>
arrayType
)
{
return
MethodHandleImpl
.
asVarargsCollector
(
target
,
arrayType
);
}
}
src/share/classes/java/lang/invoke/MethodType.java
浏览文件 @
a7fbe030
...
...
@@ -163,7 +163,13 @@ class MethodType implements java.io.Serializable {
public
static
MethodType
methodType
(
Class
<?>
rtype
,
List
<
Class
<?>>
ptypes
)
{
boolean
notrust
=
false
;
// random List impl. could return evil ptypes array
return
makeImpl
(
rtype
,
ptypes
.
toArray
(
NO_PTYPES
),
notrust
);
return
makeImpl
(
rtype
,
listToArray
(
ptypes
),
notrust
);
}
private
static
Class
<?>[]
listToArray
(
List
<
Class
<?>>
ptypes
)
{
// sanity check the size before the toArray call, since size might be huge
checkSlotCount
(
ptypes
.
size
());
return
ptypes
.
toArray
(
NO_PTYPES
);
}
/**
...
...
@@ -228,7 +234,7 @@ class MethodType implements java.io.Serializable {
*/
/*trusted*/
static
MethodType
makeImpl
(
Class
<?>
rtype
,
Class
<?>[]
ptypes
,
boolean
trusted
)
{
if
(
ptypes
==
null
||
ptypes
.
length
==
0
)
{
if
(
ptypes
.
length
==
0
)
{
ptypes
=
NO_PTYPES
;
trusted
=
true
;
}
MethodType
mt1
=
new
MethodType
(
rtype
,
ptypes
);
...
...
@@ -372,7 +378,7 @@ class MethodType implements java.io.Serializable {
* @throws NullPointerException if {@code ptypesToInsert} or any of its elements is null
*/
public
MethodType
insertParameterTypes
(
int
num
,
List
<
Class
<?>>
ptypesToInsert
)
{
return
insertParameterTypes
(
num
,
ptypesToInsert
.
toArray
(
NO_PTYPES
));
return
insertParameterTypes
(
num
,
listToArray
(
ptypesToInsert
));
}
/**
...
...
@@ -641,7 +647,8 @@ class MethodType implements java.io.Serializable {
}
return
true
;
}
private
static
boolean
canConvert
(
Class
<?>
src
,
Class
<?>
dst
)
{
/*non-public*/
static
boolean
canConvert
(
Class
<?>
src
,
Class
<?>
dst
)
{
if
(
src
==
dst
||
dst
==
void
.
class
)
return
true
;
if
(
src
.
isPrimitive
()
&&
dst
.
isPrimitive
())
{
if
(!
Wrapper
.
forPrimitiveType
(
dst
)
...
...
@@ -739,9 +746,14 @@ class MethodType implements java.io.Serializable {
public
static
MethodType
fromMethodDescriptorString
(
String
descriptor
,
ClassLoader
loader
)
throws
IllegalArgumentException
,
TypeNotPresentException
{
if
(!
descriptor
.
startsWith
(
"("
)
||
// also generates NPE if needed
descriptor
.
indexOf
(
')'
)
<
0
||
descriptor
.
indexOf
(
'.'
)
>=
0
)
throw
new
IllegalArgumentException
(
"not a method descriptor: "
+
descriptor
);
List
<
Class
<?>>
types
=
BytecodeDescriptor
.
parseMethod
(
descriptor
,
loader
);
Class
<?>
rtype
=
types
.
remove
(
types
.
size
()
-
1
);
Class
<?>[]
ptypes
=
types
.
toArray
(
NO_PTYPES
);
checkSlotCount
(
types
.
size
());
Class
<?>[]
ptypes
=
listToArray
(
types
);
return
makeImpl
(
rtype
,
ptypes
,
true
);
}
...
...
src/share/classes/java/lang/invoke/MethodTypeForm.java
浏览文件 @
a7fbe030
...
...
@@ -448,6 +448,8 @@ class MethodTypeForm {
Class
<?>[]
cs
=
null
;
for
(
int
imax
=
ts
.
length
,
i
=
0
;
i
<
imax
;
i
++)
{
Class
<?>
c
=
canonicalize
(
ts
[
i
],
how
);
if
(
c
==
void
.
class
)
c
=
null
;
// a Void parameter was unwrapped to void; ignore
if
(
c
!=
null
)
{
if
(
cs
==
null
)
cs
=
ts
.
clone
();
...
...
src/share/classes/java/lang/invoke/SpreadGeneric.java
浏览文件 @
a7fbe030
...
...
@@ -126,7 +126,7 @@ class SpreadGeneric {
return
spreadGen
;
}
public
String
to
String
()
{
String
debug
String
()
{
return
getClass
().
getSimpleName
()+
targetType
+
"["
+
spreadCount
+
"]"
;
}
...
...
@@ -224,7 +224,7 @@ class SpreadGeneric {
protected
final
MethodHandle
target
;
// (any**N) => R
@Override
public
String
to
String
()
{
String
debug
String
()
{
return
addTypeString
(
target
,
this
);
}
...
...
src/share/classes/java/lang/invoke/ToGeneric.java
浏览文件 @
a7fbe030
...
...
@@ -258,7 +258,7 @@ class ToGeneric {
return
toGen
;
}
public
String
to
String
()
{
String
debug
String
()
{
return
"ToGeneric"
+
entryType
+(
primsAtEndOrder
!=
null
?
"[reorder]"
:
""
);
}
...
...
@@ -340,7 +340,7 @@ class ToGeneric {
protected
final
MethodHandle
convert
;
// Object -> R
@Override
public
String
to
String
()
{
String
debug
String
()
{
return
target
==
null
?
"prototype:"
+
convert
:
addTypeString
(
target
,
this
);
}
...
...
src/share/classes/sun/invoke/util/Wrapper.java
浏览文件 @
a7fbe030
...
...
@@ -258,7 +258,7 @@ public enum Wrapper {
}
/** Return the wrapper that wraps values into the given wrapper type.
* If it is {@code Object}
or an interface
, return {@code OBJECT}.
* If it is {@code Object}, return {@code OBJECT}.
* Otherwise, it must be a wrapper type.
* The type must not be a primitive type.
* @throws IllegalArgumentException for unexpected types
...
...
@@ -277,8 +277,6 @@ public enum Wrapper {
if
(
w
!=
null
&&
w
.
wrapperType
==
type
)
{
return
w
;
}
if
(
type
.
isInterface
())
return
OBJECT
;
return
null
;
}
...
...
test/java/lang/invoke/6991596/Test6991596.java
浏览文件 @
a7fbe030
...
...
@@ -51,10 +51,10 @@ public class Test6991596 {
return
MethodHandles
.
lookup
().
findStatic
(
CLASS
,
NAME
,
MethodType
.
methodType
(
ret
,
arg
));
}
static
MethodHandle
getmh2
(
MethodHandle
mh1
,
Class
ret
,
Class
arg
)
{
return
MethodHandles
.
conver
tArguments
(
mh1
,
MethodType
.
methodType
(
ret
,
arg
));
return
MethodHandles
.
explicitCas
tArguments
(
mh1
,
MethodType
.
methodType
(
ret
,
arg
));
}
static
MethodHandle
getmh3
(
MethodHandle
mh1
,
Class
ret
,
Class
arg
)
{
return
MethodHandles
.
conver
tArguments
(
mh1
,
MethodType
.
methodType
(
ret
,
arg
));
return
MethodHandles
.
explicitCas
tArguments
(
mh1
,
MethodType
.
methodType
(
ret
,
arg
));
}
// test adapter_opt_i2i
...
...
test/java/lang/invoke/InvokeGenericTest.java
浏览文件 @
a7fbe030
...
...
@@ -53,9 +53,9 @@ public class InvokeGenericTest {
if
(
vstr
!=
null
)
verbosity
=
Integer
.
parseInt
(
vstr
);
}
public
static
void
main
(
String
...
av
)
throws
Throwable
{
new
InvokeGenericTest
().
testFirst
();
}
//
public static void main(String... av) throws Throwable {
//
new InvokeGenericTest().testFirst();
//
}
@Test
public
void
testFirst
()
throws
Throwable
{
...
...
@@ -470,8 +470,6 @@ public class InvokeGenericTest {
return
allMethodTypes
(
argc
,
argc
,
types
);
}
interface
RandomInterface
{
}
MethodHandle
toString_MH
;
@Test
...
...
@@ -480,33 +478,62 @@ public class InvokeGenericTest {
toString_MH
=
LOOKUP
.
findVirtual
(
Object
.
class
,
"toString"
,
MethodType
.
methodType
(
String
.
class
));
Object
[]
args
=
{
"one"
,
"two"
};
for
(
MethodType
type
:
allMethodTypes
(
2
,
Object
.
class
,
String
.
class
,
RandomInterfa
ce
.
class
))
{
for
(
MethodType
type
:
allMethodTypes
(
2
,
Object
.
class
,
String
.
class
,
CharSequen
ce
.
class
))
{
testReferenceConversions
(
type
,
args
);
}
}
public
void
testReferenceConversions
(
MethodType
type
,
Object
...
args
)
throws
Throwable
{
countTest
();
if
(
verbosity
>
3
)
System
.
out
.
println
(
"target type: "
+
type
);
int
nargs
=
args
.
length
;
List
<
Object
>
argList
=
Arrays
.
asList
(
args
);
String
expectString
=
argList
.
toString
();
if
(
verbosity
>
3
)
System
.
out
.
println
(
"target type: "
+
type
+
expectString
);
MethodHandle
mh
=
callable
(
type
.
parameterList
());
MethodHandle
tsdrop
=
MethodHandles
.
dropArguments
(
toString_MH
,
1
,
type
.
parameterList
());
mh
=
MethodHandles
.
foldArguments
(
tsdrop
,
mh
);
mh
=
MethodHandles
.
filterReturnValue
(
mh
,
toString_MH
);
mh
=
mh
.
asType
(
type
);
Object
res
=
mh
.
invoke
((
String
)
args
[
0
],
(
Object
)
args
[
1
]);
Object
res
=
null
;
if
(
nargs
==
2
)
{
res
=
mh
.
invoke
((
Object
)
args
[
0
],
(
Object
)
args
[
1
]);
assertEquals
(
expectString
,
res
);
res
=
mh
.
invoke
((
String
)
args
[
0
],
(
Object
)
args
[
1
]);
assertEquals
(
expectString
,
res
);
res
=
mh
.
invoke
((
Object
)
args
[
0
],
(
String
)
args
[
1
]);
assertEquals
(
expectString
,
res
);
res
=
mh
.
invoke
((
String
)
args
[
0
],
(
String
)
args
[
1
]);
assertEquals
(
expectString
,
res
);
res
=
mh
.
invoke
((
String
)
args
[
0
],
(
CharSequence
)
args
[
1
]);
assertEquals
(
expectString
,
res
);
res
=
mh
.
invoke
((
CharSequence
)
args
[
0
],
(
Object
)
args
[
1
]);
assertEquals
(
expectString
,
res
);
res
=
(
String
)
mh
.
invoke
((
Object
)
args
[
0
],
(
Object
)
args
[
1
]);
assertEquals
(
expectString
,
res
);
res
=
(
String
)
mh
.
invoke
((
String
)
args
[
0
],
(
Object
)
args
[
1
]);
assertEquals
(
expectString
,
res
);
res
=
(
CharSequence
)
mh
.
invoke
((
String
)
args
[
0
],
(
Object
)
args
[
1
]);
assertEquals
(
expectString
,
res
);
}
else
{
assert
(
false
);
// write this code
}
//System.out.println(res);
assertEquals
(
Arrays
.
asList
(
args
).
toString
(),
res
);
}
@Test
@Ignore
(
"known failure pending 6939861"
)
@Test
public
void
testBoxConversions
()
throws
Throwable
{
startTest
(
"testBoxConversions"
);
countTest
();
Object
[]
args
=
{
1
,
2
};
MethodHandle
mh
=
callable
(
Object
.
class
,
int
.
class
);
Object
res
;
List
resl
;
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
);
mh
=
MethodHandles
.
dropArguments
(
mh
,
1
,
int
.
class
);
res
=
resi
=
(
int
)
mh
.
invoke
((
Object
)
args
[
0
],
(
Object
)
args
[
1
]);
assertEquals
(
args
[
0
],
res
);
res
=
resi
=
(
int
)
mh
.
invoke
((
int
)
args
[
0
],
(
Object
)
args
[
1
]);
assertEquals
(
args
[
0
],
res
);
}
}
test/java/lang/invoke/MethodHandlesTest.java
浏览文件 @
a7fbe030
...
...
@@ -505,8 +505,15 @@ public class MethodHandlesTest {
System
.
out
.
print
(
':'
);
}
static
final
boolean
DEBUG_METHOD_HANDLE_NAMES
=
Boolean
.
getBoolean
(
"java.lang.invoke.MethodHandle.DEBUG_NAMES"
);
// rough check of name string
static
void
assertNameStringContains
(
Object
x
,
String
s
)
{
static
void
assertNameStringContains
(
MethodHandle
x
,
String
s
)
{
if
(!
DEBUG_METHOD_HANDLE_NAMES
)
{
// ignore s
assertEquals
(
"MethodHandle"
+
x
.
type
(),
x
.
toString
());
return
;
}
if
(
x
.
toString
().
contains
(
s
))
return
;
assertEquals
(
s
,
x
);
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录