Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
dragonwell8_jdk
提交
8992d5c6
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看板
提交
8992d5c6
编写于
1月 13, 2010
作者:
J
jcoomes
浏览文件
操作
浏览文件
下载
差异文件
Merge
上级
2c94c689
4eb43f64
变更
31
显示空白变更内容
内联
并排
Showing
31 changed file
with
10375 addition
and
1474 deletion
+10375
-1474
src/share/classes/java/dyn/CallSite.java
src/share/classes/java/dyn/CallSite.java
+38
-15
src/share/classes/java/dyn/InvokeDynamic.java
src/share/classes/java/dyn/InvokeDynamic.java
+18
-0
src/share/classes/java/dyn/InvokeDynamicBootstrapError.java
src/share/classes/java/dyn/InvokeDynamicBootstrapError.java
+12
-0
src/share/classes/java/dyn/JavaMethodHandle.java
src/share/classes/java/dyn/JavaMethodHandle.java
+168
-17
src/share/classes/java/dyn/Linkage.java
src/share/classes/java/dyn/Linkage.java
+22
-13
src/share/classes/java/dyn/LinkagePermission.java
src/share/classes/java/dyn/LinkagePermission.java
+1
-1
src/share/classes/java/dyn/MethodHandle.java
src/share/classes/java/dyn/MethodHandle.java
+441
-6
src/share/classes/java/dyn/MethodHandles.java
src/share/classes/java/dyn/MethodHandles.java
+541
-299
src/share/classes/java/dyn/MethodType.java
src/share/classes/java/dyn/MethodType.java
+151
-48
src/share/classes/java/dyn/package-info.java
src/share/classes/java/dyn/package-info.java
+1
-0
src/share/classes/sun/dyn/AdapterMethodHandle.java
src/share/classes/sun/dyn/AdapterMethodHandle.java
+267
-77
src/share/classes/sun/dyn/BoundMethodHandle.java
src/share/classes/sun/dyn/BoundMethodHandle.java
+95
-30
src/share/classes/sun/dyn/CallSiteImpl.java
src/share/classes/sun/dyn/CallSiteImpl.java
+48
-16
src/share/classes/sun/dyn/FilterGeneric.java
src/share/classes/sun/dyn/FilterGeneric.java
+4332
-170
src/share/classes/sun/dyn/FilterOneArgument.java
src/share/classes/sun/dyn/FilterOneArgument.java
+11
-11
src/share/classes/sun/dyn/FromGeneric.java
src/share/classes/sun/dyn/FromGeneric.java
+79
-74
src/share/classes/sun/dyn/Invokers.java
src/share/classes/sun/dyn/Invokers.java
+13
-3
src/share/classes/sun/dyn/MemberName.java
src/share/classes/sun/dyn/MemberName.java
+21
-14
src/share/classes/sun/dyn/MethodHandleImpl.java
src/share/classes/sun/dyn/MethodHandleImpl.java
+807
-71
src/share/classes/sun/dyn/MethodHandleNatives.java
src/share/classes/sun/dyn/MethodHandleNatives.java
+21
-18
src/share/classes/sun/dyn/MethodTypeImpl.java
src/share/classes/sun/dyn/MethodTypeImpl.java
+6
-5
src/share/classes/sun/dyn/SpreadGeneric.java
src/share/classes/sun/dyn/SpreadGeneric.java
+682
-0
src/share/classes/sun/dyn/ToGeneric.java
src/share/classes/sun/dyn/ToGeneric.java
+446
-419
src/share/classes/sun/dyn/empty/Empty.java
src/share/classes/sun/dyn/empty/Empty.java
+4
-0
src/share/classes/sun/dyn/util/BytecodeDescriptor.java
src/share/classes/sun/dyn/util/BytecodeDescriptor.java
+2
-2
src/share/classes/sun/dyn/util/BytecodeName.java
src/share/classes/sun/dyn/util/BytecodeName.java
+34
-118
src/share/classes/sun/dyn/util/ValueConversions.java
src/share/classes/sun/dyn/util/ValueConversions.java
+179
-20
src/share/classes/sun/dyn/util/VerifyAccess.java
src/share/classes/sun/dyn/util/VerifyAccess.java
+43
-5
src/share/classes/sun/dyn/util/VerifyType.java
src/share/classes/sun/dyn/util/VerifyType.java
+19
-14
src/share/classes/sun/dyn/util/Wrapper.java
src/share/classes/sun/dyn/util/Wrapper.java
+34
-8
test/java/dyn/MethodHandlesTest.java
test/java/dyn/MethodHandlesTest.java
+1839
-0
未找到文件。
src/share/classes/java/dyn/CallSite.java
浏览文件 @
8992d5c6
...
@@ -26,6 +26,9 @@
...
@@ -26,6 +26,9 @@
package
java.dyn
;
package
java.dyn
;
import
sun.dyn.util.BytecodeName
;
import
sun.dyn.util.BytecodeName
;
import
sun.dyn.Access
;
import
sun.dyn.CallSiteImpl
;
import
sun.dyn.MethodHandleImpl
;
/**
/**
* An {@code invokedynamic} call site, as reified by the
* An {@code invokedynamic} call site, as reified by the
...
@@ -52,15 +55,25 @@ import sun.dyn.util.BytecodeName;
...
@@ -52,15 +55,25 @@ import sun.dyn.util.BytecodeName;
* @see Linkage#registerBootstrapMethod(java.lang.Class, java.dyn.MethodHandle)
* @see Linkage#registerBootstrapMethod(java.lang.Class, java.dyn.MethodHandle)
* @author John Rose, JSR 292 EG
* @author John Rose, JSR 292 EG
*/
*/
public
class
CallSite
{
public
class
CallSite
// Note: This is an implementation inheritance hack, and will be removed
// with a JVM change which moves the required hidden state onto this class.
extends
CallSiteImpl
{
private
static
final
Access
IMPL_TOKEN
=
Access
.
getToken
();
/*
// Fields used only by the JVM. Do not use or change.
// Fields used only by the JVM. Do not use or change.
private Object vmmethod;
private Object vmmethod;
int callerMID, callerBCI; // supplied by the JVM
int callerMID, callerBCI; // supplied by the JVM
MethodHandle
target
;
private MethodHandle target;
final Object caller; // usually a class
final Object caller; // usually a class
final String name;
final String name;
final MethodType type;
final MethodType type;
*/
/**
/**
* Make a call site given the parameters from a call to the bootstrap method.
* Make a call site given the parameters from a call to the bootstrap method.
...
@@ -72,16 +85,21 @@ public class CallSite {
...
@@ -72,16 +85,21 @@ public class CallSite {
* @param type the method handle type derived from descriptor of the {@code invokedynamic} instruction
* @param type the method handle type derived from descriptor of the {@code invokedynamic} instruction
*/
*/
public
CallSite
(
Object
caller
,
String
name
,
MethodType
type
)
{
public
CallSite
(
Object
caller
,
String
name
,
MethodType
type
)
{
this
.
caller
=
caller
;
super
(
IMPL_TOKEN
,
caller
,
name
,
type
);
this
.
name
=
name
;
this
.
type
=
type
;
}
}
private
static
void
privateInitializeCallSite
(
CallSite
site
,
int
callerMID
,
int
callerBCI
)
{
private
static
void
privateInitializeCallSite
(
CallSite
site
,
int
callerMID
,
int
callerBCI
)
{
site
.
callerMID
=
callerMID
;
site
.
callerMID
=
callerMID
;
site
.
callerBCI
=
callerBCI
;
site
.
callerBCI
=
callerBCI
;
if
(
site
.
target
==
null
)
site
.
ensureTarget
();
site
.
setTarget
(
site
.
initialTarget
());
}
private
void
ensureTarget
()
{
// Note use of super, which accesses the field directly,
// without deferring to possible subclass overrides.
if
(
super
.
getTarget
()
==
null
)
{
super
.
setTarget
(
this
.
initialTarget
());
super
.
getTarget
().
type
();
// provoke NPE if still null
}
}
}
/**
/**
...
@@ -102,10 +120,11 @@ public class CallSite {
...
@@ -102,10 +120,11 @@ public class CallSite {
/**
/**
* Report the current linkage state of the call site. (This is mutable.)
* Report the current linkage state of the call site. (This is mutable.)
* The value maybe null only if the call site is currently unlinked.
* The value may not be null after the {@code CallSite} object is returned
* When a linked call site is invoked, the target method is used directly.
* from the bootstrap method of the {@code invokedynamic} instruction.
* When an unlinked call site is invoked, its bootstrap method receives
* When an {@code invokedynamic} instruction is executed, the target method
* the call, as if via {@link Linkage#bootstrapInvokeDynamic}.
* of its associated {@code call site} object is invoked directly,
* as if via {@link MethodHandle}{@code .invoke}.
* <p>
* <p>
* The interactions of {@code getTarget} with memory are the same
* The interactions of {@code getTarget} with memory are the same
* as of a read from an ordinary variable, such as an array element or a
* as of a read from an ordinary variable, such as an array element or a
...
@@ -118,7 +137,7 @@ public class CallSite {
...
@@ -118,7 +137,7 @@ public class CallSite {
* @see #setTarget
* @see #setTarget
*/
*/
public
MethodHandle
getTarget
()
{
public
MethodHandle
getTarget
()
{
return
target
;
return
super
.
getTarget
()
;
}
}
/**
/**
...
@@ -140,13 +159,13 @@ public class CallSite {
...
@@ -140,13 +159,13 @@ public class CallSite {
*/
*/
public
void
setTarget
(
MethodHandle
target
)
{
public
void
setTarget
(
MethodHandle
target
)
{
checkTarget
(
target
);
checkTarget
(
target
);
this
.
target
=
target
;
super
.
setTarget
(
target
)
;
}
}
protected
void
checkTarget
(
MethodHandle
target
)
{
protected
void
checkTarget
(
MethodHandle
target
)
{
target
.
type
();
// provoke NPE
target
.
type
();
// provoke NPE
if
(!
canSetTarget
(
target
))
if
(!
canSetTarget
(
target
))
throw
new
WrongMethodTypeException
(
String
.
valueOf
(
target
));
throw
new
WrongMethodTypeException
(
String
.
valueOf
(
target
)
+
target
.
type
()+
" should be of type "
+
type
()
);
}
}
protected
boolean
canSetTarget
(
MethodHandle
target
)
{
protected
boolean
canSetTarget
(
MethodHandle
target
)
{
...
@@ -219,6 +238,10 @@ public class CallSite {
...
@@ -219,6 +238,10 @@ public class CallSite {
@Override
@Override
public
String
toString
()
{
public
String
toString
()
{
return
"CallSite#"
+
hashCode
()+
"["
+
name
+
type
+
" => "
+
target
+
"]"
;
return
"CallSite#"
+
hashCode
()+
"["
+
name
+
type
+
" => "
+
getTarget
()
+
"]"
;
}
}
// Package-local constant:
static
final
MethodHandle
GET_TARGET
=
MethodHandleImpl
.
getLookup
(
IMPL_TOKEN
).
findVirtual
(
CallSite
.
class
,
"getTarget"
,
MethodType
.
methodType
(
MethodHandle
.
class
));
}
}
src/share/classes/java/dyn/InvokeDynamic.java
浏览文件 @
8992d5c6
...
@@ -45,6 +45,24 @@ package java.dyn;
...
@@ -45,6 +45,24 @@ package java.dyn;
* class or interface supertype, or an object type; it can never be instantiated.
* class or interface supertype, or an object type; it can never be instantiated.
* Logically, it denotes a source of all dynamically typed methods.
* Logically, it denotes a source of all dynamically typed methods.
* It may be viewed as a pure syntactic marker (an importable one) of static calls.
* It may be viewed as a pure syntactic marker (an importable one) of static calls.
* <p>
* Here are some examples of usage:
* <p><blockquote><pre>
* Object x; String s; int i;
* x = InvokeDynamic.greet("world"); // greet(Ljava/lang/String;)Ljava/lang/Object;
* s = InvokeDynamic.<String>hail(x); // hail(Ljava/lang/Object;)Ljava/lang/String;
* InvokeDynamic.<void>cogito(); // cogito()V
* i = InvokeDynamic.<int>#"op:+"(2, 3); // "op:+"(II)I
* </pre></blockquote>
* Each of the above calls generates a single invokedynamic instruction
* with the name-and-type descriptors indicated in the comments.
* The argument types are taken directly from the actual arguments,
* while the return type is taken from the type parameter.
* (This type parameter may be a primtive, and it defaults to {@code Object}.)
* The final example uses a special syntax for uttering non-Java names.
* Any name legal to the JVM may be given between the double quotes.
* None of these calls is complete without a bootstrap method,
* which must be registered by the static initializer of the enclosing class.
* @author John Rose, JSR 292 EG
* @author John Rose, JSR 292 EG
*/
*/
public
final
class
InvokeDynamic
{
public
final
class
InvokeDynamic
{
...
...
src/share/classes/java/dyn/InvokeDynamicBootstrapError.java
浏览文件 @
8992d5c6
...
@@ -52,4 +52,16 @@ public class InvokeDynamicBootstrapError extends LinkageError {
...
@@ -52,4 +52,16 @@ public class InvokeDynamicBootstrapError extends LinkageError {
public
InvokeDynamicBootstrapError
(
String
s
)
{
public
InvokeDynamicBootstrapError
(
String
s
)
{
super
(
s
);
super
(
s
);
}
}
/**
* Constructs a {@code InvokeDynamicBootstrapError} with the specified
* detail message and cause.
*
* @param s the detail message.
* @param cause the cause.
*/
public
InvokeDynamicBootstrapError
(
String
s
,
Throwable
cause
)
{
super
(
s
);
this
.
initCause
(
cause
);
}
}
}
src/share/classes/java/dyn/JavaMethodHandle.java
浏览文件 @
8992d5c6
...
@@ -25,6 +25,8 @@
...
@@ -25,6 +25,8 @@
package
java.dyn
;
package
java.dyn
;
import
sun.dyn.Access
;
/**
/**
* A Java method handle extends the basic method handle type with additional
* A Java method handle extends the basic method handle type with additional
* programmer defined methods and fields.
* programmer defined methods and fields.
...
@@ -39,31 +41,105 @@ package java.dyn;
...
@@ -39,31 +41,105 @@ package java.dyn;
* of the entry point method handle, with the leading parameter type
* of the entry point method handle, with the leading parameter type
* omitted.
* omitted.
* <p>
* <p>
* Here is an example of usage:
* Here is an example of usage
, creating a hybrid object/functional datum
:
* <p><blockquote><pre>
* <p><blockquote><pre>
* class Greeter extends JavaMethodHandle {
* class Greeter extends JavaMethodHandle {
* public void run() { System.out.println("hello, "+greetee); }
* private String greeting = "hello";
* public void setGreeting(String s) { greeting = s; }
* public void run() { System.out.println(greeting+", "+greetee); }
* private final String greetee;
* private final String greetee;
* Greeter(String greetee) {
* Greeter(String greetee) {
*
super(RUN);
*
super(RUN); // alternatively, super("run")
* this.greetee = greetee;
* this.greetee = greetee;
* }
* }
* // the entry point function is computed once:
* // the entry point function is computed once:
* private static final MethodHandle RUN
* private static final MethodHandle RUN
*
= MethodHandles.findVirtual(MyMethodHandle
.class, "run",
*
= MethodHandles.lookup().findVirtual(Greeter
.class, "run",
* MethodType.make(void.class));
* MethodType.make(void.class));
* }
* }
* // class Main { public static void main(String... av) { ...
* Greeter greeter = new Greeter("world");
* Greeter greeter = new Greeter("world");
* greeter.run(); // prints "hello, world"
* greeter.run(); // prints "hello, world"
* // Statically typed method handle invocation (most direct):
* MethodHandle mh = greeter;
* MethodHandle mh = greeter;
* mh.invoke(); // also prints "hello, world"
* mh.<void>invoke(); // also prints "hello, world"
* // Dynamically typed method handle invocation:
* MethodHandles.invoke(greeter); // also prints "hello, world"
* greeter.setGreeting("howdy");
* mh.invoke(); // prints "howdy, world" (object-like mutable behavior)
* </pre></blockquote>
* </pre></blockquote>
* <p>
* <p>
* In th
is example
, the method {@code run} provides the entry point.
* In th
e example of {@code Greeter}
, the method {@code run} provides the entry point.
* The entry point need not be a constant value; it may be independently
* The entry point need not be a constant value; it may be independently
* computed in each call to the constructor. The entry point does not
* computed in each call to the constructor. The entry point does not
* even need to be a method on the
Java method handle
class, though
* even need to be a method on the
{@code Greeter}
class, though
* that is the typical case.
* that is the typical case.
* <p>
* The entry point may also be provided symbolically, in which case the the
* {@code JavaMethodHandle} constructor performs the lookup of the entry point.
* This makes it possible to use {@code JavaMethodHandle} to create an anonymous
* inner class:
* <p><blockquote><pre>
* // We can also do this with symbolic names and/or inner classes:
* MethodHandles.invoke(new JavaMethodHandle("yow") {
* void yow() { System.out.println("yow, world"); }
* });
* </pre></blockquote>
* <p>
* Here is similar lower-level code which works in terms of a bound method handle.
* <p><blockquote><pre>
* class Greeter {
* public void run() { System.out.println("hello, "+greetee); }
* private final String greetee;
* Greeter(String greetee) { this.greetee = greetee; }
* // the entry point function is computed once:
* private static final MethodHandle RUN
* = MethodHandles.findVirtual(Greeter.class, "run",
* MethodType.make(void.class));
* }
* // class Main { public static void main(String... av) { ...
* Greeter greeter = new Greeter("world");
* greeter.run(); // prints "hello, world"
* MethodHandle mh = MethodHanndles.insertArgument(Greeter.RUN, 0, greeter);
* mh.invoke(); // also prints "hello, world"
* </pre></blockquote>
* Note that the method handle must be separately created as a view on the base object.
* This increases footprint, complexity, and dynamic indirections.
* <p>
* Here is a pure functional value expressed most concisely as an anonymous inner class:
* <p><blockquote><pre>
* // class Main { public static void main(String... av) { ...
* final String greetee = "world";
* MethodHandle greeter = new JavaMethodHandle("run") {
* private void run() { System.out.println("hello, "+greetee); }
* }
* greeter.invoke(); // prints "hello, world"
* </pre></blockquote>
* <p>
* Here is an abstract parameterized lvalue, efficiently expressed as a subtype of MethodHandle,
* and instantiated as an anonymous class. The data structure is a handle to 1-D array,
* with a specialized index type (long). It is created by inner class, and uses
* signature-polymorphic APIs throughout.
* <p><blockquote><pre>
* abstract class AssignableMethodHandle extends JavaMethodHandle {
* private final MethodHandle setter;
* public MethodHandle setter() { return setter; }
* public AssignableMethodHandle(String get, String set) {
* super(get);
* MethodType getType = this.type();
* MethodType setType = getType.insertParameterType(getType.parameterCount(), getType.returnType()).changeReturnType(void.class);
* this.setter = MethodHandles.publicLookup().bind(this, set, setType);
* }
* }
* // class Main { public static void main(String... av) { ...
* final Number[] stuff = { 123, 456 };
* AssignableMethodHandle stuffPtr = new AssignableMethodHandle("get", "set") {
* public Number get(long i) { return stuff[(int)i]; }
* public void set(long i, Object x) { stuff[(int)i] = x; }
* }
* int x = (Integer) stuffPtr.<Number>invoke(1L); // 456
* stuffPtr.setter().<void>invoke(0L, (Number) 789); // replaces 123 with 789
* </pre></blockquote>
* @see MethodHandle
* @see MethodHandle
* @author John Rose, JSR 292 EG
* @author John Rose, JSR 292 EG
*/
*/
...
@@ -72,12 +148,87 @@ public abstract class JavaMethodHandle
...
@@ -72,12 +148,87 @@ public abstract class JavaMethodHandle
// with a JVM change which moves the required hidden behavior onto this class.
// with a JVM change which moves the required hidden behavior onto this class.
extends
sun
.
dyn
.
BoundMethodHandle
extends
sun
.
dyn
.
BoundMethodHandle
{
{
private
static
final
Access
IMPL_TOKEN
=
Access
.
getToken
();
/**
/**
* When creating a, pass in {@code entryPoint}, any method handle which
* When creating a {@code JavaMethodHandle}, the actual method handle
* can take the current object
* invocation behavior will be delegated to the specified {@code entryPoint}.
* @param entryPoint
* This may be any method handle which can take the newly constructed object
* as a leading parameter.
* <p>
* The method handle type of {@code this} (i.e, the fully constructed object)
* will be {@code entryPoint}, minus the leading argument.
* The leading argument will be bound to {@code this} on every method
* handle invocation.
* @param entryPoint the method handle to handle calls
*/
*/
protected
JavaMethodHandle
(
MethodHandle
entryPoint
)
{
protected
JavaMethodHandle
(
MethodHandle
entryPoint
)
{
super
(
entryPoint
,
0
);
super
(
entryPoint
);
}
/**
* Create a method handle whose entry point is a non-static method
* visible in the exact (most specific) class of
* the newly constructed object.
* <p>
* The method is specified by name and type, as if via this expression:
* {@code MethodHandles.lookup().findVirtual(this.getClass(), name, type)}.
* The class defining the method might be an anonymous inner class.
* <p>
* The method handle type of {@code this} (i.e, the fully constructed object)
* will be the given method handle type.
* A call to {@code this} will invoke the selected method.
* The receiver argument will be bound to {@code this} on every method
* handle invocation.
* <p>
* <i>Rationale:</i>
* Although this constructor may seem to be a mere luxury,
* it is not subsumed by the more general constructor which
* takes any {@code MethodHandle} as the entry point argument.
* In order to convert an entry point name to a method handle,
* the self-class of the object is required (in order to do
* the lookup). The self-class, in turn, is generally not
* available at the time of the constructor invocation,
* due to the rules of Java and the JVM verifier.
* One cannot call {@code this.getClass()}, because
* the value of {@code this} is inaccessible at the point
* of the constructor call. (Changing this would require
* change to the Java language, verifiers, and compilers.)
* In particular, this constructor allows {@code JavaMethodHandle}s
* to be created in combination with the anonymous inner class syntax.
* @param entryPointName the name of the entry point method
* @param type (optional) the desired type of the method handle
*/
protected
JavaMethodHandle
(
String
entryPointName
,
MethodType
type
)
{
super
(
entryPointName
,
type
,
true
);
}
/**
* Create a method handle whose entry point is a non-static method
* visible in the exact (most specific) class of
* the newly constructed object.
* <p>
* The method is specified only by name.
* There must be exactly one method of that name visible in the object class,
* either inherited or locally declared.
* (That is, the method must not be overloaded.)
* <p>
* The method handle type of {@code this} (i.e, the fully constructed object)
* will be the same as the type of the selected non-static method.
* The receiver argument will be bound to {@code this} on every method
* handle invocation.
* <p>ISSUE: This signature wildcarding feature does not correspond to
* any MethodHandles.Lookup API element. Can we eliminate it?
* Alternatively, it is useful for naming non-overloaded methods.
* Shall we make type arguments optional in the Lookup methods,
* throwing an error in cases of ambiguity?
* <p>
* For this method's rationale, see the documentation
* for {@link #JavaMethodHandle(String,MethodType)}.
* @param entryPointName the name of the entry point method
*/
protected
JavaMethodHandle
(
String
entryPointName
)
{
super
(
entryPointName
,
(
MethodType
)
null
,
false
);
}
}
}
}
src/share/classes/java/dyn/Linkage.java
浏览文件 @
8992d5c6
...
@@ -25,7 +25,9 @@
...
@@ -25,7 +25,9 @@
package
java.dyn
;
package
java.dyn
;
import
java.dyn.MethodHandles.Lookup
;
import
java.util.WeakHashMap
;
import
java.util.WeakHashMap
;
import
sun.dyn.Access
;
import
sun.reflect.Reflection
;
import
sun.reflect.Reflection
;
import
static
sun
.
dyn
.
util
.
VerifyAccess
.
checkBootstrapPrivilege
;
import
static
sun
.
dyn
.
util
.
VerifyAccess
.
checkBootstrapPrivilege
;
...
@@ -34,6 +36,8 @@ import static sun.dyn.util.VerifyAccess.checkBootstrapPrivilege;
...
@@ -34,6 +36,8 @@ import static sun.dyn.util.VerifyAccess.checkBootstrapPrivilege;
* @author John Rose, JSR 292 EG
* @author John Rose, JSR 292 EG
*/
*/
public
class
Linkage
{
public
class
Linkage
{
private
static
final
Access
IMPL_TOKEN
=
Access
.
getToken
();
private
Linkage
()
{}
// do not instantiate
private
Linkage
()
{}
// do not instantiate
/**
/**
...
@@ -53,19 +57,23 @@ public class Linkage {
...
@@ -53,19 +57,23 @@ public class Linkage {
* call to this method.
* call to this method.
* <li>The given class is already fully initialized.
* <li>The given class is already fully initialized.
* <li>The given class is in the process of initialization, in another thread.
* <li>The given class is in the process of initialization, in another thread.
* <li>The same {@code CallSite} object has already been returned from
* a bootstrap method call to another {@code invokedynamic} call site.
* </ul>
* </ul>
* Because of these rules, a class may install its own bootstrap method in
* Because of these rules, a class may install its own bootstrap method in
* a static initializer.
* a static initializer.
* @param callerClass a class that may have {@code invokedynamic} sites
* @param bootstrapMethod the method to use to bootstrap all such sites
*/
*/
public
static
public
static
void
registerBootstrapMethod
(
Class
callerClass
,
MethodHandle
mh
)
{
void
registerBootstrapMethod
(
Class
callerClass
,
MethodHandle
bootstrapMethod
)
{
Class
callc
=
Reflection
.
getCallerClass
(
2
);
Class
callc
=
Reflection
.
getCallerClass
(
2
);
checkBootstrapPrivilege
(
callc
,
callerClass
,
"registerBootstrapMethod"
);
checkBootstrapPrivilege
(
callc
,
callerClass
,
"registerBootstrapMethod"
);
checkBSM
(
mh
);
checkBSM
(
bootstrapMethod
);
synchronized
(
bootstrapMethods
)
{
synchronized
(
bootstrapMethods
)
{
if
(
bootstrapMethods
.
containsKey
(
callerClass
))
if
(
bootstrapMethods
.
containsKey
(
callerClass
))
throw
new
IllegalStateException
(
"bootstrap method already declared in "
+
callerClass
);
throw
new
IllegalStateException
(
"bootstrap method already declared in "
+
callerClass
);
bootstrapMethods
.
put
(
callerClass
,
mh
);
bootstrapMethods
.
put
(
callerClass
,
bootstrapMethod
);
}
}
}
}
...
@@ -88,8 +96,9 @@ public class Linkage {
...
@@ -88,8 +96,9 @@ public class Linkage {
public
static
public
static
void
registerBootstrapMethod
(
Class
<?>
runtime
,
String
name
)
{
void
registerBootstrapMethod
(
Class
<?>
runtime
,
String
name
)
{
Class
callc
=
Reflection
.
getCallerClass
(
2
);
Class
callc
=
Reflection
.
getCallerClass
(
2
);
Lookup
lookup
=
new
Lookup
(
IMPL_TOKEN
,
callc
);
MethodHandle
bootstrapMethod
=
MethodHandle
bootstrapMethod
=
MethodHandles
.
findStaticFrom
(
callc
,
runtime
,
name
,
BOOTSTRAP_METHOD_TYPE
);
lookup
.
findStatic
(
runtime
,
name
,
BOOTSTRAP_METHOD_TYPE
);
// FIXME: exception processing wrong here
// FIXME: exception processing wrong here
checkBSM
(
bootstrapMethod
);
checkBSM
(
bootstrapMethod
);
Linkage
.
registerBootstrapMethod
(
callc
,
bootstrapMethod
);
Linkage
.
registerBootstrapMethod
(
callc
,
bootstrapMethod
);
...
@@ -106,8 +115,9 @@ public class Linkage {
...
@@ -106,8 +115,9 @@ public class Linkage {
public
static
public
static
void
registerBootstrapMethod
(
String
name
)
{
void
registerBootstrapMethod
(
String
name
)
{
Class
callc
=
Reflection
.
getCallerClass
(
2
);
Class
callc
=
Reflection
.
getCallerClass
(
2
);
Lookup
lookup
=
new
Lookup
(
IMPL_TOKEN
,
callc
);
MethodHandle
bootstrapMethod
=
MethodHandle
bootstrapMethod
=
MethodHandles
.
findStaticFrom
(
callc
,
callc
,
name
,
BOOTSTRAP_METHOD_TYPE
);
lookup
.
findStatic
(
callc
,
name
,
BOOTSTRAP_METHOD_TYPE
);
// FIXME: exception processing wrong here
// FIXME: exception processing wrong here
checkBSM
(
bootstrapMethod
);
checkBSM
(
bootstrapMethod
);
Linkage
.
registerBootstrapMethod
(
callc
,
bootstrapMethod
);
Linkage
.
registerBootstrapMethod
(
callc
,
bootstrapMethod
);
...
@@ -116,8 +126,7 @@ public class Linkage {
...
@@ -116,8 +126,7 @@ public class Linkage {
/**
/**
* <em>PROVISIONAL API, WORK IN PROGRESS:</em>
* <em>PROVISIONAL API, WORK IN PROGRESS:</em>
* Report the bootstrap method registered for a given class.
* Report the bootstrap method registered for a given class.
* Returns null if the class has never yet registered a bootstrap method,
* Returns null if the class has never yet registered a bootstrap method.
* or if the class has explicitly registered a null bootstrap method.
* Only callers privileged to set the bootstrap method may inquire
* Only callers privileged to set the bootstrap method may inquire
* about it, because a bootstrap method is potentially a back-door entry
* about it, because a bootstrap method is potentially a back-door entry
* point into its class.
* point into its class.
...
@@ -137,11 +146,11 @@ public class Linkage {
...
@@ -137,11 +146,11 @@ public class Linkage {
* {@code (Class, String, MethodType)} returning a {@code CallSite}.
* {@code (Class, String, MethodType)} returning a {@code CallSite}.
*/
*/
public
static
final
MethodType
BOOTSTRAP_METHOD_TYPE
public
static
final
MethodType
BOOTSTRAP_METHOD_TYPE
=
MethodType
.
m
ak
e
(
CallSite
.
class
,
=
MethodType
.
m
ethodTyp
e
(
CallSite
.
class
,
Class
.
class
,
String
.
class
,
MethodType
.
class
);
Class
.
class
,
String
.
class
,
MethodType
.
class
);
private
static
final
MethodType
OLD_BOOTSTRAP_METHOD_TYPE
private
static
final
MethodType
OLD_BOOTSTRAP_METHOD_TYPE
=
MethodType
.
m
ak
e
(
Object
.
class
,
=
MethodType
.
m
ethodTyp
e
(
Object
.
class
,
CallSite
.
class
,
Object
[].
class
);
CallSite
.
class
,
Object
[].
class
);
private
static
final
WeakHashMap
<
Class
,
MethodHandle
>
bootstrapMethods
=
private
static
final
WeakHashMap
<
Class
,
MethodHandle
>
bootstrapMethods
=
...
@@ -173,8 +182,8 @@ public class Linkage {
...
@@ -173,8 +182,8 @@ public class Linkage {
/**
/**
* <em>PROVISIONAL API, WORK IN PROGRESS:</em>
* <em>PROVISIONAL API, WORK IN PROGRESS:</em>
* Invalidate all <code>invokedynamic</code> call sites
associated
* Invalidate all <code>invokedynamic</code> call sites
in the bytecodes
*
with
the given class.
*
of any methods of
the given class.
* (These are exactly those sites which report the given class
* (These are exactly those sites which report the given class
* via the {@link CallSite#callerClass()} method.)
* via the {@link CallSite#callerClass()} method.)
* <p>
* <p>
...
...
src/share/classes/java/dyn/LinkagePermission.java
浏览文件 @
8992d5c6
...
@@ -88,7 +88,7 @@ public final class LinkagePermission extends BasicPermission {
...
@@ -88,7 +88,7 @@ public final class LinkagePermission extends BasicPermission {
/**
/**
* Create a new LinkagePermission with the given name.
* Create a new LinkagePermission with the given name.
* The name is the symbolic name of the LinkagePermission, such as
* The name is the symbolic name of the LinkagePermission, such as
* "registerBootstrapMethod", "invalidateClass.*", etc. An asterisk
* "registerBootstrapMethod", "invalidateC
allerC
lass.*", etc. An asterisk
* may appear at the end of the name, following a ".", or by itself, to
* may appear at the end of the name, following a ".", or by itself, to
* signify a wildcard match.
* signify a wildcard match.
*
*
...
...
src/share/classes/java/dyn/MethodHandle.java
浏览文件 @
8992d5c6
...
@@ -30,6 +30,9 @@ package java.dyn;
...
@@ -30,6 +30,9 @@ package java.dyn;
import
sun.dyn.Access
;
import
sun.dyn.Access
;
import
sun.dyn.MethodHandleImpl
;
import
sun.dyn.MethodHandleImpl
;
import
static
java
.
dyn
.
MethodHandles
.
invokers
;
// package-private API
import
static
sun
.
dyn
.
MemberName
.
newIllegalArgumentException
;
// utility
/**
/**
* A method handle is a typed reference to the entry point of a method.
* A method handle is a typed reference to the entry point of a method.
* <p>
* <p>
...
@@ -45,8 +48,9 @@ import sun.dyn.MethodHandleImpl;
...
@@ -45,8 +48,9 @@ import sun.dyn.MethodHandleImpl;
* Every method handle appears as an object containing a method named
* Every method handle appears as an object containing a method named
* <code>invoke</code>, whose signature exactly matches
* <code>invoke</code>, whose signature exactly matches
* the method handle's type.
* the method handle's type.
* A normal Java method call (using the <code>invokevirtual</code> instruction)
* A Java method call expression, which compiles to an
* can invoke this method from Java source code (if language support is present).
* <code>invokevirtual</code> instruction,
* can invoke this method from Java source code.
* <p>
* <p>
* Every call to a method handle specifies an intended method type,
* Every call to a method handle specifies an intended method type,
* which must exactly match the type of the method handle.
* which must exactly match the type of the method handle.
...
@@ -57,6 +61,10 @@ import sun.dyn.MethodHandleImpl;
...
@@ -57,6 +61,10 @@ import sun.dyn.MethodHandleImpl;
* The call fails with a {@link WrongMethodTypeException}
* The call fails with a {@link WrongMethodTypeException}
* if the method does not exist, even if there is an <code>invoke</code>
* if the method does not exist, even if there is an <code>invoke</code>
* method of a closely similar signature.
* method of a closely similar signature.
* As with other kinds
* of methods in the JVM, signature matching during method linkage
* is exact, and does not allow for language-level implicit conversions
* such as {@code String} to {@code Object} or {@code short} to {@code int}.
* <p>
* <p>
* A method handle is an unrestricted capability to call a method.
* A method handle is an unrestricted capability to call a method.
* A method handle can be formed on a non-public method by a class
* A method handle can be formed on a non-public method by a class
...
@@ -74,6 +82,15 @@ import sun.dyn.MethodHandleImpl;
...
@@ -74,6 +82,15 @@ import sun.dyn.MethodHandleImpl;
* (after resolving symbolic type names) must exactly match the method type
* (after resolving symbolic type names) must exactly match the method type
* of the target method.
* of the target method.
* <p>
* <p>
* Every <code>invoke</code> method always throws {@link Exception},
* which is to say that there is no static restriction on what a method handle
* can throw. Since the JVM does not distinguish between checked
* and unchecked exceptions (other than by their class, of course),
* there is no particular effect on bytecode shape from ascribing
* checked exceptions to method handle invocations. But in Java source
* code, methods which perform method handle calls must either explicitly
* throw {@code Exception}, or else must catch all checked exceptions locally.
* <p>
* Bytecode in an extended JVM can directly obtain a method handle
* Bytecode in an extended JVM can directly obtain a method handle
* for any accessible method from a <code>ldc</code> instruction
* for any accessible method from a <code>ldc</code> instruction
* which refers to a <code>CONSTANT_Methodref</code> or
* which refers to a <code>CONSTANT_Methodref</code> or
...
@@ -97,6 +114,59 @@ import sun.dyn.MethodHandleImpl;
...
@@ -97,6 +114,59 @@ import sun.dyn.MethodHandleImpl;
* can also be created. These do not perform virtual lookup based on
* can also be created. These do not perform virtual lookup based on
* receiver type. Such a method handle simulates the effect of
* receiver type. Such a method handle simulates the effect of
* an <code>invokespecial</code> instruction to the same method.
* an <code>invokespecial</code> instruction to the same method.
* <p>
* Here are some examples of usage:
* <p><blockquote><pre>
* Object x, y; String s; int i;
* MethodType mt; MethodHandle mh;
* MethodHandles.Lookup lookup = MethodHandles.lookup();
* // mt is {(char,char) => String}
* mt = MethodType.make(String.class, char.class, char.class);
* mh = lookup.findVirtual(String.class, "replace", mt);
* // (Ljava/lang/String;CC)Ljava/lang/String;
* s = mh.<String>invoke("daddy",'d','n');
* assert(s.equals("nanny"));
* // weakly typed invocation (using MHs.invoke)
* s = (String) MethodHandles.invoke(mh, "sappy", 'p', 'v');
* assert(s.equals("savvy"));
* // mt is {Object[] => List}
* mt = MethodType.make(java.util.List.class, Object[].class);
* mh = lookup.findStatic(java.util.Arrays.class, "asList", mt);
* // mt is {(Object,Object,Object) => Object}
* mt = MethodType.makeGeneric(3);
* mh = MethodHandles.collectArguments(mh, mt);
* // mt is {(Object,Object,Object) => Object}
* // (Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
* x = mh.invoke((Object)1, (Object)2, (Object)3);
* assert(x.equals(java.util.Arrays.asList(1,2,3)));
* // mt is { => int}
* mt = MethodType.make(int.class);
* mh = lookup.findVirtual(java.util.List.class, "size", mt);
* // (Ljava/util/List;)I
* i = mh.<int>invoke(java.util.Arrays.asList(1,2,3));
* assert(i == 3);
* </pre></blockquote>
* Each of the above calls generates a single invokevirtual instruction
* with the name {@code invoke} and the type descriptors indicated in the comments.
* The argument types are taken directly from the actual arguments,
* while the return type is taken from the type parameter.
* (This type parameter may be a primitive, and it defaults to {@code Object}.)
* <p>
* <em>A note on generic typing:</em> Method handles do not represent
* their function types in terms of Java parameterized (generic) types,
* because there are three mismatches between function types and parameterized
* Java types.
* <ol>
* <li>Method types range over all possible arities,
* from no arguments to an arbitrary number of arguments.
* Generics are not variadic, and so cannot represent this.</li>
* <li>Method types can specify arguments of primitive types,
* which Java generic types cannot range over.</li>
* <li>Higher order functions over method handles (combinators) are
* often generic across a wide range of function types, including
* those of multiple arities. It is impossible to represent such
* genericity with a Java type parameter.</li>
* </ol>
*
*
* @see MethodType
* @see MethodType
* @see MethodHandles
* @see MethodHandles
...
@@ -107,17 +177,19 @@ public abstract class MethodHandle
...
@@ -107,17 +177,19 @@ public abstract class MethodHandle
// with a JVM change which moves the required hidden state onto this class.
// with a JVM change which moves the required hidden state onto this class.
extends
MethodHandleImpl
extends
MethodHandleImpl
{
{
// interface MethodHandle<T extends MethodType<R,A...>>
private
static
Access
IMPL_TOKEN
=
Access
.
getToken
();
// { T type(); <R,A...> public R invoke(A...); }
// interface MethodHandle<R throws X extends Exception,A...>
// { MethodType<R throws X,A...> type(); public R invoke(A...) throws X; }
final
private
MethodType
type
;
private
MethodType
type
;
/**
/**
* Report the type of this method handle.
* Report the type of this method handle.
* Every invocation of this method handle must exactly match this type.
* Every invocation of this method handle must exactly match this type.
* @return the method handle type
* @return the method handle type
*/
*/
public
MethodType
type
()
{
public
final
MethodType
type
()
{
return
type
;
return
type
;
}
}
...
@@ -130,6 +202,369 @@ public abstract class MethodHandle
...
@@ -130,6 +202,369 @@ public abstract class MethodHandle
*/
*/
protected
MethodHandle
(
Access
token
,
MethodType
type
)
{
protected
MethodHandle
(
Access
token
,
MethodType
type
)
{
super
(
token
);
super
(
token
);
Access
.
check
(
token
);
this
.
type
=
type
;
this
.
type
=
type
;
}
}
private
void
initType
(
MethodType
type
)
{
type
.
getClass
();
// elicit NPE
if
(
this
.
type
!=
null
)
throw
new
InternalError
();
this
.
type
=
type
;
}
static
{
// This hack allows the implementation package special access to
// the internals of MethodHandle. In particular, the MTImpl has all sorts
// of cached information useful to the implementation code.
MethodHandleImpl
.
setMethodHandleFriend
(
IMPL_TOKEN
,
new
MethodHandleImpl
.
MethodHandleFriend
()
{
public
void
initType
(
MethodHandle
mh
,
MethodType
type
)
{
mh
.
initType
(
type
);
}
});
}
/** The string of a direct method handle is the simple name of its target method.
* The string of an adapter or bound method handle is the string of its
* target method handle.
* The string of a Java method handle is the string of its entry point method,
* unless the Java method handle overrides the toString method.
*/
@Override
public
String
toString
()
{
return
MethodHandleImpl
.
getNameString
(
IMPL_TOKEN
,
this
);
}
//// First draft of the "Method Handle Kernel API" discussed at the JVM Language Summit, 9/2009.
//// Implementations here currently delegate to statics in MethodHandles. Some of those statics
//// will be deprecated. Others will be kept as "algorithms" to supply degrees of freedom
//// not present in the Kernel API.
/**
* <em>PROVISIONAL API, WORK IN PROGRESS:</em>
* Perform an exact invocation. The signature at the call site of {@code invokeExact} must
* exactly match this method handle's {@code type}.
* No conversions are allowed on arguments or return values.
* <em>This is not yet implemented, pending required compiler and JVM support.</em>
*/
public
final
<
T
>
T
invokeExact
(
Object
...
arguments
)
throws
Throwable
{
// This is an approximate implementation, which discards the caller's signature and refuses the call.
throw
new
InternalError
(
"not yet implemented"
);
}
/**
* <em>PROVISIONAL API, WORK IN PROGRESS:</em>
* Perform a generic invocation. The signature at the call site of {@code invokeExact} must
* have the same arity as this method handle's {@code type}.
* The same conversions are allowed on arguments or return values as are supported by
* by {@link MethodHandles#convertArguments}.
* If the call site signature exactly matches this method handle's {@code type},
* the call proceeds as if by {@link #invokeExact}.
* <em>This is not fully implemented, pending required compiler and JVM support.</em>
*/
// This is an approximate implementation, which discards the caller's signature.
// When it is made signature polymorphic, the overloadings will disappear.
public
final
<
T
>
T
invokeGeneric
()
throws
Throwable
{
MethodHandle
invoker
=
invokers
(
this
.
type
()).
genericInvoker
();
return
invoker
.<
T
>
invoke
(
this
);
}
public
final
<
T
>
T
invokeGeneric
(
Object
a0
)
throws
Throwable
{
MethodHandle
invoker
=
invokers
(
this
.
type
()).
genericInvoker
();
return
invoker
.<
T
>
invoke
(
this
,
a0
);
}
public
final
<
T
>
T
invokeGeneric
(
Object
a0
,
Object
a1
)
throws
Throwable
{
MethodHandle
invoker
=
invokers
(
this
.
type
()).
genericInvoker
();
return
invoker
.<
T
>
invoke
(
this
,
a0
,
a1
);
}
public
final
<
T
>
T
invokeGeneric
(
Object
a0
,
Object
a1
,
Object
a2
)
throws
Throwable
{
MethodHandle
invoker
=
invokers
(
this
.
type
()).
genericInvoker
();
return
invoker
.<
T
>
invoke
(
this
,
a0
,
a1
,
a2
);
}
public
final
<
T
>
T
invokeGeneric
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
)
throws
Throwable
{
MethodHandle
invoker
=
invokers
(
this
.
type
()).
genericInvoker
();
return
invoker
.<
T
>
invoke
(
this
,
a0
,
a1
,
a2
,
a3
);
}
public
final
<
T
>
T
invokeGeneric
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
)
throws
Throwable
{
MethodHandle
invoker
=
invokers
(
this
.
type
()).
genericInvoker
();
return
invoker
.<
T
>
invoke
(
this
,
a0
,
a1
,
a2
,
a3
,
a4
);
}
public
final
<
T
>
T
invokeGeneric
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
)
throws
Throwable
{
MethodHandle
invoker
=
invokers
(
this
.
type
()).
genericInvoker
();
return
invoker
.<
T
>
invoke
(
this
,
a0
,
a1
,
a2
,
a3
,
a4
,
a5
);
}
public
final
<
T
>
T
invokeGeneric
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
a6
)
throws
Throwable
{
MethodHandle
invoker
=
invokers
(
this
.
type
()).
genericInvoker
();
return
invoker
.<
T
>
invoke
(
this
,
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
);
}
public
final
<
T
>
T
invokeGeneric
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
a6
,
Object
a7
)
throws
Throwable
{
MethodHandle
invoker
=
invokers
(
this
.
type
()).
genericInvoker
();
return
invoker
.<
T
>
invoke
(
this
,
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
);
}
public
final
<
T
>
T
invokeGeneric
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
a6
,
Object
a7
,
Object
a8
)
throws
Throwable
{
MethodHandle
invoker
=
invokers
(
this
.
type
()).
genericInvoker
();
return
invoker
.<
T
>
invoke
(
this
,
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
);
}
public
final
<
T
>
T
invokeGeneric
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
a6
,
Object
a7
,
Object
a8
,
Object
a9
)
throws
Throwable
{
MethodHandle
invoker
=
invokers
(
this
.
type
()).
genericInvoker
();
return
invoker
.<
T
>
invoke
(
this
,
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
,
a9
);
}
/**
* <em>PROVISIONAL API, WORK IN PROGRESS:</em>
* Perform a varargs invocation, passing the arguments in the given array
* to the method handle, as if via {@link #invokeGeneric} from a call site
* which mentions only the type {@code Object}, and whose arity is the length
* of the argument array.
* <p>
* The length of the arguments array must equal the parameter count
* of the target's type.
* The arguments array is spread into separate arguments.
* <p>
* In order to match the type of the target, the following argument
* conversions are applied as necessary:
* <ul>
* <li>reference casting
* <li>unboxing
* </ul>
* The following conversions are not applied:
* <ul>
* <li>primitive conversions (e.g., {@code byte} to {@code int}
* <li>varargs conversions other than the initial spread
* <li>any application-specific conversions (e.g., string to number)
* </ul>
* The result returned by the call is boxed if it is a primitive,
* or forced to null if the return type is void.
* <p>
* This call is equivalent to the following code:
* <p><blockquote><pre>
* MethodHandle invoker = MethodHandles.genericInvoker(this.type(), 0, true);
* Object result = invoker.invoke(this, arguments);
* </pre></blockquote>
* @param arguments the arguments to pass to the target
* @return the result returned by the target
* @see MethodHandles#genericInvoker
*/
public
final
Object
invokeVarargs
(
Object
[]
arguments
)
throws
Throwable
{
int
argc
=
arguments
==
null
?
0
:
arguments
.
length
;
MethodType
type
=
type
();
if
(
argc
<=
10
)
{
MethodHandle
invoker
=
MethodHandles
.
invokers
(
type
).
genericInvoker
();
switch
(
argc
)
{
case
0
:
return
invoker
.
invoke
(
this
);
case
1
:
return
invoker
.
invoke
(
this
,
arguments
[
0
]);
case
2
:
return
invoker
.
invoke
(
this
,
arguments
[
0
],
arguments
[
1
]);
case
3
:
return
invoker
.
invoke
(
this
,
arguments
[
0
],
arguments
[
1
],
arguments
[
2
]);
case
4
:
return
invoker
.
invoke
(
this
,
arguments
[
0
],
arguments
[
1
],
arguments
[
2
],
arguments
[
3
]);
case
5
:
return
invoker
.
invoke
(
this
,
arguments
[
0
],
arguments
[
1
],
arguments
[
2
],
arguments
[
3
],
arguments
[
4
]);
case
6
:
return
invoker
.
invoke
(
this
,
arguments
[
0
],
arguments
[
1
],
arguments
[
2
],
arguments
[
3
],
arguments
[
4
],
arguments
[
5
]);
case
7
:
return
invoker
.
invoke
(
this
,
arguments
[
0
],
arguments
[
1
],
arguments
[
2
],
arguments
[
3
],
arguments
[
4
],
arguments
[
5
],
arguments
[
6
]);
case
8
:
return
invoker
.
invoke
(
this
,
arguments
[
0
],
arguments
[
1
],
arguments
[
2
],
arguments
[
3
],
arguments
[
4
],
arguments
[
5
],
arguments
[
6
],
arguments
[
7
]);
case
9
:
return
invoker
.
invoke
(
this
,
arguments
[
0
],
arguments
[
1
],
arguments
[
2
],
arguments
[
3
],
arguments
[
4
],
arguments
[
5
],
arguments
[
6
],
arguments
[
7
],
arguments
[
8
]);
case
10
:
return
invoker
.
invoke
(
this
,
arguments
[
0
],
arguments
[
1
],
arguments
[
2
],
arguments
[
3
],
arguments
[
4
],
arguments
[
5
],
arguments
[
6
],
arguments
[
7
],
arguments
[
8
],
arguments
[
9
]);
}
}
// more than ten arguments get boxed in a varargs list:
MethodHandle
invoker
=
MethodHandles
.
invokers
(
type
).
varargsInvoker
(
0
);
return
invoker
.
invoke
(
this
,
arguments
);
}
/** Equivalent to {@code invokeVarargs(arguments.toArray())}. */
public
final
Object
invokeVarargs
(
java
.
util
.
List
<?>
arguments
)
throws
Throwable
{
return
invokeVarargs
(
arguments
.
toArray
());
}
/* --- this is intentionally NOT a javadoc yet ---
* <em>PROVISIONAL API, WORK IN PROGRESS:</em>
* Produce an adapter method handle which adapts the type of the
* current method handle to a new type by pairwise argument conversion.
* The original type and new type must have the same number of arguments.
* The resulting method handle is guaranteed to confess a type
* which is equal to the desired new type.
* <p>
* If the original type and new type are equal, returns {@code this}.
* <p>
* The following conversions are applied as needed both to
* arguments and return types. Let T0 and T1 be the differing
* new and old parameter types (or old and new return types)
* for corresponding values passed by the new and old method types.
* Given those types T0, T1, one of the following conversions is applied
* if possible:
* <ul>
* <li>If T0 and T1 are references, and T1 is not an interface type,
* then a cast to T1 is applied.
* (The types do not need to be related in any particular way.)
* <li>If T0 and T1 are references, and T1 is an interface type,
* then the value of type T0 is passed as a T1 without a cast.
* (This treatment of interfaces follows the usage of the bytecode verifier.)
* <li>If T0 and T1 are primitives, then a Java casting
* conversion (JLS 5.5) is applied, if one exists.
* <li>If T0 and T1 are primitives and one is boolean,
* the boolean is treated as a one-bit unsigned integer.
* (This treatment follows the usage of the bytecode verifier.)
* A conversion from another primitive type behaves as if
* it first converts to byte, and then masks all but the low bit.
* <li>If T0 is a primitive and T1 a reference, a boxing
* conversion is applied if one exists, possibly followed by
* an reference conversion to a superclass.
* T1 must be a wrapper class or a supertype of one.
* If T1 is a wrapper class, T0 is converted if necessary
* to T1's primitive type by one of the preceding conversions.
* Otherwise, T0 is boxed, and its wrapper converted to T1.
* <li>If T0 is a reference and T1 a primitive, an unboxing
* conversion is applied if one exists, possibly preceded by
* a reference conversion to a wrapper class.
* T0 must be a wrapper class or a supertype of one.
* If T0 is a wrapper class, its primitive value is converted
* if necessary to T1 by one of the preceding conversions.
* Otherwise, T0 is converted directly to the wrapper type for T1,
* which is then unboxed.
* <li>If the return type T1 is void, any returned value is discarded
* <li>If the return type T0 is void and T1 a reference, a null value is introduced.
* <li>If the return type T0 is void and T1 a primitive, a zero value is introduced.
* </ul>
* <p>
*/
/**
* <em>PROVISIONAL API, WORK IN PROGRESS:</em>
* Produce an adapter method handle which adapts the type of the
* current method handle to a new type by pairwise argument conversion.
* The original type and new type must have the same number of arguments.
* The resulting method handle is guaranteed to confess a type
* which is equal to the desired new type.
* <p>
* If the original type and new type are equal, returns {@code this}.
* <p>
* This method is equivalent to {@link MethodHandles#convertArguments}.
* @param newType the expected type of the new method handle
* @return a method handle which delegates to {@code this} after performing
* any necessary argument conversions, and arranges for any
* necessary return value conversions
* @throws IllegalArgumentException if the conversion cannot be made
* @see MethodHandles#convertArguments
*/
public
final
MethodHandle
asType
(
MethodType
newType
)
{
return
MethodHandles
.
convertArguments
(
this
,
newType
);
}
/**
* <em>PROVISIONAL API, WORK IN PROGRESS:</em>
* Produce a method handle which adapts, as its <i>target</i>,
* the current method handle. The type of the adapter will be
* the same as the type of the target, except that all but the first
* {@code keepPosArgs} parameters of the target's type are replaced
* by a single array parameter of type {@code Object[]}.
* Thus, if {@code keepPosArgs} is zero, the adapter will take all
* arguments in a single object array.
* <p>
* When called, the adapter replaces a trailing array argument
* by the array's elements, each as its own argument to the target.
* (The order of the arguments is preserved.)
* They are converted pairwise by casting and/or unboxing
* (as if by {@link MethodHandles#convertArguments})
* to the types of the trailing parameters of the target.
* Finally the target is called.
* What the target eventually returns is returned unchanged by the adapter.
* <p>
* Before calling the target, the adapter verifies that the array
* contains exactly enough elements to provide a correct argument count
* to the target method handle.
* (The array may also be null when zero elements are required.)
* @param keepPosArgs the number of leading positional arguments to preserve
* @return a new method handle which spreads its final argument,
* before calling the original method handle
* @throws IllegalArgumentException if target does not have at least
* {@code keepPosArgs} parameter types
*/
public
final
MethodHandle
asSpreader
(
int
keepPosArgs
)
{
MethodType
oldType
=
type
();
int
nargs
=
oldType
.
parameterCount
();
MethodType
newType
=
oldType
.
dropParameterTypes
(
keepPosArgs
,
nargs
);
newType
=
newType
.
insertParameterTypes
(
keepPosArgs
,
Object
[].
class
);
return
MethodHandles
.
spreadArguments
(
this
,
newType
);
}
/**
* <em>PROVISIONAL API, WORK IN PROGRESS:</em>
* Produce a method handle which adapts, as its <i>target</i>,
* the current method handle. The type of the adapter will be
* the same as the type of the target, except that a single trailing
* array parameter of type {@code Object[]} is replaced by
* {@code spreadArrayArgs} parameters of type {@code Object}.
* <p>
* When called, the adapter replaces its trailing {@code spreadArrayArgs}
* arguments by a single new {@code Object} array, whose elements
* comprise (in order) the replaced arguments.
* Finally the target is called.
* What the target eventually returns is returned unchanged by the adapter.
* <p>
* (The array may also be a shared constant when {@code spreadArrayArgs} is zero.)
* @param spreadArrayArgs the number of arguments to spread from the trailing array
* @return a new method handle which collects some trailing argument
* into an array, before calling the original method handle
* @throws IllegalArgumentException if the last argument of the target
* is not {@code Object[]}
* @throws IllegalArgumentException if {@code spreadArrayArgs} is not
* a legal array size
* @deprecated Provisional and unstable; use {@link MethodHandles#collectArguments}.
*/
public
final
MethodHandle
asCollector
(
int
spreadArrayArgs
)
{
MethodType
oldType
=
type
();
int
nargs
=
oldType
.
parameterCount
();
MethodType
newType
=
oldType
.
dropParameterTypes
(
nargs
-
1
,
nargs
);
newType
=
newType
.
insertParameterTypes
(
nargs
-
1
,
MethodType
.
genericMethodType
(
spreadArrayArgs
).
parameterArray
());
return
MethodHandles
.
collectArguments
(
this
,
newType
);
}
/**
* <em>PROVISIONAL API, WORK IN PROGRESS:</em>
* Produce a method handle which binds the given argument
* to the current method handle as <i>target</i>.
* The type of the bound handle will be
* the same as the type of the target, except that a single leading
* reference parameter will be omitted.
* <p>
* When called, the bound handle inserts the given value {@code x}
* as a new leading argument to the target. The other arguments are
* also passed unchanged.
* What the target eventually returns is returned unchanged by the bound handle.
* <p>
* The reference {@code x} must be convertible to the first parameter
* type of the target.
* @param x the value to bind to the first argument of the target
* @return a new method handle which collects some trailing argument
* into an array, before calling the original method handle
* @throws IllegalArgumentException if the target does not have a
* leading parameter type that is a reference type
* @throws ClassCastException if {@code x} cannot be converted
* to the leading parameter type of the target
* @deprecated Provisional and unstable; use {@link MethodHandles#insertArguments}.
*/
public
final
MethodHandle
bindTo
(
Object
x
)
{
return
MethodHandles
.
insertArguments
(
this
,
0
,
x
);
}
}
}
src/share/classes/java/dyn/MethodHandles.java
浏览文件 @
8992d5c6
...
@@ -34,6 +34,7 @@ import sun.dyn.util.Wrapper;
...
@@ -34,6 +34,7 @@ import sun.dyn.util.Wrapper;
import
java.lang.reflect.Field
;
import
java.lang.reflect.Field
;
import
java.lang.reflect.Method
;
import
java.lang.reflect.Method
;
import
java.lang.reflect.Modifier
;
import
java.lang.reflect.Modifier
;
import
java.util.List
;
import
java.util.ArrayList
;
import
java.util.ArrayList
;
import
java.util.Arrays
;
import
java.util.Arrays
;
import
sun.dyn.Invokers
;
import
sun.dyn.Invokers
;
...
@@ -44,17 +45,14 @@ import static sun.dyn.MemberName.newNoAccessException;
...
@@ -44,17 +45,14 @@ import static sun.dyn.MemberName.newNoAccessException;
/**
/**
* Fundamental operations and utilities for MethodHandle.
* Fundamental operations and utilities for MethodHandle.
* They fall into several categories:
* <ul>
* <li>Reifying methods and fields. This is subject to access checks.
* <li>Invoking method handles on dynamically typed arguments and/or varargs arrays.
* <li>Combining or transforming pre-existing method handles into new ones.
* <li>Miscellaneous emulation of common JVM operations or control flow patterns.
* </ul>
* <p>
* <p>
* <em>API Note:</em> The matching of method types in this API cannot
* be completely checked by Java's generic type system for three reasons:
* <ol>
* <li>Method types range over all possible arities,
* from no arguments to an arbitrary number of arguments.
* Generics are not variadic, and so cannot represent this.</li>
* <li>Method types can specify arguments of primitive types,
* which Java generic types cannot range over.</li>
* <li>Method types can optionally specify varargs (ellipsis).</li>
* </ol>
* @author John Rose, JSR 292 EG
* @author John Rose, JSR 292 EG
*/
*/
public
class
MethodHandles
{
public
class
MethodHandles
{
...
@@ -68,12 +66,22 @@ public class MethodHandles {
...
@@ -68,12 +66,22 @@ public class MethodHandles {
//// Method handle creation from ordinary methods.
//// Method handle creation from ordinary methods.
/** Create a {@link Lookup} lookup object on the caller.
*
*/
public
static
Lookup
lookup
()
{
public
static
Lookup
lookup
()
{
return
new
Lookup
();
return
new
Lookup
();
}
}
/** Version of lookup which is trusted minimally.
* It can only be used to create method handles to
* publicly accessible members.
*/
public
static
Lookup
publicLookup
()
{
return
Lookup
.
PUBLIC_LOOKUP
;
}
/**
/**
* <em>PROVISIONAL API, WORK IN PROGRESS:</em>
* A factory object for creating method handles, when the creation
* A factory object for creating method handles, when the creation
* requires access checking. Method handles do not perform
* requires access checking. Method handles do not perform
* access checks when they are called; this is a major difference
* access checks when they are called; this is a major difference
...
@@ -121,7 +129,8 @@ public class MethodHandles {
...
@@ -121,7 +129,8 @@ public class MethodHandles {
/** Which class is performing the lookup? It is this class against
/** Which class is performing the lookup? It is this class against
* which checks are performed for visibility and access permissions.
* which checks are performed for visibility and access permissions.
* <p>
* <p>
* This value is null if and only if this lookup is {@link #PUBLIC_LOOKUP}.
* This value is null if and only if this lookup was produced
* by {@link MethodHandles#publicLookup}.
*/
*/
public
Class
<?>
lookupClass
()
{
public
Class
<?>
lookupClass
()
{
return
lookupClass
;
return
lookupClass
;
...
@@ -135,23 +144,46 @@ public class MethodHandles {
...
@@ -135,23 +144,46 @@ public class MethodHandles {
* an access$N method.
* an access$N method.
*/
*/
Lookup
()
{
Lookup
()
{
Class
caller
=
getCallerClassAtEntryPoint
();
this
(
IMPL_TOKEN
,
getCallerClassAtEntryPoint
());
// make sure we haven't accidentally picked up this class:
}
checkUnprivilegedlookupClass
(
caller
);
this
.
lookupClass
=
caller
;
Lookup
(
Access
token
,
Class
<?>
lookupClass
)
{
// make sure we haven't accidentally picked up a privileged class:
checkUnprivilegedlookupClass
(
lookupClass
);
this
.
lookupClass
=
lookupClass
;
}
/**
* Create a lookup on the specified class.
* The result is guaranteed to have no more access privileges
* than the original.
*/
public
Lookup
in
(
Class
<?>
newLookupClass
)
{
if
(
this
==
PUBLIC_LOOKUP
)
return
PUBLIC_LOOKUP
;
if
(
newLookupClass
==
null
)
return
PUBLIC_LOOKUP
;
if
(
newLookupClass
==
lookupClass
)
return
this
;
if
(
this
!=
IMPL_LOOKUP
)
{
if
(!
VerifyAccess
.
isSamePackage
(
lookupClass
,
newLookupClass
))
throw
newNoAccessException
(
new
MemberName
(
newLookupClass
),
this
);
checkUnprivilegedlookupClass
(
newLookupClass
);
}
return
new
Lookup
(
newLookupClass
);
}
}
private
Lookup
(
Class
<?>
lookupClass
)
{
private
Lookup
(
Class
<?>
lookupClass
)
{
this
.
lookupClass
=
lookupClass
;
this
.
lookupClass
=
lookupClass
;
}
}
// Make sure outer class is initialized first.
static
{
IMPL_TOKEN
.
getClass
();
}
private
static
final
Class
<?>
PUBLIC_ONLY
=
sun
.
dyn
.
empty
.
Empty
.
class
;
private
static
final
Class
<?>
PUBLIC_ONLY
=
sun
.
dyn
.
empty
.
Empty
.
class
;
/** Version of lookup which is trusted minimally.
/** Version of lookup which is trusted minimally.
* It can only be used to create method handles to
* It can only be used to create method handles to
* publicly accessible members.
* publicly accessible members.
*/
*/
public
static
final
Lookup
PUBLIC_LOOKUP
=
new
Lookup
(
PUBLIC_ONLY
);
static
final
Lookup
PUBLIC_LOOKUP
=
new
Lookup
(
PUBLIC_ONLY
);
/** Package-private version of lookup which is trusted. */
/** Package-private version of lookup which is trusted. */
static
final
Lookup
IMPL_LOOKUP
=
new
Lookup
(
null
);
static
final
Lookup
IMPL_LOOKUP
=
new
Lookup
(
null
);
...
@@ -178,12 +210,16 @@ public class MethodHandles {
...
@@ -178,12 +210,16 @@ public class MethodHandles {
// 0: Reflection.getCC, 1: getCallerClassAtEntryPoint,
// 0: Reflection.getCC, 1: getCallerClassAtEntryPoint,
// 2: Lookup.<init>, 3: MethodHandles.*, 4: caller
// 2: Lookup.<init>, 3: MethodHandles.*, 4: caller
// Note: This should be the only use of getCallerClass in this file.
// Note: This should be the only use of getCallerClass in this file.
assert
(
Reflection
.
getCallerClass
(
CALLER_DEPTH
-
1
)
==
MethodHandles
.
class
);
return
Reflection
.
getCallerClass
(
CALLER_DEPTH
);
return
Reflection
.
getCallerClass
(
CALLER_DEPTH
);
}
}
/**
/**
* Produce a method handle for a static method.
* Produce a method handle for a static method.
* The type of the method handle will be that of the method.
* The type of the method handle will be that of the method.
* (Since static methods do not take receivers, there is no
* additional receiver argument inserted into the method handle type,
* as there would be with {@linkplain #findVirtual} or {@linkplain #findSpecial}.)
* The method and all its argument types must be accessible to the lookup class.
* The method and all its argument types must be accessible to the lookup class.
* If the method's class has not yet been initialized, that is done
* If the method's class has not yet been initialized, that is done
* immediately, before the method handle is returned.
* immediately, before the method handle is returned.
...
@@ -196,10 +232,11 @@ public class MethodHandles {
...
@@ -196,10 +232,11 @@ public class MethodHandles {
*/
*/
public
public
MethodHandle
findStatic
(
Class
<?>
defc
,
String
name
,
MethodType
type
)
throws
NoAccessException
{
MethodHandle
findStatic
(
Class
<?>
defc
,
String
name
,
MethodType
type
)
throws
NoAccessException
{
MemberName
method
=
IMPL_NAMES
.
resolveOrFail
(
new
MemberName
(
defc
,
name
,
type
,
Modifier
.
STATIC
),
true
,
lookupClass
);
MemberName
method
=
IMPL_NAMES
.
resolveOrFail
(
new
MemberName
(
defc
,
name
,
type
,
Modifier
.
STATIC
),
true
,
lookupClass
());
checkStatic
(
true
,
method
,
lookupClass
);
VerifyAccess
.
checkName
(
method
,
this
);
checkStatic
(
true
,
method
,
this
);
//throw NoSuchMethodException
//throw NoSuchMethodException
return
MethodHandleImpl
.
findMethod
(
IMPL_TOKEN
,
method
,
false
,
lookupClass
);
return
MethodHandleImpl
.
findMethod
(
IMPL_TOKEN
,
method
,
false
,
lookupClass
()
);
}
}
/**
/**
...
@@ -228,9 +265,10 @@ public class MethodHandles {
...
@@ -228,9 +265,10 @@ public class MethodHandles {
* @exception NoAccessException if the method does not exist or access checking fails
* @exception NoAccessException if the method does not exist or access checking fails
*/
*/
public
MethodHandle
findVirtual
(
Class
<?>
defc
,
String
name
,
MethodType
type
)
throws
NoAccessException
{
public
MethodHandle
findVirtual
(
Class
<?>
defc
,
String
name
,
MethodType
type
)
throws
NoAccessException
{
MemberName
method
=
IMPL_NAMES
.
resolveOrFail
(
new
MemberName
(
defc
,
name
,
type
),
true
,
lookupClass
);
MemberName
method
=
IMPL_NAMES
.
resolveOrFail
(
new
MemberName
(
defc
,
name
,
type
),
true
,
lookupClass
());
checkStatic
(
false
,
method
,
lookupClass
);
VerifyAccess
.
checkName
(
method
,
this
);
return
MethodHandleImpl
.
findMethod
(
IMPL_TOKEN
,
method
,
true
,
lookupClass
);
checkStatic
(
false
,
method
,
this
);
return
MethodHandleImpl
.
findMethod
(
IMPL_TOKEN
,
method
,
true
,
lookupClass
());
}
}
/**
/**
...
@@ -259,15 +297,17 @@ public class MethodHandles {
...
@@ -259,15 +297,17 @@ public class MethodHandles {
*/
*/
public
MethodHandle
findSpecial
(
Class
<?>
defc
,
String
name
,
MethodType
type
,
public
MethodHandle
findSpecial
(
Class
<?>
defc
,
String
name
,
MethodType
type
,
Class
<?>
specialCaller
)
throws
NoAccessException
{
Class
<?>
specialCaller
)
throws
NoAccessException
{
checkSpecialCaller
(
specialCaller
,
lookupClass
);
checkSpecialCaller
(
specialCaller
,
this
);
MemberName
method
=
IMPL_NAMES
.
resolveOrFail
(
new
MemberName
(
defc
,
name
,
type
),
false
,
specialCaller
);
Lookup
slookup
=
this
.
in
(
specialCaller
);
checkStatic
(
false
,
method
,
lookupClass
);
MemberName
method
=
IMPL_NAMES
.
resolveOrFail
(
new
MemberName
(
defc
,
name
,
type
),
false
,
slookup
.
lookupClass
());
VerifyAccess
.
checkName
(
method
,
this
);
checkStatic
(
false
,
method
,
this
);
if
(
name
.
equals
(
"<init>"
))
{
if
(
name
.
equals
(
"<init>"
))
{
throw
newNoAccessException
(
"cannot directly invoke a constructor"
,
method
,
null
);
throw
newNoAccessException
(
"cannot directly invoke a constructor"
,
method
,
null
);
}
else
if
(
defc
.
isInterface
()
||
!
defc
.
isAssignableFrom
(
specialCaller
))
{
}
else
if
(
defc
.
isInterface
()
||
!
defc
.
isAssignableFrom
(
specialCaller
))
{
throw
newNoAccessException
(
"method must be in a superclass of lookup class"
,
method
,
lookupClass
);
throw
newNoAccessException
(
"method must be in a superclass of lookup class"
,
method
,
slookup
.
lookupClass
()
);
}
}
return
MethodHandleImpl
.
findMethod
(
IMPL_TOKEN
,
method
,
false
,
s
pecialCaller
);
return
MethodHandleImpl
.
findMethod
(
IMPL_TOKEN
,
method
,
false
,
s
lookup
.
lookupClass
()
);
}
}
/**
/**
...
@@ -275,13 +315,19 @@ public class MethodHandles {
...
@@ -275,13 +315,19 @@ public class MethodHandles {
* The receiver must have a supertype {@code defc} in which a method
* The receiver must have a supertype {@code defc} in which a method
* of the given name and type is accessible to the lookup class.
* of the given name and type is accessible to the lookup class.
* The method and all its argument types must be accessible to the lookup class.
* The method and all its argument types must be accessible to the lookup class.
* The type of the method handle will be that of the method.
* The type of the method handle will be that of the method,
* The given receiver will be bound into the method handle.
* without any insertion of an additional receiver parameter.
* The given receiver will be bound into the method handle,
* so that every call to the method handle will invoke the
* requested method on the given receiver.
* <p>
* <p>
*
E
quivalent to the following expression:
*
This is e
quivalent to the following expression:
* <code>
* <code>
* {@link #insertArgument}({@link #findVirtual}(defc, name, type), receiver)
* {@link #insertArgument
s
}({@link #findVirtual}(defc, name, type), receiver)
* </code>
* </code>
* where {@code defc} is either {@code receiver.getClass()} or a super
* type of that class, in which the requested method is accessible
* to the lookup class.
* @param receiver the object from which the method is accessed
* @param receiver the object from which the method is accessed
* @param name the name of the method
* @param name the name of the method
* @param type the type of the method, with the receiver argument omitted
* @param type the type of the method, with the receiver argument omitted
...
@@ -292,16 +338,18 @@ public class MethodHandles {
...
@@ -292,16 +338,18 @@ public class MethodHandles {
public
MethodHandle
bind
(
Object
receiver
,
String
name
,
MethodType
type
)
throws
NoAccessException
{
public
MethodHandle
bind
(
Object
receiver
,
String
name
,
MethodType
type
)
throws
NoAccessException
{
Class
<?
extends
Object
>
rcvc
=
receiver
.
getClass
();
// may get NPE
Class
<?
extends
Object
>
rcvc
=
receiver
.
getClass
();
// may get NPE
MemberName
reference
=
new
MemberName
(
rcvc
,
name
,
type
);
MemberName
reference
=
new
MemberName
(
rcvc
,
name
,
type
);
MemberName
method
=
IMPL_NAMES
.
resolveOrFail
(
reference
,
true
,
lookupClass
);
MemberName
method
=
IMPL_NAMES
.
resolveOrFail
(
reference
,
true
,
lookupClass
());
checkStatic
(
false
,
method
,
lookupClass
);
VerifyAccess
.
checkName
(
method
,
this
);
MethodHandle
dmh
=
MethodHandleImpl
.
findMethod
(
IMPL_TOKEN
,
method
,
true
,
lookupClass
);
checkStatic
(
false
,
method
,
this
);
MethodHandle
dmh
=
MethodHandleImpl
.
findMethod
(
IMPL_TOKEN
,
method
,
true
,
lookupClass
());
MethodHandle
bmh
=
MethodHandleImpl
.
bindReceiver
(
IMPL_TOKEN
,
dmh
,
receiver
);
MethodHandle
bmh
=
MethodHandleImpl
.
bindReceiver
(
IMPL_TOKEN
,
dmh
,
receiver
);
if
(
bmh
==
null
)
if
(
bmh
==
null
)
throw
newNoAccessException
(
method
,
lookupClas
s
);
throw
newNoAccessException
(
method
,
thi
s
);
return
bmh
;
return
bmh
;
}
}
/**
/**
* <em>PROVISIONAL API, WORK IN PROGRESS:</em>
* Make a direct method handle to <i>m</i>, if the lookup class has permission.
* Make a direct method handle to <i>m</i>, if the lookup class has permission.
* If <i>m</i> is non-static, the receiver argument is treated as an initial argument.
* If <i>m</i> is non-static, the receiver argument is treated as an initial argument.
* If <i>m</i> is virtual, overriding is respected on every call.
* If <i>m</i> is virtual, overriding is respected on every call.
...
@@ -316,10 +364,11 @@ public class MethodHandles {
...
@@ -316,10 +364,11 @@ public class MethodHandles {
* @exception NoAccessException if access checking fails
* @exception NoAccessException if access checking fails
*/
*/
public
MethodHandle
unreflect
(
Method
m
)
throws
NoAccessException
{
public
MethodHandle
unreflect
(
Method
m
)
throws
NoAccessException
{
return
unreflectImpl
(
new
MemberName
(
m
),
m
.
isAccessible
(),
true
,
lookupClas
s
);
return
unreflectImpl
(
new
MemberName
(
m
),
m
.
isAccessible
(),
true
,
false
,
thi
s
);
}
}
/**
/**
* <em>PROVISIONAL API, WORK IN PROGRESS:</em>
* Produce a method handle for a reflected method.
* Produce a method handle for a reflected method.
* It will bypass checks for overriding methods on the receiver,
* It will bypass checks for overriding methods on the receiver,
* as if by the {@code invokespecial} instruction.
* as if by the {@code invokespecial} instruction.
...
@@ -333,37 +382,41 @@ public class MethodHandles {
...
@@ -333,37 +382,41 @@ public class MethodHandles {
* @exception NoAccessException if access checking fails
* @exception NoAccessException if access checking fails
*/
*/
public
MethodHandle
unreflectSpecial
(
Method
m
,
Class
<?>
specialCaller
)
throws
NoAccessException
{
public
MethodHandle
unreflectSpecial
(
Method
m
,
Class
<?>
specialCaller
)
throws
NoAccessException
{
checkSpecialCaller
(
specialCaller
,
lookupClass
);
checkSpecialCaller
(
specialCaller
,
this
);
Lookup
slookup
=
this
.
in
(
specialCaller
);
MemberName
mname
=
new
MemberName
(
m
);
MemberName
mname
=
new
MemberName
(
m
);
checkStatic
(
false
,
mname
,
lookupClas
s
);
checkStatic
(
false
,
mname
,
thi
s
);
return
unreflectImpl
(
mname
,
m
.
isAccessible
(),
false
,
specialCaller
);
return
unreflectImpl
(
mname
,
m
.
isAccessible
(),
false
,
false
,
slookup
);
}
}
/**
/**
* <em>PROVISIONAL API, WORK IN PROGRESS:</em>
* Produce a method handle for a reflected constructor.
* Produce a method handle for a reflected constructor.
* The type of the method handle will be that of the constructor.
* The type of the method handle will be that of the constructor,
* with the return type changed to the declaring class.
* The method handle will perform a {@code newInstance} operation,
* The method handle will perform a {@code newInstance} operation,
* creating a new instance of the constructor's class on the
* creating a new instance of the constructor's class on the
* arguments passed to the method handle.
* arguments passed to the method handle.
* <p>
* <p>
* If the constructor's {@code accessible} flag is not set,
* If the constructor's {@code accessible} flag is not set,
* access checking is performed immediately on behalf of the lookup class,
* access checking is performed immediately on behalf of the lookup class.
* as if {@code invokespecial} instruction were being linked.
* @param ctor the reflected constructor
* @param ctor the reflected constructor
* @return a method handle which can invoke the reflected constructor
* @return a method handle which can invoke the reflected constructor
* @exception NoAccessException if access checking fails
* @exception NoAccessException if access checking fails
*/
*/
public
MethodHandle
unreflectConstructor
(
Constructor
ctor
)
throws
NoAccessException
{
public
MethodHandle
unreflectConstructor
(
Constructor
ctor
)
throws
NoAccessException
{
MemberName
m
=
new
MemberName
(
ctor
);
MemberName
m
=
new
MemberName
(
ctor
);
return
unreflectImpl
(
m
,
ctor
.
isAccessible
(),
false
,
lookupClas
s
);
return
unreflectImpl
(
m
,
ctor
.
isAccessible
(),
false
,
false
,
thi
s
);
}
}
/**
/**
* <em>PROVISIONAL API, WORK IN PROGRESS:</em>
* <em>PROVISIONAL API, WORK IN PROGRESS:</em>
* Produce a method handle giving read access to a reflected field.
* Produce a method handle giving read access to a reflected field.
* The type of the method handle will have a return type of the field's
* The type of the method handle will have a return type of the field's
* value type. Its sole argument will be the field's containing class
* value type.
* (but only if it is non-static).
* If the field is static, the method handle will take no arguments.
* Otherwise, its single argument will be the instance containing
* the field.
* If the method's {@code accessible} flag is not set,
* If the method's {@code accessible} flag is not set,
* access checking is performed immediately on behalf of the lookup class.
* access checking is performed immediately on behalf of the lookup class.
* @param f the reflected field
* @param f the reflected field
...
@@ -371,16 +424,18 @@ public class MethodHandles {
...
@@ -371,16 +424,18 @@ public class MethodHandles {
* @exception NoAccessException if access checking fails
* @exception NoAccessException if access checking fails
*/
*/
public
MethodHandle
unreflectGetter
(
Field
f
)
throws
NoAccessException
{
public
MethodHandle
unreflectGetter
(
Field
f
)
throws
NoAccessException
{
return
MethodHandleImpl
.
accessField
(
IMPL_TOKEN
,
new
MemberName
(
f
),
false
,
lookupClass
);
MemberName
m
=
new
MemberName
(
f
);
return
unreflectImpl
(
m
,
f
.
isAccessible
(),
false
,
false
,
this
);
}
}
/**
/**
* <em>PROVISIONAL API, WORK IN PROGRESS:</em>
* <em>PROVISIONAL API, WORK IN PROGRESS:</em>
* Produce a method handle giving write access to a reflected field.
* Produce a method handle giving write access to a reflected field.
* The type of the method handle will have a void return type.
* The type of the method handle will have a void return type.
* Its last argument will be the field's value type.
* If the field is static, the method handle will take a single
* Its other argument will be the field's containing class
* argument, of the field's value type, the value to be stored.
* (but only if it is non-static).
* Otherwise, the two arguments will be the instance containing
* the field, and the value to be stored.
* If the method's {@code accessible} flag is not set,
* If the method's {@code accessible} flag is not set,
* access checking is performed immediately on behalf of the lookup class.
* access checking is performed immediately on behalf of the lookup class.
* @param f the reflected field
* @param f the reflected field
...
@@ -388,59 +443,75 @@ public class MethodHandles {
...
@@ -388,59 +443,75 @@ public class MethodHandles {
* @exception NoAccessException if access checking fails
* @exception NoAccessException if access checking fails
*/
*/
public
MethodHandle
unreflectSetter
(
Field
f
)
throws
NoAccessException
{
public
MethodHandle
unreflectSetter
(
Field
f
)
throws
NoAccessException
{
return
MethodHandleImpl
.
accessField
(
IMPL_TOKEN
,
new
MemberName
(
f
),
true
,
lookupClass
);
MemberName
m
=
new
MemberName
(
f
);
return
unreflectImpl
(
m
,
f
.
isAccessible
(),
false
,
true
,
this
);
}
}
}
}
static
/*must not be public*/
static
/*must not be public*/
MethodHandle
findStaticFrom
(
Class
<?>
lookupClass
,
MethodHandle
findStaticFrom
(
Lookup
lookup
,
Class
<?>
defc
,
String
name
,
MethodType
type
)
throws
NoAccessException
{
Class
<?>
defc
,
String
name
,
MethodType
type
)
throws
NoAccessException
{
MemberName
method
=
IMPL_NAMES
.
resolveOrFail
(
new
MemberName
(
defc
,
name
,
type
,
Modifier
.
STATIC
),
true
,
lookupClass
);
MemberName
method
=
IMPL_NAMES
.
resolveOrFail
(
new
MemberName
(
defc
,
name
,
type
,
Modifier
.
STATIC
),
true
,
lookup
.
lookupClass
());
checkStatic
(
true
,
method
,
lookupClass
);
VerifyAccess
.
checkName
(
method
,
lookup
);
return
MethodHandleImpl
.
findMethod
(
IMPL_TOKEN
,
method
,
false
,
lookupClass
);
checkStatic
(
true
,
method
,
lookup
);
return
MethodHandleImpl
.
findMethod
(
IMPL_TOKEN
,
method
,
false
,
lookup
.
lookupClass
());
}
}
static
void
checkStatic
(
boolean
wantStatic
,
MemberName
m
,
Class
<?>
lookupClass
)
{
static
void
checkStatic
(
boolean
wantStatic
,
MemberName
m
,
Lookup
lookup
)
{
if
(
wantStatic
!=
m
.
isStatic
())
{
if
(
wantStatic
!=
m
.
isStatic
())
{
String
message
=
wantStatic
?
"expected a static method"
:
"expected a non-static method"
;
String
message
=
wantStatic
?
"expected a static method"
:
"expected a non-static method"
;
throw
newNoAccessException
(
message
,
m
,
lookup
Class
);
throw
newNoAccessException
(
message
,
m
,
lookup
.
lookupClass
()
);
}
}
}
}
static
void
checkSpecialCaller
(
Class
<?>
specialCaller
,
Class
<?>
lookupClass
)
{
static
void
checkSpecialCaller
(
Class
<?>
specialCaller
,
Lookup
lookup
)
{
if
(
lookup
Class
==
Lookup
.
IMPL_LOOKUP
.
lookupClass
()
)
if
(
lookup
==
Lookup
.
IMPL_LOOKUP
)
return
;
// privileged action
return
;
// privileged action
if
(
lookupClass
==
null
||
// public-only access
assert
(
lookup
.
lookupClass
()
!=
null
);
!
VerifyAccess
.
isSamePackageMember
(
specialCaller
,
lookupClass
))
if
(!
VerifyAccess
.
isSamePackageMember
(
specialCaller
,
lookup
.
lookupClass
()
))
throw
newNoAccessException
(
"no private access"
,
new
MemberName
(
specialCaller
),
lookup
Class
);
throw
newNoAccessException
(
"no private access"
,
new
MemberName
(
specialCaller
),
lookup
.
lookupClass
()
);
}
}
// Helper for creating handles on reflected methods and constructors.
// Helper for creating handles on reflected methods and constructors.
static
MethodHandle
unreflectImpl
(
MemberName
m
,
boolean
isAccessible
,
static
MethodHandle
unreflectImpl
(
MemberName
m
,
boolean
isAccessible
,
boolean
doDispatch
,
Class
<?>
lookupClass
)
{
boolean
doDispatch
,
boolean
isSetter
,
Lookup
lookup
)
{
MethodType
mtype
=
m
.
getInvocationType
()
;
MethodType
narrowMethodType
=
null
;
Class
<?>
defc
=
m
.
getDeclaringClass
();
Class
<?>
defc
=
m
.
getDeclaringClass
();
boolean
isSpecialInvoke
=
m
.
isInvocable
()
&&
!
doDispatch
;
int
mods
=
m
.
getModifiers
();
int
mods
=
m
.
getModifiers
();
if
(
m
.
isStatic
())
{
if
(
m
.
isStatic
())
{
if
(!
isAccessible
&&
if
(!
isAccessible
&&
VerifyAccess
.
isAccessible
(
defc
,
mods
,
false
,
lookupClass
)
==
null
)
VerifyAccess
.
isAccessible
(
defc
,
mods
,
lookup
.
lookupClass
(),
false
)
==
null
)
throw
newNoAccessException
(
m
,
lookup
Class
);
throw
newNoAccessException
(
m
,
lookup
);
}
else
{
}
else
{
Class
<?>
constraint
;
Class
<?>
constraint
;
if
(
isAccessible
)
{
if
(
isAccessible
)
{
// abbreviated access check for "unlocked" method
// abbreviated access check for "unlocked" method
constraint
=
doDispatch
?
defc
:
lookup
Class
;
constraint
=
doDispatch
?
defc
:
lookup
.
lookupClass
()
;
}
else
{
}
else
{
constraint
=
VerifyAccess
.
isAccessible
(
defc
,
mods
,
doDispatch
,
lookupClass
);
constraint
=
VerifyAccess
.
isAccessible
(
defc
,
mods
,
lookup
.
lookupClass
(),
isSpecialInvoke
);
}
if
(
constraint
==
null
)
{
throw
newNoAccessException
(
m
,
lookup
);
}
}
if
(
constraint
!=
defc
&&
!
constraint
.
isAssignableFrom
(
defc
))
{
if
(
constraint
!=
defc
&&
!
constraint
.
isAssignableFrom
(
defc
))
{
if
(!
defc
.
isAssignableFrom
(
constraint
))
if
(!
defc
.
isAssignableFrom
(
constraint
))
throw
newNoAccessException
(
"receiver must be in caller class"
,
m
,
lookupClass
);
throw
newNoAccessException
(
"receiver must be in caller class"
,
m
,
lookup
.
lookupClass
());
mtype
=
mtype
.
changeParameterType
(
0
,
constraint
);
if
(
m
.
isInvocable
())
narrowMethodType
=
m
.
getInvocationType
().
changeParameterType
(
0
,
constraint
);
else
if
(
m
.
isField
())
narrowMethodType
=
(!
isSetter
?
MethodType
.
methodType
(
m
.
getFieldType
(),
constraint
)
:
MethodType
.
methodType
(
void
.
class
,
constraint
,
m
.
getFieldType
()));
}
}
}
}
return
MethodHandleImpl
.
findMethod
(
IMPL_TOKEN
,
m
,
doDispatch
,
lookupClass
);
if
(
m
.
isInvocable
())
return
MethodHandleImpl
.
findMethod
(
IMPL_TOKEN
,
m
,
doDispatch
,
lookup
.
lookupClass
());
else
if
(
m
.
isField
())
return
MethodHandleImpl
.
accessField
(
IMPL_TOKEN
,
m
,
isSetter
,
lookup
.
lookupClass
());
else
throw
new
InternalError
();
}
}
/**
/**
...
@@ -472,138 +543,104 @@ public class MethodHandles {
...
@@ -472,138 +543,104 @@ public class MethodHandles {
return
MethodHandleImpl
.
accessArrayElement
(
IMPL_TOKEN
,
arrayClass
,
true
);
return
MethodHandleImpl
.
accessArrayElement
(
IMPL_TOKEN
,
arrayClass
,
true
);
}
}
/// method handle invocation (reflective style)
/// method handle invocation (reflective style)
/**
/**
* <em>PROVISIONAL API, WORK IN PROGRESS:</em>
* @deprecated Alias for MethodHandle.invokeVarargs.
* Call the {@code invoke} method of a given method handle,
* with arguments that exactly match the parameter types of the method handle.
* The length of the arguments array must equal the parameter count
* of the target's type.
* The arguments array is spread into separate arguments, and
* basic reference and unboxing conversions are applied.
* <p>
* In order to match the type of the target, the following argument
* conversions are applied as necessary:
* <ul>
* <li>reference casting
* <li>unboxing
* </ul>
* The following conversions are not applied:
* <ul>
* <li>primitive conversions (e.g., {@code byte} to {@code int}
* <li>varargs conversions other than the initial spread
* <li>any application-specific conversions (e.g., string to number)
* </ul>
* The result returned by the call is boxed if it is a primitive,
* or forced to null if the return type is void.
* <p>
* This call is a convenience method for the following code:
* <pre>
* MethodHandle invoker = MethodHandles.genericInvoker(target.type(), 0, true);
* Object result = invoker.invoke(arguments);
* </pre>
* @param target the method handle to invoke
* @param arguments the arguments to pass to the target
* @return the result returned by the target
*/
*/
@Deprecated
public
static
public
static
Object
invoke
(
MethodHandle
target
,
Object
...
arguments
)
{
Object
invokeVarargs
(
MethodHandle
target
,
Object
...
arguments
)
throws
Throwable
{
int
argc
=
arguments
==
null
?
0
:
arguments
.
length
;
return
target
.
invokeVarargs
(
arguments
);
MethodType
type
=
target
.
type
();
if
(
argc
<=
4
)
{
MethodHandle
invoker
=
invokers
(
type
).
genericInvoker
();
switch
(
argc
)
{
case
0
:
return
invoker
.<
Object
>
invoke
(
target
);
case
1
:
return
invoker
.<
Object
>
invoke
(
target
,
arguments
[
0
]);
case
2
:
return
invoker
.<
Object
>
invoke
(
target
,
arguments
[
0
],
arguments
[
1
]);
case
3
:
return
invoker
.<
Object
>
invoke
(
target
,
arguments
[
0
],
arguments
[
1
],
arguments
[
2
]);
case
4
:
return
invoker
.<
Object
>
invoke
(
target
,
arguments
[
0
],
arguments
[
1
],
arguments
[
2
],
arguments
[
3
]);
}
}
MethodHandle
invoker
=
invokers
(
type
).
varargsInvoker
();
return
invoker
.<
Object
>
invoke
(
target
,
arguments
);
}
}
/**
* @deprecated Alias for MethodHandle.invokeVarargs.
*/
@Deprecated
public
static
public
static
Object
invoke_0
(
MethodHandle
target
)
{
Object
invoke
(
MethodHandle
target
,
Object
...
arguments
)
throws
Throwable
{
MethodHandle
invoker
=
invokers
(
target
.
type
()).
genericInvoker
();
return
target
.
invokeVarargs
(
arguments
);
return
invoker
.<
Object
>
invoke
(
target
);
}
public
static
Object
invoke_1
(
MethodHandle
target
,
Object
a0
)
{
MethodHandle
invoker
=
invokers
(
target
.
type
()).
genericInvoker
();
return
invoker
.<
Object
>
invoke
(
target
,
a0
);
}
public
static
Object
invoke_2
(
MethodHandle
target
,
Object
a0
,
Object
a1
)
{
MethodHandle
invoker
=
invokers
(
target
.
type
()).
genericInvoker
();
return
invoker
.<
Object
>
invoke
(
target
,
a0
,
a1
);
}
public
static
Object
invoke_3
(
MethodHandle
target
,
Object
a0
,
Object
a1
,
Object
a2
)
{
MethodHandle
invoker
=
invokers
(
target
.
type
()).
genericInvoker
();
return
invoker
.<
Object
>
invoke
(
target
,
a0
,
a1
,
a2
);
}
public
static
Object
invoke_4
(
MethodHandle
target
,
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
)
{
MethodHandle
invoker
=
invokers
(
target
.
type
()).
genericInvoker
();
return
invoker
.<
Object
>
invoke
(
target
,
a0
,
a1
,
a2
,
a3
);
}
}
/**
/**
* <em>PROVISIONAL API, WORK IN PROGRESS:</em>
* <em>PROVISIONAL API, WORK IN PROGRESS:</em>
*
Giv
e a method handle which will invoke any method handle of the
*
Produc
e a method handle which will invoke any method handle of the
* given type on a standard set of {@code Object} type arguments.
* given type on a standard set of {@code Object} type arguments.
* The
the
resulting invoker will be a method handle with the following
* The resulting invoker will be a method handle with the following
* arguments:
* arguments:
* <ul>
* <ul>
* <li>a single {@code MethodHandle} target
* <li>a single {@code MethodHandle} target
* <li>zero or more {@code Object} values
* <li>zero or more {@code Object} values (one for each argument in {@code type})
* <li>an optional {@code Object[]} array containing more arguments
* </ul>
* </ul>
* The invoker will
spread the varargs array (if present), apply
* The invoker will
apply reference casts as necessary and unbox primitive arguments,
*
reference casts as necessary, and unbox primitive arguments
.
*
as if by {@link #convertArguments}
.
* The return value of the invoker will be an {@code Object} reference,
* The return value of the invoker will be an {@code Object} reference,
* boxing a primitive value if the original type returns a primitive,
* boxing a primitive value if the original type returns a primitive,
* and always null if the original type returns void.
* and always null if the original type returns void.
* <p>
* <p>
* This
is a convenience method equivalent to the following code
:
* This
method is equivalent to the following code (though it may be more efficient)
:
* <pre>
* <p
><blockquote><p
re>
* MethodHandle invoker = exactInvoker(type);
* MethodHandle invoker = exactInvoker(type);
* MethodType genericType =
MethodType.makeGeneric(objectArgCount, varargs
);
* MethodType genericType =
type.generic(
);
* genericType = genericType.insertParameterType(0, MethodHandle.class);
* genericType = genericType.insertParameterType(0, MethodHandle.class);
* if (!varargs)
* return convertArguments(invoker, genericType);
* return convertArguments(invoker, genericType);
* else
* </pre></blockquote>
* return spreadArguments(invoker, genericType);
* @param type the type of target methods which the invoker will apply to
* </pre>
* @return a method handle suitable for invoking any method handle of the given type
*/
static
public
MethodHandle
genericInvoker
(
MethodType
type
)
{
return
invokers
(
type
).
genericInvoker
();
}
/**
* <em>PROVISIONAL API, WORK IN PROGRESS:</em>
* Produce a method handle which will invoke any method handle of the
* given type on a standard set of {@code Object} type arguments
* and a single trailing {@code Object[]} array.
* The resulting invoker will be a method handle with the following
* arguments:
* <ul>
* <li>a single {@code MethodHandle} target
* <li>zero or more {@code Object} values (counted by {@code objectArgCount})
* <li>an {@code Object[]} array containing more arguments
* </ul>
* The invoker will spread the varargs array, apply
* reference casts as necessary, and unbox primitive arguments.
* The return value of the invoker will be an {@code Object} reference,
* boxing a primitive value if the original type returns a primitive,
* and always null if the original type returns void.
* <p>
* This method is equivalent to the following code (though it may be more efficient):
* <p><blockquote><pre>
* MethodHandle invoker = exactInvoker(type);
* MethodType vaType = MethodType.makeGeneric(objectArgCount, true);
* vaType = vaType.insertParameterType(0, MethodHandle.class);
* return spreadArguments(invoker, vaType);
* </pre></blockquote>
* @param type the desired target type
* @param type the desired target type
* @param objectArgCount number of fixed (non-varargs) {@code Object} arguments
* @param objectArgCount number of fixed (non-varargs) {@code Object} arguments
* @param varargs if true, the invoker will accept a final {@code Object[]} argument
* @return a method handle suitable for invoking any method handle of the given type
* @return a method handle suitable for invoking any method handle of the given type
*/
*/
static
public
static
public
MethodHandle
genericInvoker
(
MethodType
type
,
int
objectArgCount
,
boolean
varargs
)
{
MethodHandle
varargsInvoker
(
MethodType
type
,
int
objectArgCount
)
{
return
invokers
(
type
).
genericInvoker
();
if
(
objectArgCount
<
0
||
objectArgCount
>
type
.
parameterCount
())
throw
new
IllegalArgumentException
(
"bad argument count "
+
objectArgCount
);
return
invokers
(
type
).
varargsInvoker
(
objectArgCount
);
}
}
/**
/**
* <em>PROVISIONAL API, WORK IN PROGRESS:</em>
* <em>PROVISIONAL API, WORK IN PROGRESS:</em>
*
Giv
e a method handle which will take a invoke any method handle of the
*
Produc
e a method handle which will take a invoke any method handle of the
* given type. The resulting invoker will have a type which is
* given type. The resulting invoker will have a type which is
* exactly equal to the desired type, except that it will accept
* exactly equal to the desired type, except that it will accept
* an additional leading argument of type {@code MethodHandle}.
* an additional leading argument of type {@code MethodHandle}.
* <p>
* <p>
* This
is a convenience method equivalent to the following code
:
* This
method is equivalent to the following code (though it may be more efficient)
:
* <pre>
* <p
><blockquote><p
re>
*
MethodHandles.
lookup().findVirtual(MethodHandle.class, "invoke", type);
* lookup().findVirtual(MethodHandle.class, "invoke", type);
* </pre>
* </pre>
</blockquote>
* @param type the desired target type
* @param type the desired target type
* @return a method handle suitable for invoking any method handle of the given type
* @return a method handle suitable for invoking any method handle of the given type
*/
*/
...
@@ -612,7 +649,30 @@ public class MethodHandles {
...
@@ -612,7 +649,30 @@ public class MethodHandles {
return
invokers
(
type
).
exactInvoker
();
return
invokers
(
type
).
exactInvoker
();
}
}
static
private
Invokers
invokers
(
MethodType
type
)
{
/**
* <em>PROVISIONAL API, WORK IN PROGRESS:</em>
* Produce a method handle equivalent to an invokedynamic instruction
* which has been linked to the given call site.
* Along with {@link Lookup#findVirtual}, {@link Lookup#findStatic},
* and {@link Lookup#findSpecial}, this completes the emulation
* of the JVM's {@code invoke} instructions.
* <p>This method is equivalent to the following code:
* <p><blockquote><pre>
* MethodHandle getTarget, invoker, result;
* getTarget = lookup().bind(site, "getTarget", methodType(MethodHandle.class));
* invoker = exactInvoker(site.type());
* result = foldArguments(invoker, getTarget)
* </pre></blockquote>
* @return a method handle which always invokes the call site's target
*/
public
static
MethodHandle
dynamicInvoker
(
CallSite
site
)
{
MethodHandle
getTarget
=
MethodHandleImpl
.
bindReceiver
(
IMPL_TOKEN
,
CallSite
.
GET_TARGET
,
site
);
MethodHandle
invoker
=
exactInvoker
(
site
.
type
());
return
foldArguments
(
invoker
,
getTarget
);
}
static
Invokers
invokers
(
MethodType
type
)
{
return
MethodTypeImpl
.
invokers
(
IMPL_TOKEN
,
type
);
return
MethodTypeImpl
.
invokers
(
IMPL_TOKEN
,
type
);
}
}
...
@@ -688,14 +748,11 @@ public class MethodHandles {
...
@@ -688,14 +748,11 @@ public class MethodHandles {
/// method handle modification (creation from other method handles)
/// method handle modification (creation from other method handles)
/**
/**
* <em>PROVISIONAL API, WORK IN PROGRESS:</em>
* Produce a method handle which adapts the type of the
* Produce a method handle which adapts the type of the
* given method handle to a new type, by pairwise argument conversion,
* given method handle to a new type by pairwise argument conversion.
* and/or varargs conversion.
* The original type and new type must have the same number of arguments.
* The original type and new type must have the same number of
* arguments, or else one or both them the must be varargs types.
* The resulting method handle is guaranteed to confess a type
* The resulting method handle is guaranteed to confess a type
* which is equal to the desired new type
, with any varargs property erased
.
* which is equal to the desired new type.
* <p>
* <p>
* If the original type and new type are equal, returns target.
* If the original type and new type are equal, returns target.
* <p>
* <p>
...
@@ -703,26 +760,15 @@ public class MethodHandles {
...
@@ -703,26 +760,15 @@ public class MethodHandles {
* arguments and return types. Let T0 and T1 be the differing
* arguments and return types. Let T0 and T1 be the differing
* new and old parameter types (or old and new return types)
* new and old parameter types (or old and new return types)
* for corresponding values passed by the new and old method types.
* for corresponding values passed by the new and old method types.
* <p>
* If an ordinary (non-varargs) parameter of the new type is
* to be boxed in a varargs parameter of the old type of type T1[],
* then T1 is the element type of the varargs array.
* Otherwise, if a varargs parameter of the new type of type T0[]
* is to be spread into one or more outgoing old type parameters,
* then T0 is the element type of the
* If the new type is varargs and the old type is not, the varargs
* argument will be checked and must be a non-null array of exactly
* the right length. If there are no parameters in the old type
* corresponding to the new varargs parameter, the varargs argument
* is also allowed to be null.
* <p>
* Given those types T0, T1, one of the following conversions is applied
* Given those types T0, T1, one of the following conversions is applied
* if possible:
* if possible:
* <ul>
* <ul>
* <li>If T0 and T1 are references, then a cast to T2 is applied,
* <li>If T0 and T1 are references, and T1 is not an interface type,
* where T2 is Object if T1 is an interface, else T1.
* then a cast to T1 is applied.
* (The types do not need to be related in any particular way.
* (The types do not need to be related in any particular way.)
* The treatment of interfaces follows the usage of the bytecode verifier.)
* <li>If T0 and T1 are references, and T1 is an interface type,
* then the value of type T0 is passed as a T1 without a cast.
* (This treatment of interfaces follows the usage of the bytecode verifier.)
* <li>If T0 and T1 are primitives, then a Java casting
* <li>If T0 and T1 are primitives, then a Java casting
* conversion (JLS 5.5) is applied, if one exists.
* conversion (JLS 5.5) is applied, if one exists.
* <li>If T0 and T1 are primitives and one is boolean,
* <li>If T0 and T1 are primitives and one is boolean,
...
@@ -745,16 +791,17 @@ public class MethodHandles {
...
@@ -745,16 +791,17 @@ public class MethodHandles {
* if necessary to T1 by one of the preceding conversions.
* if necessary to T1 by one of the preceding conversions.
* Otherwise, T0 is converted directly to the wrapper type for T1,
* Otherwise, T0 is converted directly to the wrapper type for T1,
* which is then unboxed.
* which is then unboxed.
* <li>If T1 is void, any returned value is discarded
* <li>If
the return type
T1 is void, any returned value is discarded
* <li>If T0 is void and T1 a reference, a null value is introduced.
* <li>If
the return type
T0 is void and T1 a reference, a null value is introduced.
* <li>If T0 is void and T1 a primitive, a zero value is introduced.
* <li>If
the return type
T0 is void and T1 a primitive, a zero value is introduced.
* </ul>
* </ul>
* @param target the method handle to invoke after arguments are retyped
* @param target the method handle to invoke after arguments are retyped
* @param newType the expected type of the new method handle
* @param newType the expected type of the new method handle
* @return a method handle which delegates to {@code target} after performing
* @return a method handle which delegates to {@code target} after performing
* any necessary argument conversions, and arranges for any
* any necessary argument conversions, and arranges for any
* necessary return value conversions
* necessary return value conversions
* @throws WrongMethodTypeException if the conversion cannot be made
* @throws IllegalArgumentException if the conversion cannot be made
* @see MethodHandle#asType
*/
*/
public
static
public
static
MethodHandle
convertArguments
(
MethodHandle
target
,
MethodType
newType
)
{
MethodHandle
convertArguments
(
MethodHandle
target
,
MethodType
newType
)
{
...
@@ -872,23 +919,17 @@ public class MethodHandles {
...
@@ -872,23 +919,17 @@ public class MethodHandles {
* <em>PROVISIONAL API, WORK IN PROGRESS:</em>
* <em>PROVISIONAL API, WORK IN PROGRESS:</em>
* Produce a method handle which adapts the type of the
* Produce a method handle which adapts the type of the
* given method handle to a new type, by collecting a series of
* given method handle to a new type, by collecting a series of
* trailing arguments into an array.
* trailing arguments as elements to a single argument array.
* The resulting method handle is guaranteed to confess a type
* which is equal to the desired new type.
* <p>
* <p>
* This method
is
inverse to {@link #spreadArguments}.
* This method
may be used as an
inverse to {@link #spreadArguments}.
* The final parameter type of the old type must be an array type T[],
* The final parameter type of the old type must be an array type T[],
* which is the type of what is called the <i>spread</i> argument.
* which is the type of what is called the <i>spread</i> argument.
* The trailing arguments of the new type which correspond to
* The trailing arguments of the new type which correspond to
* the spread argument are all converted to type T and collected
* the spread argument are all converted to type T and collected
* into an array before the original method is called.
* into an array before the original method is called.
* <p>
* ISSUE: Unify this with combineArguments. CollectArguments
* is combineArguments with (a) new Object[]{...} as a combiner,
* and (b) the combined arguments dropped, in favor of the combined result.
* @param target the method handle to invoke after the argument is prepended
* @param target the method handle to invoke after the argument is prepended
* @param newType the expected type of the new method handle
* @param newType the expected type of the new method handle
* @return a new method handle which collects some trailing
s
argument
* @return a new method handle which collects some trailing argument
* into an array, before calling the original method handle
* into an array, before calling the original method handle
*/
*/
public
static
public
static
...
@@ -900,50 +941,72 @@ public class MethodHandles {
...
@@ -900,50 +941,72 @@ public class MethodHandles {
int
numCollect
=
(
inargs
-
collectPos
);
int
numCollect
=
(
inargs
-
collectPos
);
if
(
collectPos
<
0
||
numCollect
<
0
)
if
(
collectPos
<
0
||
numCollect
<
0
)
throw
newIllegalArgumentException
(
"wrong number of arguments"
);
throw
newIllegalArgumentException
(
"wrong number of arguments"
);
return
MethodHandleImpl
.
collectArguments
(
IMPL_TOKEN
,
target
,
newType
,
collectPos
);
MethodHandle
res
=
MethodHandleImpl
.
collectArguments
(
IMPL_TOKEN
,
target
,
newType
,
collectPos
,
null
);
if
(
res
==
null
)
{
throw
newIllegalArgumentException
(
"cannot collect from "
+
newType
+
" to "
+
oldType
);
}
return
res
;
}
}
/**
/**
* <em>PROVISIONAL API, WORK IN PROGRESS:</em>
* <em>PROVISIONAL API, WORK IN PROGRESS:</em>
* Produce a method handle which calls the original method handle,
* Produce a method handle which calls the original method handle {@code target},
* after inserting the given argument at the given position.
* after inserting the given argument(s) at the given position.
* The type of the new method handle will drop the corresponding argument
* The formal parameters to {@code target} which will be supplied by those
* type from the original handle's type.
* arguments are called <em>bound parameters</em>, because the new method
* will contain bindings for those parameters take from {@code values}.
* The type of the new method handle will drop the types for the bound
* parameters from the original target type, since the new method handle
* will no longer require those arguments to be supplied by its callers.
* <p>
* <p>
*
The given argument object must match the dropped argument
type.
*
Each given argument object must match the corresponding bound parameter
type.
* If
the dropped argument
type is a primitive, the argument object
* If
a bound parameter
type is a primitive, the argument object
* must be a wrapper, and
is unboxed to produce the primitiv
e.
* must be a wrapper, and
will be unboxed to produce the primitive valu
e.
* <p>
* <p>
* The <i>pos</i> may range between zero and <i>N</i> (inclusively),
* The <i>pos</i> may range between zero and <i>N</i> (inclusively),
* where <i>N</i> is the number of argument types in <i>target</i>,
* where <i>N</i> is the number of argument types in resulting method handle
* meaning to insert the new argument as the first or last (respectively),
* (after bound parameter types are dropped).
* or somewhere in between.
* @param target the method handle to invoke after the argument is inserted
* @param target the method handle to invoke after the argument is inserted
* @param pos where to insert the argument (zero for the first)
* @param pos where to insert the argument (zero for the first)
* @param value
the argument
to insert
* @param value
s the series of arguments
to insert
* @return a new method handle which inserts an additional argument,
* @return a new method handle which inserts an additional argument,
* before calling the original method handle
* before calling the original method handle
*/
*/
public
static
public
static
MethodHandle
insertArgument
(
MethodHandle
target
,
int
pos
,
Object
value
)
{
MethodHandle
insertArguments
(
MethodHandle
target
,
int
pos
,
Object
...
values
)
{
int
insCount
=
values
.
length
;
MethodType
oldType
=
target
.
type
();
MethodType
oldType
=
target
.
type
();
ArrayList
<
Class
<?>>
ptypes
=
ArrayList
<
Class
<?>>
ptypes
=
new
ArrayList
<
Class
<?>>(
oldType
.
parameterList
());
new
ArrayList
<
Class
<?>>(
oldType
.
parameterList
());
int
outargs
=
oldType
.
parameterCount
();
int
outargs
=
oldType
.
parameterCount
();
int
inargs
=
outargs
-
1
;
int
inargs
=
outargs
-
insCount
;
if
(
pos
<
0
||
pos
>=
outargs
)
if
(
inargs
<
0
)
throw
newIllegalArgumentException
(
"too many values to insert"
);
if
(
pos
<
0
||
pos
>
inargs
)
throw
newIllegalArgumentException
(
"no argument type to append"
);
throw
newIllegalArgumentException
(
"no argument type to append"
);
Class
<?>
valueType
=
ptypes
.
remove
(
pos
);
MethodHandle
result
=
target
;
for
(
int
i
=
0
;
i
<
insCount
;
i
++)
{
Object
value
=
values
[
i
];
Class
<?>
valueType
=
oldType
.
parameterType
(
pos
+
i
);
value
=
checkValue
(
valueType
,
value
);
value
=
checkValue
(
valueType
,
value
);
if
(
pos
==
0
&&
!
valueType
.
isPrimitive
())
{
if
(
pos
==
0
&&
!
valueType
.
isPrimitive
())
{
// At least for now, make bound method handles a special case.
// At least for now, make bound method handles a special case.
// This lets us get by with minimal JVM support, at the expense
MethodHandle
bmh
=
MethodHandleImpl
.
bindReceiver
(
IMPL_TOKEN
,
result
,
value
);
// of generating signature-specific adapters as Java bytecodes.
if
(
bmh
!=
null
)
{
MethodHandle
bmh
=
MethodHandleImpl
.
bindReceiver
(
IMPL_TOKEN
,
target
,
value
);
result
=
bmh
;
if
(
bmh
!=
null
)
return
bmh
;
continue
;
}
// else fall through to general adapter machinery
// else fall through to general adapter machinery
}
}
return
MethodHandleImpl
.
bindArgument
(
IMPL_TOKEN
,
target
,
pos
,
value
);
result
=
MethodHandleImpl
.
bindArgument
(
IMPL_TOKEN
,
result
,
pos
,
value
);
}
return
result
;
}
@Deprecated
// "use MethodHandles.insertArguments instead"
public
static
MethodHandle
insertArgument
(
MethodHandle
target
,
int
pos
,
Object
value
)
{
return
insertArguments
(
target
,
pos
,
value
);
}
}
/**
/**
...
@@ -953,10 +1016,25 @@ public class MethodHandles {
...
@@ -953,10 +1016,25 @@ public class MethodHandles {
* The type of the new method handle will insert the given argument
* The type of the new method handle will insert the given argument
* type(s), at that position, into the original handle's type.
* type(s), at that position, into the original handle's type.
* <p>
* <p>
* The <i>pos</i> may range between zero and <i>N
-1
</i>,
* The <i>pos</i> may range between zero and <i>N</i>,
* where <i>N</i> is the number of argument types in <i>target</i>,
* where <i>N</i> is the number of argument types in <i>target</i>,
* meaning to drop the first or last argument (respectively),
* meaning to drop the first or last argument (respectively),
* or an argument somewhere in between.
* or an argument somewhere in between.
* <p>
* <b>Example:</b>
* <p><blockquote><pre>
* MethodHandle cat = MethodHandles.lookup().
* findVirtual(String.class, "concat", String.class, String.class);
* System.out.println(cat.<String>invoke("x", "y")); // xy
* MethodHandle d0 = dropArguments(cat, 0, String.class);
* System.out.println(d0.<String>invoke("x", "y", "z")); // xy
* MethodHandle d1 = dropArguments(cat, 1, String.class);
* System.out.println(d1.<String>invoke("x", "y", "z")); // xz
* MethodHandle d2 = dropArguments(cat, 2, String.class);
* System.out.println(d2.<String>invoke("x", "y", "z")); // yz
* MethodHandle d12 = dropArguments(cat, 1, String.class, String.class);
* System.out.println(d12.<String>invoke("w", "x", "y", "z")); // wz
* </pre></blockquote>
* @param target the method handle to invoke after the argument is dropped
* @param target the method handle to invoke after the argument is dropped
* @param valueTypes the type(s) of the argument to drop
* @param valueTypes the type(s) of the argument to drop
* @param pos which argument to drop (zero for the first)
* @param pos which argument to drop (zero for the first)
...
@@ -964,20 +1042,150 @@ public class MethodHandles {
...
@@ -964,20 +1042,150 @@ public class MethodHandles {
* before calling the original method handle
* before calling the original method handle
*/
*/
public
static
public
static
MethodHandle
dropArguments
(
MethodHandle
target
,
int
pos
,
Class
<?>...
valueTypes
)
{
MethodHandle
dropArguments
(
MethodHandle
target
,
int
pos
,
List
<
Class
<?>>
valueTypes
)
{
if
(
valueTypes
.
length
==
0
)
return
target
;
if
(
valueTypes
.
size
()
==
0
)
return
target
;
MethodType
oldType
=
target
.
type
();
MethodType
oldType
=
target
.
type
();
int
outargs
=
oldType
.
parameterCount
();
int
outargs
=
oldType
.
parameterCount
();
int
inargs
=
outargs
+
valueTypes
.
length
;
int
inargs
=
outargs
+
valueTypes
.
size
()
;
if
(
pos
<
0
||
pos
>=
inargs
)
if
(
pos
<
0
||
pos
>=
inargs
)
throw
newIllegalArgumentException
(
"no argument type to remove"
);
throw
newIllegalArgumentException
(
"no argument type to remove"
);
ArrayList
<
Class
<?>>
ptypes
=
ArrayList
<
Class
<?>>
ptypes
=
new
ArrayList
<
Class
<?>>(
oldType
.
parameterList
());
new
ArrayList
<
Class
<?>>(
oldType
.
parameterList
());
ptypes
.
addAll
(
pos
,
Arrays
.
asList
(
valueTypes
)
);
ptypes
.
addAll
(
pos
,
valueTypes
);
MethodType
newType
=
MethodType
.
m
ak
e
(
oldType
.
returnType
(),
ptypes
);
MethodType
newType
=
MethodType
.
m
ethodTyp
e
(
oldType
.
returnType
(),
ptypes
);
return
MethodHandleImpl
.
dropArguments
(
IMPL_TOKEN
,
target
,
newType
,
pos
);
return
MethodHandleImpl
.
dropArguments
(
IMPL_TOKEN
,
target
,
newType
,
pos
);
}
}
public
static
MethodHandle
dropArguments
(
MethodHandle
target
,
int
pos
,
Class
<?>...
valueTypes
)
{
return
dropArguments
(
target
,
pos
,
Arrays
.
asList
(
valueTypes
));
}
/**
* <em>PROVISIONAL API, WORK IN PROGRESS:</em>
* Adapt a target method handle {@code target} by pre-processing
* one or more of its arguments, each with its own unary filter function,
* and then calling the target with each pre-processed argument
* replaced by the result of its corresponding filter function.
* <p>
* The pre-processing is performed by one or more method handles,
* specified in the non-null elements of the {@code filters} array.
* (If there are no such elements, the original target is returned.)
* Each filter (that is, each non-null element of {@code filters})
* is applied to the corresponding argument of the adapter.
* <p>
* If a filter {@code F} applies to the {@code N}th argument of
* the method handle, then {@code F} must be a method handle which
* takes exactly one argument. The type of {@code F}'s sole argument
* replaces the corresponding argument type of the target
* in the resulting adapted method handle.
* The return type of {@code F} must be identical to the corresponding
* parameter type of the target.
* <p>
* It is an error if there are non-null elements of {@code filters}
* which do not correspond to argument positions in the target.
* The actual length of the target array may be any number, it need
* not be the same as the parameter count of the target type.
* (This provides an easy way to filter just the first argument or two
* of a target method handle.)
* <p> Here is pseudocode for the resulting adapter:
* <blockquote><pre>
* // there are N arguments in the A sequence
* T target(A[N]...);
* [i<N] V[i] filter[i](B[i]) = filters[i] ?: identity;
* T adapter(B[N]... b) {
* A[N] a...;
* [i<N] a[i] = filter[i](b[i]);
* return target(a...);
* }
* </pre></blockquote>
* @param target the method handle to invoke after arguments are filtered
* @param filters method handles to call initially on filtered arguments
* @return method handle which incorporates the specified argument filtering logic
* @throws IllegalArgumentException if a non-null element of {@code filters}
* does not match a corresponding argument type of {@code target}
*/
public
static
MethodHandle
filterArguments
(
MethodHandle
target
,
MethodHandle
...
filters
)
{
MethodType
targetType
=
target
.
type
();
MethodHandle
adapter
=
target
;
MethodType
adapterType
=
targetType
;
int
pos
=
-
1
,
maxPos
=
targetType
.
parameterCount
();
for
(
MethodHandle
filter
:
filters
)
{
pos
+=
1
;
if
(
filter
==
null
)
continue
;
if
(
pos
>=
maxPos
)
throw
newIllegalArgumentException
(
"too many filters"
);
MethodType
filterType
=
filter
.
type
();
if
(
filterType
.
parameterCount
()
!=
1
||
filterType
.
returnType
()
!=
targetType
.
parameterType
(
pos
))
throw
newIllegalArgumentException
(
"target and filter types do not match"
);
adapterType
=
adapterType
.
changeParameterType
(
pos
,
filterType
.
parameterType
(
0
));
adapter
=
MethodHandleImpl
.
filterArgument
(
IMPL_TOKEN
,
adapter
,
pos
,
filter
);
}
MethodType
midType
=
adapter
.
type
();
if
(
midType
!=
adapterType
)
adapter
=
MethodHandleImpl
.
convertArguments
(
IMPL_TOKEN
,
adapter
,
adapterType
,
midType
,
null
);
return
adapter
;
}
/**
* <em>PROVISIONAL API, WORK IN PROGRESS:</em>
* Adapt a target method handle {@code target} by pre-processing
* some of its arguments, and then calling the target with
* the result of the pre-processing, plus all original arguments.
* <p>
* The pre-processing is performed by a second method handle, the {@code combiner}.
* The first {@code N} arguments passed to the adapter,
* are copied to the combiner, which then produces a result.
* (Here, {@code N} is defined as the parameter count of the adapter.)
* After this, control passes to the {@code target}, with both the result
* of the combiner, and all the original incoming arguments.
* <p>
* The first argument type of the target must be identical with the
* return type of the combiner.
* The resulting adapter is the same type as the target, except that the
* initial argument type of the target is dropped.
* <p>
* (Note that {@link #dropArguments} can be used to remove any arguments
* that either the {@code combiner} or {@code target} does not wish to receive.
* If some of the incoming arguments are destined only for the combiner,
* consider using {@link #collectArguments} instead, since those
* arguments will not need to be live on the stack on entry to the
* target.)
* <p>
* The first argument of the target must be identical with the
* return value of the combiner.
* <p> Here is pseudocode for the resulting adapter:
* <blockquote><pre>
* // there are N arguments in the A sequence
* T target(V, A[N]..., B...);
* V combiner(A...);
* T adapter(A... a, B... b) {
* V v = combiner(a...);
* return target(v, a..., b...);
* }
* </pre></blockquote>
* @param target the method handle to invoke after arguments are combined
* @param combiner method handle to call initially on the incoming arguments
* @return method handle which incorporates the specified argument folding logic
* @throws IllegalArgumentException if the first argument type of
* {@code target} is not the same as {@code combiner}'s return type,
* or if the next {@code foldArgs} argument types of {@code target}
* are not identical with the argument types of {@code combiner}
*/
public
static
MethodHandle
foldArguments
(
MethodHandle
target
,
MethodHandle
combiner
)
{
MethodType
targetType
=
target
.
type
();
MethodType
combinerType
=
combiner
.
type
();
int
foldArgs
=
combinerType
.
parameterCount
();
boolean
ok
=
(
targetType
.
parameterCount
()
>=
1
+
foldArgs
);
if
(!
ok
)
throw
misMatchedTypes
(
"target and combiner types"
,
targetType
,
combinerType
);
MethodType
newType
=
targetType
.
dropParameterTypes
(
0
,
1
);
return
MethodHandleImpl
.
foldArguments
(
IMPL_TOKEN
,
target
,
newType
,
combiner
);
}
/**
/**
* <em>PROVISIONAL API, WORK IN PROGRESS:</em>
* <em>PROVISIONAL API, WORK IN PROGRESS:</em>
* Make a method handle which adapts a target method handle,
* Make a method handle which adapts a target method handle,
...
@@ -985,18 +1193,18 @@ public class MethodHandles {
...
@@ -985,18 +1193,18 @@ public class MethodHandles {
* If the guard fails, a fallback handle is called instead.
* If the guard fails, a fallback handle is called instead.
* All three method handles must have the same corresponding
* All three method handles must have the same corresponding
* argument and return types, except that the return type
* argument and return types, except that the return type
* of the test must be boolean.
* of the test must be boolean, and the test is allowed
* to have fewer arguments than the other two method handles.
* <p> Here is pseudocode for the resulting adapter:
* <p> Here is pseudocode for the resulting adapter:
* <blockquote><pre>
* <blockquote><pre>
* signature T(A...);
* boolean test(A...);
* boolean test(A...);
* T target(A...);
* T target(A...
,B...
);
* T fallback(A...);
* T fallback(A...
,B...
);
* T adapter(A... a) {
* T adapter(A... a
,B... b
) {
* if (test(a...))
* if (test(a...))
* return target(a...);
* return target(a...
, b...
);
* else
* else
* return fallback(a...);
* return fallback(a...
, b...
);
* }
* }
* </pre></blockquote>
* </pre></blockquote>
* @param test method handle used for test, must return boolean
* @param test method handle used for test, must return boolean
...
@@ -1011,10 +1219,23 @@ public class MethodHandles {
...
@@ -1011,10 +1219,23 @@ public class MethodHandles {
MethodHandle
guardWithTest
(
MethodHandle
test
,
MethodHandle
guardWithTest
(
MethodHandle
test
,
MethodHandle
target
,
MethodHandle
target
,
MethodHandle
fallback
)
{
MethodHandle
fallback
)
{
if
(
target
.
type
()
!=
fallback
.
type
())
MethodType
gtype
=
test
.
type
();
throw
newIllegalArgumentException
(
"target and fallback types do not match"
);
MethodType
ttype
=
target
.
type
();
if
(
target
.
type
().
changeReturnType
(
boolean
.
class
)
!=
test
.
type
())
MethodType
ftype
=
fallback
.
type
();
throw
newIllegalArgumentException
(
"target and test types do not match"
);
if
(
ttype
!=
ftype
)
throw
misMatchedTypes
(
"target and fallback types"
,
ttype
,
ftype
);
MethodType
gtype2
=
ttype
.
changeReturnType
(
boolean
.
class
);
if
(
gtype2
!=
gtype
)
{
if
(
gtype
.
returnType
()
!=
boolean
.
class
)
throw
newIllegalArgumentException
(
"guard type is not a predicate "
+
gtype
);
int
gpc
=
gtype
.
parameterCount
(),
tpc
=
ttype
.
parameterCount
();
if
(
gpc
<
tpc
)
{
test
=
dropArguments
(
test
,
gpc
,
ttype
.
parameterList
().
subList
(
gpc
,
tpc
));
gtype
=
test
.
type
();
}
if
(
gtype2
!=
gtype
)
throw
misMatchedTypes
(
"target and test types"
,
ttype
,
gtype
);
}
/* {
/* {
MethodHandle invoke = findVirtual(MethodHandle.class, "invoke", target.type());
MethodHandle invoke = findVirtual(MethodHandle.class, "invoke", target.type());
static MethodHandle choose(boolean z, MethodHandle t, MethodHandle f) {
static MethodHandle choose(boolean z, MethodHandle t, MethodHandle f) {
...
@@ -1027,7 +1248,7 @@ public class MethodHandles {
...
@@ -1027,7 +1248,7 @@ public class MethodHandles {
}
}
// choose = \z.(z ? target : fallback)
// choose = \z.(z ? target : fallback)
MethodHandle choose = findVirtual(MethodHandles.class, "choose",
MethodHandle choose = findVirtual(MethodHandles.class, "choose",
MethodType.m
ak
e(boolean.class, MethodHandle.class, MethodHandle.class));
MethodType.m
ethodTyp
e(boolean.class, MethodHandle.class, MethodHandle.class));
choose = appendArgument(choose, target);
choose = appendArgument(choose, target);
choose = appendArgument(choose, fallback);
choose = appendArgument(choose, fallback);
MethodHandle dispatch = compose(choose, test);
MethodHandle dispatch = compose(choose, test);
...
@@ -1038,67 +1259,88 @@ public class MethodHandles {
...
@@ -1038,67 +1259,88 @@ public class MethodHandles {
return
MethodHandleImpl
.
makeGuardWithTest
(
IMPL_TOKEN
,
test
,
target
,
fallback
);
return
MethodHandleImpl
.
makeGuardWithTest
(
IMPL_TOKEN
,
test
,
target
,
fallback
);
}
}
static
RuntimeException
misMatchedTypes
(
String
what
,
MethodType
t1
,
MethodType
t2
)
{
return
newIllegalArgumentException
(
what
+
" must match: "
+
t1
+
" != "
+
t2
);
}
/**
/**
* <em>PROVISIONAL API, WORK IN PROGRESS:</em>
* <em>PROVISIONAL API, WORK IN PROGRESS:</em>
* Adapt a target method handle {@code target} by first processing
* Make a method handle which adapts a target method handle,
* its arguments, and then calling the target.
* by running it inside an exception handler.
* The initial processing is performed by a second method handle, the {@code combiner}.
* If the target returns normally, the adapter returns that value.
* After this, control passes to the {@code target}, with the same arguments.
* If an exception matching the specified type is thrown, the fallback
* <p>
* handle is called instead on the exception, plus the original arguments.
* The return value of the {@code combiner} is inserted into the argument list
* for the {@code target} at the indicated position {@code pos}, if it is non-negative.
* Except for this inserted argument (if any), the argument types of
* the target {@code target} and the {@code combiner} must be identical.
* <p>
* (Note that {@link #dropArguments} can be used to remove any arguments
* that either the {@code combiner} or {@code target} does not wish to receive.)
* <p>
* <p>
* The
combiner handle must have the same argument types as the
* The
handler must have leading parameter of {@code exType} or a supertype,
*
target handle, but must return {@link MethodHandle} instead of
*
followed by arguments which correspond <em>(how? TBD)</em> to
*
the ultimate return type. The returned method handle, in turn,
*
all the parameters of the target.
*
is required to have exactly the given final method
type.
*
The target and handler must return the same
type.
* <p> Here is pseudocode for the resulting adapter:
* <p> Here is pseudocode for the resulting adapter:
* <blockquote><pre>
* <blockquote><pre>
* signature V(A[pos]..., B...);
* T target(A...);
* signature T(A[pos]..., V, B...);
* T handler(ExType, A...);
* T target(A... a, V v, B... b);
* T adapter(A... a) {
* V combiner(A..., B...);
* try {
* T adapter(A... a, B... b) {
* return target(a...);
* V v = combiner(a..., b...);
* } catch (ExType ex) {
* return target(a..., v, b...);
* return handler(ex, a...);
* }
* }
* }
* </pre></blockquote>
* </pre></blockquote>
* @param target the method handle to invoke after arguments are combined
* @param target method handle to call
* @param pos where the return value of {@code combiner} is to
* @param exType the type of exception which the handler will catch
* be inserted as an argument to {@code target}
* @param handler method handle to call if a matching exception is thrown
* @param combiner method handle to call initially on the incoming arguments
* @return method handle which incorporates the specified try/catch logic
* @return method handle which incorporates the specified dispatch logic
* @throws IllegalArgumentException if {@code handler} does not accept
* @throws IllegalArgumentException if {@code combiner} does not itself
* the given exception type, or if the method handle types do
* return either void or the {@code pos}-th argument of {@code target},
* not match in their return types and their
* or does not have the same argument types as {@code target}
* corresponding parameters
* (minus the inserted argument)
*/
*/
public
static
public
static
MethodHandle
combineArguments
(
MethodHandle
target
,
int
pos
,
MethodHandle
combiner
)
{
MethodHandle
catchException
(
MethodHandle
target
,
MethodType
mhType
=
target
.
type
();
Class
<?
extends
Throwable
>
exType
,
Class
<?>
combineType
=
combiner
.
type
().
returnType
();
MethodHandle
handler
)
{
MethodType
incomingArgs
;
MethodType
targetType
=
target
.
type
();
if
(
pos
<
0
)
{
MethodType
handlerType
=
handler
.
type
();
// No inserted argument; target & combiner must have same argument types.
boolean
ok
=
(
targetType
.
parameterCount
()
==
incomingArgs
=
mhType
;
handlerType
.
parameterCount
()
-
1
);
if
(!
incomingArgs
.
changeReturnType
(
combineType
).
equals
(
combiner
.
type
()))
// for (int i = 0; ok && i < numExArgs; i++) {
throw
newIllegalArgumentException
(
"target and combiner types do not match"
);
// if (targetType.parameterType(i) != handlerType.parameterType(1+i))
}
else
{
// ok = false;
// Inserted argument.
// }
if
(
pos
>=
mhType
.
parameterCount
()
if
(!
ok
)
||
mhType
.
parameterType
(
pos
)
!=
combineType
)
throw
newIllegalArgumentException
(
"target and handler types do not match"
);
throw
newIllegalArgumentException
(
"inserted combiner argument does not match target"
);
return
MethodHandleImpl
.
makeGuardWithCatch
(
IMPL_TOKEN
,
target
,
exType
,
handler
);
incomingArgs
=
mhType
.
dropParameterType
(
pos
);
}
/**
* Produce a method handle which will throw exceptions of the given {@code exType}.
* The method handle will accept a single argument of {@code exType},
* and immediately throw it as an exception.
* The method type will nominally specify a return of {@code returnType}.
* The return type may be anything convenient: It doesn't matter to the
* method handle's behavior, since it will never return normally.
*/
public
static
MethodHandle
throwException
(
Class
<?>
returnType
,
Class
<?
extends
Throwable
>
exType
)
{
return
MethodHandleImpl
.
throwException
(
IMPL_TOKEN
,
MethodType
.
methodType
(
returnType
,
exType
));
}
}
if
(!
incomingArgs
.
changeReturnType
(
combineType
).
equals
(
combiner
.
type
()))
{
throw
newIllegalArgumentException
(
"target and combiner types do not match"
);
/** Alias for {@link MethodType#methodType}. */
@Deprecated
// "use MethodType.methodType instead"
public
static
MethodType
methodType
(
Class
<?>
rtype
)
{
return
MethodType
.
methodType
(
rtype
);
}
}
return
MethodHandleImpl
.
combineArguments
(
IMPL_TOKEN
,
target
,
combiner
,
pos
);
/** Alias for {@link MethodType#methodType}. */
@Deprecated
// "use MethodType.methodType instead"
public
static
MethodType
methodType
(
Class
<?>
rtype
,
Class
<?>
ptype
)
{
return
MethodType
.
methodType
(
rtype
,
ptype
);
}
}
/** Alias for {@link MethodType#methodType}. */
@Deprecated
// "use MethodType.methodType instead"
public
static
MethodType
methodType
(
Class
<?>
rtype
,
Class
<?>
ptype0
,
Class
<?>...
ptypes
)
{
return
MethodType
.
methodType
(
rtype
,
ptype0
,
ptypes
);
}
}
}
src/share/classes/java/dyn/MethodType.java
浏览文件 @
8992d5c6
...
@@ -32,7 +32,7 @@ import java.util.List;
...
@@ -32,7 +32,7 @@ import java.util.List;
import
sun.dyn.Access
;
import
sun.dyn.Access
;
import
sun.dyn.Invokers
;
import
sun.dyn.Invokers
;
import
sun.dyn.MethodTypeImpl
;
import
sun.dyn.MethodTypeImpl
;
import
sun.dyn.util.Bytecode
Signature
;
import
sun.dyn.util.Bytecode
Descriptor
;
import
static
sun
.
dyn
.
MemberName
.
newIllegalArgumentException
;
import
static
sun
.
dyn
.
MemberName
.
newIllegalArgumentException
;
/**
/**
...
@@ -63,7 +63,7 @@ class MethodType {
...
@@ -63,7 +63,7 @@ class MethodType {
static
{
static
{
// This hack allows the implementation package special access to
// This hack allows the implementation package special access to
// the internals of MethodType. In particular, the
Form
has all sorts
// the internals of MethodType. In particular, the
MTImpl
has all sorts
// of cached information useful to the implementation code.
// of cached information useful to the implementation code.
MethodTypeImpl
.
setMethodTypeFriend
(
IMPL_TOKEN
,
new
MethodTypeImpl
.
MethodTypeFriend
()
{
MethodTypeImpl
.
setMethodTypeFriend
(
IMPL_TOKEN
,
new
MethodTypeImpl
.
MethodTypeFriend
()
{
public
Class
<?>[]
ptypes
(
MethodType
mt
)
{
return
mt
.
ptypes
;
}
public
Class
<?>[]
ptypes
(
MethodType
mt
)
{
return
mt
.
ptypes
;
}
...
@@ -114,51 +114,76 @@ class MethodType {
...
@@ -114,51 +114,76 @@ class MethodType {
* @throws IllegalArgumentException if any of the ptypes is void
* @throws IllegalArgumentException if any of the ptypes is void
*/
*/
public
static
public
static
MethodType
m
ak
e
(
Class
<?>
rtype
,
Class
<?>[]
ptypes
)
{
MethodType
m
ethodTyp
e
(
Class
<?>
rtype
,
Class
<?>[]
ptypes
)
{
return
makeImpl
(
rtype
,
ptypes
,
false
);
return
makeImpl
(
rtype
,
ptypes
,
false
);
}
}
@Deprecated
public
static
MethodType
make
(
Class
<?>
rtype
,
Class
<?>[]
ptypes
)
{
return
methodType
(
rtype
,
ptypes
);
}
/** Convenience method for {@link #m
ak
e(java.lang.Class, java.lang.Class[])}. */
/** Convenience method for {@link #m
ethodTyp
e(java.lang.Class, java.lang.Class[])}. */
public
static
public
static
MethodType
methodType
(
Class
<?>
rtype
,
List
<?
extends
Class
<?>>
ptypes
)
{
boolean
notrust
=
false
;
// random List impl. could return evil ptypes array
return
makeImpl
(
rtype
,
ptypes
.
toArray
(
NO_PTYPES
),
notrust
);
}
@Deprecated
public
static
MethodType
make
(
Class
<?>
rtype
,
List
<?
extends
Class
<?>>
ptypes
)
{
MethodType
make
(
Class
<?>
rtype
,
List
<?
extends
Class
<?>>
ptypes
)
{
return
m
akeImpl
(
rtype
,
ptypes
.
toArray
(
NO_PTYPES
),
true
);
return
m
ethodType
(
rtype
,
ptypes
);
}
}
/** Convenience method for {@link #m
ak
e(java.lang.Class, java.lang.Class[])}.
/** Convenience method for {@link #m
ethodTyp
e(java.lang.Class, java.lang.Class[])}.
* The leading parameter type is prepended to the remaining array.
* The leading parameter type is prepended to the remaining array.
*/
*/
public
static
public
static
MethodType
m
ak
e
(
Class
<?>
rtype
,
Class
<?>
ptype0
,
Class
<?>...
ptypes
)
{
MethodType
m
ethodTyp
e
(
Class
<?>
rtype
,
Class
<?>
ptype0
,
Class
<?>...
ptypes
)
{
Class
<?>[]
ptypes1
=
new
Class
<?>[
1
+
ptypes
.
length
];
Class
<?>[]
ptypes1
=
new
Class
<?>[
1
+
ptypes
.
length
];
ptypes1
[
0
]
=
ptype0
;
ptypes1
[
0
]
=
ptype0
;
System
.
arraycopy
(
ptypes
,
0
,
ptypes1
,
1
,
ptypes
.
length
);
System
.
arraycopy
(
ptypes
,
0
,
ptypes1
,
1
,
ptypes
.
length
);
return
makeImpl
(
rtype
,
ptypes1
,
true
);
return
makeImpl
(
rtype
,
ptypes1
,
true
);
}
}
@Deprecated
public
static
MethodType
make
(
Class
<?>
rtype
,
Class
<?>
ptype0
,
Class
<?>...
ptypes
)
{
return
methodType
(
rtype
,
ptype0
,
ptypes
);
}
/** Convenience method for {@link #m
ak
e(java.lang.Class, java.lang.Class[])}.
/** Convenience method for {@link #m
ethodTyp
e(java.lang.Class, java.lang.Class[])}.
* The resulting method has no parameter types.
* The resulting method has no parameter types.
*/
*/
public
static
public
static
MethodType
m
ak
e
(
Class
<?>
rtype
)
{
MethodType
m
ethodTyp
e
(
Class
<?>
rtype
)
{
return
makeImpl
(
rtype
,
NO_PTYPES
,
true
);
return
makeImpl
(
rtype
,
NO_PTYPES
,
true
);
}
}
@Deprecated
public
static
MethodType
make
(
Class
<?>
rtype
)
{
return
methodType
(
rtype
);
}
/** Convenience method for {@link #m
ak
e(java.lang.Class, java.lang.Class[])}.
/** Convenience method for {@link #m
ethodTyp
e(java.lang.Class, java.lang.Class[])}.
* The resulting method has the single given parameter type.
* The resulting method has the single given parameter type.
*/
*/
public
static
public
static
MethodType
m
ak
e
(
Class
<?>
rtype
,
Class
<?>
ptype0
)
{
MethodType
m
ethodTyp
e
(
Class
<?>
rtype
,
Class
<?>
ptype0
)
{
return
makeImpl
(
rtype
,
new
Class
<?>[]{
ptype0
},
true
);
return
makeImpl
(
rtype
,
new
Class
<?>[]{
ptype0
},
true
);
}
}
@Deprecated
public
static
MethodType
make
(
Class
<?>
rtype
,
Class
<?>
ptype0
)
{
return
methodType
(
rtype
,
ptype0
);
}
/** Convenience method for {@link #m
ak
e(java.lang.Class, java.lang.Class[])}.
/** Convenience method for {@link #m
ethodTyp
e(java.lang.Class, java.lang.Class[])}.
* The resulting method has the same parameter types as {@code ptypes},
* The resulting method has the same parameter types as {@code ptypes},
* and the specified return type.
* and the specified return type.
*/
*/
public
static
public
static
MethodType
m
ak
e
(
Class
<?>
rtype
,
MethodType
ptypes
)
{
MethodType
m
ethodTyp
e
(
Class
<?>
rtype
,
MethodType
ptypes
)
{
return
makeImpl
(
rtype
,
ptypes
.
ptypes
,
true
);
return
makeImpl
(
rtype
,
ptypes
.
ptypes
,
true
);
}
}
@Deprecated
public
static
MethodType
make
(
Class
<?>
rtype
,
MethodType
ptypes
)
{
return
methodType
(
rtype
,
ptypes
);
}
/**
/**
* Sole factory method to find or create an interned method type.
* Sole factory method to find or create an interned method type.
...
@@ -202,15 +227,16 @@ class MethodType {
...
@@ -202,15 +227,16 @@ class MethodType {
private
static
final
MethodType
[]
objectOnlyTypes
=
new
MethodType
[
20
];
private
static
final
MethodType
[]
objectOnlyTypes
=
new
MethodType
[
20
];
/**
/**
* Convenience method for {@link #make(java.lang.Class, java.lang.Class[], boolean)}.
* Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[])}.
* All parameters and the return type will be Object, except the final varargs parameter if any.
* All parameters and the return type will be {@code Object},
* except the final varargs parameter if any, which will be {@code Object[]}.
* @param objectArgCount number of parameters (excluding the varargs parameter if any)
* @param objectArgCount number of parameters (excluding the varargs parameter if any)
* @param varargs whether there will be a varargs parameter, of type
Object[]
* @param varargs whether there will be a varargs parameter, of type
{@code Object[]}
* @return a totally generic method type, given only its count of parameters and varargs
* @return a totally generic method type, given only its count of parameters and varargs
* @see #
makeGeneric
(int)
* @see #
genericMethodType
(int)
*/
*/
public
static
public
static
MethodType
makeGeneric
(
int
objectArgCount
,
boolean
varargs
)
{
MethodType
genericMethodType
(
int
objectArgCount
,
boolean
varargs
)
{
MethodType
mt
;
MethodType
mt
;
int
ivarargs
=
(!
varargs
?
0
:
1
);
int
ivarargs
=
(!
varargs
?
0
:
1
);
int
ootIndex
=
objectArgCount
*
2
+
ivarargs
;
int
ootIndex
=
objectArgCount
*
2
+
ivarargs
;
...
@@ -227,19 +253,27 @@ class MethodType {
...
@@ -227,19 +253,27 @@ class MethodType {
}
}
return
mt
;
return
mt
;
}
}
@Deprecated
public
static
MethodType
makeGeneric
(
int
objectArgCount
,
boolean
varargs
)
{
return
genericMethodType
(
objectArgCount
,
varargs
);
}
/**
/**
* All parameters and the return type will be Object.
* All parameters and the return type will be Object.
* @param objectArgCount number of parameters
* @param objectArgCount number of parameters
* @return a totally generic method type, given only its count of parameters
* @return a totally generic method type, given only its count of parameters
* @see #
makeGeneric
(int, boolean)
* @see #
genericMethodType
(int, boolean)
*/
*/
public
static
public
static
MethodType
genericMethodType
(
int
objectArgCount
)
{
return
genericMethodType
(
objectArgCount
,
false
);
}
@Deprecated
public
static
MethodType
makeGeneric
(
int
objectArgCount
)
{
MethodType
makeGeneric
(
int
objectArgCount
)
{
return
makeGeneric
(
objectArgCount
,
false
);
return
genericMethodType
(
objectArgCount
);
}
}
/** Convenience method for {@link #m
ake(java.lang.Class, java.lang.Class[], boolean
)}.
/** Convenience method for {@link #m
ethodType(java.lang.Class, java.lang.Class[]
)}.
* @param num the index (zero-based) of the parameter type to change
* @param num the index (zero-based) of the parameter type to change
* @param nptype a new parameter type to replace the old one with
* @param nptype a new parameter type to replace the old one with
* @return the same type, except with the selected parameter changed
* @return the same type, except with the selected parameter changed
...
@@ -251,11 +285,10 @@ class MethodType {
...
@@ -251,11 +285,10 @@ class MethodType {
return
makeImpl
(
rtype
,
nptypes
,
true
);
return
makeImpl
(
rtype
,
nptypes
,
true
);
}
}
/** Convenience method for {@link #make(java.lang.Class, java.lang.Class[], boolean)}.
/** Convenience method for {@link #insertParameterTypes}.
* @param num the position (zero-based) of the inserted parameter type
* @deprecated Use {@link #insertParameterTypes} instead.
* @param nptype a new parameter type to insert into the parameter list
* @return the same type, except with the selected parameter inserted
*/
*/
@Deprecated
public
MethodType
insertParameterType
(
int
num
,
Class
<?>
nptype
)
{
public
MethodType
insertParameterType
(
int
num
,
Class
<?>
nptype
)
{
int
len
=
ptypes
.
length
;
int
len
=
ptypes
.
length
;
Class
<?>[]
nptypes
=
Arrays
.
copyOfRange
(
ptypes
,
0
,
len
+
1
);
Class
<?>[]
nptypes
=
Arrays
.
copyOfRange
(
ptypes
,
0
,
len
+
1
);
...
@@ -264,23 +297,73 @@ class MethodType {
...
@@ -264,23 +297,73 @@ class MethodType {
return
makeImpl
(
rtype
,
nptypes
,
true
);
return
makeImpl
(
rtype
,
nptypes
,
true
);
}
}
/** Convenience method for {@link #make(java.lang.Class, java.lang.Class[], boolean)}.
/** Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[])}.
* @param num the index (zero-based) of the parameter type to remove
* @param num the position (zero-based) of the inserted parameter type(s)
* @return the same type, except with the selected parameter removed
* @param ptypesToInsert zero or more a new parameter types to insert into the parameter list
* @return the same type, except with the selected parameter(s) inserted
*/
*/
public
MethodType
dropParameterType
(
int
num
)
{
public
MethodType
insertParameterTypes
(
int
num
,
Class
<?>...
ptypesToInsert
)
{
int
len
=
ptypes
.
length
;
if
(
num
<
0
||
num
>
len
)
throw
newIllegalArgumentException
(
"num="
+
num
);
//SPECME
int
ilen
=
ptypesToInsert
.
length
;
if
(
ilen
==
0
)
return
this
;
Class
<?>[]
nptypes
=
Arrays
.
copyOfRange
(
ptypes
,
0
,
len
+
ilen
);
System
.
arraycopy
(
nptypes
,
num
,
nptypes
,
num
+
ilen
,
len
-
num
);
System
.
arraycopy
(
ptypesToInsert
,
0
,
nptypes
,
num
,
ilen
);
return
makeImpl
(
rtype
,
nptypes
,
true
);
}
/** Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[])}.
* @param num the position (zero-based) of the inserted parameter type(s)
* @param ptypesToInsert zero or more a new parameter types to insert into the parameter list
* @return the same type, except with the selected parameter(s) inserted
*/
public
MethodType
insertParameterTypes
(
int
num
,
List
<
Class
<?>>
ptypesToInsert
)
{
return
insertParameterTypes
(
num
,
ptypesToInsert
.
toArray
(
NO_PTYPES
));
}
/** Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[])}.
* @param start the index (zero-based) of the first parameter type to remove
* @param end the index (greater than {@code start}) of the first parameter type after not to remove
* @return the same type, except with the selected parameter(s) removed
*/
public
MethodType
dropParameterTypes
(
int
start
,
int
end
)
{
int
len
=
ptypes
.
length
;
int
len
=
ptypes
.
length
;
if
(!(
0
<=
start
&&
start
<=
end
&&
end
<=
len
))
throw
newIllegalArgumentException
(
"start="
+
start
+
" end="
+
end
);
//SPECME
if
(
start
==
end
)
return
this
;
Class
<?>[]
nptypes
;
Class
<?>[]
nptypes
;
if
(
num
==
0
)
{
if
(
start
==
0
)
{
nptypes
=
Arrays
.
copyOfRange
(
ptypes
,
1
,
len
);
if
(
end
==
len
)
{
// drop all parameters
nptypes
=
NO_PTYPES
;
}
else
{
// drop initial parameter(s)
nptypes
=
Arrays
.
copyOfRange
(
ptypes
,
end
,
len
);
}
}
else
{
if
(
end
==
len
)
{
// drop trailing parameter(s)
nptypes
=
Arrays
.
copyOfRange
(
ptypes
,
0
,
start
);
}
else
{
}
else
{
nptypes
=
Arrays
.
copyOfRange
(
ptypes
,
0
,
len
-
1
);
int
tail
=
len
-
end
;
System
.
arraycopy
(
ptypes
,
num
+
1
,
nptypes
,
num
,
(
len
-
1
)-
num
);
nptypes
=
Arrays
.
copyOfRange
(
ptypes
,
0
,
start
+
tail
);
System
.
arraycopy
(
ptypes
,
end
,
nptypes
,
start
,
tail
);
}
}
}
return
makeImpl
(
rtype
,
nptypes
,
true
);
return
makeImpl
(
rtype
,
nptypes
,
true
);
}
}
/** Convenience method for {@link #make(java.lang.Class, java.lang.Class[], boolean)}.
/** Convenience method for {@link #dropParameterTypes}.
* @deprecated Use {@link #dropParameterTypes} instead.
*/
@Deprecated
public
MethodType
dropParameterType
(
int
num
)
{
return
dropParameterTypes
(
num
,
num
+
1
);
}
/** Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[])}.
* @param nrtype a return parameter type to replace the old one with
* @param nrtype a return parameter type to replace the old one with
* @return the same type, except with the return type change
* @return the same type, except with the return type change
*/
*/
...
@@ -291,6 +374,7 @@ class MethodType {
...
@@ -291,6 +374,7 @@ class MethodType {
/** Convenience method.
/** Convenience method.
* Report if this type contains a primitive argument or return value.
* Report if this type contains a primitive argument or return value.
* The return type {@code void} counts as a primitive.
* @return true if any of the types are primitives
* @return true if any of the types are primitives
*/
*/
public
boolean
hasPrimitives
()
{
public
boolean
hasPrimitives
()
{
...
@@ -300,39 +384,47 @@ class MethodType {
...
@@ -300,39 +384,47 @@ class MethodType {
/** Convenience method.
/** Convenience method.
* Report if this type contains a wrapper argument or return value.
* Report if this type contains a wrapper argument or return value.
* Wrappers are types which box primitive values, such as {@link Integer}.
* Wrappers are types which box primitive values, such as {@link Integer}.
* The reference type {@code java.lang.Void} counts as a wrapper.
* @return true if any of the types are wrappers
* @return true if any of the types are wrappers
*/
*/
public
boolean
hasWrappers
()
{
public
boolean
hasWrappers
()
{
return
unwrap
()
!=
this
;
return
unwrap
()
!=
this
;
}
}
/** Convenience method for {@link #make(java.lang.Class, java.lang.Class[])}.
/** Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[])}.
* Erase all reference types to Object.
* Erase all reference types to {@code Object}.
* All primitive types (including {@code void}) will remain unchanged.
* @return a version of the original type with all reference types replaced
* @return a version of the original type with all reference types replaced
*/
*/
public
MethodType
erase
()
{
public
MethodType
erase
()
{
return
form
.
erasedType
();
return
form
.
erasedType
();
}
}
/** Convenience method for {@link #makeGeneric(int)}.
/** Convenience method for {@link #genericMethodType(int)}.
* Convert all types, both reference and primitive, to Object.
* Convert all types, both reference and primitive, to {@code Object}.
* The expression {@code type.wrap().erase()} produces the same value
* as {@code type.generic()}.
* @return a version of the original type with all types replaced
* @return a version of the original type with all types replaced
*/
*/
public
MethodType
generic
()
{
public
MethodType
generic
()
{
return
makeGeneric
(
parameterCount
());
return
genericMethodType
(
parameterCount
());
}
}
/** Convenience method for {@link #m
ak
e(java.lang.Class, java.lang.Class[])}.
/** Convenience method for {@link #m
ethodTyp
e(java.lang.Class, java.lang.Class[])}.
* Convert all primitive types to their corresponding wrapper types.
* Convert all primitive types to their corresponding wrapper types.
* All reference types (including wrapper types) will remain unchanged.
* A {@code void} return type is changed to the type {@code java.lang.Void}.
* A {@code void} return type is changed to the type {@code java.lang.Void}.
* The expression {@code type.wrap().erase()} produces the same value
* as {@code type.generic()}.
* @return a version of the original type with all primitive types replaced
* @return a version of the original type with all primitive types replaced
*/
*/
public
MethodType
wrap
()
{
public
MethodType
wrap
()
{
return
hasPrimitives
()
?
wrapWithPrims
(
this
)
:
this
;
return
hasPrimitives
()
?
wrapWithPrims
(
this
)
:
this
;
}
}
/** Convenience method for {@link #m
ak
e(java.lang.Class, java.lang.Class[])}.
/** Convenience method for {@link #m
ethodTyp
e(java.lang.Class, java.lang.Class[])}.
* Convert all wrapper types to their corresponding primitive types.
* Convert all wrapper types to their corresponding primitive types.
* All primitive types (including {@code void}) will remain unchanged.
* A return type of {@code java.lang.Void} is changed to {@code void}.
* A return type of {@code java.lang.Void} is changed to {@code void}.
* @return a version of the original type with all wrapper types replaced
* @return a version of the original type with all wrapper types replaced
*/
*/
...
@@ -391,6 +483,7 @@ class MethodType {
...
@@ -391,6 +483,7 @@ class MethodType {
/**
/**
* Convenience method to present the arguments as an array.
* Convenience method to present the arguments as an array.
* Changes to the array will not result in changes to the type.
* @return the parameter types (as a fresh copy if necessary)
* @return the parameter types (as a fresh copy if necessary)
*/
*/
public
Class
<?>[]
parameterArray
()
{
public
Class
<?>[]
parameterArray
()
{
...
@@ -491,7 +584,7 @@ class MethodType {
...
@@ -491,7 +584,7 @@ class MethodType {
return
form
.
parameterSlotCount
();
return
form
.
parameterSlotCount
();
}
}
/** Number of JVM stack slots which carry all parameters after
/** Number of JVM stack slots which carry all parameters
including and
after
* the given position, which must be in the range of 0 to
* the given position, which must be in the range of 0 to
* {@code parameterCount} inclusive. Successive parameters are
* {@code parameterCount} inclusive. Successive parameters are
* more shallowly stacked, and parameters are indexed in the bytecodes
* more shallowly stacked, and parameters are indexed in the bytecodes
...
@@ -532,7 +625,7 @@ class MethodType {
...
@@ -532,7 +625,7 @@ class MethodType {
return
form
.
returnSlotCount
();
return
form
.
returnSlotCount
();
}
}
/** Convenience method for {@link #m
ak
e(java.lang.Class, java.lang.Class[])}.
/** Convenience method for {@link #m
ethodTyp
e(java.lang.Class, java.lang.Class[])}.
* Find or create an instance (interned) of the given method type.
* Find or create an instance (interned) of the given method type.
* Any class or interface name embedded in the signature string
* Any class or interface name embedded in the signature string
* will be resolved by calling {@link ClassLoader#loadClass(java.lang.String)}
* will be resolved by calling {@link ClassLoader#loadClass(java.lang.String)}
...
@@ -544,16 +637,16 @@ class MethodType {
...
@@ -544,16 +637,16 @@ class MethodType {
* <p>
* <p>
* This method is included for the benfit of applications that must
* This method is included for the benfit of applications that must
* generate bytecodes that process method handles and invokedynamic.
* generate bytecodes that process method handles and invokedynamic.
* @param
bytecodeSignature
a bytecode-level signature string "(T...)T"
* @param
descriptor
a bytecode-level signature string "(T...)T"
* @param loader the class loader in which to look up the types
* @param loader the class loader in which to look up the types
* @return a method type matching the bytecode-level signature
* @return a method type matching the bytecode-level signature
* @throws IllegalArgumentException if the string is not well-formed
* @throws IllegalArgumentException if the string is not well-formed
* @throws TypeNotPresentException if a named type cannot be found
* @throws TypeNotPresentException if a named type cannot be found
*/
*/
public
static
MethodType
from
BytecodeString
(
String
bytecodeSignature
,
ClassLoader
loader
)
public
static
MethodType
from
MethodDescriptorString
(
String
descriptor
,
ClassLoader
loader
)
throws
IllegalArgumentException
,
TypeNotPresentException
throws
IllegalArgumentException
,
TypeNotPresentException
{
{
List
<
Class
<?>>
types
=
Bytecode
Signature
.
parseMethod
(
bytecodeSignature
,
loader
);
List
<
Class
<?>>
types
=
Bytecode
Descriptor
.
parseMethod
(
descriptor
,
loader
);
Class
<?>
rtype
=
types
.
remove
(
types
.
size
()
-
1
);
Class
<?>
rtype
=
types
.
remove
(
types
.
size
()
-
1
);
Class
<?>[]
ptypes
=
types
.
toArray
(
NO_PTYPES
);
Class
<?>[]
ptypes
=
types
.
toArray
(
NO_PTYPES
);
return
makeImpl
(
rtype
,
ptypes
,
true
);
return
makeImpl
(
rtype
,
ptypes
,
true
);
...
@@ -565,11 +658,21 @@ class MethodType {
...
@@ -565,11 +658,21 @@ class MethodType {
* <p>
* <p>
* This method is included for the benfit of applications that must
* This method is included for the benfit of applications that must
* generate bytecodes that process method handles and invokedynamic.
* generate bytecodes that process method handles and invokedynamic.
* {@link #from
Bytecode
String(java.lang.String, java.lang.ClassLoader)},
* {@link #from
MethodDescriptor
String(java.lang.String, java.lang.ClassLoader)},
* because the latter requires a suitable class loader argument.
* because the latter requires a suitable class loader argument.
* @return the bytecode signature representation
* @return the bytecode signature representation
*/
*/
public
String
toMethodDescriptorString
()
{
return
BytecodeDescriptor
.
unparse
(
this
);
}
/** Temporary alias for toMethodDescriptorString; delete after M3. */
public
String
toBytecodeString
()
{
public
String
toBytecodeString
()
{
return
BytecodeSignature
.
unparse
(
this
);
return
toMethodDescriptorString
();
}
/** Temporary alias for fromMethodDescriptorString; delete after M3. */
public
static
MethodType
fromBytecodeString
(
String
descriptor
,
ClassLoader
loader
)
throws
IllegalArgumentException
,
TypeNotPresentException
{
return
fromMethodDescriptorString
(
descriptor
,
loader
);
}
}
}
}
src/share/classes/java/dyn/package-info.java
浏览文件 @
8992d5c6
...
@@ -24,6 +24,7 @@
...
@@ -24,6 +24,7 @@
*/
*/
/**
/**
* <em>PROVISIONAL API, WORK IN PROGRESS:</em>
* This package contains dynamic language support provided directly by
* This package contains dynamic language support provided directly by
* the Java core class libraries and virtual machine.
* the Java core class libraries and virtual machine.
* @author John Rose, JSR 292 EG
* @author John Rose, JSR 292 EG
...
...
src/share/classes/sun/dyn/AdapterMethodHandle.java
浏览文件 @
8992d5c6
...
@@ -30,7 +30,7 @@ import sun.dyn.util.Wrapper;
...
@@ -30,7 +30,7 @@ import sun.dyn.util.Wrapper;
import
java.dyn.*
;
import
java.dyn.*
;
import
java.util.Arrays
;
import
java.util.Arrays
;
import
static
sun
.
dyn
.
MethodHandleNatives
.
Constants
.*;
import
static
sun
.
dyn
.
MethodHandleNatives
.
Constants
.*;
import
static
sun
.
dyn
.
Me
thodHandleImpl
.
newIllegalArgumentException
;
import
static
sun
.
dyn
.
Me
mberName
.
newIllegalArgumentException
;
/**
/**
* This method handle performs simple conversion or checking of a single argument.
* This method handle performs simple conversion or checking of a single argument.
...
@@ -302,7 +302,22 @@ public class AdapterMethodHandle extends BoundMethodHandle {
...
@@ -302,7 +302,22 @@ public class AdapterMethodHandle extends BoundMethodHandle {
*/
*/
private
static
int
type2size
(
int
type
)
{
private
static
int
type2size
(
int
type
)
{
assert
(
type
>=
T_BOOLEAN
&&
type
<=
T_OBJECT
);
assert
(
type
>=
T_BOOLEAN
&&
type
<=
T_OBJECT
);
return
(
type
==
T_FLOAT
||
type
==
T_DOUBLE
)
?
2
:
1
;
return
(
type
==
T_LONG
||
type
==
T_DOUBLE
)
?
2
:
1
;
}
private
static
int
type2size
(
Class
<?>
type
)
{
return
type2size
(
basicType
(
type
));
}
/** The given stackMove is the number of slots pushed.
* It might be negative. Scale it (multiply) by the
* VM's notion of how an address changes with a push,
* to get the raw SP change for stackMove.
* Then shift and mask it into the correct field.
*/
private
static
long
insertStackMove
(
int
stackMove
)
{
// following variable must be long to avoid sign extension after '<<'
long
spChange
=
stackMove
*
MethodHandleNatives
.
JVM_STACK_MOVE_UNIT
;
return
(
spChange
&
CONV_STACK_MOVE_MASK
)
<<
CONV_STACK_MOVE_SHIFT
;
}
}
/** Construct an adapter conversion descriptor for a single-argument conversion. */
/** Construct an adapter conversion descriptor for a single-argument conversion. */
...
@@ -310,16 +325,16 @@ public class AdapterMethodHandle extends BoundMethodHandle {
...
@@ -310,16 +325,16 @@ public class AdapterMethodHandle extends BoundMethodHandle {
assert
(
src
==
(
src
&
0xF
));
assert
(
src
==
(
src
&
0xF
));
assert
(
dest
==
(
dest
&
0xF
));
assert
(
dest
==
(
dest
&
0xF
));
assert
(
convOp
>=
OP_CHECK_CAST
&&
convOp
<=
OP_PRIM_TO_REF
);
assert
(
convOp
>=
OP_CHECK_CAST
&&
convOp
<=
OP_PRIM_TO_REF
);
long
stackMove
=
type2size
(
dest
)
-
type2size
(
src
);
int
stackMove
=
type2size
(
dest
)
-
type2size
(
src
);
return
((
long
)
argnum
<<
32
|
return
((
long
)
argnum
<<
32
|
(
long
)
convOp
<<
CONV_OP_SHIFT
|
(
long
)
convOp
<<
CONV_OP_SHIFT
|
(
int
)
src
<<
CONV_SRC_TYPE_SHIFT
|
(
int
)
src
<<
CONV_SRC_TYPE_SHIFT
|
(
int
)
dest
<<
CONV_DEST_TYPE_SHIFT
|
(
int
)
dest
<<
CONV_DEST_TYPE_SHIFT
|
stackMove
<<
CONV_STACK_MOVE_SHIFT
insertStackMove
(
stackMove
)
);
);
}
}
private
static
long
makeConv
(
int
convOp
,
int
argnum
,
int
stackMove
)
{
private
static
long
makeConv
(
int
convOp
,
int
argnum
,
int
stackMove
)
{
assert
(
convOp
>=
OP_
SWA
P_ARGS
&&
convOp
<=
OP_SPREAD_ARGS
);
assert
(
convOp
>=
OP_
DU
P_ARGS
&&
convOp
<=
OP_SPREAD_ARGS
);
byte
src
=
0
,
dest
=
0
;
byte
src
=
0
,
dest
=
0
;
if
(
convOp
>=
OP_COLLECT_ARGS
&&
convOp
<=
OP_SPREAD_ARGS
)
if
(
convOp
>=
OP_COLLECT_ARGS
&&
convOp
<=
OP_SPREAD_ARGS
)
src
=
dest
=
T_OBJECT
;
src
=
dest
=
T_OBJECT
;
...
@@ -327,12 +342,21 @@ public class AdapterMethodHandle extends BoundMethodHandle {
...
@@ -327,12 +342,21 @@ public class AdapterMethodHandle extends BoundMethodHandle {
(
long
)
convOp
<<
CONV_OP_SHIFT
|
(
long
)
convOp
<<
CONV_OP_SHIFT
|
(
int
)
src
<<
CONV_SRC_TYPE_SHIFT
|
(
int
)
src
<<
CONV_SRC_TYPE_SHIFT
|
(
int
)
dest
<<
CONV_DEST_TYPE_SHIFT
|
(
int
)
dest
<<
CONV_DEST_TYPE_SHIFT
|
stackMove
<<
CONV_STACK_MOVE_SHIFT
insertStackMove
(
stackMove
)
);
}
private
static
long
makeSwapConv
(
int
convOp
,
int
srcArg
,
byte
type
,
int
destSlot
)
{
assert
(
convOp
>=
OP_SWAP_ARGS
&&
convOp
<=
OP_ROT_ARGS
);
return
((
long
)
srcArg
<<
32
|
(
long
)
convOp
<<
CONV_OP_SHIFT
|
(
int
)
type
<<
CONV_SRC_TYPE_SHIFT
|
(
int
)
type
<<
CONV_DEST_TYPE_SHIFT
|
(
int
)
destSlot
<<
CONV_VMINFO_SHIFT
);
);
}
}
private
static
long
makeConv
(
int
convOp
)
{
private
static
long
makeConv
(
int
convOp
)
{
assert
(
convOp
==
OP_RETYPE_ONLY
);
assert
(
convOp
==
OP_RETYPE_ONLY
||
convOp
==
OP_RETYPE_RAW
);
return
(
long
)
convOp
<<
CONV_OP_SHIFT
;
// stackMove, src, dst, argnum
all zero
return
(
(
long
)-
1
<<
32
)
|
(
convOp
<<
CONV_OP_SHIFT
);
// stackMove, src, dst
all zero
}
}
private
static
int
convCode
(
long
conv
)
{
private
static
int
convCode
(
long
conv
)
{
return
(
int
)
conv
;
return
(
int
)
conv
;
...
@@ -348,16 +372,6 @@ public class AdapterMethodHandle extends BoundMethodHandle {
...
@@ -348,16 +372,6 @@ public class AdapterMethodHandle extends BoundMethodHandle {
/** One of OP_RETYPE_ONLY, etc. */
/** One of OP_RETYPE_ONLY, etc. */
int
conversionOp
()
{
return
(
conversion
&
CONV_OP_MASK
)
>>
CONV_OP_SHIFT
;
}
int
conversionOp
()
{
return
(
conversion
&
CONV_OP_MASK
)
>>
CONV_OP_SHIFT
;
}
@Override
public
String
toString
()
{
return
addTypeString
(
this
,
"Adapted["
+
basicToString
(
nonAdapter
((
MethodHandle
)
vmtarget
))
+
"]"
);
}
private
static
MethodHandle
nonAdapter
(
MethodHandle
mh
)
{
return
(
MethodHandle
)
MethodHandleNatives
.
getTarget
(
mh
,
ETF_DIRECT_HANDLE
);
}
/* Return one plus the position of the first non-trivial difference
/* Return one plus the position of the first non-trivial difference
* between the given types. This is not a symmetric operation;
* between the given types. This is not a symmetric operation;
* we are considering adapting the targetType to adapterType.
* we are considering adapting the targetType to adapterType.
...
@@ -399,14 +413,14 @@ public class AdapterMethodHandle extends BoundMethodHandle {
...
@@ -399,14 +413,14 @@ public class AdapterMethodHandle extends BoundMethodHandle {
//if (false) return 1; // never adaptable!
//if (false) return 1; // never adaptable!
return
-
1
;
// some significant difference
return
-
1
;
// some significant difference
}
}
private
static
int
diffParamTypes
(
MethodType
adapterType
,
int
t
start
,
private
static
int
diffParamTypes
(
MethodType
adapterType
,
int
a
start
,
MethodType
targetType
,
int
a
start
,
MethodType
targetType
,
int
t
start
,
int
nargs
,
boolean
raw
)
{
int
nargs
,
boolean
raw
)
{
assert
(
nargs
>=
0
);
assert
(
nargs
>=
0
);
int
res
=
0
;
int
res
=
0
;
for
(
int
i
=
0
;
i
<
nargs
;
i
++)
{
for
(
int
i
=
0
;
i
<
nargs
;
i
++)
{
Class
<?>
src
=
adapterType
.
parameterType
(
t
start
+
i
);
Class
<?>
src
=
adapterType
.
parameterType
(
a
start
+
i
);
Class
<?>
dest
=
targetType
.
parameterType
(
a
start
+
i
);
Class
<?>
dest
=
targetType
.
parameterType
(
t
start
+
i
);
if
((!
raw
if
((!
raw
?
VerifyType
.
canPassUnchecked
(
src
,
dest
)
?
VerifyType
.
canPassUnchecked
(
src
,
dest
)
:
VerifyType
.
canPassRaw
(
src
,
dest
)
:
VerifyType
.
canPassRaw
(
src
,
dest
)
...
@@ -422,7 +436,7 @@ public class AdapterMethodHandle extends BoundMethodHandle {
...
@@ -422,7 +436,7 @@ public class AdapterMethodHandle extends BoundMethodHandle {
/** Can a retyping adapter (alone) validly convert the target to newType? */
/** Can a retyping adapter (alone) validly convert the target to newType? */
public
static
boolean
canRetypeOnly
(
MethodType
newType
,
MethodType
targetType
)
{
public
static
boolean
canRetypeOnly
(
MethodType
newType
,
MethodType
targetType
)
{
return
canRetype
Only
(
newType
,
targetType
,
false
);
return
canRetype
(
newType
,
targetType
,
false
);
}
}
/** Can a retyping adapter (alone) convert the target to newType?
/** Can a retyping adapter (alone) convert the target to newType?
* It is allowed to widen subword types and void to int, to make bitwise
* It is allowed to widen subword types and void to int, to make bitwise
...
@@ -430,14 +444,14 @@ public class AdapterMethodHandle extends BoundMethodHandle {
...
@@ -430,14 +444,14 @@ public class AdapterMethodHandle extends BoundMethodHandle {
* reference conversions on return. This last feature requires that the
* reference conversions on return. This last feature requires that the
* caller be trusted, and perform explicit cast conversions on return values.
* caller be trusted, and perform explicit cast conversions on return values.
*/
*/
static
boolean
canRawRetypeOnly
(
MethodType
newType
,
MethodType
targetType
)
{
public
static
boolean
canRetypeRaw
(
MethodType
newType
,
MethodType
targetType
)
{
return
canRetype
Only
(
newType
,
targetType
,
true
);
return
canRetype
(
newType
,
targetType
,
true
);
}
}
static
boolean
canRetype
Only
(
MethodType
newType
,
MethodType
targetType
,
boolean
raw
)
{
static
boolean
canRetype
(
MethodType
newType
,
MethodType
targetType
,
boolean
raw
)
{
if
(!
convOpSupported
(
OP_RETYPE_ONLY
))
return
false
;
if
(!
convOpSupported
(
raw
?
OP_RETYPE_RAW
:
OP_RETYPE_ONLY
))
return
false
;
int
diff
=
diffTypes
(
newType
,
targetType
,
raw
);
int
diff
=
diffTypes
(
newType
,
targetType
,
raw
);
// %%% This assert is too strong. Factor diff into VerifyType and reconcile.
// %%% This assert is too strong. Factor diff into VerifyType and reconcile.
assert
((
diff
==
0
)
==
VerifyType
.
isNullConversion
(
newType
,
targetType
));
assert
(
raw
||
(
diff
==
0
)
==
VerifyType
.
isNullConversion
(
newType
,
targetType
));
return
diff
==
0
;
return
diff
==
0
;
}
}
...
@@ -447,19 +461,21 @@ public class AdapterMethodHandle extends BoundMethodHandle {
...
@@ -447,19 +461,21 @@ public class AdapterMethodHandle extends BoundMethodHandle {
*/
*/
public
static
MethodHandle
makeRetypeOnly
(
Access
token
,
public
static
MethodHandle
makeRetypeOnly
(
Access
token
,
MethodType
newType
,
MethodHandle
target
)
{
MethodType
newType
,
MethodHandle
target
)
{
return
makeRetype
Only
(
token
,
newType
,
target
,
false
);
return
makeRetype
(
token
,
newType
,
target
,
false
);
}
}
public
static
MethodHandle
makeR
awRetypeOnly
(
Access
token
,
public
static
MethodHandle
makeR
etypeRaw
(
Access
token
,
MethodType
newType
,
MethodHandle
target
)
{
MethodType
newType
,
MethodHandle
target
)
{
return
makeRetype
Only
(
token
,
newType
,
target
,
true
);
return
makeRetype
(
token
,
newType
,
target
,
true
);
}
}
static
MethodHandle
makeRetype
Only
(
Access
token
,
static
MethodHandle
makeRetype
(
Access
token
,
MethodType
newType
,
MethodHandle
target
,
boolean
raw
)
{
MethodType
newType
,
MethodHandle
target
,
boolean
raw
)
{
Access
.
check
(
token
);
Access
.
check
(
token
);
if
(!
canRetypeOnly
(
newType
,
target
.
type
(),
raw
))
MethodType
oldType
=
target
.
type
();
if
(
oldType
==
newType
)
return
target
;
if
(!
canRetype
(
newType
,
oldType
,
raw
))
return
null
;
return
null
;
// TO DO: clone the target guy, whatever he is, with new type.
// TO DO: clone the target guy, whatever he is, with new type.
return
new
AdapterMethodHandle
(
target
,
newType
,
makeConv
(
OP_RETYPE_ONLY
));
return
new
AdapterMethodHandle
(
target
,
newType
,
makeConv
(
raw
?
OP_RETYPE_RAW
:
OP_RETYPE_ONLY
));
}
}
/** Can a checkcast adapter validly convert the target to newType?
/** Can a checkcast adapter validly convert the target to newType?
...
@@ -492,7 +508,7 @@ public class AdapterMethodHandle extends BoundMethodHandle {
...
@@ -492,7 +508,7 @@ public class AdapterMethodHandle extends BoundMethodHandle {
Access
.
check
(
token
);
Access
.
check
(
token
);
if
(!
canCheckCast
(
newType
,
target
.
type
(),
arg
,
castType
))
if
(!
canCheckCast
(
newType
,
target
.
type
(),
arg
,
castType
))
return
null
;
return
null
;
long
conv
=
makeConv
(
OP_CHECK_CAST
,
arg
,
0
);
long
conv
=
makeConv
(
OP_CHECK_CAST
,
arg
,
T_OBJECT
,
T_OBJECT
);
return
new
AdapterMethodHandle
(
target
,
newType
,
conv
,
castType
);
return
new
AdapterMethodHandle
(
target
,
newType
,
conv
,
castType
);
}
}
...
@@ -537,10 +553,9 @@ public class AdapterMethodHandle extends BoundMethodHandle {
...
@@ -537,10 +553,9 @@ public class AdapterMethodHandle extends BoundMethodHandle {
int
arg
,
Class
<?>
convType
)
{
int
arg
,
Class
<?>
convType
)
{
Access
.
check
(
token
);
Access
.
check
(
token
);
MethodType
oldType
=
target
.
type
();
MethodType
oldType
=
target
.
type
();
Class
<?>
src
=
newType
.
parameterType
(
arg
);
Class
<?>
dst
=
oldType
.
parameterType
(
arg
);
if
(!
canPrimCast
(
newType
,
oldType
,
arg
,
convType
))
if
(!
canPrimCast
(
newType
,
oldType
,
arg
,
convType
))
return
null
;
return
null
;
Class
<?>
src
=
newType
.
parameterType
(
arg
);
long
conv
=
makeConv
(
OP_PRIM_TO_PRIM
,
arg
,
basicType
(
src
),
basicType
(
convType
));
long
conv
=
makeConv
(
OP_PRIM_TO_PRIM
,
arg
,
basicType
(
src
),
basicType
(
convType
));
return
new
AdapterMethodHandle
(
target
,
newType
,
conv
);
return
new
AdapterMethodHandle
(
target
,
newType
,
conv
);
}
}
...
@@ -607,8 +622,6 @@ public class AdapterMethodHandle extends BoundMethodHandle {
...
@@ -607,8 +622,6 @@ public class AdapterMethodHandle extends BoundMethodHandle {
return
null
;
return
null
;
}
}
// TO DO: makeSwapArguments, makeRotateArguments, makeDuplicateArguments
/** Can an adapter simply drop arguments to convert the target to newType? */
/** Can an adapter simply drop arguments to convert the target to newType? */
public
static
boolean
canDropArguments
(
MethodType
newType
,
MethodType
targetType
,
public
static
boolean
canDropArguments
(
MethodType
newType
,
MethodType
targetType
,
int
dropArgPos
,
int
dropArgCount
)
{
int
dropArgPos
,
int
dropArgCount
)
{
...
@@ -643,26 +656,195 @@ public class AdapterMethodHandle extends BoundMethodHandle {
...
@@ -643,26 +656,195 @@ public class AdapterMethodHandle extends BoundMethodHandle {
Access
.
check
(
token
);
Access
.
check
(
token
);
if
(
dropArgCount
==
0
)
if
(
dropArgCount
==
0
)
return
makeRetypeOnly
(
IMPL_TOKEN
,
newType
,
target
);
return
makeRetypeOnly
(
IMPL_TOKEN
,
newType
,
target
);
MethodType
mt
=
target
.
type
();
if
(!
canDropArguments
(
newType
,
target
.
type
(),
dropArgPos
,
dropArgCount
))
int
argCount
=
mt
.
parameterCount
();
return
null
;
if
(!
canDropArguments
(
newType
,
mt
,
dropArgPos
,
dropArgCount
))
// in arglist: [0: ...keep1 | dpos: drop... | dpos+dcount: keep2... ]
// out arglist: [0: ...keep1 | dpos: keep2... ]
int
keep2InPos
=
dropArgPos
+
dropArgCount
;
int
dropSlot
=
newType
.
parameterSlotDepth
(
keep2InPos
);
int
keep1InSlot
=
newType
.
parameterSlotDepth
(
dropArgPos
);
int
slotCount
=
keep1InSlot
-
dropSlot
;
assert
(
slotCount
>=
dropArgCount
);
assert
(
target
.
type
().
parameterSlotCount
()
+
slotCount
==
newType
.
parameterSlotCount
());
long
conv
=
makeConv
(
OP_DROP_ARGS
,
dropArgPos
+
dropArgCount
-
1
,
-
slotCount
);
return
new
AdapterMethodHandle
(
target
,
newType
,
conv
);
}
/** Can an adapter duplicate an argument to convert the target to newType? */
public
static
boolean
canDupArguments
(
MethodType
newType
,
MethodType
targetType
,
int
dupArgPos
,
int
dupArgCount
)
{
if
(!
convOpSupported
(
OP_DUP_ARGS
))
return
false
;
if
(
diffReturnTypes
(
newType
,
targetType
,
false
)
!=
0
)
return
false
;
int
nptypes
=
newType
.
parameterCount
();
if
(
dupArgCount
<
0
||
dupArgPos
+
dupArgCount
>
nptypes
)
return
false
;
if
(
targetType
.
parameterCount
()
!=
nptypes
+
dupArgCount
)
return
false
;
// parameter types must be the same up to the duplicated arguments
if
(
diffParamTypes
(
newType
,
0
,
targetType
,
0
,
nptypes
,
false
)
!=
0
)
return
false
;
// duplicated types must be, well, duplicates
if
(
diffParamTypes
(
newType
,
dupArgPos
,
targetType
,
nptypes
,
dupArgCount
,
false
)
!=
0
)
return
false
;
return
true
;
}
/** Factory method: Duplicate the selected argument.
* Return null if this is not possible.
*/
public
static
MethodHandle
makeDupArguments
(
Access
token
,
MethodType
newType
,
MethodHandle
target
,
int
dupArgPos
,
int
dupArgCount
)
{
Access
.
check
(
token
);
if
(!
canDupArguments
(
newType
,
target
.
type
(),
dupArgPos
,
dupArgCount
))
return
null
;
if
(
dupArgCount
==
0
)
return
target
;
// in arglist: [0: ...keep1 | dpos: dup... | dpos+dcount: keep2... ]
// out arglist: [0: ...keep1 | dpos: dup... | dpos+dcount: keep2... | dup... ]
int
keep2InPos
=
dupArgPos
+
dupArgCount
;
int
dupSlot
=
newType
.
parameterSlotDepth
(
keep2InPos
);
int
keep1InSlot
=
newType
.
parameterSlotDepth
(
dupArgPos
);
int
slotCount
=
keep1InSlot
-
dupSlot
;
assert
(
target
.
type
().
parameterSlotCount
()
-
slotCount
==
newType
.
parameterSlotCount
());
long
conv
=
makeConv
(
OP_DUP_ARGS
,
dupArgPos
+
dupArgCount
-
1
,
slotCount
);
return
new
AdapterMethodHandle
(
target
,
newType
,
conv
);
}
/** Can an adapter swap two arguments to convert the target to newType? */
public
static
boolean
canSwapArguments
(
MethodType
newType
,
MethodType
targetType
,
int
swapArg1
,
int
swapArg2
)
{
if
(!
convOpSupported
(
OP_SWAP_ARGS
))
return
false
;
if
(
diffReturnTypes
(
newType
,
targetType
,
false
)
!=
0
)
return
false
;
if
(
swapArg1
>=
swapArg2
)
return
false
;
// caller resp
int
nptypes
=
newType
.
parameterCount
();
if
(
targetType
.
parameterCount
()
!=
nptypes
)
return
false
;
if
(
swapArg1
<
0
||
swapArg2
>=
nptypes
)
return
false
;
if
(
diffParamTypes
(
newType
,
0
,
targetType
,
0
,
swapArg1
,
false
)
!=
0
)
return
false
;
if
(
diffParamTypes
(
newType
,
swapArg1
,
targetType
,
swapArg2
,
1
,
false
)
!=
0
)
return
false
;
if
(
diffParamTypes
(
newType
,
swapArg1
+
1
,
targetType
,
swapArg1
+
1
,
swapArg2
-
swapArg1
-
1
,
false
)
!=
0
)
return
false
;
if
(
diffParamTypes
(
newType
,
swapArg2
,
targetType
,
swapArg1
,
1
,
false
)
!=
0
)
return
false
;
if
(
diffParamTypes
(
newType
,
swapArg2
+
1
,
targetType
,
swapArg2
+
1
,
nptypes
-
swapArg2
-
1
,
false
)
!=
0
)
return
false
;
return
true
;
}
/** Factory method: Swap the selected arguments.
* Return null if this is not possible.
*/
public
static
MethodHandle
makeSwapArguments
(
Access
token
,
MethodType
newType
,
MethodHandle
target
,
int
swapArg1
,
int
swapArg2
)
{
Access
.
check
(
token
);
if
(
swapArg1
==
swapArg2
)
return
target
;
if
(
swapArg1
>
swapArg2
)
{
int
t
=
swapArg1
;
swapArg1
=
swapArg2
;
swapArg2
=
t
;
}
if
(!
canSwapArguments
(
newType
,
target
.
type
(),
swapArg1
,
swapArg2
))
return
null
;
return
null
;
int
dropSlotCount
,
dropSlotPos
;
Class
<?>
swapType
=
newType
.
parameterType
(
swapArg1
);
if
(
dropArgCount
>=
argCount
)
{
// in arglist: [0: ...keep1 | pos1: a1 | pos1+1: keep2... | pos2: a2 | pos2+1: keep3... ]
assert
(
dropArgPos
==
argCount
-
1
);
// out arglist: [0: ...keep1 | pos1: a2 | pos1+1: keep2... | pos2: a1 | pos2+1: keep3... ]
dropSlotPos
=
0
;
int
swapSlot2
=
newType
.
parameterSlotDepth
(
swapArg2
+
1
);
dropSlotCount
=
mt
.
parameterSlotCount
();
long
conv
=
makeSwapConv
(
OP_SWAP_ARGS
,
swapArg1
,
basicType
(
swapType
),
swapSlot2
);
return
new
AdapterMethodHandle
(
target
,
newType
,
conv
);
}
static
int
positiveRotation
(
int
argCount
,
int
rotateBy
)
{
assert
(
argCount
>
0
);
if
(
rotateBy
>=
0
)
{
if
(
rotateBy
<
argCount
)
return
rotateBy
;
return
rotateBy
%
argCount
;
}
else
if
(
rotateBy
>=
-
argCount
)
{
return
rotateBy
+
argCount
;
}
else
{
}
else
{
// arglist: [0: keep... | dpos: drop... | dpos+dcount: keep... ]
return
(-
1
-((-
1
-
rotateBy
)
%
argCount
))
+
argCount
;
int
lastDroppedArg
=
dropArgPos
+
dropArgCount
-
1
;
int
lastKeptArg
=
dropArgPos
-
1
;
// might be -1, which is OK
dropSlotPos
=
mt
.
parameterSlotDepth
(
1
+
lastDroppedArg
);
int
lastKeptSlot
=
mt
.
parameterSlotDepth
(
1
+
lastKeptArg
);
dropSlotCount
=
lastKeptSlot
-
dropSlotPos
;
assert
(
dropSlotCount
>=
dropArgCount
);
}
}
long
conv
=
makeConv
(
OP_DROP_ARGS
,
dropArgPos
,
+
dropSlotCount
);
}
return
new
AdapterMethodHandle
(
target
,
newType
,
dropSlotCount
,
conv
);
final
static
int
MAX_ARG_ROTATION
=
1
;
/** Can an adapter rotate arguments to convert the target to newType? */
public
static
boolean
canRotateArguments
(
MethodType
newType
,
MethodType
targetType
,
int
firstArg
,
int
argCount
,
int
rotateBy
)
{
if
(!
convOpSupported
(
OP_ROT_ARGS
))
return
false
;
if
(
argCount
<=
2
)
return
false
;
// must be a swap, not a rotate
rotateBy
=
positiveRotation
(
argCount
,
rotateBy
);
if
(
rotateBy
==
0
)
return
false
;
// no rotation
if
(
rotateBy
>
MAX_ARG_ROTATION
&&
rotateBy
<
argCount
-
MAX_ARG_ROTATION
)
return
false
;
// too many argument positions
// Rotate incoming args right N to the out args, N in 1..(argCouunt-1).
if
(
diffReturnTypes
(
newType
,
targetType
,
false
)
!=
0
)
return
false
;
int
nptypes
=
newType
.
parameterCount
();
if
(
targetType
.
parameterCount
()
!=
nptypes
)
return
false
;
if
(
firstArg
<
0
||
firstArg
>=
nptypes
)
return
false
;
int
argLimit
=
firstArg
+
argCount
;
if
(
argLimit
>
nptypes
)
return
false
;
if
(
diffParamTypes
(
newType
,
0
,
targetType
,
0
,
firstArg
,
false
)
!=
0
)
return
false
;
int
newChunk1
=
argCount
-
rotateBy
,
newChunk2
=
rotateBy
;
// swap new chunk1 with target chunk2
if
(
diffParamTypes
(
newType
,
firstArg
,
targetType
,
argLimit
-
newChunk1
,
newChunk1
,
false
)
!=
0
)
return
false
;
// swap new chunk2 with target chunk1
if
(
diffParamTypes
(
newType
,
firstArg
+
newChunk1
,
targetType
,
firstArg
,
newChunk2
,
false
)
!=
0
)
return
false
;
return
true
;
}
/** Factory method: Rotate the selected argument range.
* Return null if this is not possible.
*/
public
static
MethodHandle
makeRotateArguments
(
Access
token
,
MethodType
newType
,
MethodHandle
target
,
int
firstArg
,
int
argCount
,
int
rotateBy
)
{
Access
.
check
(
token
);
rotateBy
=
positiveRotation
(
argCount
,
rotateBy
);
if
(!
canRotateArguments
(
newType
,
target
.
type
(),
firstArg
,
argCount
,
rotateBy
))
return
null
;
// Decide whether it should be done as a right or left rotation,
// on the JVM stack. Return the number of stack slots to rotate by,
// positive if right, negative if left.
int
limit
=
firstArg
+
argCount
;
int
depth0
=
newType
.
parameterSlotDepth
(
firstArg
);
int
depth1
=
newType
.
parameterSlotDepth
(
limit
-
rotateBy
);
int
depth2
=
newType
.
parameterSlotDepth
(
limit
);
int
chunk1Slots
=
depth0
-
depth1
;
assert
(
chunk1Slots
>
0
);
int
chunk2Slots
=
depth1
-
depth2
;
assert
(
chunk2Slots
>
0
);
// From here on out, it assumes a single-argument shift.
assert
(
MAX_ARG_ROTATION
==
1
);
int
srcArg
,
dstArg
;
byte
basicType
;
if
(
chunk2Slots
<=
chunk1Slots
)
{
// Rotate right/down N (rotateBy = +N, N small, c2 small):
// in arglist: [0: ...keep1 | arg1: c1... | limit-N: c2 | limit: keep2... ]
// out arglist: [0: ...keep1 | arg1: c2 | arg1+N: c1... | limit: keep2... ]
srcArg
=
limit
-
1
;
dstArg
=
firstArg
;
basicType
=
basicType
(
newType
.
parameterType
(
srcArg
));
assert
(
chunk2Slots
==
type2size
(
basicType
));
}
else
{
// Rotate left/up N (rotateBy = -N, N small, c1 small):
// in arglist: [0: ...keep1 | arg1: c1 | arg1+N: c2... | limit: keep2... ]
// out arglist: [0: ...keep1 | arg1: c2 ... | limit-N: c1 | limit: keep2... ]
srcArg
=
firstArg
;
dstArg
=
limit
-
1
;
basicType
=
basicType
(
newType
.
parameterType
(
srcArg
));
assert
(
chunk1Slots
==
type2size
(
basicType
));
}
int
dstSlot
=
newType
.
parameterSlotDepth
(
dstArg
+
1
);
long
conv
=
makeSwapConv
(
OP_ROT_ARGS
,
srcArg
,
basicType
,
dstSlot
);
return
new
AdapterMethodHandle
(
target
,
newType
,
conv
);
}
}
/** Can an adapter spread an argument to convert the target to newType? */
/** Can an adapter spread an argument to convert the target to newType? */
...
@@ -676,10 +858,10 @@ public class AdapterMethodHandle extends BoundMethodHandle {
...
@@ -676,10 +858,10 @@ public class AdapterMethodHandle extends BoundMethodHandle {
if
(
spreadArgPos
!=
0
&&
diffParamTypes
(
newType
,
0
,
targetType
,
0
,
spreadArgPos
,
false
)
!=
0
)
if
(
spreadArgPos
!=
0
&&
diffParamTypes
(
newType
,
0
,
targetType
,
0
,
spreadArgPos
,
false
)
!=
0
)
return
false
;
return
false
;
int
afterPos
=
spreadArgPos
+
spreadArgCount
;
int
afterPos
=
spreadArgPos
+
spreadArgCount
;
int
afterCount
=
nptypes
-
afterPos
;
int
afterCount
=
nptypes
-
(
spreadArgPos
+
1
)
;
if
(
spreadArgPos
<
0
||
spreadArgPos
>=
nptypes
||
if
(
spreadArgPos
<
0
||
spreadArgPos
>=
nptypes
||
spreadArgCount
<
0
||
spreadArgCount
<
0
||
targetType
.
parameterCount
()
!=
nptypes
-
1
+
spreadArg
Count
)
targetType
.
parameterCount
()
!=
afterPos
+
after
Count
)
return
false
;
return
false
;
// parameter types after the spread point must also be the same
// parameter types after the spread point must also be the same
if
(
afterCount
!=
0
&&
diffParamTypes
(
newType
,
spreadArgPos
+
1
,
targetType
,
afterPos
,
afterCount
,
false
)
!=
0
)
if
(
afterCount
!=
0
&&
diffParamTypes
(
newType
,
spreadArgPos
+
1
,
targetType
,
afterPos
,
afterCount
,
false
)
!=
0
)
...
@@ -697,32 +879,40 @@ public class AdapterMethodHandle extends BoundMethodHandle {
...
@@ -697,32 +879,40 @@ public class AdapterMethodHandle extends BoundMethodHandle {
return
true
;
return
true
;
}
}
/** Factory method: Spread selected argument. */
/** Factory method: Spread selected argument. */
public
static
MethodHandle
makeSpreadArguments
(
Access
token
,
public
static
MethodHandle
makeSpreadArguments
(
Access
token
,
MethodType
newType
,
MethodHandle
target
,
MethodType
newType
,
MethodHandle
target
,
Class
<?>
spreadArgType
,
int
spreadArgPos
,
int
spreadArgCount
)
{
Class
<?>
spreadArgType
,
int
spreadArgPos
,
int
spreadArgCount
)
{
Access
.
check
(
token
);
Access
.
check
(
token
);
MethodType
mt
=
target
.
type
();
MethodType
targetType
=
target
.
type
();
int
argCount
=
mt
.
parameterCount
();
if
(!
canSpreadArguments
(
newType
,
targetType
,
spreadArgType
,
spreadArgPos
,
spreadArgCount
))
if
(!
canSpreadArguments
(
newType
,
mt
,
spreadArgType
,
spreadArgPos
,
spreadArgCount
))
return
null
;
return
null
;
int
spreadSlotCount
,
spreadSlotPos
;
// in arglist: [0: ...keep1 | spos: spreadArg | spos+1: keep2... ]
if
(
spreadArgCount
>=
argCount
)
{
// out arglist: [0: ...keep1 | spos: spread... | spos+scount: keep2... ]
assert
(
spreadArgPos
==
argCount
-
1
);
int
keep2OutPos
=
spreadArgPos
+
spreadArgCount
;
spreadSlotPos
=
0
;
int
spreadSlot
=
targetType
.
parameterSlotDepth
(
keep2OutPos
);
spreadSlotCount
=
mt
.
parameterSlotCount
();
int
keep1OutSlot
=
targetType
.
parameterSlotDepth
(
spreadArgPos
);
}
else
{
int
slotCount
=
keep1OutSlot
-
spreadSlot
;
// arglist: [0: keep... | dpos: spread... | dpos+dcount: keep... ]
assert
(
spreadSlot
==
newType
.
parameterSlotDepth
(
spreadArgPos
+
1
));
int
lastSpreadArg
=
spreadArgPos
+
spreadArgCount
-
1
;
assert
(
slotCount
>=
spreadArgCount
);
int
lastKeptArg
=
spreadArgPos
-
1
;
// might be -1, which is OK
long
conv
=
makeConv
(
OP_SPREAD_ARGS
,
spreadArgPos
,
slotCount
-
1
);
spreadSlotPos
=
mt
.
parameterSlotDepth
(
1
+
lastSpreadArg
);
MethodHandle
res
=
new
AdapterMethodHandle
(
target
,
newType
,
conv
,
spreadArgType
);
int
lastKeptSlot
=
mt
.
parameterSlotDepth
(
1
+
lastKeptArg
);
assert
(
res
.
type
().
parameterType
(
spreadArgPos
)
==
spreadArgType
);
spreadSlotCount
=
lastKeptSlot
-
spreadSlotPos
;
return
res
;
assert
(
spreadSlotCount
>=
spreadArgCount
);
}
long
conv
=
makeConv
(
OP_SPREAD_ARGS
,
spreadArgPos
,
spreadSlotCount
);
return
new
AdapterMethodHandle
(
target
,
newType
,
conv
,
spreadArgType
);
}
}
// TO DO: makeCollectArguments, makeFlyby, makeRicochet
// TO DO: makeCollectArguments, makeFlyby, makeRicochet
@Override
public
String
toString
()
{
return
nonAdapter
((
MethodHandle
)
vmtarget
).
toString
();
}
private
static
MethodHandle
nonAdapter
(
MethodHandle
mh
)
{
while
(
mh
instanceof
AdapterMethodHandle
)
{
mh
=
(
MethodHandle
)
mh
.
vmtarget
;
}
return
mh
;
}
}
}
src/share/classes/sun/dyn/BoundMethodHandle.java
浏览文件 @
8992d5c6
...
@@ -28,6 +28,10 @@ package sun.dyn;
...
@@ -28,6 +28,10 @@ package sun.dyn;
import
sun.dyn.util.VerifyType
;
import
sun.dyn.util.VerifyType
;
import
sun.dyn.util.Wrapper
;
import
sun.dyn.util.Wrapper
;
import
java.dyn.*
;
import
java.dyn.*
;
import
java.util.List
;
import
sun.dyn.MethodHandleNatives.Constants
;
import
static
sun
.
dyn
.
MethodHandleImpl
.
IMPL_LOOKUP
;
import
static
sun
.
dyn
.
MemberName
.
newIllegalArgumentException
;
/**
/**
* The flavor of method handle which emulates an invoke instruction
* The flavor of method handle which emulates an invoke instruction
...
@@ -40,13 +44,18 @@ public class BoundMethodHandle extends MethodHandle {
...
@@ -40,13 +44,18 @@ public class BoundMethodHandle extends MethodHandle {
private
final
Object
argument
;
// argument to insert
private
final
Object
argument
;
// argument to insert
private
final
int
vmargslot
;
// position at which it is inserted
private
final
int
vmargslot
;
// position at which it is inserted
private
static
final
Access
IMPL_TOKEN
=
Access
.
getToken
();
private
static
final
MemberName
.
Factory
IMPL_NAMES
=
MemberName
.
getFactory
(
IMPL_TOKEN
);
// Constructors in this class *must* be package scoped or private.
// Constructors in this class *must* be package scoped or private.
// Exception: JavaMethodHandle constructors are protected.
// (The link between JMH and BMH is temporary.)
/** Bind a direct MH to its receiver (or first ref. argument).
/** Bind a direct MH to its receiver (or first ref. argument).
* The JVM will pre-dispatch the MH if it is not already static.
* The JVM will pre-dispatch the MH if it is not already static.
*/
*/
BoundMethodHandle
(
DirectMethodHandle
mh
,
Object
argument
)
{
BoundMethodHandle
(
DirectMethodHandle
mh
,
Object
argument
)
{
super
(
Access
.
TOKEN
,
mh
.
type
().
dropParameterType
(
0
));
super
(
Access
.
TOKEN
,
mh
.
type
().
dropParameterType
s
(
0
,
1
));
// check the type now, once for all:
// check the type now, once for all:
this
.
argument
=
checkReferenceArgument
(
argument
,
mh
,
0
);
this
.
argument
=
checkReferenceArgument
(
argument
,
mh
,
0
);
this
.
vmargslot
=
this
.
type
().
parameterSlotCount
();
this
.
vmargslot
=
this
.
type
().
parameterSlotCount
();
...
@@ -58,28 +67,30 @@ public class BoundMethodHandle extends MethodHandle {
...
@@ -58,28 +67,30 @@ public class BoundMethodHandle extends MethodHandle {
}
}
}
}
private
static
final
int
REF_ARG
=
0
,
PRIM_ARG
=
1
,
SELF_ARG
=
2
;
/** Insert an argument into an arbitrary method handle.
/** Insert an argument into an arbitrary method handle.
* If argnum is zero, inserts the first argument, etc.
* If argnum is zero, inserts the first argument, etc.
* The argument type must be a reference.
* The argument type must be a reference.
*/
*/
BoundMethodHandle
(
MethodHandle
mh
,
Object
argument
,
int
argnum
)
{
BoundMethodHandle
(
MethodHandle
mh
,
Object
argument
,
int
argnum
)
{
this
(
mh
,
argument
,
argnum
,
mh
.
type
().
parameterType
(
argnum
).
isPrimitive
()
?
PRIM_ARG
:
REF_ARG
);
this
(
mh
.
type
().
dropParameterTypes
(
argnum
,
argnum
+
1
),
mh
,
argument
,
argnum
);
}
}
/** Insert an argument into an arbitrary method handle.
/** Insert an argument into an arbitrary method handle.
* If argnum is zero, inserts the first argument, etc.
* If argnum is zero, inserts the first argument, etc.
*/
*/
BoundMethodHandle
(
Method
Handle
mh
,
Object
argument
,
int
argnum
,
int
whichArg
)
{
BoundMethodHandle
(
Method
Type
type
,
MethodHandle
mh
,
Object
argument
,
int
argnum
)
{
super
(
Access
.
TOKEN
,
mh
.
type
().
dropParameterType
(
argnum
)
);
super
(
Access
.
TOKEN
,
type
);
if
(
whichArg
==
PRIM_ARG
)
if
(
mh
.
type
().
parameterType
(
argnum
).
isPrimitive
()
)
this
.
argument
=
bindPrimitiveArgument
(
argument
,
mh
,
argnum
);
this
.
argument
=
bindPrimitiveArgument
(
argument
,
mh
,
argnum
);
else
{
else
{
if
(
whichArg
==
SELF_ARG
)
argument
=
this
;
this
.
argument
=
checkReferenceArgument
(
argument
,
mh
,
argnum
);
this
.
argument
=
checkReferenceArgument
(
argument
,
mh
,
argnum
);
}
}
this
.
vmargslot
=
this
.
type
().
parameterSlotDepth
(
argnum
);
this
.
vmargslot
=
type
.
parameterSlotDepth
(
argnum
);
initTarget
(
mh
,
argnum
);
}
private
void
initTarget
(
MethodHandle
mh
,
int
argnum
)
{
if
(
MethodHandleNatives
.
JVM_SUPPORT
)
{
if
(
MethodHandleNatives
.
JVM_SUPPORT
)
{
this
.
vmtarget
=
null
;
// maybe updated by JVM
this
.
vmtarget
=
null
;
// maybe updated by JVM
MethodHandleNatives
.
init
(
this
,
mh
,
argnum
);
MethodHandleNatives
.
init
(
this
,
mh
,
argnum
);
...
@@ -97,29 +108,65 @@ public class BoundMethodHandle extends MethodHandle {
...
@@ -97,29 +108,65 @@ public class BoundMethodHandle extends MethodHandle {
assert
(
this
.
getClass
()
==
AdapterMethodHandle
.
class
);
assert
(
this
.
getClass
()
==
AdapterMethodHandle
.
class
);
}
}
/** Initialize the current object as a method handle, binding it
/** Initialize the current object as a
Java
method handle, binding it
* as the
{@code argnum}th
argument of the method handle {@code entryPoint}.
* as the
first
argument of the method handle {@code entryPoint}.
* The invocation type of the resulting method handle will be the
* The invocation type of the resulting method handle will be the
* same as {@code entryPoint}, except that the
{@code argnum}th
argument
* same as {@code entryPoint}, except that the
first
argument
* type will be dropped.
* type will be dropped.
*/
*/
public
BoundMethodHandle
(
MethodHandle
entryPoint
,
int
argnum
)
{
protected
BoundMethodHandle
(
MethodHandle
entryPoint
)
{
this
(
entryPoint
,
null
,
argnum
,
SELF_ARG
);
super
(
Access
.
TOKEN
,
entryPoint
.
type
().
dropParameterTypes
(
0
,
1
));
this
.
argument
=
this
;
// kludge; get rid of
// Note: If the conversion fails, perhaps because of a bad entryPoint,
this
.
vmargslot
=
this
.
type
().
parameterSlotDepth
(
0
);
// the MethodHandle.type field will not be filled in, and therefore
initTarget
(
entryPoint
,
0
);
// no MH.invoke call will ever succeed. The caller may retain a pointer
assert
(
this
instanceof
JavaMethodHandle
);
// to the broken method handle, but no harm can be done with it.
}
}
/** Initialize the current object as a method handle, binding it
/** Initialize the current object as a Java method handle.
* as the first argument of the method handle {@code entryPoint}.
* The invocation type of the resulting method handle will be the
* same as {@code entryPoint}, except that the first argument
* type will be dropped.
*/
*/
public
BoundMethodHandle
(
MethodHandle
entryPoint
)
{
protected
BoundMethodHandle
(
String
entryPointName
,
MethodType
type
,
boolean
matchArity
)
{
this
(
entryPoint
,
null
,
0
,
SELF_ARG
);
super
(
Access
.
TOKEN
,
null
);
MethodHandle
entryPoint
=
findJavaMethodHandleEntryPoint
(
this
.
getClass
(),
entryPointName
,
type
,
matchArity
);
MethodHandleImpl
.
initType
(
this
,
entryPoint
.
type
().
dropParameterTypes
(
0
,
1
));
this
.
argument
=
this
;
// kludge; get rid of
this
.
vmargslot
=
this
.
type
().
parameterSlotDepth
(
0
);
initTarget
(
entryPoint
,
0
);
assert
(
this
instanceof
JavaMethodHandle
);
}
private
static
MethodHandle
findJavaMethodHandleEntryPoint
(
Class
<?>
caller
,
String
name
,
MethodType
type
,
boolean
matchArity
)
{
if
(
matchArity
)
type
.
getClass
();
// elicit NPE
List
<
MemberName
>
methods
=
IMPL_NAMES
.
getMethods
(
caller
,
true
,
name
,
null
,
caller
);
MethodType
foundType
=
null
;
MemberName
foundMethod
=
null
;
for
(
MemberName
method
:
methods
)
{
MethodType
mtype
=
method
.
getMethodType
();
if
(
type
!=
null
&&
type
.
parameterCount
()
!=
mtype
.
parameterCount
())
continue
;
else
if
(
foundType
==
null
)
foundType
=
mtype
;
else
if
(
foundType
!=
mtype
)
throw
newIllegalArgumentException
(
"more than one method named "
+
name
+
" in "
+
caller
.
getName
());
// discard overrides
if
(
foundMethod
==
null
)
foundMethod
=
method
;
else
if
(
foundMethod
.
getDeclaringClass
().
isAssignableFrom
(
method
.
getDeclaringClass
()))
foundMethod
=
method
;
}
if
(
foundMethod
==
null
)
throw
newIllegalArgumentException
(
"no method named "
+
name
+
" in "
+
caller
.
getName
());
MethodHandle
entryPoint
=
MethodHandleImpl
.
findMethod
(
IMPL_TOKEN
,
foundMethod
,
true
,
caller
);
if
(
type
!=
null
)
{
MethodType
epType
=
type
.
insertParameterTypes
(
0
,
entryPoint
.
type
().
parameterType
(
0
));
entryPoint
=
MethodHandles
.
convertArguments
(
entryPoint
,
epType
);
}
return
entryPoint
;
}
}
/** Make sure the given {@code argument} can be used as {@code argnum}-th
/** Make sure the given {@code argument} can be used as {@code argnum}-th
...
@@ -175,6 +222,24 @@ public class BoundMethodHandle extends MethodHandle {
...
@@ -175,6 +222,24 @@ public class BoundMethodHandle extends MethodHandle {
@Override
@Override
public
String
toString
()
{
public
String
toString
()
{
return
"Bound["
+
super
.
toString
()
+
"]"
;
MethodHandle
mh
=
this
;
while
(
mh
instanceof
BoundMethodHandle
)
{
Object
info
=
MethodHandleNatives
.
getTargetInfo
(
mh
);
if
(
info
instanceof
MethodHandle
)
{
mh
=
(
MethodHandle
)
info
;
}
else
{
String
name
=
null
;
if
(
info
instanceof
MemberName
)
name
=
((
MemberName
)
info
).
getName
();
if
(
name
!=
null
)
return
name
;
else
return
super
.
toString
();
// <unknown>, probably
}
assert
(
mh
!=
this
);
if
(
mh
instanceof
JavaMethodHandle
)
break
;
// access JMH.toString(), not BMH.toString()
}
return
mh
.
toString
();
}
}
}
}
src/share/classes/sun/dyn/CallSiteImpl.java
浏览文件 @
8992d5c6
...
@@ -26,34 +26,51 @@
...
@@ -26,34 +26,51 @@
package
sun.dyn
;
package
sun.dyn
;
import
java.dyn.*
;
import
java.dyn.*
;
import
java.util.logging.Level
;
import
java.util.logging.Logger
;
/**
/**
* The CallSite privately created by the JVM at every invokedynamic instruction.
* Parts of CallSite known to the JVM.
* FIXME: Merge all this into CallSite proper.
* @author jrose
* @author jrose
*/
*/
class
CallSiteImpl
extends
CallSite
{
public
class
CallSiteImpl
{
// Field
s
used only by the JVM. Do not use or change.
// Field used only by the JVM. Do not use or change.
private
Object
vmmethod
;
private
Object
vmmethod
;
// Values supplied by the JVM:
// Values supplied by the JVM:
int
callerMID
,
callerBCI
;
protected
int
callerMID
,
callerBCI
;
private
CallSiteImpl
(
Class
<?>
caller
,
String
name
,
MethodType
type
)
{
private
MethodHandle
target
;
super
(
caller
,
name
,
type
);
protected
final
Object
caller
;
// usually a class
protected
final
String
name
;
protected
final
MethodType
type
;
/** called only directly from CallSite() */
protected
CallSiteImpl
(
Access
token
,
Object
caller
,
String
name
,
MethodType
type
)
{
Access
.
check
(
token
);
this
.
caller
=
caller
;
this
.
name
=
name
;
this
.
type
=
type
;
}
/** native version of setTarget */
protected
void
setTarget
(
MethodHandle
mh
)
{
//System.out.println("setTarget "+this+" := "+mh);
// XXX I don't know how to fix this properly.
// if (false && MethodHandleNatives.JVM_SUPPORT) // FIXME: enable this
// MethodHandleNatives.linkCallSite(this, mh);
// else
this
.
target
=
mh
;
}
}
@Override
protected
MethodHandle
getTarget
()
{
public
void
setTarget
(
MethodHandle
mh
)
{
return
target
;
checkTarget
(
mh
);
if
(
MethodHandleNatives
.
JVM_SUPPORT
)
MethodHandleNatives
.
linkCallSite
(
this
,
(
MethodHandle
)
mh
);
else
super
.
setTarget
(
mh
);
}
}
private
static
final
MethodHandle
PRIVATE_INITIALIZE_CALL_SITE
=
private
static
final
MethodHandle
PRIVATE_INITIALIZE_CALL_SITE
=
MethodHandleImpl
.
IMPL_LOOKUP
.
findStatic
(
CallSite
.
class
,
"privateInitializeCallSite"
,
MethodHandleImpl
.
IMPL_LOOKUP
.
findStatic
(
CallSite
.
class
,
"privateInitializeCallSite"
,
MethodType
.
m
ak
e
(
void
.
class
,
CallSite
.
class
,
int
.
class
,
int
.
class
));
MethodType
.
m
ethodTyp
e
(
void
.
class
,
CallSite
.
class
,
int
.
class
,
int
.
class
));
// this is the up-call from the JVM:
// this is the up-call from the JVM:
static
CallSite
makeSite
(
Class
<?>
caller
,
String
name
,
MethodType
type
,
static
CallSite
makeSite
(
Class
<?>
caller
,
String
name
,
MethodType
type
,
...
@@ -61,10 +78,25 @@ class CallSiteImpl extends CallSite {
...
@@ -61,10 +78,25 @@ class CallSiteImpl extends CallSite {
MethodHandle
bsm
=
Linkage
.
getBootstrapMethod
(
caller
);
MethodHandle
bsm
=
Linkage
.
getBootstrapMethod
(
caller
);
if
(
bsm
==
null
)
if
(
bsm
==
null
)
throw
new
InvokeDynamicBootstrapError
(
"class has no bootstrap method: "
+
caller
);
throw
new
InvokeDynamicBootstrapError
(
"class has no bootstrap method: "
+
caller
);
CallSite
site
=
bsm
.<
CallSite
>
invoke
(
caller
,
name
,
type
);
CallSite
site
;
try
{
site
=
bsm
.<
CallSite
>
invoke
(
caller
,
name
,
type
);
}
catch
(
Throwable
ex
)
{
throw
new
InvokeDynamicBootstrapError
(
"exception thrown while linking"
,
ex
);
}
if
(
site
==
null
)
if
(
site
==
null
)
throw
new
InvokeDynamicBootstrapError
(
"class bootstrap method failed to create a call site: "
+
caller
);
throw
new
InvokeDynamicBootstrapError
(
"class bootstrap method failed to create a call site: "
+
caller
);
if
(
site
.
type
()
!=
type
)
throw
new
InvokeDynamicBootstrapError
(
"call site type not initialized correctly: "
+
site
);
if
(
site
.
callerClass
()
!=
caller
)
throw
new
InvokeDynamicBootstrapError
(
"call site caller not initialized correctly: "
+
site
);
if
((
Object
)
site
.
name
()
!=
name
)
throw
new
InvokeDynamicBootstrapError
(
"call site name not initialized correctly: "
+
site
);
try
{
PRIVATE_INITIALIZE_CALL_SITE
.<
void
>
invoke
(
site
,
callerMID
,
callerBCI
);
PRIVATE_INITIALIZE_CALL_SITE
.<
void
>
invoke
(
site
,
callerMID
,
callerBCI
);
}
catch
(
Throwable
ex
)
{
throw
new
InvokeDynamicBootstrapError
(
"call site initialization exception"
,
ex
);
}
return
site
;
return
site
;
}
}
}
}
src/share/classes/sun/dyn/FilterGeneric.java
浏览文件 @
8992d5c6
因为 它太大了无法显示 source diff 。你可以改为
查看blob
。
src/share/classes/sun/dyn/FilterOneArgument.java
浏览文件 @
8992d5c6
...
@@ -27,7 +27,6 @@ package sun.dyn;
...
@@ -27,7 +27,6 @@ package sun.dyn;
import
java.dyn.JavaMethodHandle
;
import
java.dyn.JavaMethodHandle
;
import
java.dyn.MethodHandle
;
import
java.dyn.MethodHandle
;
import
java.dyn.MethodHandles
;
import
java.dyn.MethodType
;
import
java.dyn.MethodType
;
/**
/**
...
@@ -42,16 +41,21 @@ public class FilterOneArgument extends JavaMethodHandle {
...
@@ -42,16 +41,21 @@ public class FilterOneArgument extends JavaMethodHandle {
protected
final
MethodHandle
filter
;
// Object -> Object
protected
final
MethodHandle
filter
;
// Object -> Object
protected
final
MethodHandle
target
;
// Object -> Object
protected
final
MethodHandle
target
;
// Object -> Object
protected
Object
entryPoint
(
Object
argument
)
{
@Override
Object
filteredArgument
=
filter
.<
Object
>
invoke
(
argument
);
public
String
toString
()
{
return
target
.<
Object
>
invoke
(
filteredArgument
);
return
target
.
toString
();
}
protected
Object
invoke
(
Object
argument
)
throws
Throwable
{
Object
filteredArgument
=
filter
.
invoke
(
argument
);
return
target
.
invoke
(
filteredArgument
);
}
}
private
static
final
MethodHandle
entryPoint
=
private
static
final
MethodHandle
INVOKE
=
MethodHandleImpl
.
IMPL_LOOKUP
.
findVirtual
(
FilterOneArgument
.
class
,
"
entryPoint"
,
MethodType
.
makeGeneric
(
1
));
MethodHandleImpl
.
IMPL_LOOKUP
.
findVirtual
(
FilterOneArgument
.
class
,
"
invoke"
,
MethodType
.
genericMethodType
(
1
));
protected
FilterOneArgument
(
MethodHandle
filter
,
MethodHandle
target
)
{
protected
FilterOneArgument
(
MethodHandle
filter
,
MethodHandle
target
)
{
super
(
entryPoint
);
super
(
INVOKE
);
this
.
filter
=
filter
;
this
.
filter
=
filter
;
this
.
target
=
target
;
this
.
target
=
target
;
}
}
...
@@ -62,10 +66,6 @@ public class FilterOneArgument extends JavaMethodHandle {
...
@@ -62,10 +66,6 @@ public class FilterOneArgument extends JavaMethodHandle {
return
new
FilterOneArgument
(
filter
,
target
);
return
new
FilterOneArgument
(
filter
,
target
);
}
}
public
String
toString
()
{
return
filter
+
"|>"
+
target
;
}
// MethodHandle make(MethodHandle filter1, MethodHandle filter2, MethodHandle target) {
// MethodHandle make(MethodHandle filter1, MethodHandle filter2, MethodHandle target) {
// MethodHandle filter = make(filter1, filter2);
// MethodHandle filter = make(filter1, filter2);
// return make(filter, target);
// return make(filter, target);
...
...
src/share/classes/sun/dyn/FromGeneric.java
浏览文件 @
8992d5c6
...
@@ -36,8 +36,8 @@ import sun.dyn.util.ValueConversions;
...
@@ -36,8 +36,8 @@ import sun.dyn.util.ValueConversions;
import
sun.dyn.util.Wrapper
;
import
sun.dyn.util.Wrapper
;
/**
/**
* Adapters which mediate between incoming calls which are
not
generic
* Adapters which mediate between incoming calls which are generic
* and outgoing calls which are. Any call can be represented generically
* and outgoing calls which are
not
. Any call can be represented generically
* boxing up its arguments, and (on return) unboxing the return value.
* boxing up its arguments, and (on return) unboxing the return value.
* <p>
* <p>
* A call is "generic" (in MethodHandle terms) if its MethodType features
* A call is "generic" (in MethodHandle terms) if its MethodType features
...
@@ -50,9 +50,6 @@ import sun.dyn.util.Wrapper;
...
@@ -50,9 +50,6 @@ import sun.dyn.util.Wrapper;
* either binds internally or else takes as a leading argument).
* either binds internally or else takes as a leading argument).
* (To stretch the term, adapter-like method handles may have multiple
* (To stretch the term, adapter-like method handles may have multiple
* targets or be polymorphic across multiple call types.)
* targets or be polymorphic across multiple call types.)
* <p>
* This adapter can sometimes be more directly implemented
* by the JVM's built-in OP_SPREAD_ARGS adapter.
* @author jrose
* @author jrose
*/
*/
class
FromGeneric
{
class
FromGeneric
{
...
@@ -99,7 +96,7 @@ class FromGeneric {
...
@@ -99,7 +96,7 @@ class FromGeneric {
}
}
this
.
internalType
=
internalType0
;
this
.
internalType
=
internalType0
;
this
.
adapter
=
ad
;
this
.
adapter
=
ad
;
MethodType
tepType
=
targetType
.
insertParameterType
(
0
,
adapter
.
getClass
());
MethodType
tepType
=
targetType
.
insertParameterType
s
(
0
,
adapter
.
getClass
());
this
.
entryPoint
=
ad
.
prototypeEntryPoint
();
this
.
entryPoint
=
ad
.
prototypeEntryPoint
();
this
.
returnConversion
=
computeReturnConversion
(
targetType
,
internalType0
);
this
.
returnConversion
=
computeReturnConversion
(
targetType
,
internalType0
);
this
.
unboxingInvoker
=
computeUnboxingInvoker
(
targetType
,
internalType0
);
this
.
unboxingInvoker
=
computeUnboxingInvoker
(
targetType
,
internalType0
);
...
@@ -146,7 +143,7 @@ class FromGeneric {
...
@@ -146,7 +143,7 @@ class FromGeneric {
if
(
fixArgs
==
null
)
if
(
fixArgs
==
null
)
throw
new
InternalError
(
"bad fixArgs"
);
throw
new
InternalError
(
"bad fixArgs"
);
// reinterpret the calling sequence as raw:
// reinterpret the calling sequence as raw:
MethodHandle
retyper
=
AdapterMethodHandle
.
makeR
awRetypeOnly
(
Access
.
TOKEN
,
MethodHandle
retyper
=
AdapterMethodHandle
.
makeR
etypeRaw
(
Access
.
TOKEN
,
Invokers
.
invokerType
(
internalType
),
fixArgs
);
Invokers
.
invokerType
(
internalType
),
fixArgs
);
if
(
retyper
==
null
)
if
(
retyper
==
null
)
throw
new
InternalError
(
"bad retyper"
);
throw
new
InternalError
(
"bad retyper"
);
...
@@ -226,7 +223,10 @@ class FromGeneric {
...
@@ -226,7 +223,10 @@ class FromGeneric {
// Produce an instance configured as a prototype.
// Produce an instance configured as a prototype.
return
ctor
.
newInstance
(
entryPoint
);
return
ctor
.
newInstance
(
entryPoint
);
}
catch
(
IllegalArgumentException
ex
)
{
}
catch
(
IllegalArgumentException
ex
)
{
}
catch
(
InvocationTargetException
ex
)
{
}
catch
(
InvocationTargetException
wex
)
{
Throwable
ex
=
wex
.
getTargetException
();
if
(
ex
instanceof
Error
)
throw
(
Error
)
ex
;
if
(
ex
instanceof
RuntimeException
)
throw
(
RuntimeException
)
ex
;
}
catch
(
InstantiationException
ex
)
{
}
catch
(
InstantiationException
ex
)
{
}
catch
(
IllegalAccessException
ex
)
{
}
catch
(
IllegalAccessException
ex
)
{
}
}
...
@@ -260,6 +260,11 @@ class FromGeneric {
...
@@ -260,6 +260,11 @@ class FromGeneric {
protected
final
MethodHandle
convert
;
// raw(R) => Object
protected
final
MethodHandle
convert
;
// raw(R) => Object
protected
final
MethodHandle
target
;
// (any**N) => R
protected
final
MethodHandle
target
;
// (any**N) => R
@Override
public
String
toString
()
{
return
target
.
toString
();
}
protected
boolean
isPrototype
()
{
return
target
==
null
;
}
protected
boolean
isPrototype
()
{
return
target
==
null
;
}
protected
Adapter
(
MethodHandle
entryPoint
)
{
protected
Adapter
(
MethodHandle
entryPoint
)
{
this
(
entryPoint
,
null
,
entryPoint
,
null
);
this
(
entryPoint
,
null
,
entryPoint
,
null
);
...
@@ -284,11 +289,11 @@ class FromGeneric {
...
@@ -284,11 +289,11 @@ class FromGeneric {
// { return new ThisType(entryPoint, convert, target); }
// { return new ThisType(entryPoint, convert, target); }
/// Conversions on the value returned from the target.
/// Conversions on the value returned from the target.
protected
Object
convert_L
(
Object
result
)
{
return
convert
.<
Object
>
invoke
(
result
);
}
protected
Object
convert_L
(
Object
result
)
throws
Throwable
{
return
convert
.<
Object
>
invoke
(
result
);
}
protected
Object
convert_I
(
int
result
)
{
return
convert
.<
Object
>
invoke
(
result
);
}
protected
Object
convert_I
(
int
result
)
throws
Throwable
{
return
convert
.<
Object
>
invoke
(
result
);
}
protected
Object
convert_J
(
long
result
)
{
return
convert
.<
Object
>
invoke
(
result
);
}
protected
Object
convert_J
(
long
result
)
throws
Throwable
{
return
convert
.<
Object
>
invoke
(
result
);
}
protected
Object
convert_F
(
float
result
)
{
return
convert
.<
Object
>
invoke
(
result
);
}
protected
Object
convert_F
(
float
result
)
throws
Throwable
{
return
convert
.<
Object
>
invoke
(
result
);
}
protected
Object
convert_D
(
double
result
)
{
return
convert
.<
Object
>
invoke
(
result
);
}
protected
Object
convert_D
(
double
result
)
throws
Throwable
{
return
convert
.<
Object
>
invoke
(
result
);
}
static
private
final
String
CLASS_PREFIX
;
// "sun.dyn.FromGeneric$"
static
private
final
String
CLASS_PREFIX
;
// "sun.dyn.FromGeneric$"
static
{
static
{
...
@@ -317,11 +322,11 @@ class FromGeneric {
...
@@ -317,11 +322,11 @@ class FromGeneric {
{ super(e, i, c, t); }
{ super(e, i, c, t); }
protected xA2 makeInstance(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t)
protected xA2 makeInstance(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t)
{ return new xA2(e, i, c, t); }
{ return new xA2(e, i, c, t); }
protected Object invoke_L2(Object a0, Object a1) { return convert_L(invoker.<Object>invoke(target, a0, a1)); }
protected Object invoke_L2(Object a0, Object a1)
throws Throwable
{ return convert_L(invoker.<Object>invoke(target, a0, a1)); }
protected Object invoke_I2(Object a0, Object a1) { return convert_I(invoker.<int >invoke(target, a0, a1)); }
protected Object invoke_I2(Object a0, Object a1)
throws Throwable
{ return convert_I(invoker.<int >invoke(target, a0, a1)); }
protected Object invoke_J2(Object a0, Object a1) { return convert_J(invoker.<long >invoke(target, a0, a1)); }
protected Object invoke_J2(Object a0, Object a1)
throws Throwable
{ return convert_J(invoker.<long >invoke(target, a0, a1)); }
protected Object invoke_F2(Object a0, Object a1) { return convert_F(invoker.<float >invoke(target, a0, a1)); }
protected Object invoke_F2(Object a0, Object a1)
throws Throwable
{ return convert_F(invoker.<float >invoke(target, a0, a1)); }
protected Object invoke_D2(Object a0, Object a1) { return convert_D(invoker.<double>invoke(target, a0, a1)); }
protected Object invoke_D2(Object a0, Object a1)
throws Throwable
{ return convert_D(invoker.<double>invoke(target, a0, a1)); }
}
}
// */
// */
...
@@ -342,7 +347,7 @@ class genclasses {
...
@@ -342,7 +347,7 @@ class genclasses {
" protected @cat@ makeInstance(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t)",
" protected @cat@ makeInstance(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t)",
" { return new @cat@(e, i, c, t); }",
" { return new @cat@(e, i, c, t); }",
" //@each-R@",
" //@each-R@",
" protected Object invoke_@catN@(@Tvav@) { return convert_@Rc@(invoker.<@R@>invoke(target@av@)); }",
" protected Object invoke_@catN@(@Tvav@)
throws Throwable
{ return convert_@Rc@(invoker.<@R@>invoke(target@av@)); }",
" //@end-R@",
" //@end-R@",
" }",
" }",
} };
} };
...
@@ -498,11 +503,11 @@ class genclasses {
...
@@ -498,11 +503,11 @@ class genclasses {
{
super
(
e
,
i
,
c
,
t
);
}
{
super
(
e
,
i
,
c
,
t
);
}
protected
A0
makeInstance
(
MethodHandle
e
,
MethodHandle
i
,
MethodHandle
c
,
MethodHandle
t
)
protected
A0
makeInstance
(
MethodHandle
e
,
MethodHandle
i
,
MethodHandle
c
,
MethodHandle
t
)
{
return
new
A0
(
e
,
i
,
c
,
t
);
}
{
return
new
A0
(
e
,
i
,
c
,
t
);
}
protected
Object
invoke_L0
()
{
return
convert_L
(
invoker
.<
Object
>
invoke
(
target
));
}
protected
Object
invoke_L0
()
throws
Throwable
{
return
convert_L
(
invoker
.<
Object
>
invoke
(
target
));
}
protected
Object
invoke_I0
()
{
return
convert_I
(
invoker
.<
int
>
invoke
(
target
));
}
protected
Object
invoke_I0
()
throws
Throwable
{
return
convert_I
(
invoker
.<
int
>
invoke
(
target
));
}
protected
Object
invoke_J0
()
{
return
convert_J
(
invoker
.<
long
>
invoke
(
target
));
}
protected
Object
invoke_J0
()
throws
Throwable
{
return
convert_J
(
invoker
.<
long
>
invoke
(
target
));
}
protected
Object
invoke_F0
()
{
return
convert_F
(
invoker
.<
float
>
invoke
(
target
));
}
protected
Object
invoke_F0
()
throws
Throwable
{
return
convert_F
(
invoker
.<
float
>
invoke
(
target
));
}
protected
Object
invoke_D0
()
{
return
convert_D
(
invoker
.<
double
>
invoke
(
target
));
}
protected
Object
invoke_D0
()
throws
Throwable
{
return
convert_D
(
invoker
.<
double
>
invoke
(
target
));
}
}
}
static
class
A1
extends
Adapter
{
static
class
A1
extends
Adapter
{
protected
A1
(
MethodHandle
entryPoint
)
{
super
(
entryPoint
);
}
// to build prototype
protected
A1
(
MethodHandle
entryPoint
)
{
super
(
entryPoint
);
}
// to build prototype
...
@@ -510,11 +515,11 @@ class genclasses {
...
@@ -510,11 +515,11 @@ class genclasses {
{
super
(
e
,
i
,
c
,
t
);
}
{
super
(
e
,
i
,
c
,
t
);
}
protected
A1
makeInstance
(
MethodHandle
e
,
MethodHandle
i
,
MethodHandle
c
,
MethodHandle
t
)
protected
A1
makeInstance
(
MethodHandle
e
,
MethodHandle
i
,
MethodHandle
c
,
MethodHandle
t
)
{
return
new
A1
(
e
,
i
,
c
,
t
);
}
{
return
new
A1
(
e
,
i
,
c
,
t
);
}
protected
Object
invoke_L1
(
Object
a0
)
{
return
convert_L
(
invoker
.<
Object
>
invoke
(
target
,
a0
));
}
protected
Object
invoke_L1
(
Object
a0
)
throws
Throwable
{
return
convert_L
(
invoker
.<
Object
>
invoke
(
target
,
a0
));
}
protected
Object
invoke_I1
(
Object
a0
)
{
return
convert_I
(
invoker
.<
int
>
invoke
(
target
,
a0
));
}
protected
Object
invoke_I1
(
Object
a0
)
throws
Throwable
{
return
convert_I
(
invoker
.<
int
>
invoke
(
target
,
a0
));
}
protected
Object
invoke_J1
(
Object
a0
)
{
return
convert_J
(
invoker
.<
long
>
invoke
(
target
,
a0
));
}
protected
Object
invoke_J1
(
Object
a0
)
throws
Throwable
{
return
convert_J
(
invoker
.<
long
>
invoke
(
target
,
a0
));
}
protected
Object
invoke_F1
(
Object
a0
)
{
return
convert_F
(
invoker
.<
float
>
invoke
(
target
,
a0
));
}
protected
Object
invoke_F1
(
Object
a0
)
throws
Throwable
{
return
convert_F
(
invoker
.<
float
>
invoke
(
target
,
a0
));
}
protected
Object
invoke_D1
(
Object
a0
)
{
return
convert_D
(
invoker
.<
double
>
invoke
(
target
,
a0
));
}
protected
Object
invoke_D1
(
Object
a0
)
throws
Throwable
{
return
convert_D
(
invoker
.<
double
>
invoke
(
target
,
a0
));
}
}
}
static
class
A2
extends
Adapter
{
static
class
A2
extends
Adapter
{
protected
A2
(
MethodHandle
entryPoint
)
{
super
(
entryPoint
);
}
// to build prototype
protected
A2
(
MethodHandle
entryPoint
)
{
super
(
entryPoint
);
}
// to build prototype
...
@@ -522,11 +527,11 @@ class genclasses {
...
@@ -522,11 +527,11 @@ class genclasses {
{
super
(
e
,
i
,
c
,
t
);
}
{
super
(
e
,
i
,
c
,
t
);
}
protected
A2
makeInstance
(
MethodHandle
e
,
MethodHandle
i
,
MethodHandle
c
,
MethodHandle
t
)
protected
A2
makeInstance
(
MethodHandle
e
,
MethodHandle
i
,
MethodHandle
c
,
MethodHandle
t
)
{
return
new
A2
(
e
,
i
,
c
,
t
);
}
{
return
new
A2
(
e
,
i
,
c
,
t
);
}
protected
Object
invoke_L2
(
Object
a0
,
Object
a1
)
{
return
convert_L
(
invoker
.<
Object
>
invoke
(
target
,
a0
,
a1
));
}
protected
Object
invoke_L2
(
Object
a0
,
Object
a1
)
throws
Throwable
{
return
convert_L
(
invoker
.<
Object
>
invoke
(
target
,
a0
,
a1
));
}
protected
Object
invoke_I2
(
Object
a0
,
Object
a1
)
{
return
convert_I
(
invoker
.<
int
>
invoke
(
target
,
a0
,
a1
));
}
protected
Object
invoke_I2
(
Object
a0
,
Object
a1
)
throws
Throwable
{
return
convert_I
(
invoker
.<
int
>
invoke
(
target
,
a0
,
a1
));
}
protected
Object
invoke_J2
(
Object
a0
,
Object
a1
)
{
return
convert_J
(
invoker
.<
long
>
invoke
(
target
,
a0
,
a1
));
}
protected
Object
invoke_J2
(
Object
a0
,
Object
a1
)
throws
Throwable
{
return
convert_J
(
invoker
.<
long
>
invoke
(
target
,
a0
,
a1
));
}
protected
Object
invoke_F2
(
Object
a0
,
Object
a1
)
{
return
convert_F
(
invoker
.<
float
>
invoke
(
target
,
a0
,
a1
));
}
protected
Object
invoke_F2
(
Object
a0
,
Object
a1
)
throws
Throwable
{
return
convert_F
(
invoker
.<
float
>
invoke
(
target
,
a0
,
a1
));
}
protected
Object
invoke_D2
(
Object
a0
,
Object
a1
)
{
return
convert_D
(
invoker
.<
double
>
invoke
(
target
,
a0
,
a1
));
}
protected
Object
invoke_D2
(
Object
a0
,
Object
a1
)
throws
Throwable
{
return
convert_D
(
invoker
.<
double
>
invoke
(
target
,
a0
,
a1
));
}
}
}
static
class
A3
extends
Adapter
{
static
class
A3
extends
Adapter
{
protected
A3
(
MethodHandle
entryPoint
)
{
super
(
entryPoint
);
}
// to build prototype
protected
A3
(
MethodHandle
entryPoint
)
{
super
(
entryPoint
);
}
// to build prototype
...
@@ -534,11 +539,11 @@ class genclasses {
...
@@ -534,11 +539,11 @@ class genclasses {
{
super
(
e
,
i
,
c
,
t
);
}
{
super
(
e
,
i
,
c
,
t
);
}
protected
A3
makeInstance
(
MethodHandle
e
,
MethodHandle
i
,
MethodHandle
c
,
MethodHandle
t
)
protected
A3
makeInstance
(
MethodHandle
e
,
MethodHandle
i
,
MethodHandle
c
,
MethodHandle
t
)
{
return
new
A3
(
e
,
i
,
c
,
t
);
}
{
return
new
A3
(
e
,
i
,
c
,
t
);
}
protected
Object
invoke_L3
(
Object
a0
,
Object
a1
,
Object
a2
)
{
return
convert_L
(
invoker
.<
Object
>
invoke
(
target
,
a0
,
a1
,
a2
));
}
protected
Object
invoke_L3
(
Object
a0
,
Object
a1
,
Object
a2
)
throws
Throwable
{
return
convert_L
(
invoker
.<
Object
>
invoke
(
target
,
a0
,
a1
,
a2
));
}
protected
Object
invoke_I3
(
Object
a0
,
Object
a1
,
Object
a2
)
{
return
convert_I
(
invoker
.<
int
>
invoke
(
target
,
a0
,
a1
,
a2
));
}
protected
Object
invoke_I3
(
Object
a0
,
Object
a1
,
Object
a2
)
throws
Throwable
{
return
convert_I
(
invoker
.<
int
>
invoke
(
target
,
a0
,
a1
,
a2
));
}
protected
Object
invoke_J3
(
Object
a0
,
Object
a1
,
Object
a2
)
{
return
convert_J
(
invoker
.<
long
>
invoke
(
target
,
a0
,
a1
,
a2
));
}
protected
Object
invoke_J3
(
Object
a0
,
Object
a1
,
Object
a2
)
throws
Throwable
{
return
convert_J
(
invoker
.<
long
>
invoke
(
target
,
a0
,
a1
,
a2
));
}
protected
Object
invoke_F3
(
Object
a0
,
Object
a1
,
Object
a2
)
{
return
convert_F
(
invoker
.<
float
>
invoke
(
target
,
a0
,
a1
,
a2
));
}
protected
Object
invoke_F3
(
Object
a0
,
Object
a1
,
Object
a2
)
throws
Throwable
{
return
convert_F
(
invoker
.<
float
>
invoke
(
target
,
a0
,
a1
,
a2
));
}
protected
Object
invoke_D3
(
Object
a0
,
Object
a1
,
Object
a2
)
{
return
convert_D
(
invoker
.<
double
>
invoke
(
target
,
a0
,
a1
,
a2
));
}
protected
Object
invoke_D3
(
Object
a0
,
Object
a1
,
Object
a2
)
throws
Throwable
{
return
convert_D
(
invoker
.<
double
>
invoke
(
target
,
a0
,
a1
,
a2
));
}
}
}
static
class
A4
extends
Adapter
{
static
class
A4
extends
Adapter
{
protected
A4
(
MethodHandle
entryPoint
)
{
super
(
entryPoint
);
}
// to build prototype
protected
A4
(
MethodHandle
entryPoint
)
{
super
(
entryPoint
);
}
// to build prototype
...
@@ -546,11 +551,11 @@ class genclasses {
...
@@ -546,11 +551,11 @@ class genclasses {
{
super
(
e
,
i
,
c
,
t
);
}
{
super
(
e
,
i
,
c
,
t
);
}
protected
A4
makeInstance
(
MethodHandle
e
,
MethodHandle
i
,
MethodHandle
c
,
MethodHandle
t
)
protected
A4
makeInstance
(
MethodHandle
e
,
MethodHandle
i
,
MethodHandle
c
,
MethodHandle
t
)
{
return
new
A4
(
e
,
i
,
c
,
t
);
}
{
return
new
A4
(
e
,
i
,
c
,
t
);
}
protected
Object
invoke_L4
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
)
{
return
convert_L
(
invoker
.<
Object
>
invoke
(
target
,
a0
,
a1
,
a2
,
a3
));
}
protected
Object
invoke_L4
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
)
throws
Throwable
{
return
convert_L
(
invoker
.<
Object
>
invoke
(
target
,
a0
,
a1
,
a2
,
a3
));
}
protected
Object
invoke_I4
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
)
{
return
convert_I
(
invoker
.<
int
>
invoke
(
target
,
a0
,
a1
,
a2
,
a3
));
}
protected
Object
invoke_I4
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
)
throws
Throwable
{
return
convert_I
(
invoker
.<
int
>
invoke
(
target
,
a0
,
a1
,
a2
,
a3
));
}
protected
Object
invoke_J4
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
)
{
return
convert_J
(
invoker
.<
long
>
invoke
(
target
,
a0
,
a1
,
a2
,
a3
));
}
protected
Object
invoke_J4
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
)
throws
Throwable
{
return
convert_J
(
invoker
.<
long
>
invoke
(
target
,
a0
,
a1
,
a2
,
a3
));
}
protected
Object
invoke_F4
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
)
{
return
convert_F
(
invoker
.<
float
>
invoke
(
target
,
a0
,
a1
,
a2
,
a3
));
}
protected
Object
invoke_F4
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
)
throws
Throwable
{
return
convert_F
(
invoker
.<
float
>
invoke
(
target
,
a0
,
a1
,
a2
,
a3
));
}
protected
Object
invoke_D4
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
)
{
return
convert_D
(
invoker
.<
double
>
invoke
(
target
,
a0
,
a1
,
a2
,
a3
));
}
protected
Object
invoke_D4
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
)
throws
Throwable
{
return
convert_D
(
invoker
.<
double
>
invoke
(
target
,
a0
,
a1
,
a2
,
a3
));
}
}
}
static
class
A5
extends
Adapter
{
static
class
A5
extends
Adapter
{
protected
A5
(
MethodHandle
entryPoint
)
{
super
(
entryPoint
);
}
// to build prototype
protected
A5
(
MethodHandle
entryPoint
)
{
super
(
entryPoint
);
}
// to build prototype
...
@@ -558,11 +563,11 @@ class genclasses {
...
@@ -558,11 +563,11 @@ class genclasses {
{
super
(
e
,
i
,
c
,
t
);
}
{
super
(
e
,
i
,
c
,
t
);
}
protected
A5
makeInstance
(
MethodHandle
e
,
MethodHandle
i
,
MethodHandle
c
,
MethodHandle
t
)
protected
A5
makeInstance
(
MethodHandle
e
,
MethodHandle
i
,
MethodHandle
c
,
MethodHandle
t
)
{
return
new
A5
(
e
,
i
,
c
,
t
);
}
{
return
new
A5
(
e
,
i
,
c
,
t
);
}
protected
Object
invoke_L5
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
)
{
return
convert_L
(
invoker
.<
Object
>
invoke
(
target
,
a0
,
a1
,
a2
,
a3
,
a4
));
}
protected
Object
invoke_L5
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
)
throws
Throwable
{
return
convert_L
(
invoker
.<
Object
>
invoke
(
target
,
a0
,
a1
,
a2
,
a3
,
a4
));
}
protected
Object
invoke_I5
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
)
{
return
convert_I
(
invoker
.<
int
>
invoke
(
target
,
a0
,
a1
,
a2
,
a3
,
a4
));
}
protected
Object
invoke_I5
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
)
throws
Throwable
{
return
convert_I
(
invoker
.<
int
>
invoke
(
target
,
a0
,
a1
,
a2
,
a3
,
a4
));
}
protected
Object
invoke_J5
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
)
{
return
convert_J
(
invoker
.<
long
>
invoke
(
target
,
a0
,
a1
,
a2
,
a3
,
a4
));
}
protected
Object
invoke_J5
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
)
throws
Throwable
{
return
convert_J
(
invoker
.<
long
>
invoke
(
target
,
a0
,
a1
,
a2
,
a3
,
a4
));
}
protected
Object
invoke_F5
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
)
{
return
convert_F
(
invoker
.<
float
>
invoke
(
target
,
a0
,
a1
,
a2
,
a3
,
a4
));
}
protected
Object
invoke_F5
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
)
throws
Throwable
{
return
convert_F
(
invoker
.<
float
>
invoke
(
target
,
a0
,
a1
,
a2
,
a3
,
a4
));
}
protected
Object
invoke_D5
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
)
{
return
convert_D
(
invoker
.<
double
>
invoke
(
target
,
a0
,
a1
,
a2
,
a3
,
a4
));
}
protected
Object
invoke_D5
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
)
throws
Throwable
{
return
convert_D
(
invoker
.<
double
>
invoke
(
target
,
a0
,
a1
,
a2
,
a3
,
a4
));
}
}
}
static
class
A6
extends
Adapter
{
static
class
A6
extends
Adapter
{
protected
A6
(
MethodHandle
entryPoint
)
{
super
(
entryPoint
);
}
// to build prototype
protected
A6
(
MethodHandle
entryPoint
)
{
super
(
entryPoint
);
}
// to build prototype
...
@@ -570,11 +575,11 @@ class genclasses {
...
@@ -570,11 +575,11 @@ class genclasses {
{
super
(
e
,
i
,
c
,
t
);
}
{
super
(
e
,
i
,
c
,
t
);
}
protected
A6
makeInstance
(
MethodHandle
e
,
MethodHandle
i
,
MethodHandle
c
,
MethodHandle
t
)
protected
A6
makeInstance
(
MethodHandle
e
,
MethodHandle
i
,
MethodHandle
c
,
MethodHandle
t
)
{
return
new
A6
(
e
,
i
,
c
,
t
);
}
{
return
new
A6
(
e
,
i
,
c
,
t
);
}
protected
Object
invoke_L6
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
)
{
return
convert_L
(
invoker
.<
Object
>
invoke
(
target
,
a0
,
a1
,
a2
,
a3
,
a4
,
a5
));
}
protected
Object
invoke_L6
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
)
throws
Throwable
{
return
convert_L
(
invoker
.<
Object
>
invoke
(
target
,
a0
,
a1
,
a2
,
a3
,
a4
,
a5
));
}
protected
Object
invoke_I6
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
)
{
return
convert_I
(
invoker
.<
int
>
invoke
(
target
,
a0
,
a1
,
a2
,
a3
,
a4
,
a5
));
}
protected
Object
invoke_I6
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
)
throws
Throwable
{
return
convert_I
(
invoker
.<
int
>
invoke
(
target
,
a0
,
a1
,
a2
,
a3
,
a4
,
a5
));
}
protected
Object
invoke_J6
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
)
{
return
convert_J
(
invoker
.<
long
>
invoke
(
target
,
a0
,
a1
,
a2
,
a3
,
a4
,
a5
));
}
protected
Object
invoke_J6
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
)
throws
Throwable
{
return
convert_J
(
invoker
.<
long
>
invoke
(
target
,
a0
,
a1
,
a2
,
a3
,
a4
,
a5
));
}
protected
Object
invoke_F6
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
)
{
return
convert_F
(
invoker
.<
float
>
invoke
(
target
,
a0
,
a1
,
a2
,
a3
,
a4
,
a5
));
}
protected
Object
invoke_F6
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
)
throws
Throwable
{
return
convert_F
(
invoker
.<
float
>
invoke
(
target
,
a0
,
a1
,
a2
,
a3
,
a4
,
a5
));
}
protected
Object
invoke_D6
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
)
{
return
convert_D
(
invoker
.<
double
>
invoke
(
target
,
a0
,
a1
,
a2
,
a3
,
a4
,
a5
));
}
protected
Object
invoke_D6
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
)
throws
Throwable
{
return
convert_D
(
invoker
.<
double
>
invoke
(
target
,
a0
,
a1
,
a2
,
a3
,
a4
,
a5
));
}
}
}
static
class
A7
extends
Adapter
{
static
class
A7
extends
Adapter
{
protected
A7
(
MethodHandle
entryPoint
)
{
super
(
entryPoint
);
}
// to build prototype
protected
A7
(
MethodHandle
entryPoint
)
{
super
(
entryPoint
);
}
// to build prototype
...
@@ -582,11 +587,11 @@ class genclasses {
...
@@ -582,11 +587,11 @@ class genclasses {
{
super
(
e
,
i
,
c
,
t
);
}
{
super
(
e
,
i
,
c
,
t
);
}
protected
A7
makeInstance
(
MethodHandle
e
,
MethodHandle
i
,
MethodHandle
c
,
MethodHandle
t
)
protected
A7
makeInstance
(
MethodHandle
e
,
MethodHandle
i
,
MethodHandle
c
,
MethodHandle
t
)
{
return
new
A7
(
e
,
i
,
c
,
t
);
}
{
return
new
A7
(
e
,
i
,
c
,
t
);
}
protected
Object
invoke_L7
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
a6
)
{
return
convert_L
(
invoker
.<
Object
>
invoke
(
target
,
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
));
}
protected
Object
invoke_L7
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
a6
)
throws
Throwable
{
return
convert_L
(
invoker
.<
Object
>
invoke
(
target
,
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
));
}
protected
Object
invoke_I7
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
a6
)
{
return
convert_I
(
invoker
.<
int
>
invoke
(
target
,
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
));
}
protected
Object
invoke_I7
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
a6
)
throws
Throwable
{
return
convert_I
(
invoker
.<
int
>
invoke
(
target
,
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
));
}
protected
Object
invoke_J7
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
a6
)
{
return
convert_J
(
invoker
.<
long
>
invoke
(
target
,
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
));
}
protected
Object
invoke_J7
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
a6
)
throws
Throwable
{
return
convert_J
(
invoker
.<
long
>
invoke
(
target
,
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
));
}
protected
Object
invoke_F7
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
a6
)
{
return
convert_F
(
invoker
.<
float
>
invoke
(
target
,
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
));
}
protected
Object
invoke_F7
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
a6
)
throws
Throwable
{
return
convert_F
(
invoker
.<
float
>
invoke
(
target
,
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
));
}
protected
Object
invoke_D7
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
a6
)
{
return
convert_D
(
invoker
.<
double
>
invoke
(
target
,
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
));
}
protected
Object
invoke_D7
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
a6
)
throws
Throwable
{
return
convert_D
(
invoker
.<
double
>
invoke
(
target
,
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
));
}
}
}
static
class
A8
extends
Adapter
{
static
class
A8
extends
Adapter
{
protected
A8
(
MethodHandle
entryPoint
)
{
super
(
entryPoint
);
}
// to build prototype
protected
A8
(
MethodHandle
entryPoint
)
{
super
(
entryPoint
);
}
// to build prototype
...
@@ -594,11 +599,11 @@ class genclasses {
...
@@ -594,11 +599,11 @@ class genclasses {
{
super
(
e
,
i
,
c
,
t
);
}
{
super
(
e
,
i
,
c
,
t
);
}
protected
A8
makeInstance
(
MethodHandle
e
,
MethodHandle
i
,
MethodHandle
c
,
MethodHandle
t
)
protected
A8
makeInstance
(
MethodHandle
e
,
MethodHandle
i
,
MethodHandle
c
,
MethodHandle
t
)
{
return
new
A8
(
e
,
i
,
c
,
t
);
}
{
return
new
A8
(
e
,
i
,
c
,
t
);
}
protected
Object
invoke_L8
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
a6
,
Object
a7
)
{
return
convert_L
(
invoker
.<
Object
>
invoke
(
target
,
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
));
}
protected
Object
invoke_L8
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
a6
,
Object
a7
)
throws
Throwable
{
return
convert_L
(
invoker
.<
Object
>
invoke
(
target
,
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
));
}
protected
Object
invoke_I8
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
a6
,
Object
a7
)
{
return
convert_I
(
invoker
.<
int
>
invoke
(
target
,
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
));
}
protected
Object
invoke_I8
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
a6
,
Object
a7
)
throws
Throwable
{
return
convert_I
(
invoker
.<
int
>
invoke
(
target
,
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
));
}
protected
Object
invoke_J8
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
a6
,
Object
a7
)
{
return
convert_J
(
invoker
.<
long
>
invoke
(
target
,
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
));
}
protected
Object
invoke_J8
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
a6
,
Object
a7
)
throws
Throwable
{
return
convert_J
(
invoker
.<
long
>
invoke
(
target
,
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
));
}
protected
Object
invoke_F8
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
a6
,
Object
a7
)
{
return
convert_F
(
invoker
.<
float
>
invoke
(
target
,
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
));
}
protected
Object
invoke_F8
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
a6
,
Object
a7
)
throws
Throwable
{
return
convert_F
(
invoker
.<
float
>
invoke
(
target
,
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
));
}
protected
Object
invoke_D8
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
a6
,
Object
a7
)
{
return
convert_D
(
invoker
.<
double
>
invoke
(
target
,
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
));
}
protected
Object
invoke_D8
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
a6
,
Object
a7
)
throws
Throwable
{
return
convert_D
(
invoker
.<
double
>
invoke
(
target
,
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
));
}
}
}
static
class
A9
extends
Adapter
{
static
class
A9
extends
Adapter
{
protected
A9
(
MethodHandle
entryPoint
)
{
super
(
entryPoint
);
}
// to build prototype
protected
A9
(
MethodHandle
entryPoint
)
{
super
(
entryPoint
);
}
// to build prototype
...
@@ -606,11 +611,11 @@ class genclasses {
...
@@ -606,11 +611,11 @@ class genclasses {
{
super
(
e
,
i
,
c
,
t
);
}
{
super
(
e
,
i
,
c
,
t
);
}
protected
A9
makeInstance
(
MethodHandle
e
,
MethodHandle
i
,
MethodHandle
c
,
MethodHandle
t
)
protected
A9
makeInstance
(
MethodHandle
e
,
MethodHandle
i
,
MethodHandle
c
,
MethodHandle
t
)
{
return
new
A9
(
e
,
i
,
c
,
t
);
}
{
return
new
A9
(
e
,
i
,
c
,
t
);
}
protected
Object
invoke_L9
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
a6
,
Object
a7
,
Object
a8
)
{
return
convert_L
(
invoker
.<
Object
>
invoke
(
target
,
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
));
}
protected
Object
invoke_L9
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
a6
,
Object
a7
,
Object
a8
)
throws
Throwable
{
return
convert_L
(
invoker
.<
Object
>
invoke
(
target
,
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
));
}
protected
Object
invoke_I9
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
a6
,
Object
a7
,
Object
a8
)
{
return
convert_I
(
invoker
.<
int
>
invoke
(
target
,
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
));
}
protected
Object
invoke_I9
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
a6
,
Object
a7
,
Object
a8
)
throws
Throwable
{
return
convert_I
(
invoker
.<
int
>
invoke
(
target
,
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
));
}
protected
Object
invoke_J9
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
a6
,
Object
a7
,
Object
a8
)
{
return
convert_J
(
invoker
.<
long
>
invoke
(
target
,
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
));
}
protected
Object
invoke_J9
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
a6
,
Object
a7
,
Object
a8
)
throws
Throwable
{
return
convert_J
(
invoker
.<
long
>
invoke
(
target
,
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
));
}
protected
Object
invoke_F9
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
a6
,
Object
a7
,
Object
a8
)
{
return
convert_F
(
invoker
.<
float
>
invoke
(
target
,
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
));
}
protected
Object
invoke_F9
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
a6
,
Object
a7
,
Object
a8
)
throws
Throwable
{
return
convert_F
(
invoker
.<
float
>
invoke
(
target
,
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
));
}
protected
Object
invoke_D9
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
a6
,
Object
a7
,
Object
a8
)
{
return
convert_D
(
invoker
.<
double
>
invoke
(
target
,
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
));
}
protected
Object
invoke_D9
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
a6
,
Object
a7
,
Object
a8
)
throws
Throwable
{
return
convert_D
(
invoker
.<
double
>
invoke
(
target
,
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
));
}
}
}
static
class
A10
extends
Adapter
{
static
class
A10
extends
Adapter
{
protected
A10
(
MethodHandle
entryPoint
)
{
super
(
entryPoint
);
}
// to build prototype
protected
A10
(
MethodHandle
entryPoint
)
{
super
(
entryPoint
);
}
// to build prototype
...
@@ -618,10 +623,10 @@ class genclasses {
...
@@ -618,10 +623,10 @@ class genclasses {
{
super
(
e
,
i
,
c
,
t
);
}
{
super
(
e
,
i
,
c
,
t
);
}
protected
A10
makeInstance
(
MethodHandle
e
,
MethodHandle
i
,
MethodHandle
c
,
MethodHandle
t
)
protected
A10
makeInstance
(
MethodHandle
e
,
MethodHandle
i
,
MethodHandle
c
,
MethodHandle
t
)
{
return
new
A10
(
e
,
i
,
c
,
t
);
}
{
return
new
A10
(
e
,
i
,
c
,
t
);
}
protected
Object
invoke_L10
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
a6
,
Object
a7
,
Object
a8
,
Object
a9
)
{
return
convert_L
(
invoker
.<
Object
>
invoke
(
target
,
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
,
a9
));
}
protected
Object
invoke_L10
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
a6
,
Object
a7
,
Object
a8
,
Object
a9
)
throws
Throwable
{
return
convert_L
(
invoker
.<
Object
>
invoke
(
target
,
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
,
a9
));
}
protected
Object
invoke_I10
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
a6
,
Object
a7
,
Object
a8
,
Object
a9
)
{
return
convert_I
(
invoker
.<
int
>
invoke
(
target
,
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
,
a9
));
}
protected
Object
invoke_I10
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
a6
,
Object
a7
,
Object
a8
,
Object
a9
)
throws
Throwable
{
return
convert_I
(
invoker
.<
int
>
invoke
(
target
,
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
,
a9
));
}
protected
Object
invoke_J10
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
a6
,
Object
a7
,
Object
a8
,
Object
a9
)
{
return
convert_J
(
invoker
.<
long
>
invoke
(
target
,
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
,
a9
));
}
protected
Object
invoke_J10
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
a6
,
Object
a7
,
Object
a8
,
Object
a9
)
throws
Throwable
{
return
convert_J
(
invoker
.<
long
>
invoke
(
target
,
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
,
a9
));
}
protected
Object
invoke_F10
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
a6
,
Object
a7
,
Object
a8
,
Object
a9
)
{
return
convert_F
(
invoker
.<
float
>
invoke
(
target
,
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
,
a9
));
}
protected
Object
invoke_F10
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
a6
,
Object
a7
,
Object
a8
,
Object
a9
)
throws
Throwable
{
return
convert_F
(
invoker
.<
float
>
invoke
(
target
,
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
,
a9
));
}
protected
Object
invoke_D10
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
a6
,
Object
a7
,
Object
a8
,
Object
a9
)
{
return
convert_D
(
invoker
.<
double
>
invoke
(
target
,
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
,
a9
));
}
protected
Object
invoke_D10
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
a6
,
Object
a7
,
Object
a8
,
Object
a9
)
throws
Throwable
{
return
convert_D
(
invoker
.<
double
>
invoke
(
target
,
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
,
a9
));
}
}
}
}
}
src/share/classes/sun/dyn/Invokers.java
浏览文件 @
8992d5c6
...
@@ -44,16 +44,20 @@ public class Invokers {
...
@@ -44,16 +44,20 @@ public class Invokers {
// generic (untyped) invoker for the outgoing call
// generic (untyped) invoker for the outgoing call
private
/*lazy*/
MethodHandle
genericInvoker
;
private
/*lazy*/
MethodHandle
genericInvoker
;
// generic (untyped) invoker for the outgoing call; accepts a single Object[]
private
final
/*lazy*/
MethodHandle
[]
varargsInvokers
;
/** Compute and cache information common to all collecting adapters
/** Compute and cache information common to all collecting adapters
* that implement members of the erasure-family of the given erased type.
* that implement members of the erasure-family of the given erased type.
*/
*/
public
Invokers
(
Access
token
,
MethodType
targetType
)
{
public
Invokers
(
Access
token
,
MethodType
targetType
)
{
Access
.
check
(
token
);
Access
.
check
(
token
);
this
.
targetType
=
targetType
;
this
.
targetType
=
targetType
;
this
.
varargsInvokers
=
new
MethodHandle
[
targetType
.
parameterCount
()+
1
];
}
}
public
static
MethodType
invokerType
(
MethodType
targetType
)
{
public
static
MethodType
invokerType
(
MethodType
targetType
)
{
return
targetType
.
insertParameterType
(
0
,
MethodHandle
.
class
);
return
targetType
.
insertParameterType
s
(
0
,
MethodHandle
.
class
);
}
}
public
MethodHandle
exactInvoker
()
{
public
MethodHandle
exactInvoker
()
{
...
@@ -76,8 +80,14 @@ public class Invokers {
...
@@ -76,8 +80,14 @@ public class Invokers {
return
invoker
;
return
invoker
;
}
}
public
MethodHandle
varargsInvoker
()
{
public
MethodHandle
varargsInvoker
(
int
objectArgCount
)
{
throw
new
UnsupportedOperationException
(
"NYI"
);
MethodHandle
vaInvoker
=
varargsInvokers
[
objectArgCount
];
if
(
vaInvoker
!=
null
)
return
vaInvoker
;
MethodHandle
gInvoker
=
genericInvoker
();
MethodType
vaType
=
MethodType
.
genericMethodType
(
objectArgCount
,
true
);
vaInvoker
=
MethodHandles
.
spreadArguments
(
gInvoker
,
invokerType
(
vaType
));
varargsInvokers
[
objectArgCount
]
=
vaInvoker
;
return
vaInvoker
;
}
}
public
String
toString
()
{
public
String
toString
()
{
...
...
src/share/classes/sun/dyn/MemberName.java
浏览文件 @
8992d5c6
...
@@ -25,7 +25,7 @@
...
@@ -25,7 +25,7 @@
package
sun.dyn
;
package
sun.dyn
;
import
sun.dyn.util.Bytecode
Signature
;
import
sun.dyn.util.Bytecode
Descriptor
;
import
java.dyn.*
;
import
java.dyn.*
;
import
java.lang.reflect.Constructor
;
import
java.lang.reflect.Constructor
;
import
java.lang.reflect.Field
;
import
java.lang.reflect.Field
;
...
@@ -33,6 +33,7 @@ import java.lang.reflect.Method;
...
@@ -33,6 +33,7 @@ import java.lang.reflect.Method;
import
java.lang.reflect.Member
;
import
java.lang.reflect.Member
;
import
java.lang.reflect.Modifier
;
import
java.lang.reflect.Modifier
;
import
java.util.ArrayList
;
import
java.util.ArrayList
;
import
java.util.Arrays
;
import
java.util.Collections
;
import
java.util.Collections
;
import
java.util.Iterator
;
import
java.util.Iterator
;
import
java.util.List
;
import
java.util.List
;
...
@@ -93,7 +94,7 @@ public final class MemberName implements Member, Cloneable {
...
@@ -93,7 +94,7 @@ public final class MemberName implements Member, Cloneable {
}
}
if
(
type
instanceof
String
)
{
if
(
type
instanceof
String
)
{
String
sig
=
(
String
)
type
;
String
sig
=
(
String
)
type
;
MethodType
res
=
MethodType
.
from
Bytecode
String
(
sig
,
getClassLoader
());
MethodType
res
=
MethodType
.
from
MethodDescriptor
String
(
sig
,
getClassLoader
());
this
.
type
=
res
;
this
.
type
=
res
;
return
res
;
return
res
;
}
}
...
@@ -101,7 +102,7 @@ public final class MemberName implements Member, Cloneable {
...
@@ -101,7 +102,7 @@ public final class MemberName implements Member, Cloneable {
Object
[]
typeInfo
=
(
Object
[])
type
;
Object
[]
typeInfo
=
(
Object
[])
type
;
Class
<?>[]
ptypes
=
(
Class
<?>[])
typeInfo
[
1
];
Class
<?>[]
ptypes
=
(
Class
<?>[])
typeInfo
[
1
];
Class
<?>
rtype
=
(
Class
<?>)
typeInfo
[
0
];
Class
<?>
rtype
=
(
Class
<?>)
typeInfo
[
0
];
MethodType
res
=
MethodType
.
m
ak
e
(
rtype
,
ptypes
);
MethodType
res
=
MethodType
.
m
ethodTyp
e
(
rtype
,
ptypes
);
this
.
type
=
res
;
this
.
type
=
res
;
return
res
;
return
res
;
}
}
...
@@ -111,7 +112,7 @@ public final class MemberName implements Member, Cloneable {
...
@@ -111,7 +112,7 @@ public final class MemberName implements Member, Cloneable {
public
MethodType
getInvocationType
()
{
public
MethodType
getInvocationType
()
{
MethodType
itype
=
getMethodType
();
MethodType
itype
=
getMethodType
();
if
(!
isStatic
())
if
(!
isStatic
())
itype
=
itype
.
insertParameterType
(
0
,
clazz
);
itype
=
itype
.
insertParameterType
s
(
0
,
clazz
);
return
itype
;
return
itype
;
}
}
...
@@ -135,7 +136,7 @@ public final class MemberName implements Member, Cloneable {
...
@@ -135,7 +136,7 @@ public final class MemberName implements Member, Cloneable {
}
}
if
(
type
instanceof
String
)
{
if
(
type
instanceof
String
)
{
String
sig
=
(
String
)
type
;
String
sig
=
(
String
)
type
;
MethodType
mtype
=
MethodType
.
from
Bytecode
String
(
"()"
+
sig
,
getClassLoader
());
MethodType
mtype
=
MethodType
.
from
MethodDescriptor
String
(
"()"
+
sig
,
getClassLoader
());
Class
<?>
res
=
mtype
.
returnType
();
Class
<?>
res
=
mtype
.
returnType
();
this
.
type
=
res
;
this
.
type
=
res
;
return
res
;
return
res
;
...
@@ -155,9 +156,9 @@ public final class MemberName implements Member, Cloneable {
...
@@ -155,9 +156,9 @@ public final class MemberName implements Member, Cloneable {
if
(
type
instanceof
String
)
if
(
type
instanceof
String
)
return
(
String
)
type
;
return
(
String
)
type
;
if
(
isInvocable
())
if
(
isInvocable
())
return
Bytecode
Signature
.
unparse
(
getMethodType
());
return
Bytecode
Descriptor
.
unparse
(
getMethodType
());
else
else
return
Bytecode
Signature
.
unparse
(
getFieldType
());
return
Bytecode
Descriptor
.
unparse
(
getFieldType
());
}
}
public
int
getModifiers
()
{
public
int
getModifiers
()
{
...
@@ -353,6 +354,8 @@ public final class MemberName implements Member, Cloneable {
...
@@ -353,6 +354,8 @@ public final class MemberName implements Member, Cloneable {
return
type
.
toString
();
// class java.lang.String
return
type
.
toString
();
// class java.lang.String
// else it is a field, method, or constructor
// else it is a field, method, or constructor
StringBuilder
buf
=
new
StringBuilder
();
StringBuilder
buf
=
new
StringBuilder
();
if
(!
isResolved
())
buf
.
append
(
"*."
);
if
(
getDeclaringClass
()
!=
null
)
{
if
(
getDeclaringClass
()
!=
null
)
{
buf
.
append
(
getName
(
clazz
));
buf
.
append
(
getName
(
clazz
));
buf
.
append
(
'.'
);
buf
.
append
(
'.'
);
...
@@ -381,7 +384,7 @@ public final class MemberName implements Member, Cloneable {
...
@@ -381,7 +384,7 @@ public final class MemberName implements Member, Cloneable {
private
static
String
getName
(
Object
obj
)
{
private
static
String
getName
(
Object
obj
)
{
if
(
obj
instanceof
Class
<?>)
if
(
obj
instanceof
Class
<?>)
return
((
Class
<?>)
obj
).
getName
();
return
((
Class
<?>)
obj
).
getName
();
return
obj
.
toString
(
);
return
String
.
valueOf
(
obj
);
}
}
// Queries to the JVM:
// Queries to the JVM:
...
@@ -408,6 +411,9 @@ public final class MemberName implements Member, Cloneable {
...
@@ -408,6 +411,9 @@ public final class MemberName implements Member, Cloneable {
public
static
NoAccessException
newNoAccessException
(
MemberName
name
,
Class
<?>
lookupClass
)
{
public
static
NoAccessException
newNoAccessException
(
MemberName
name
,
Class
<?>
lookupClass
)
{
return
newNoAccessException
(
"cannot access"
,
name
,
lookupClass
);
return
newNoAccessException
(
"cannot access"
,
name
,
lookupClass
);
}
}
public
static
NoAccessException
newNoAccessException
(
MemberName
name
,
MethodHandles
.
Lookup
lookup
)
{
return
newNoAccessException
(
name
,
lookup
.
lookupClass
());
}
public
static
NoAccessException
newNoAccessException
(
String
message
,
public
static
NoAccessException
newNoAccessException
(
String
message
,
MemberName
name
,
Class
<?>
lookupClass
)
{
MemberName
name
,
Class
<?>
lookupClass
)
{
message
+=
": "
+
name
;
message
+=
": "
+
name
;
...
@@ -436,7 +442,7 @@ public final class MemberName implements Member, Cloneable {
...
@@ -436,7 +442,7 @@ public final class MemberName implements Member, Cloneable {
matchFlags
&=
ALLOWED_FLAGS
;
matchFlags
&=
ALLOWED_FLAGS
;
String
matchSig
=
null
;
String
matchSig
=
null
;
if
(
matchType
!=
null
)
{
if
(
matchType
!=
null
)
{
matchSig
=
Bytecode
Signature
.
unparse
(
matchType
);
matchSig
=
Bytecode
Descriptor
.
unparse
(
matchType
);
if
(
matchSig
.
startsWith
(
"("
))
if
(
matchSig
.
startsWith
(
"("
))
matchFlags
&=
~(
ALL_KINDS
&
~
IS_INVOCABLE
);
matchFlags
&=
~(
ALL_KINDS
&
~
IS_INVOCABLE
);
else
else
...
@@ -447,17 +453,18 @@ public final class MemberName implements Member, Cloneable {
...
@@ -447,17 +453,18 @@ public final class MemberName implements Member, Cloneable {
MemberName
[]
buf
=
newMemberBuffer
(
len1
);
MemberName
[]
buf
=
newMemberBuffer
(
len1
);
int
totalCount
=
0
;
int
totalCount
=
0
;
ArrayList
<
MemberName
[]>
bufs
=
null
;
ArrayList
<
MemberName
[]>
bufs
=
null
;
int
bufCount
=
0
;
for
(;;)
{
for
(;;)
{
int
bufCount
=
MethodHandleNatives
.
getMembers
(
defc
,
bufCount
=
MethodHandleNatives
.
getMembers
(
defc
,
matchName
,
matchSig
,
matchFlags
,
matchName
,
matchSig
,
matchFlags
,
lookupClass
,
lookupClass
,
totalCount
,
buf
);
totalCount
,
buf
);
if
(
bufCount
<=
buf
.
length
)
{
if
(
bufCount
<=
buf
.
length
)
{
if
(
bufCount
>=
0
)
if
(
bufCount
<
0
)
bufCount
=
0
;
totalCount
+=
bufCount
;
totalCount
+=
bufCount
;
break
;
break
;
}
}
// JVM returned t
p
us with an intentional overflow!
// JVM returned t
o
us with an intentional overflow!
totalCount
+=
buf
.
length
;
totalCount
+=
buf
.
length
;
int
excess
=
bufCount
-
buf
.
length
;
int
excess
=
bufCount
-
buf
.
length
;
if
(
bufs
==
null
)
bufs
=
new
ArrayList
<
MemberName
[]>(
1
);
if
(
bufs
==
null
)
bufs
=
new
ArrayList
<
MemberName
[]>(
1
);
...
@@ -473,7 +480,7 @@ public final class MemberName implements Member, Cloneable {
...
@@ -473,7 +480,7 @@ public final class MemberName implements Member, Cloneable {
Collections
.
addAll
(
result
,
buf0
);
Collections
.
addAll
(
result
,
buf0
);
}
}
}
}
Collections
.
addAll
(
result
,
buf
);
result
.
addAll
(
Arrays
.
asList
(
buf
).
subList
(
0
,
bufCount
)
);
// Signature matching is not the same as type matching, since
// Signature matching is not the same as type matching, since
// one signature might correspond to several types.
// one signature might correspond to several types.
// So if matchType is a Class or MethodType, refilter the results.
// So if matchType is a Class or MethodType, refilter the results.
...
...
src/share/classes/sun/dyn/MethodHandleImpl.java
浏览文件 @
8992d5c6
...
@@ -25,12 +25,25 @@
...
@@ -25,12 +25,25 @@
package
sun.dyn
;
package
sun.dyn
;
import
java.dyn.JavaMethodHandle
;
import
java.dyn.MethodHandle
;
import
java.dyn.MethodHandle
;
import
java.dyn.MethodHandles
;
import
java.dyn.MethodHandles
;
import
java.dyn.MethodHandles.Lookup
;
import
java.dyn.MethodHandles.Lookup
;
import
java.dyn.MethodType
;
import
java.dyn.MethodType
;
import
java.util.logging.Level
;
import
java.util.logging.Logger
;
import
sun.dyn.util.VerifyType
;
import
sun.dyn.util.VerifyType
;
import
java.dyn.NoAccessException
;
import
java.dyn.NoAccessException
;
import
java.util.ArrayList
;
import
java.util.Arrays
;
import
java.util.Collections
;
import
java.util.HashMap
;
import
java.util.Iterator
;
import
java.util.List
;
import
sun.dyn.empty.Empty
;
import
sun.dyn.util.ValueConversions
;
import
sun.dyn.util.Wrapper
;
import
sun.misc.Unsafe
;
import
static
sun
.
dyn
.
MemberName
.
newIllegalArgumentException
;
import
static
sun
.
dyn
.
MemberName
.
newIllegalArgumentException
;
import
static
sun
.
dyn
.
MemberName
.
newNoAccessException
;
import
static
sun
.
dyn
.
MemberName
.
newNoAccessException
;
...
@@ -57,6 +70,25 @@ public abstract class MethodHandleImpl {
...
@@ -57,6 +70,25 @@ public abstract class MethodHandleImpl {
static
final
int
INT_FIELD
=
0
;
static
final
int
INT_FIELD
=
0
;
static
final
long
LONG_FIELD
=
0
;
static
final
long
LONG_FIELD
=
0
;
/** Access methods for the internals of MethodHandle, supplied to
* MethodHandleImpl as a trusted agent.
*/
static
public
interface
MethodHandleFriend
{
void
initType
(
MethodHandle
mh
,
MethodType
type
);
}
public
static
void
setMethodHandleFriend
(
Access
token
,
MethodHandleFriend
am
)
{
Access
.
check
(
token
);
if
(
METHOD_HANDLE_FRIEND
!=
null
)
throw
new
InternalError
();
// just once
METHOD_HANDLE_FRIEND
=
am
;
}
static
private
MethodHandleFriend
METHOD_HANDLE_FRIEND
;
// NOT public
static
void
initType
(
MethodHandle
mh
,
MethodType
type
)
{
METHOD_HANDLE_FRIEND
.
initType
(
mh
,
type
);
}
// type is defined in java.dyn.MethodHandle, which is platform-independent
// type is defined in java.dyn.MethodHandle, which is platform-independent
// vmentry (a void* field) is used *only* by by the JVM.
// vmentry (a void* field) is used *only* by by the JVM.
...
@@ -106,8 +138,8 @@ public abstract class MethodHandleImpl {
...
@@ -106,8 +138,8 @@ public abstract class MethodHandleImpl {
}
}
static
{
static
{
// Force initialization:
// Force initialization
of Lookup, so it calls us back as initLookup
:
Lookup
.
PUBLIC_LOOKUP
.
lookupClass
();
MethodHandles
.
publicLookup
();
if
(
IMPL_LOOKUP_INIT
==
null
)
if
(
IMPL_LOOKUP_INIT
==
null
)
throw
new
InternalError
();
throw
new
InternalError
();
}
}
...
@@ -151,7 +183,7 @@ public abstract class MethodHandleImpl {
...
@@ -151,7 +183,7 @@ public abstract class MethodHandleImpl {
// adjust the advertised receiver type to be exactly the one requested
// adjust the advertised receiver type to be exactly the one requested
// (in the case of invokespecial, this will be the calling class)
// (in the case of invokespecial, this will be the calling class)
Class
<?>
recvType
=
method
.
getDeclaringClass
();
Class
<?>
recvType
=
method
.
getDeclaringClass
();
mtype
=
mtype
.
insertParameterType
(
0
,
recvType
);
mtype
=
mtype
.
insertParameterType
s
(
0
,
recvType
);
if
(
method
.
isConstructor
())
if
(
method
.
isConstructor
())
doDispatch
=
true
;
doDispatch
=
true
;
// FIXME: JVM has trouble building MH.invoke sites for
// FIXME: JVM has trouble building MH.invoke sites for
...
@@ -173,8 +205,9 @@ public abstract class MethodHandleImpl {
...
@@ -173,8 +205,9 @@ public abstract class MethodHandleImpl {
MemberName
member
,
boolean
isSetter
,
MemberName
member
,
boolean
isSetter
,
Class
<?>
lookupClass
)
{
Class
<?>
lookupClass
)
{
Access
.
check
(
token
);
Access
.
check
(
token
);
// FIXME: Use sun.misc.Unsafe to dig up the dirt on the field.
// Use sun. misc.Unsafe to dig up the dirt on the field.
throw
new
UnsupportedOperationException
(
"Not yet implemented"
);
MethodHandle
mh
=
new
FieldAccessor
(
token
,
member
,
isSetter
);
return
mh
;
}
}
public
static
public
static
...
@@ -183,8 +216,209 @@ public abstract class MethodHandleImpl {
...
@@ -183,8 +216,209 @@ public abstract class MethodHandleImpl {
Access
.
check
(
token
);
Access
.
check
(
token
);
if
(!
arrayClass
.
isArray
())
if
(!
arrayClass
.
isArray
())
throw
newIllegalArgumentException
(
"not an array: "
+
arrayClass
);
throw
newIllegalArgumentException
(
"not an array: "
+
arrayClass
);
// FIXME: Use sun.misc.Unsafe to dig up the dirt on the array.
Class
<?>
elemClass
=
arrayClass
.
getComponentType
();
throw
new
UnsupportedOperationException
(
"Not yet implemented"
);
MethodHandle
[]
mhs
=
FieldAccessor
.
ARRAY_CACHE
.
get
(
elemClass
);
if
(
mhs
==
null
)
{
if
(!
FieldAccessor
.
doCache
(
elemClass
))
return
FieldAccessor
.
ahandle
(
arrayClass
,
isSetter
);
mhs
=
new
MethodHandle
[]
{
FieldAccessor
.
ahandle
(
arrayClass
,
false
),
FieldAccessor
.
ahandle
(
arrayClass
,
true
)
};
if
(
mhs
[
0
].
type
().
parameterType
(
0
)
==
Class
.
class
)
{
mhs
[
0
]
=
MethodHandles
.
insertArguments
(
mhs
[
0
],
0
,
elemClass
);
mhs
[
1
]
=
MethodHandles
.
insertArguments
(
mhs
[
1
],
0
,
elemClass
);
}
synchronized
(
FieldAccessor
.
ARRAY_CACHE
)
{}
// memory barrier
FieldAccessor
.
ARRAY_CACHE
.
put
(
elemClass
,
mhs
);
}
return
mhs
[
isSetter
?
1
:
0
];
}
static
final
class
FieldAccessor
<
C
,
V
>
extends
JavaMethodHandle
{
private
static
final
Unsafe
unsafe
=
Unsafe
.
getUnsafe
();
final
Object
base
;
// for static refs only
final
long
offset
;
final
String
name
;
public
FieldAccessor
(
Access
token
,
MemberName
field
,
boolean
isSetter
)
{
super
(
fhandle
(
field
.
getDeclaringClass
(),
field
.
getFieldType
(),
isSetter
,
field
.
isStatic
()));
this
.
offset
=
(
long
)
field
.
getVMIndex
(
token
);
this
.
name
=
field
.
getName
();
this
.
base
=
staticBase
(
field
);
}
public
String
toString
()
{
return
name
;
}
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
);
}
// cast (V) is OK here, since we wrap convertArguments around the MH.
static
Object
staticBase
(
MemberName
field
)
{
if
(!
field
.
isStatic
())
return
null
;
Class
c
=
field
.
getDeclaringClass
();
java
.
lang
.
reflect
.
Field
f
;
try
{
// FIXME: Should not have to create 'f' to get this value.
f
=
c
.
getDeclaredField
(
field
.
getName
());
return
unsafe
.
staticFieldBase
(
f
);
}
catch
(
Exception
ee
)
{
Error
e
=
new
InternalError
();
e
.
initCause
(
ee
);
throw
e
;
}
}
int
getStaticI
()
{
return
unsafe
.
getInt
(
base
,
offset
);
}
void
setStaticI
(
int
x
)
{
unsafe
.
putInt
(
base
,
offset
,
x
);
}
long
getStaticJ
()
{
return
unsafe
.
getLong
(
base
,
offset
);
}
void
setStaticJ
(
long
x
)
{
unsafe
.
putLong
(
base
,
offset
,
x
);
}
float
getStaticF
()
{
return
unsafe
.
getFloat
(
base
,
offset
);
}
void
setStaticF
(
float
x
)
{
unsafe
.
putFloat
(
base
,
offset
,
x
);
}
double
getStaticD
()
{
return
unsafe
.
getDouble
(
base
,
offset
);
}
void
setStaticD
(
double
x
)
{
unsafe
.
putDouble
(
base
,
offset
,
x
);
}
boolean
getStaticZ
()
{
return
unsafe
.
getBoolean
(
base
,
offset
);
}
void
setStaticZ
(
boolean
x
)
{
unsafe
.
putBoolean
(
base
,
offset
,
x
);
}
byte
getStaticB
()
{
return
unsafe
.
getByte
(
base
,
offset
);
}
void
setStaticB
(
byte
x
)
{
unsafe
.
putByte
(
base
,
offset
,
x
);
}
short
getStaticS
()
{
return
unsafe
.
getShort
(
base
,
offset
);
}
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
);
}
static
String
fname
(
Class
<?>
vclass
,
boolean
isSetter
,
boolean
isStatic
)
{
String
stem
;
if
(!
isStatic
)
stem
=
(!
isSetter
?
"getField"
:
"setField"
);
else
stem
=
(!
isSetter
?
"getStatic"
:
"setStatic"
);
return
stem
+
Wrapper
.
basicTypeChar
(
vclass
);
}
static
MethodType
ftype
(
Class
<?>
cclass
,
Class
<?>
vclass
,
boolean
isSetter
,
boolean
isStatic
)
{
MethodType
type
;
if
(!
isStatic
)
{
if
(!
isSetter
)
return
MethodType
.
methodType
(
vclass
,
cclass
);
else
return
MethodType
.
methodType
(
void
.
class
,
cclass
,
vclass
);
}
else
{
if
(!
isSetter
)
return
MethodType
.
methodType
(
vclass
);
else
return
MethodType
.
methodType
(
void
.
class
,
vclass
);
}
}
static
MethodHandle
fhandle
(
Class
<?>
cclass
,
Class
<?>
vclass
,
boolean
isSetter
,
boolean
isStatic
)
{
String
name
=
FieldAccessor
.
fname
(
vclass
,
isSetter
,
isStatic
);
if
(
cclass
.
isPrimitive
())
throw
newIllegalArgumentException
(
"primitive "
+
cclass
);
Class
<?>
ecclass
=
Object
.
class
;
//erase this type
Class
<?>
evclass
=
vclass
;
if
(!
evclass
.
isPrimitive
())
evclass
=
Object
.
class
;
MethodType
type
=
FieldAccessor
.
ftype
(
ecclass
,
evclass
,
isSetter
,
isStatic
);
MethodHandle
mh
;
try
{
mh
=
IMPL_LOOKUP
.
findVirtual
(
FieldAccessor
.
class
,
name
,
type
);
}
catch
(
NoAccessException
ee
)
{
Error
e
=
new
InternalError
(
"name,type="
+
name
+
type
);
e
.
initCause
(
ee
);
throw
e
;
}
if
(
evclass
!=
vclass
||
(!
isStatic
&&
ecclass
!=
cclass
))
{
MethodType
strongType
=
FieldAccessor
.
ftype
(
cclass
,
vclass
,
isSetter
,
isStatic
);
strongType
=
strongType
.
insertParameterTypes
(
0
,
FieldAccessor
.
class
);
mh
=
MethodHandles
.
convertArguments
(
mh
,
strongType
);
}
return
mh
;
}
/// Support for array element access
static
final
HashMap
<
Class
<?>,
MethodHandle
[]>
ARRAY_CACHE
=
new
HashMap
<
Class
<?>,
MethodHandle
[]>();
// FIXME: Cache on the classes themselves, not here.
static
boolean
doCache
(
Class
<?>
elemClass
)
{
if
(
elemClass
.
isPrimitive
())
return
true
;
ClassLoader
cl
=
elemClass
.
getClassLoader
();
return
cl
==
null
||
cl
==
ClassLoader
.
getSystemClassLoader
();
}
static
int
getElementI
(
int
[]
a
,
int
i
)
{
return
a
[
i
];
}
static
void
setElementI
(
int
[]
a
,
int
i
,
int
x
)
{
a
[
i
]
=
x
;
}
static
long
getElementJ
(
long
[]
a
,
int
i
)
{
return
a
[
i
];
}
static
void
setElementJ
(
long
[]
a
,
int
i
,
long
x
)
{
a
[
i
]
=
x
;
}
static
float
getElementF
(
float
[]
a
,
int
i
)
{
return
a
[
i
];
}
static
void
setElementF
(
float
[]
a
,
int
i
,
float
x
)
{
a
[
i
]
=
x
;
}
static
double
getElementD
(
double
[]
a
,
int
i
)
{
return
a
[
i
];
}
static
void
setElementD
(
double
[]
a
,
int
i
,
double
x
)
{
a
[
i
]
=
x
;
}
static
boolean
getElementZ
(
boolean
[]
a
,
int
i
)
{
return
a
[
i
];
}
static
void
setElementZ
(
boolean
[]
a
,
int
i
,
boolean
x
)
{
a
[
i
]
=
x
;
}
static
byte
getElementB
(
byte
[]
a
,
int
i
)
{
return
a
[
i
];
}
static
void
setElementB
(
byte
[]
a
,
int
i
,
byte
x
)
{
a
[
i
]
=
x
;
}
static
short
getElementS
(
short
[]
a
,
int
i
)
{
return
a
[
i
];
}
static
void
setElementS
(
short
[]
a
,
int
i
,
short
x
)
{
a
[
i
]
=
x
;
}
static
char
getElementC
(
char
[]
a
,
int
i
)
{
return
a
[
i
];
}
static
void
setElementC
(
char
[]
a
,
int
i
,
char
x
)
{
a
[
i
]
=
x
;
}
static
Object
getElementL
(
Object
[]
a
,
int
i
)
{
return
a
[
i
];
}
static
void
setElementL
(
Object
[]
a
,
int
i
,
Object
x
)
{
a
[
i
]
=
x
;
}
static
<
V
>
V
getElementL
(
Class
<
V
[]>
aclass
,
V
[]
a
,
int
i
)
{
return
aclass
.
cast
(
a
)[
i
];
}
static
<
V
>
void
setElementL
(
Class
<
V
[]>
aclass
,
V
[]
a
,
int
i
,
V
x
)
{
aclass
.
cast
(
a
)[
i
]
=
x
;
}
static
String
aname
(
Class
<?>
aclass
,
boolean
isSetter
)
{
Class
<?>
vclass
=
aclass
.
getComponentType
();
if
(
vclass
==
null
)
throw
new
IllegalArgumentException
();
return
(!
isSetter
?
"getElement"
:
"setElement"
)
+
Wrapper
.
basicTypeChar
(
vclass
);
}
static
MethodType
atype
(
Class
<?>
aclass
,
boolean
isSetter
)
{
Class
<?>
vclass
=
aclass
.
getComponentType
();
if
(!
isSetter
)
return
MethodType
.
methodType
(
vclass
,
aclass
,
int
.
class
);
else
return
MethodType
.
methodType
(
void
.
class
,
aclass
,
int
.
class
,
vclass
);
}
static
MethodHandle
ahandle
(
Class
<?>
aclass
,
boolean
isSetter
)
{
Class
<?>
vclass
=
aclass
.
getComponentType
();
String
name
=
FieldAccessor
.
aname
(
aclass
,
isSetter
);
Class
<?>
caclass
=
null
;
if
(!
vclass
.
isPrimitive
()
&&
vclass
!=
Object
.
class
)
{
caclass
=
aclass
;
aclass
=
Object
[].
class
;
vclass
=
Object
.
class
;
}
MethodType
type
=
FieldAccessor
.
atype
(
aclass
,
isSetter
);
if
(
caclass
!=
null
)
type
=
type
.
insertParameterTypes
(
0
,
Class
.
class
);
MethodHandle
mh
;
try
{
mh
=
IMPL_LOOKUP
.
findStatic
(
FieldAccessor
.
class
,
name
,
type
);
}
catch
(
NoAccessException
ee
)
{
Error
e
=
new
InternalError
(
"name,type="
+
name
+
type
);
e
.
initCause
(
ee
);
throw
e
;
}
if
(
caclass
!=
null
)
{
MethodType
strongType
=
FieldAccessor
.
atype
(
caclass
,
isSetter
);
mh
=
MethodHandles
.
insertArguments
(
mh
,
0
,
caclass
);
mh
=
MethodHandles
.
convertArguments
(
mh
,
strongType
);
}
return
mh
;
}
}
}
/** Bind a predetermined first argument to the given direct method handle.
/** Bind a predetermined first argument to the given direct method handle.
...
@@ -203,8 +437,11 @@ public abstract class MethodHandleImpl {
...
@@ -203,8 +437,11 @@ public abstract class MethodHandleImpl {
if
(
info
instanceof
DirectMethodHandle
)
{
if
(
info
instanceof
DirectMethodHandle
)
{
DirectMethodHandle
dmh
=
(
DirectMethodHandle
)
info
;
DirectMethodHandle
dmh
=
(
DirectMethodHandle
)
info
;
if
(
receiver
==
null
||
if
(
receiver
==
null
||
dmh
.
type
().
parameterType
(
0
).
isAssignableFrom
(
receiver
.
getClass
()))
dmh
.
type
().
parameterType
(
0
).
isAssignableFrom
(
receiver
.
getClass
()))
{
target
=
dmh
;
MethodHandle
bmh
=
new
BoundMethodHandle
(
dmh
,
receiver
,
0
);
MethodType
newType
=
target
.
type
().
dropParameterTypes
(
0
,
1
);
return
convertArguments
(
token
,
bmh
,
newType
,
bmh
.
type
(),
null
);
}
}
}
}
}
if
(
target
instanceof
DirectMethodHandle
)
if
(
target
instanceof
DirectMethodHandle
)
...
@@ -223,7 +460,7 @@ public abstract class MethodHandleImpl {
...
@@ -223,7 +460,7 @@ public abstract class MethodHandleImpl {
MethodHandle
bindArgument
(
Access
token
,
MethodHandle
bindArgument
(
Access
token
,
MethodHandle
target
,
int
argnum
,
Object
receiver
)
{
MethodHandle
target
,
int
argnum
,
Object
receiver
)
{
Access
.
check
(
token
);
Access
.
check
(
token
);
throw
new
UnsupportedOperationException
(
"NYI"
);
return
new
BoundMethodHandle
(
target
,
receiver
,
argnum
);
}
}
public
static
MethodHandle
convertArguments
(
Access
token
,
public
static
MethodHandle
convertArguments
(
Access
token
,
...
@@ -232,6 +469,189 @@ public abstract class MethodHandleImpl {
...
@@ -232,6 +469,189 @@ public abstract class MethodHandleImpl {
MethodType
oldType
,
MethodType
oldType
,
int
[]
permutationOrNull
)
{
int
[]
permutationOrNull
)
{
Access
.
check
(
token
);
Access
.
check
(
token
);
if
(
permutationOrNull
!=
null
)
{
int
outargs
=
oldType
.
parameterCount
(),
inargs
=
newType
.
parameterCount
();
if
(
permutationOrNull
.
length
!=
outargs
)
throw
newIllegalArgumentException
(
"wrong number of arguments in permutation"
);
// Make the individual outgoing argument types match up first.
Class
<?>[]
callTypeArgs
=
new
Class
<?>[
outargs
];
for
(
int
i
=
0
;
i
<
outargs
;
i
++)
callTypeArgs
[
i
]
=
newType
.
parameterType
(
permutationOrNull
[
i
]);
MethodType
callType
=
MethodType
.
methodType
(
oldType
.
returnType
(),
callTypeArgs
);
target
=
convertArguments
(
token
,
target
,
callType
,
oldType
,
null
);
assert
(
target
!=
null
);
oldType
=
target
.
type
();
List
<
Integer
>
goal
=
new
ArrayList
<
Integer
>();
// i*TOKEN
List
<
Integer
>
state
=
new
ArrayList
<
Integer
>();
// i*TOKEN
List
<
Integer
>
drops
=
new
ArrayList
<
Integer
>();
// not tokens
List
<
Integer
>
dups
=
new
ArrayList
<
Integer
>();
// not tokens
final
int
TOKEN
=
10
;
// to mark items which are symbolic only
// state represents the argument values coming into target
for
(
int
i
=
0
;
i
<
outargs
;
i
++)
{
state
.
add
(
permutationOrNull
[
i
]
*
TOKEN
);
}
// goal represents the desired state
for
(
int
i
=
0
;
i
<
inargs
;
i
++)
{
if
(
state
.
contains
(
i
*
TOKEN
))
{
goal
.
add
(
i
*
TOKEN
);
}
else
{
// adapter must initially drop all unused arguments
drops
.
add
(
i
);
}
}
// detect duplications
while
(
state
.
size
()
>
goal
.
size
())
{
for
(
int
i2
=
0
;
i2
<
state
.
size
();
i2
++)
{
int
arg1
=
state
.
get
(
i2
);
int
i1
=
state
.
indexOf
(
arg1
);
if
(
i1
!=
i2
)
{
// found duplicate occurrence at i2
int
arg2
=
(
inargs
++)
*
TOKEN
;
state
.
set
(
i2
,
arg2
);
dups
.
add
(
goal
.
indexOf
(
arg1
));
goal
.
add
(
arg2
);
}
}
}
assert
(
state
.
size
()
==
goal
.
size
());
int
size
=
goal
.
size
();
while
(!
state
.
equals
(
goal
))
{
// Look for a maximal sequence of adjacent misplaced arguments,
// and try to rotate them into place.
int
bestRotArg
=
-
10
*
TOKEN
,
bestRotLen
=
0
;
int
thisRotArg
=
-
10
*
TOKEN
,
thisRotLen
=
0
;
for
(
int
i
=
0
;
i
<
size
;
i
++)
{
int
arg
=
state
.
get
(
i
);
// Does this argument match the current run?
if
(
arg
==
thisRotArg
+
TOKEN
)
{
thisRotArg
=
arg
;
thisRotLen
+=
1
;
if
(
bestRotLen
<
thisRotLen
)
{
bestRotLen
=
thisRotLen
;
bestRotArg
=
thisRotArg
;
}
}
else
{
// The old sequence (if any) stops here.
thisRotLen
=
0
;
thisRotArg
=
-
10
*
TOKEN
;
// But maybe a new one starts here also.
int
wantArg
=
goal
.
get
(
i
);
final
int
MAX_ARG_ROTATION
=
AdapterMethodHandle
.
MAX_ARG_ROTATION
;
if
(
arg
!=
wantArg
&&
arg
>=
wantArg
-
TOKEN
*
MAX_ARG_ROTATION
&&
arg
<=
wantArg
+
TOKEN
*
MAX_ARG_ROTATION
)
{
thisRotArg
=
arg
;
thisRotLen
=
1
;
}
}
}
if
(
bestRotLen
>=
2
)
{
// Do a rotation if it can improve argument positioning
// by at least 2 arguments. This is not always optimal,
// but it seems to catch common cases.
int
dstEnd
=
state
.
indexOf
(
bestRotArg
);
int
srcEnd
=
goal
.
indexOf
(
bestRotArg
);
int
rotBy
=
dstEnd
-
srcEnd
;
int
dstBeg
=
dstEnd
-
(
bestRotLen
-
1
);
int
srcBeg
=
srcEnd
-
(
bestRotLen
-
1
);
assert
((
dstEnd
|
dstBeg
|
srcEnd
|
srcBeg
)
>=
0
);
// no negs
// Make a span which covers both source and destination.
int
rotBeg
=
Math
.
min
(
dstBeg
,
srcBeg
);
int
rotEnd
=
Math
.
max
(
dstEnd
,
srcEnd
);
int
score
=
0
;
for
(
int
i
=
rotBeg
;
i
<=
rotEnd
;
i
++)
{
if
((
int
)
state
.
get
(
i
)
!=
(
int
)
goal
.
get
(
i
))
score
+=
1
;
}
List
<
Integer
>
rotSpan
=
state
.
subList
(
rotBeg
,
rotEnd
+
1
);
Collections
.
rotate
(
rotSpan
,
-
rotBy
);
// reverse direction
for
(
int
i
=
rotBeg
;
i
<=
rotEnd
;
i
++)
{
if
((
int
)
state
.
get
(
i
)
!=
(
int
)
goal
.
get
(
i
))
score
-=
1
;
}
if
(
score
>=
2
)
{
// Improved at least two argument positions. Do it.
List
<
Class
<?>>
ptypes
=
Arrays
.
asList
(
oldType
.
parameterArray
());
Collections
.
rotate
(
ptypes
.
subList
(
rotBeg
,
rotEnd
+
1
),
-
rotBy
);
MethodType
rotType
=
MethodType
.
methodType
(
oldType
.
returnType
(),
ptypes
);
MethodHandle
nextTarget
=
AdapterMethodHandle
.
makeRotateArguments
(
token
,
rotType
,
target
,
rotBeg
,
rotSpan
.
size
(),
rotBy
);
if
(
nextTarget
!=
null
)
{
//System.out.println("Rot: "+rotSpan+" by "+rotBy);
target
=
nextTarget
;
oldType
=
rotType
;
continue
;
}
}
// Else de-rotate, and drop through to the swap-fest.
Collections
.
rotate
(
rotSpan
,
rotBy
);
}
// Now swap like the wind!
List
<
Class
<?>>
ptypes
=
Arrays
.
asList
(
oldType
.
parameterArray
());
for
(
int
i
=
0
;
i
<
size
;
i
++)
{
// What argument do I want here?
int
arg
=
goal
.
get
(
i
);
if
(
arg
!=
state
.
get
(
i
))
{
// Where is it now?
int
j
=
state
.
indexOf
(
arg
);
Collections
.
swap
(
ptypes
,
i
,
j
);
MethodType
swapType
=
MethodType
.
methodType
(
oldType
.
returnType
(),
ptypes
);
target
=
AdapterMethodHandle
.
makeSwapArguments
(
token
,
swapType
,
target
,
i
,
j
);
if
(
target
==
null
)
throw
newIllegalArgumentException
(
"cannot swap"
);
assert
(
target
.
type
()
==
swapType
);
oldType
=
swapType
;
Collections
.
swap
(
state
,
i
,
j
);
}
}
// One pass of swapping must finish the job.
assert
(
state
.
equals
(
goal
));
}
while
(!
dups
.
isEmpty
())
{
// Grab a contiguous trailing sequence of dups.
int
grab
=
dups
.
size
()
-
1
;
int
dupArgPos
=
dups
.
get
(
grab
),
dupArgCount
=
1
;
while
(
grab
-
1
>=
0
)
{
int
dup0
=
dups
.
get
(
grab
-
1
);
if
(
dup0
!=
dupArgPos
-
1
)
break
;
dupArgPos
-=
1
;
dupArgCount
+=
1
;
grab
-=
1
;
}
//if (dupArgCount > 1) System.out.println("Dup: "+dups.subList(grab, dups.size()));
dups
.
subList
(
grab
,
dups
.
size
()).
clear
();
// In the new target type drop that many args from the tail:
List
<
Class
<?>>
ptypes
=
oldType
.
parameterList
();
ptypes
=
ptypes
.
subList
(
0
,
ptypes
.
size
()
-
dupArgCount
);
MethodType
dupType
=
MethodType
.
methodType
(
oldType
.
returnType
(),
ptypes
);
target
=
AdapterMethodHandle
.
makeDupArguments
(
token
,
dupType
,
target
,
dupArgPos
,
dupArgCount
);
if
(
target
==
null
)
throw
newIllegalArgumentException
(
"cannot dup"
);
oldType
=
target
.
type
();
}
while
(!
drops
.
isEmpty
())
{
// Grab a contiguous initial sequence of drops.
int
dropArgPos
=
drops
.
get
(
0
),
dropArgCount
=
1
;
while
(
dropArgCount
<
drops
.
size
())
{
int
drop1
=
drops
.
get
(
dropArgCount
);
if
(
drop1
!=
dropArgPos
+
dropArgCount
)
break
;
dropArgCount
+=
1
;
}
//if (dropArgCount > 1) System.out.println("Drop: "+drops.subList(0, dropArgCount));
drops
.
subList
(
0
,
dropArgCount
).
clear
();
List
<
Class
<?>>
dropTypes
=
newType
.
parameterList
()
.
subList
(
dropArgPos
,
dropArgPos
+
dropArgCount
);
MethodType
dropType
=
oldType
.
insertParameterTypes
(
dropArgPos
,
dropTypes
);
target
=
AdapterMethodHandle
.
makeDropArguments
(
token
,
dropType
,
target
,
dropArgPos
,
dropArgCount
);
if
(
target
==
null
)
throw
newIllegalArgumentException
(
"cannot drop"
);
oldType
=
target
.
type
();
}
}
if
(
newType
==
oldType
)
return
target
;
if
(
oldType
.
parameterCount
()
!=
newType
.
parameterCount
())
throw
newIllegalArgumentException
(
"mismatched parameter count"
);
MethodHandle
res
=
AdapterMethodHandle
.
makePairwiseConvert
(
token
,
newType
,
target
);
MethodHandle
res
=
AdapterMethodHandle
.
makePairwiseConvert
(
token
,
newType
,
target
);
if
(
res
!=
null
)
if
(
res
!=
null
)
return
res
;
return
res
;
...
@@ -241,7 +661,7 @@ public abstract class MethodHandleImpl {
...
@@ -241,7 +661,7 @@ public abstract class MethodHandleImpl {
// Use a heavier method: Convert all the arguments to Object,
// Use a heavier method: Convert all the arguments to Object,
// then back to the desired types. We might have to use Java-based
// then back to the desired types. We might have to use Java-based
// method handles to do this.
// method handles to do this.
MethodType
objType
=
MethodType
.
makeGeneric
(
argc
);
MethodType
objType
=
MethodType
.
genericMethodType
(
argc
);
MethodHandle
objTarget
=
AdapterMethodHandle
.
makePairwiseConvert
(
token
,
objType
,
target
);
MethodHandle
objTarget
=
AdapterMethodHandle
.
makePairwiseConvert
(
token
,
objType
,
target
);
if
(
objTarget
==
null
)
if
(
objTarget
==
null
)
objTarget
=
FromGeneric
.
make
(
target
);
objTarget
=
FromGeneric
.
make
(
target
);
...
@@ -272,83 +692,386 @@ public abstract class MethodHandleImpl {
...
@@ -272,83 +692,386 @@ public abstract class MethodHandleImpl {
Class
<?>[]
ptypes
=
oldType
.
parameterArray
();
Class
<?>[]
ptypes
=
oldType
.
parameterArray
();
for
(
int
i
=
0
;
i
<
spreadCount
;
i
++)
for
(
int
i
=
0
;
i
<
spreadCount
;
i
++)
ptypes
[
spreadArg
+
i
]
=
VerifyType
.
spreadArgElementType
(
spreadType
,
i
);
ptypes
[
spreadArg
+
i
]
=
VerifyType
.
spreadArgElementType
(
spreadType
,
i
);
MethodType
midType
=
MethodType
.
m
ak
e
(
newType
.
returnType
(),
ptypes
);
MethodType
midType
=
MethodType
.
m
ethodTyp
e
(
newType
.
returnType
(),
ptypes
);
// after spreading, some arguments may need further conversion
// after spreading, some arguments may need further conversion
target
=
convertArguments
(
token
,
target
,
midType
,
oldType
,
null
);
MethodHandle
target2
=
convertArguments
(
token
,
target
,
midType
,
oldType
,
null
);
if
(
target
==
null
)
if
(
target
2
==
null
)
throw
new
UnsupportedOperationException
(
"NYI: convert "
+
midType
+
" =calls=> "
+
oldType
);
throw
new
UnsupportedOperationException
(
"NYI: convert "
+
midType
+
" =calls=> "
+
oldType
);
res
=
AdapterMethodHandle
.
makeSpreadArguments
(
token
,
newType
,
target
,
spreadArgType
,
spreadArg
,
spreadCount
);
res
=
AdapterMethodHandle
.
makeSpreadArguments
(
token
,
newType
,
target2
,
spreadArgType
,
spreadArg
,
spreadCount
);
if
(
res
!=
null
)
return
res
;
res
=
SpreadGeneric
.
make
(
target2
,
spreadCount
);
if
(
res
!=
null
)
res
=
convertArguments
(
token
,
res
,
newType
,
res
.
type
(),
null
);
return
res
;
return
res
;
}
}
public
static
MethodHandle
collectArguments
(
Access
token
,
public
static
MethodHandle
collectArguments
(
Access
token
,
MethodHandle
target
,
MethodHandle
target
,
MethodType
newType
,
MethodType
newType
,
int
collectArg
)
{
int
collectArg
,
if
(
collectArg
>
0
)
MethodHandle
collector
)
{
throw
new
UnsupportedOperationException
(
"NYI"
);
MethodType
oldType
=
target
.
type
();
// (a...,c)=>r
throw
new
UnsupportedOperationException
(
"NYI"
);
if
(
collector
==
null
)
{
int
numCollect
=
newType
.
parameterCount
()
-
oldType
.
parameterCount
()
+
1
;
collector
=
ValueConversions
.
varargsArray
(
numCollect
);
}
// newType // (a..., b...)=>r
MethodType
colType
=
collector
.
type
();
// (b...)=>c
// oldType // (a..., b...)=>r
assert
(
newType
.
parameterCount
()
==
collectArg
+
colType
.
parameterCount
());
assert
(
oldType
.
parameterCount
()
==
collectArg
+
1
);
MethodHandle
gtarget
=
convertArguments
(
token
,
target
,
oldType
.
generic
(),
oldType
,
null
);
MethodHandle
gcollector
=
convertArguments
(
token
,
collector
,
colType
.
generic
(),
colType
,
null
);
if
(
gtarget
==
null
||
gcollector
==
null
)
return
null
;
MethodHandle
gresult
=
FilterGeneric
.
makeArgumentCollector
(
gcollector
,
gtarget
);
MethodHandle
result
=
convertArguments
(
token
,
gresult
,
newType
,
gresult
.
type
(),
null
);
return
result
;
}
public
static
MethodHandle
filterArgument
(
Access
token
,
MethodHandle
target
,
int
pos
,
MethodHandle
filter
)
{
Access
.
check
(
token
);
MethodType
ttype
=
target
.
type
(),
gttype
=
ttype
.
generic
();
if
(
ttype
!=
gttype
)
{
target
=
convertArguments
(
token
,
target
,
gttype
,
ttype
,
null
);
ttype
=
gttype
;
}
MethodType
ftype
=
filter
.
type
(),
gftype
=
ftype
.
generic
();
if
(
ftype
.
parameterCount
()
!=
1
)
throw
new
InternalError
();
if
(
ftype
!=
gftype
)
{
filter
=
convertArguments
(
token
,
filter
,
gftype
,
ftype
,
null
);
ftype
=
gftype
;
}
if
(
ftype
==
ttype
)
{
// simple unary case
return
FilterOneArgument
.
make
(
filter
,
target
);
}
return
FilterGeneric
.
makeArgumentFilter
(
pos
,
filter
,
target
);
}
public
static
MethodHandle
foldArguments
(
Access
token
,
MethodHandle
target
,
MethodType
newType
,
MethodHandle
combiner
)
{
Access
.
check
(
token
);
MethodType
oldType
=
target
.
type
();
MethodType
ctype
=
combiner
.
type
();
MethodHandle
gtarget
=
convertArguments
(
token
,
target
,
oldType
.
generic
(),
oldType
,
null
);
MethodHandle
gcombiner
=
convertArguments
(
token
,
combiner
,
ctype
.
generic
(),
ctype
,
null
);
if
(
gtarget
==
null
||
gcombiner
==
null
)
return
null
;
MethodHandle
gresult
=
FilterGeneric
.
makeArgumentFolder
(
gcombiner
,
gtarget
);
MethodHandle
result
=
convertArguments
(
token
,
gresult
,
newType
,
gresult
.
type
(),
null
);
return
result
;
}
}
public
static
public
static
MethodHandle
dropArguments
(
Access
token
,
MethodHandle
target
,
MethodHandle
dropArguments
(
Access
token
,
MethodHandle
target
,
MethodType
newType
,
int
argnum
)
{
MethodType
newType
,
int
argnum
)
{
Access
.
check
(
token
);
Access
.
check
(
token
);
int
drops
=
newType
.
parameterCount
()
-
target
.
type
().
parameterCount
();
MethodHandle
res
=
AdapterMethodHandle
.
makeDropArguments
(
token
,
newType
,
target
,
argnum
,
drops
);
if
(
res
!=
null
)
return
res
;
throw
new
UnsupportedOperationException
(
"NYI"
);
throw
new
UnsupportedOperationException
(
"NYI"
);
}
}
private
static
class
GuardWithTest
extends
JavaMethodHandle
{
private
final
MethodHandle
test
,
target
,
fallback
;
public
GuardWithTest
(
MethodHandle
test
,
MethodHandle
target
,
MethodHandle
fallback
)
{
this
(
INVOKES
[
target
.
type
().
parameterCount
()],
test
,
target
,
fallback
);
}
public
GuardWithTest
(
MethodHandle
invoker
,
MethodHandle
test
,
MethodHandle
target
,
MethodHandle
fallback
)
{
super
(
invoker
);
this
.
test
=
test
;
this
.
target
=
target
;
this
.
fallback
=
fallback
;
}
@Override
public
String
toString
()
{
return
target
.
toString
();
}
private
Object
invoke_V
(
Object
...
av
)
throws
Throwable
{
if
(
test
.<
boolean
>
invoke
(
av
))
return
target
.<
Object
>
invoke
(
av
);
return
fallback
.<
Object
>
invoke
(
av
);
}
private
Object
invoke_L0
()
throws
Throwable
{
if
(
test
.<
boolean
>
invoke
())
return
target
.<
Object
>
invoke
();
return
fallback
.<
Object
>
invoke
();
}
private
Object
invoke_L1
(
Object
a0
)
throws
Throwable
{
if
(
test
.<
boolean
>
invoke
(
a0
))
return
target
.<
Object
>
invoke
(
a0
);
return
fallback
.<
Object
>
invoke
(
a0
);
}
private
Object
invoke_L2
(
Object
a0
,
Object
a1
)
throws
Throwable
{
if
(
test
.<
boolean
>
invoke
(
a0
,
a1
))
return
target
.<
Object
>
invoke
(
a0
,
a1
);
return
fallback
.<
Object
>
invoke
(
a0
,
a1
);
}
private
Object
invoke_L3
(
Object
a0
,
Object
a1
,
Object
a2
)
throws
Throwable
{
if
(
test
.<
boolean
>
invoke
(
a0
,
a1
,
a2
))
return
target
.<
Object
>
invoke
(
a0
,
a1
,
a2
);
return
fallback
.<
Object
>
invoke
(
a0
,
a1
,
a2
);
}
private
Object
invoke_L4
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
)
throws
Throwable
{
if
(
test
.<
boolean
>
invoke
(
a0
,
a1
,
a2
,
a3
))
return
target
.<
Object
>
invoke
(
a0
,
a1
,
a2
,
a3
);
return
fallback
.<
Object
>
invoke
(
a0
,
a1
,
a2
,
a3
);
}
private
Object
invoke_L5
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
)
throws
Throwable
{
if
(
test
.<
boolean
>
invoke
(
a0
,
a1
,
a2
,
a3
,
a4
))
return
target
.<
Object
>
invoke
(
a0
,
a1
,
a2
,
a3
,
a4
);
return
fallback
.<
Object
>
invoke
(
a0
,
a1
,
a2
,
a3
,
a4
);
}
private
Object
invoke_L6
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
)
throws
Throwable
{
if
(
test
.<
boolean
>
invoke
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
))
return
target
.<
Object
>
invoke
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
);
return
fallback
.<
Object
>
invoke
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
);
}
private
Object
invoke_L7
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
a6
)
throws
Throwable
{
if
(
test
.<
boolean
>
invoke
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
))
return
target
.<
Object
>
invoke
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
);
return
fallback
.<
Object
>
invoke
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
);
}
private
Object
invoke_L8
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
a6
,
Object
a7
)
throws
Throwable
{
if
(
test
.<
boolean
>
invoke
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
))
return
target
.<
Object
>
invoke
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
);
return
fallback
.<
Object
>
invoke
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
);
}
static
MethodHandle
[]
makeInvokes
()
{
ArrayList
<
MethodHandle
>
invokes
=
new
ArrayList
<
MethodHandle
>();
MethodHandles
.
Lookup
lookup
=
IMPL_LOOKUP
;
for
(;;)
{
int
nargs
=
invokes
.
size
();
String
name
=
"invoke_L"
+
nargs
;
MethodHandle
invoke
=
null
;
try
{
invoke
=
lookup
.
findVirtual
(
GuardWithTest
.
class
,
name
,
MethodType
.
genericMethodType
(
nargs
));
}
catch
(
NoAccessException
ex
)
{
}
if
(
invoke
==
null
)
break
;
invokes
.
add
(
invoke
);
}
assert
(
invokes
.
size
()
==
9
);
// current number of methods
return
invokes
.
toArray
(
new
MethodHandle
[
0
]);
};
static
final
MethodHandle
[]
INVOKES
=
makeInvokes
();
// For testing use this:
//static final MethodHandle[] INVOKES = Arrays.copyOf(makeInvokes(), 2);
static
final
MethodHandle
VARARGS_INVOKE
;
static
{
try
{
VARARGS_INVOKE
=
IMPL_LOOKUP
.
findVirtual
(
GuardWithTest
.
class
,
"invoke_V"
,
MethodType
.
genericMethodType
(
0
,
true
));
}
catch
(
NoAccessException
ex
)
{
throw
new
InternalError
(
""
);
}
}
}
public
static
public
static
MethodHandle
makeGuardWithTest
(
Access
token
,
MethodHandle
makeGuardWithTest
(
Access
token
,
final
MethodHandle
test
,
MethodHandle
test
,
final
MethodHandle
target
,
MethodHandle
target
,
final
MethodHandle
fallback
)
{
MethodHandle
fallback
)
{
Access
.
check
(
token
);
MethodType
type
=
target
.
type
();
int
nargs
=
type
.
parameterCount
();
if
(
nargs
<
GuardWithTest
.
INVOKES
.
length
)
{
MethodType
gtype
=
type
.
generic
();
MethodHandle
gtest
=
convertArguments
(
token
,
test
,
gtype
.
changeReturnType
(
boolean
.
class
),
test
.
type
(),
null
);
MethodHandle
gtarget
=
convertArguments
(
token
,
target
,
gtype
,
type
,
null
);
MethodHandle
gfallback
=
convertArguments
(
token
,
fallback
,
gtype
,
type
,
null
);
if
(
gtest
==
null
||
gtarget
==
null
||
gfallback
==
null
)
return
null
;
MethodHandle
gguard
=
new
GuardWithTest
(
gtest
,
gtarget
,
gfallback
);
return
convertArguments
(
token
,
gguard
,
type
,
gtype
,
null
);
}
else
{
MethodType
gtype
=
MethodType
.
genericMethodType
(
0
,
true
);
MethodHandle
gtest
=
spreadArguments
(
token
,
test
,
gtype
.
changeReturnType
(
boolean
.
class
),
0
);
MethodHandle
gtarget
=
spreadArguments
(
token
,
target
,
gtype
,
0
);
MethodHandle
gfallback
=
spreadArguments
(
token
,
fallback
,
gtype
,
0
);
MethodHandle
gguard
=
new
GuardWithTest
(
GuardWithTest
.
VARARGS_INVOKE
,
gtest
,
gtarget
,
gfallback
);
if
(
gtest
==
null
||
gtarget
==
null
||
gfallback
==
null
)
return
null
;
return
collectArguments
(
token
,
gguard
,
type
,
0
,
null
);
}
}
private
static
class
GuardWithCatch
extends
JavaMethodHandle
{
private
final
MethodHandle
target
;
private
final
Class
<?
extends
Throwable
>
exType
;
private
final
MethodHandle
catcher
;
public
GuardWithCatch
(
MethodHandle
target
,
Class
<?
extends
Throwable
>
exType
,
MethodHandle
catcher
)
{
this
(
INVOKES
[
target
.
type
().
parameterCount
()],
target
,
exType
,
catcher
);
}
public
GuardWithCatch
(
MethodHandle
invoker
,
MethodHandle
target
,
Class
<?
extends
Throwable
>
exType
,
MethodHandle
catcher
)
{
super
(
invoker
);
this
.
target
=
target
;
this
.
exType
=
exType
;
this
.
catcher
=
catcher
;
}
@Override
public
String
toString
()
{
return
target
.
toString
();
}
private
Object
invoke_V
(
Object
...
av
)
throws
Throwable
{
try
{
return
target
.<
Object
>
invoke
(
av
);
}
catch
(
Throwable
t
)
{
if
(!
exType
.
isInstance
(
t
))
throw
t
;
return
catcher
.<
Object
>
invoke
(
t
,
av
);
}
}
private
Object
invoke_L0
()
throws
Throwable
{
try
{
return
target
.<
Object
>
invoke
();
}
catch
(
Throwable
t
)
{
if
(!
exType
.
isInstance
(
t
))
throw
t
;
return
catcher
.<
Object
>
invoke
(
t
);
}
}
private
Object
invoke_L1
(
Object
a0
)
throws
Throwable
{
try
{
return
target
.<
Object
>
invoke
(
a0
);
}
catch
(
Throwable
t
)
{
if
(!
exType
.
isInstance
(
t
))
throw
t
;
return
catcher
.<
Object
>
invoke
(
t
,
a0
);
}
}
private
Object
invoke_L2
(
Object
a0
,
Object
a1
)
throws
Throwable
{
try
{
return
target
.<
Object
>
invoke
(
a0
,
a1
);
}
catch
(
Throwable
t
)
{
if
(!
exType
.
isInstance
(
t
))
throw
t
;
return
catcher
.<
Object
>
invoke
(
t
,
a0
,
a1
);
}
}
private
Object
invoke_L3
(
Object
a0
,
Object
a1
,
Object
a2
)
throws
Throwable
{
try
{
return
target
.<
Object
>
invoke
(
a0
,
a1
,
a2
);
}
catch
(
Throwable
t
)
{
if
(!
exType
.
isInstance
(
t
))
throw
t
;
return
catcher
.<
Object
>
invoke
(
t
,
a0
,
a1
,
a2
);
}
}
private
Object
invoke_L4
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
)
throws
Throwable
{
try
{
return
target
.<
Object
>
invoke
(
a0
,
a1
,
a2
,
a3
);
}
catch
(
Throwable
t
)
{
if
(!
exType
.
isInstance
(
t
))
throw
t
;
return
catcher
.<
Object
>
invoke
(
t
,
a0
,
a1
,
a2
,
a3
);
}
}
private
Object
invoke_L5
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
)
throws
Throwable
{
try
{
return
target
.<
Object
>
invoke
(
a0
,
a1
,
a2
,
a3
,
a4
);
}
catch
(
Throwable
t
)
{
if
(!
exType
.
isInstance
(
t
))
throw
t
;
return
catcher
.<
Object
>
invoke
(
t
,
a0
,
a1
,
a2
,
a3
,
a4
);
}
}
private
Object
invoke_L6
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
)
throws
Throwable
{
try
{
return
target
.<
Object
>
invoke
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
);
}
catch
(
Throwable
t
)
{
if
(!
exType
.
isInstance
(
t
))
throw
t
;
return
catcher
.<
Object
>
invoke
(
t
,
a0
,
a1
,
a2
,
a3
,
a4
,
a5
);
}
}
private
Object
invoke_L7
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
a6
)
throws
Throwable
{
try
{
return
target
.<
Object
>
invoke
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
);
}
catch
(
Throwable
t
)
{
if
(!
exType
.
isInstance
(
t
))
throw
t
;
return
catcher
.<
Object
>
invoke
(
t
,
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
);
}
}
private
Object
invoke_L8
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
a6
,
Object
a7
)
throws
Throwable
{
try
{
return
target
.<
Object
>
invoke
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
);
}
catch
(
Throwable
t
)
{
if
(!
exType
.
isInstance
(
t
))
throw
t
;
return
catcher
.<
Object
>
invoke
(
t
,
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
);
}
}
static
MethodHandle
[]
makeInvokes
()
{
ArrayList
<
MethodHandle
>
invokes
=
new
ArrayList
<
MethodHandle
>();
MethodHandles
.
Lookup
lookup
=
IMPL_LOOKUP
;
for
(;;)
{
int
nargs
=
invokes
.
size
();
String
name
=
"invoke_L"
+
nargs
;
MethodHandle
invoke
=
null
;
try
{
invoke
=
lookup
.
findVirtual
(
GuardWithCatch
.
class
,
name
,
MethodType
.
genericMethodType
(
nargs
));
}
catch
(
NoAccessException
ex
)
{
}
if
(
invoke
==
null
)
break
;
invokes
.
add
(
invoke
);
}
assert
(
invokes
.
size
()
==
9
);
// current number of methods
return
invokes
.
toArray
(
new
MethodHandle
[
0
]);
};
static
final
MethodHandle
[]
INVOKES
=
makeInvokes
();
// For testing use this:
//static final MethodHandle[] INVOKES = Arrays.copyOf(makeInvokes(), 2);
static
final
MethodHandle
VARARGS_INVOKE
;
static
{
try
{
VARARGS_INVOKE
=
IMPL_LOOKUP
.
findVirtual
(
GuardWithCatch
.
class
,
"invoke_V"
,
MethodType
.
genericMethodType
(
0
,
true
));
}
catch
(
NoAccessException
ex
)
{
throw
new
InternalError
(
""
);
}
}
}
public
static
MethodHandle
makeGuardWithCatch
(
Access
token
,
MethodHandle
target
,
Class
<?
extends
Throwable
>
exType
,
MethodHandle
catcher
)
{
Access
.
check
(
token
);
Access
.
check
(
token
);
// %%% This is just a sketch. It needs to be de-boxed.
// Adjust the handles to accept varargs lists.
MethodType
type
=
target
.
type
();
MethodType
type
=
target
.
type
();
Class
<?>
rtype
=
type
.
returnType
();
MethodType
ctype
=
catcher
.
type
();
if
(
type
.
parameterCount
()
!=
1
||
type
.
parameterType
(
0
).
isPrimitive
())
{
int
nargs
=
type
.
parameterCount
();
MethodType
vatestType
=
MethodType
.
make
(
boolean
.
class
,
Object
[].
class
);
if
(
nargs
<
GuardWithCatch
.
INVOKES
.
length
)
{
MethodType
vatargetType
=
MethodType
.
make
(
rtype
,
Object
[].
class
);
MethodType
gtype
=
type
.
generic
();
MethodHandle
vaguard
=
makeGuardWithTest
(
token
,
MethodType
gcatchType
=
gtype
.
insertParameterTypes
(
0
,
Throwable
.
class
);
MethodHandles
.
spreadArguments
(
test
,
vatestType
),
MethodHandle
gtarget
=
convertArguments
(
token
,
target
,
gtype
,
type
,
null
);
MethodHandles
.
spreadArguments
(
target
,
vatargetType
),
MethodHandle
gcatcher
=
convertArguments
(
token
,
catcher
,
gcatchType
,
ctype
,
null
);
MethodHandles
.
spreadArguments
(
fallback
,
vatargetType
));
MethodHandle
gguard
=
new
GuardWithCatch
(
gtarget
,
exType
,
gcatcher
);
return
MethodHandles
.
collectArguments
(
vaguard
,
type
);
if
(
gtarget
==
null
||
gcatcher
==
null
||
gguard
==
null
)
return
null
;
}
return
convertArguments
(
token
,
gguard
,
type
,
gtype
,
null
);
if
(
rtype
.
isPrimitive
())
{
}
else
{
MethodType
boxtype
=
type
.
changeReturnType
(
Object
.
class
);
MethodType
gtype
=
MethodType
.
genericMethodType
(
0
,
true
);
MethodHandle
boxguard
=
makeGuardWithTest
(
token
,
MethodType
gcatchType
=
gtype
.
insertParameterTypes
(
0
,
Throwable
.
class
);
test
,
MethodHandle
gtarget
=
spreadArguments
(
token
,
target
,
gtype
,
0
);
MethodHandles
.
convertArguments
(
target
,
boxtype
),
MethodHandle
gcatcher
=
spreadArguments
(
token
,
catcher
,
gcatchType
,
1
);
MethodHandles
.
convertArguments
(
fallback
,
boxtype
));
MethodHandle
gguard
=
new
GuardWithCatch
(
GuardWithCatch
.
VARARGS_INVOKE
,
gtarget
,
exType
,
gcatcher
);
return
MethodHandles
.
convertArguments
(
boxguard
,
type
);
if
(
gtarget
==
null
||
gcatcher
==
null
||
gguard
==
null
)
return
null
;
}
return
collectArguments
(
token
,
gguard
,
type
,
0
,
null
);
// Got here? Reduced calling sequence to Object(Object).
}
class
Guarder
{
Object
invoke
(
Object
x
)
{
// If javac supports MethodHandle.invoke directly:
//z = vatest.invoke<boolean>(arguments);
// If javac does not support direct MH.invoke calls:
boolean
z
=
(
Boolean
)
MethodHandles
.
invoke_1
(
test
,
x
);
MethodHandle
mh
=
(
z
?
target
:
fallback
);
return
MethodHandles
.
invoke_1
(
mh
,
x
);
}
MethodHandle
handle
()
{
MethodType
invokeType
=
MethodType
.
makeGeneric
(
0
,
true
);
MethodHandle
vh
=
IMPL_LOOKUP
.
bind
(
this
,
"invoke"
,
invokeType
);
return
MethodHandles
.
collectArguments
(
vh
,
target
.
type
());
}
}
return
new
Guarder
().
handle
();
}
}
public
static
public
static
MethodHandle
combineArguments
(
Access
token
,
MethodHandle
target
,
MethodHandle
checker
,
int
pos
)
{
MethodHandle
throwException
(
Access
token
,
MethodType
type
)
{
Access
.
check
(
token
);
Access
.
check
(
token
);
throw
new
UnsupportedOperationException
(
"Not yet implemented"
);
return
AdapterMethodHandle
.
makeRetypeRaw
(
token
,
type
,
THROW_EXCEPTION
);
}
}
protected
static
String
basicToString
(
MethodHandle
target
)
{
static
final
MethodHandle
THROW_EXCEPTION
=
IMPL_LOOKUP
.
findStatic
(
MethodHandleImpl
.
class
,
"throwException"
,
MethodType
.
methodType
(
Empty
.
class
,
Throwable
.
class
));
static
<
T
extends
Throwable
>
Empty
throwException
(
T
t
)
throws
T
{
throw
t
;
}
public
static
String
getNameString
(
Access
token
,
MethodHandle
target
)
{
Access
.
check
(
token
);
MemberName
name
=
null
;
MemberName
name
=
null
;
if
(
target
!=
null
)
if
(
target
!=
null
)
name
=
MethodHandleNatives
.
getMethodName
(
target
);
name
=
MethodHandleNatives
.
getMethodName
(
target
);
...
@@ -357,17 +1080,30 @@ public abstract class MethodHandleImpl {
...
@@ -357,17 +1080,30 @@ public abstract class MethodHandleImpl {
return
name
.
getName
();
return
name
.
getName
();
}
}
p
rotected
static
String
addTypeString
(
MethodHandle
target
,
String
name
)
{
p
ublic
static
String
addTypeString
(
MethodHandle
target
)
{
if
(
target
==
null
)
return
name
;
if
(
target
==
null
)
return
"null"
;
return
name
+
target
.
type
();
return
target
.
toString
()
+
target
.
type
();
}
}
static
RuntimeException
newIllegalArgumentException
(
String
string
)
{
return
new
IllegalArgumentException
(
string
);
public
static
void
checkSpreadArgument
(
Object
av
,
int
n
)
{
if
(
av
==
null
?
n
!=
0
:
((
Object
[])
av
).
length
!=
n
)
throw
newIllegalArgumentException
(
"Array is not of length "
+
n
);
}
}
@Override
public
static
void
raiseException
(
int
code
,
Object
actual
,
Object
required
)
{
public
String
toString
()
{
String
message
;
MethodHandle
self
=
(
MethodHandle
)
this
;
// disregard the identity of the actual object, if it is not a class:
return
addTypeString
(
self
,
basicToString
(
self
));
if
(!(
actual
instanceof
Class
)
&&
!(
actual
instanceof
MethodType
))
actual
=
actual
.
getClass
();
if
(
actual
!=
null
)
message
=
"required "
+
required
+
" but encountered "
+
actual
;
else
message
=
"required "
+
required
;
switch
(
code
)
{
case
192
:
// checkcast
throw
new
ClassCastException
(
message
);
default
:
throw
new
InternalError
(
"unexpected code "
+
code
+
": "
+
message
);
}
}
}
}
}
src/share/classes/sun/dyn/MethodHandleNatives.java
浏览文件 @
8992d5c6
...
@@ -25,6 +25,7 @@
...
@@ -25,6 +25,7 @@
package
sun.dyn
;
package
sun.dyn
;
import
java.dyn.CallSite
;
import
java.dyn.MethodHandle
;
import
java.dyn.MethodHandle
;
import
java.dyn.MethodType
;
import
java.dyn.MethodType
;
import
java.lang.reflect.AccessibleObject
;
import
java.lang.reflect.AccessibleObject
;
...
@@ -60,7 +61,7 @@ class MethodHandleNatives {
...
@@ -60,7 +61,7 @@ class MethodHandleNatives {
static
native
void
init
(
MethodType
self
);
static
native
void
init
(
MethodType
self
);
/** Tell the JVM that we need to change the target of an invokedynamic. */
/** Tell the JVM that we need to change the target of an invokedynamic. */
static
native
void
linkCallSite
(
CallSite
Impl
site
,
MethodHandle
target
);
static
native
void
linkCallSite
(
CallSite
site
,
MethodHandle
target
);
/** Fetch the vmtarget field.
/** Fetch the vmtarget field.
* It will be sanitized as necessary to avoid exposing non-Java references.
* It will be sanitized as necessary to avoid exposing non-Java references.
...
@@ -84,8 +85,7 @@ class MethodHandleNatives {
...
@@ -84,8 +85,7 @@ class MethodHandleNatives {
}
}
/** Fetch the target of this method handle.
/** Fetch the target of this method handle.
* If it directly targets a method, return a tuple of method info.
* If it directly targets a method, return a MemberName for the method.
* The info is of the form new Object[]{defclass, name, sig, refclass}.
* If it is chained to another method handle, return that handle.
* If it is chained to another method handle, return that handle.
*/
*/
static
Object
getTargetInfo
(
MethodHandle
self
)
{
static
Object
getTargetInfo
(
MethodHandle
self
)
{
...
@@ -123,7 +123,7 @@ class MethodHandleNatives {
...
@@ -123,7 +123,7 @@ class MethodHandleNatives {
registerNatives
();
registerNatives
();
JVM_SUPPORT_
=
true
;
JVM_SUPPORT_
=
true
;
JVM_PUSH_LIMIT_
=
getConstant
(
Constants
.
GC_JVM_PUSH_LIMIT
);
JVM_PUSH_LIMIT_
=
getConstant
(
Constants
.
GC_JVM_PUSH_LIMIT
);
JVM_STACK_MOVE_UNIT_
=
getConstant
(
Constants
.
GC_JVM_STACK_MOVE_
LIM
IT
);
JVM_STACK_MOVE_UNIT_
=
getConstant
(
Constants
.
GC_JVM_STACK_MOVE_
UN
IT
);
//sun.reflect.Reflection.registerMethodsToFilter(MethodHandleImpl.class, "init");
//sun.reflect.Reflection.registerMethodsToFilter(MethodHandleImpl.class, "init");
}
catch
(
UnsatisfiedLinkError
ee
)
{
}
catch
(
UnsatisfiedLinkError
ee
)
{
// ignore; if we use init() methods later we'll see linkage errors
// ignore; if we use init() methods later we'll see linkage errors
...
@@ -149,7 +149,7 @@ class MethodHandleNatives {
...
@@ -149,7 +149,7 @@ class MethodHandleNatives {
// MethodHandleImpl
// MethodHandleImpl
static
final
int
// for getConstant
static
final
int
// for getConstant
GC_JVM_PUSH_LIMIT
=
0
,
GC_JVM_PUSH_LIMIT
=
0
,
GC_JVM_STACK_MOVE_
LIM
IT
=
1
;
GC_JVM_STACK_MOVE_
UN
IT
=
1
;
static
final
int
static
final
int
ETF_HANDLE_OR_METHOD_NAME
=
0
,
// all available data (immediate MH or method)
ETF_HANDLE_OR_METHOD_NAME
=
0
,
// all available data (immediate MH or method)
ETF_DIRECT_HANDLE
=
1
,
// ultimate method handle (will be a DMH, may be self)
ETF_DIRECT_HANDLE
=
1
,
// ultimate method handle (will be a DMH, may be self)
...
@@ -178,19 +178,20 @@ class MethodHandleNatives {
...
@@ -178,19 +178,20 @@ class MethodHandleNatives {
*/
*/
static
final
int
static
final
int
OP_RETYPE_ONLY
=
0x0
,
// no argument changes; straight retype
OP_RETYPE_ONLY
=
0x0
,
// no argument changes; straight retype
OP_CHECK_CAST
=
0x1
,
// ref-to-ref conversion; requires a Class argument
OP_RETYPE_RAW
=
0x1
,
// no argument changes; straight retype
OP_PRIM_TO_PRIM
=
0x2
,
// converts from one primitive to another
OP_CHECK_CAST
=
0x2
,
// ref-to-ref conversion; requires a Class argument
OP_REF_TO_PRIM
=
0x3
,
// unboxes a wrapper to produce a primitive
OP_PRIM_TO_PRIM
=
0x3
,
// converts from one primitive to another
OP_PRIM_TO_REF
=
0x4
,
// boxes a primitive into a wrapper (NYI)
OP_REF_TO_PRIM
=
0x4
,
// unboxes a wrapper to produce a primitive
OP_SWAP_ARGS
=
0x5
,
// swap arguments (vminfo is 2nd arg)
OP_PRIM_TO_REF
=
0x5
,
// boxes a primitive into a wrapper (NYI)
OP_ROT_ARGS
=
0x6
,
// rotate arguments (vminfo is displaced arg)
OP_SWAP_ARGS
=
0x6
,
// swap arguments (vminfo is 2nd arg)
OP_DUP_ARGS
=
0x7
,
// duplicates one or more arguments (at TOS)
OP_ROT_ARGS
=
0x7
,
// rotate arguments (vminfo is displaced arg)
OP_DROP_ARGS
=
0x8
,
// remove one or more argument slots
OP_DUP_ARGS
=
0x8
,
// duplicates one or more arguments (at TOS)
OP_COLLECT_ARGS
=
0x9
,
// combine one or more arguments into a varargs (NYI)
OP_DROP_ARGS
=
0x9
,
// remove one or more argument slots
OP_SPREAD_ARGS
=
0xA
,
// expand in place a varargs array (of known size)
OP_COLLECT_ARGS
=
0xA
,
// combine one or more arguments into a varargs (NYI)
OP_FLYBY
=
0xB
,
// operate first on reified argument list (NYI)
OP_SPREAD_ARGS
=
0xB
,
// expand in place a varargs array (of known size)
OP_RICOCHET
=
0xC
,
// run an adapter chain on the return value (NYI)
OP_FLYBY
=
0xC
,
// operate first on reified argument list (NYI)
CONV_OP_LIMIT
=
0xD
;
// limit of CONV_OP enumeration
OP_RICOCHET
=
0xD
,
// run an adapter chain on the return value (NYI)
CONV_OP_LIMIT
=
0xE
;
// limit of CONV_OP enumeration
/** Shift and mask values for decoding the AMH.conversion field.
/** Shift and mask values for decoding the AMH.conversion field.
* These numbers are shared with the JVM for creating AMHs.
* These numbers are shared with the JVM for creating AMHs.
*/
*/
...
@@ -209,6 +210,7 @@ class MethodHandleNatives {
...
@@ -209,6 +210,7 @@ class MethodHandleNatives {
// TODO: The following expression should be replaced by
// TODO: The following expression should be replaced by
// a JVM query.
// a JVM query.
((
1
<<
OP_RETYPE_ONLY
)
((
1
<<
OP_RETYPE_ONLY
)
|(
1
<<
OP_RETYPE_RAW
)
|(
1
<<
OP_CHECK_CAST
)
|(
1
<<
OP_CHECK_CAST
)
|(
1
<<
OP_PRIM_TO_PRIM
)
|(
1
<<
OP_PRIM_TO_PRIM
)
|(
1
<<
OP_REF_TO_PRIM
)
|(
1
<<
OP_REF_TO_PRIM
)
...
@@ -216,6 +218,7 @@ class MethodHandleNatives {
...
@@ -216,6 +218,7 @@ class MethodHandleNatives {
|(
1
<<
OP_ROT_ARGS
)
|(
1
<<
OP_ROT_ARGS
)
|(
1
<<
OP_DUP_ARGS
)
|(
1
<<
OP_DUP_ARGS
)
|(
1
<<
OP_DROP_ARGS
)
|(
1
<<
OP_DROP_ARGS
)
//|(1<<OP_SPREAD_ARGS) // FIXME: Check JVM assembly code.
);
);
/**
/**
...
...
src/share/classes/sun/dyn/MethodTypeImpl.java
浏览文件 @
8992d5c6
...
@@ -27,6 +27,7 @@ package sun.dyn;
...
@@ -27,6 +27,7 @@ package sun.dyn;
import
java.dyn.*
;
import
java.dyn.*
;
import
sun.dyn.util.Wrapper
;
import
sun.dyn.util.Wrapper
;
import
static
sun
.
dyn
.
MemberName
.
newIllegalArgumentException
;
/**
/**
* Shared information for a group of method types, which differ
* Shared information for a group of method types, which differ
...
@@ -56,8 +57,8 @@ public class MethodTypeImpl {
...
@@ -56,8 +57,8 @@ public class MethodTypeImpl {
// Cached adapter information:
// Cached adapter information:
/*lazy*/
ToGeneric
toGeneric
;
// convert cs. with prims to w/o
/*lazy*/
ToGeneric
toGeneric
;
// convert cs. with prims to w/o
/*lazy*/
FromGeneric
fromGeneric
;
// convert cs. w/o prims to with
/*lazy*/
FromGeneric
fromGeneric
;
// convert cs. w/o prims to with
/*lazy*/
SpreadGeneric
[]
spreadGeneric
;
// expand one argument to many
/*lazy*/
FilterGeneric
filterGeneric
;
// convert argument(s) on the fly
/*lazy*/
FilterGeneric
filterGeneric
;
// convert argument(s) on the fly
///*lazy*/ Invokers invokers; // cache of handy higher-order adapters
public
MethodType
erasedType
()
{
public
MethodType
erasedType
()
{
return
erasedType
;
return
erasedType
;
...
@@ -68,7 +69,7 @@ public class MethodTypeImpl {
...
@@ -68,7 +69,7 @@ public class MethodTypeImpl {
}
}
/** Access methods for the internals of MethodType, supplied to
/** Access methods for the internals of MethodType, supplied to
* MethodType
Form
as a trusted agent.
* MethodType
Impl
as a trusted agent.
*/
*/
static
public
interface
MethodTypeFriend
{
static
public
interface
MethodTypeFriend
{
Class
<?>[]
ptypes
(
MethodType
mt
);
Class
<?>[]
ptypes
(
MethodType
mt
);
...
@@ -150,7 +151,7 @@ public class MethodTypeImpl {
...
@@ -150,7 +151,7 @@ public class MethodTypeImpl {
this
.
argToSlotTable
=
argToSlotTab
;
this
.
argToSlotTable
=
argToSlotTab
;
this
.
slotToArgTable
=
slotToArgTab
;
this
.
slotToArgTable
=
slotToArgTab
;
if
(
pslotCount
>=
256
)
throw
new
IllegalArgumentException
(
"too many arguments"
);
if
(
pslotCount
>=
256
)
throw
newIllegalArgumentException
(
"too many arguments"
);
// send a few bits down to the JVM:
// send a few bits down to the JVM:
this
.
vmslots
=
parameterSlotCount
();
this
.
vmslots
=
parameterSlotCount
();
...
@@ -378,10 +379,10 @@ public class MethodTypeImpl {
...
@@ -378,10 +379,10 @@ public class MethodTypeImpl {
static
MethodTypeImpl
findForm
(
MethodType
mt
)
{
static
MethodTypeImpl
findForm
(
MethodType
mt
)
{
MethodType
erased
=
canonicalize
(
mt
,
ERASE
,
ERASE
);
MethodType
erased
=
canonicalize
(
mt
,
ERASE
,
ERASE
);
if
(
erased
==
null
)
{
if
(
erased
==
null
)
{
// It is already erased. Make a new MethodType
Form
.
// It is already erased. Make a new MethodType
Impl
.
return
METHOD_TYPE_FRIEND
.
newMethodTypeForm
(
mt
);
return
METHOD_TYPE_FRIEND
.
newMethodTypeForm
(
mt
);
}
else
{
}
else
{
// Share the MethodType
Form
with the erased version.
// Share the MethodType
Impl
with the erased version.
return
METHOD_TYPE_FRIEND
.
form
(
erased
);
return
METHOD_TYPE_FRIEND
.
form
(
erased
);
}
}
}
}
...
...
src/share/classes/sun/dyn/SpreadGeneric.java
0 → 100644
浏览文件 @
8992d5c6
/*
* Copyright 2008-2009 Sun Microsystems, Inc. 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. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
package
sun.dyn
;
import
java.dyn.JavaMethodHandle
;
import
java.dyn.MethodHandle
;
import
java.dyn.MethodHandles
;
import
java.dyn.MethodType
;
import
java.dyn.NoAccessException
;
import
java.lang.reflect.Constructor
;
import
java.lang.reflect.InvocationTargetException
;
import
java.util.ArrayList
;
import
sun.dyn.util.ValueConversions
;
import
static
sun
.
dyn
.
MemberName
.
newIllegalArgumentException
;
/**
* Generic spread adapter.
* Expands a final argument into multiple (zero or more) arguments, keeping the others the same.
* @author jrose
*/
class
SpreadGeneric
{
// type for the outgoing call
private
final
MethodType
targetType
;
// number of arguments to spread
private
final
int
spreadCount
;
// prototype adapter (clone and customize for each new target!)
private
final
Adapter
adapter
;
// entry point for adapter (Adapter mh, a...) => ...
private
final
MethodHandle
entryPoint
;
/** Compute and cache information common to all spreading adapters
* that accept calls of the given (generic) type.
*/
private
SpreadGeneric
(
MethodType
targetType
,
int
spreadCount
)
{
assert
(
targetType
==
targetType
.
generic
());
this
.
targetType
=
targetType
;
this
.
spreadCount
=
spreadCount
;
// the target invoker will generally need casts on reference arguments
MethodHandle
[]
ep
=
{
null
};
Adapter
ad
=
findAdapter
(
this
,
ep
);
if
(
ad
!=
null
)
{
this
.
adapter
=
ad
;
this
.
entryPoint
=
ep
[
0
];
return
;
}
this
.
adapter
=
buildAdapterFromBytecodes
(
targetType
,
spreadCount
,
ep
);
this
.
entryPoint
=
ep
[
0
];
}
/** From targetType remove the last spreadCount arguments, and instead
* append a simple Object argument.
*/
static
MethodType
preSpreadType
(
MethodType
targetType
,
int
spreadCount
)
{
@SuppressWarnings
(
"unchecked"
)
ArrayList
<
Class
<?>>
params
=
new
ArrayList
(
targetType
.
parameterList
());
int
outargs
=
params
.
size
();
params
.
subList
(
outargs
-
spreadCount
,
outargs
).
clear
();
params
.
add
(
Object
.
class
);
return
MethodType
.
methodType
(
targetType
.
returnType
(),
params
);
}
MethodHandle
makeInstance
(
MethodHandle
target
)
{
MethodType
type
=
target
.
type
();
if
(
type
!=
targetType
)
{
throw
new
UnsupportedOperationException
(
"NYI type="
+
type
);
}
return
adapter
.
makeInstance
(
this
,
target
);
}
/** Build an adapter of the given generic type, which invokes typedTarget
* on the incoming arguments, after unboxing as necessary.
* The return value is boxed if necessary.
* @param genericType the required type of the result
* @param typedTarget the target
* @return an adapter method handle
*/
public
static
MethodHandle
make
(
MethodHandle
target
,
int
spreadCount
)
{
MethodType
type
=
target
.
type
();
MethodType
gtype
=
type
.
generic
();
if
(
type
==
gtype
)
{
return
SpreadGeneric
.
of
(
type
,
spreadCount
).
makeInstance
(
target
);
}
else
{
MethodHandle
gtarget
=
FromGeneric
.
make
(
target
);
assert
(
gtarget
.
type
()
==
gtype
);
MethodHandle
gspread
=
SpreadGeneric
.
of
(
gtype
,
spreadCount
).
makeInstance
(
gtarget
);
return
ToGeneric
.
make
(
preSpreadType
(
type
,
spreadCount
),
gspread
);
}
}
/** Return the adapter information for this type's erasure. */
static
SpreadGeneric
of
(
MethodType
targetType
,
int
spreadCount
)
{
if
(
targetType
!=
targetType
.
generic
())
throw
new
UnsupportedOperationException
(
"NYI type="
+
targetType
);
MethodTypeImpl
form
=
MethodTypeImpl
.
of
(
targetType
);
int
outcount
=
form
.
parameterCount
();
assert
(
spreadCount
<=
outcount
);
SpreadGeneric
[]
spreadGens
=
form
.
spreadGeneric
;
if
(
spreadGens
==
null
)
form
.
spreadGeneric
=
spreadGens
=
new
SpreadGeneric
[
outcount
+
1
];
SpreadGeneric
spreadGen
=
spreadGens
[
spreadCount
];
if
(
spreadGen
==
null
)
spreadGens
[
spreadCount
]
=
spreadGen
=
new
SpreadGeneric
(
form
.
erasedType
(),
spreadCount
);
return
spreadGen
;
}
public
String
toString
()
{
return
getClass
().
getSimpleName
()+
targetType
+
"["
+
spreadCount
+
"]"
;
}
// This mini-api is called from an Adapter to manage the spread.
/** A check/coercion that happens once before any selections. */
protected
Object
check
(
Object
av
,
int
n
)
{
MethodHandleImpl
.
checkSpreadArgument
(
av
,
n
);
return
av
;
}
/** The selection operator for spreading; note that it takes Object not Object[]. */
protected
Object
select
(
Object
av
,
int
n
)
{
return
((
Object
[])
av
)[
n
];
}
/*
protected int select_I(Object av, int n) {
// maybe return ((int[])select)[n]
throw new UnsupportedOperationException("subclass resp.");
}
protected int select_J(Object av, int n) {
// maybe return ((long[])select)[n]
throw new UnsupportedOperationException("subclass resp.");
}
// */
/* Create an adapter that handles spreading calls for the given type. */
static
Adapter
findAdapter
(
SpreadGeneric
outer
,
MethodHandle
[]
ep
)
{
MethodType
targetType
=
outer
.
targetType
;
int
spreadCount
=
outer
.
spreadCount
;
int
outargs
=
targetType
.
parameterCount
();
int
inargs
=
outargs
-
spreadCount
;
if
(
inargs
<
0
)
return
null
;
MethodType
entryType
=
MethodType
.
genericMethodType
(
inargs
+
1
);
// 1 for av
String
cname1
=
"S"
+
outargs
;
String
[]
cnames
=
{
cname1
};
String
iname
=
"invoke_S"
+
spreadCount
;
// e.g., D5I2, D5, L5I2, L5; invoke_D5
for
(
String
cname
:
cnames
)
{
Class
<?
extends
Adapter
>
acls
=
Adapter
.
findSubClass
(
cname
);
if
(
acls
==
null
)
continue
;
// see if it has the required invoke method
MethodHandle
entryPoint
=
null
;
try
{
entryPoint
=
MethodHandleImpl
.
IMPL_LOOKUP
.
findSpecial
(
acls
,
iname
,
entryType
,
acls
);
}
catch
(
NoAccessException
ex
)
{
}
if
(
entryPoint
==
null
)
continue
;
Constructor
<?
extends
Adapter
>
ctor
=
null
;
try
{
ctor
=
acls
.
getDeclaredConstructor
(
SpreadGeneric
.
class
);
}
catch
(
NoSuchMethodException
ex
)
{
}
catch
(
SecurityException
ex
)
{
}
if
(
ctor
==
null
)
continue
;
try
{
// Produce an instance configured as a prototype.
Adapter
ad
=
ctor
.
newInstance
(
outer
);
ep
[
0
]
=
entryPoint
;
return
ad
;
}
catch
(
IllegalArgumentException
ex
)
{
}
catch
(
InvocationTargetException
wex
)
{
Throwable
ex
=
wex
.
getTargetException
();
if
(
ex
instanceof
Error
)
throw
(
Error
)
ex
;
if
(
ex
instanceof
RuntimeException
)
throw
(
RuntimeException
)
ex
;
}
catch
(
InstantiationException
ex
)
{
}
catch
(
IllegalAccessException
ex
)
{
}
}
return
null
;
}
static
Adapter
buildAdapterFromBytecodes
(
MethodType
targetType
,
int
spreadCount
,
MethodHandle
[]
ep
)
{
throw
new
UnsupportedOperationException
(
"NYI"
);
}
/**
* This adapter takes some untyped arguments, and returns an untyped result.
* Internally, it applies the invoker to the target, which causes the
* objects to be unboxed; the result is a raw type in L/I/J/F/D.
* This result is passed to convert, which is responsible for
* converting the raw result into a boxed object.
* The invoker is kept separate from the target because it can be
* generated once per type erasure family, and reused across adapters.
*/
static
abstract
class
Adapter
extends
JavaMethodHandle
{
/*
* class X<<R,int M,int N>> extends Adapter {
* (Object**N)=>R target;
* static int S = N-M;
* Object invoke(Object**M a, Object v) = target(a..., v[0]...v[S-1]);
* }
*/
protected
final
SpreadGeneric
outer
;
protected
final
MethodHandle
target
;
// (any**N) => R
@Override
public
String
toString
()
{
return
target
.
toString
();
}
static
final
MethodHandle
NO_ENTRY
=
ValueConversions
.
identity
();
protected
boolean
isPrototype
()
{
return
target
==
null
;
}
protected
Adapter
(
SpreadGeneric
outer
)
{
super
(
NO_ENTRY
);
this
.
outer
=
outer
;
this
.
target
=
null
;
assert
(
isPrototype
());
}
protected
Adapter
(
SpreadGeneric
outer
,
MethodHandle
target
)
{
super
(
outer
.
entryPoint
);
this
.
outer
=
outer
;
this
.
target
=
target
;
}
/** Make a copy of self, with new fields. */
protected
abstract
Adapter
makeInstance
(
SpreadGeneric
outer
,
MethodHandle
target
);
// { return new ThisType(outer, target); }
protected
Object
check
(
Object
av
,
int
n
)
{
return
outer
.
check
(
av
,
n
);
}
protected
Object
select
(
Object
av
,
int
n
)
{
return
outer
.
select
(
av
,
n
);
}
static
private
final
String
CLASS_PREFIX
;
// "sun.dyn.SpreadGeneric$"
static
{
String
aname
=
Adapter
.
class
.
getName
();
String
sname
=
Adapter
.
class
.
getSimpleName
();
if
(!
aname
.
endsWith
(
sname
))
throw
new
InternalError
();
CLASS_PREFIX
=
aname
.
substring
(
0
,
aname
.
length
()
-
sname
.
length
());
}
/** Find a sibing class of Adapter. */
static
Class
<?
extends
Adapter
>
findSubClass
(
String
name
)
{
String
cname
=
Adapter
.
CLASS_PREFIX
+
name
;
try
{
return
Class
.
forName
(
cname
).
asSubclass
(
Adapter
.
class
);
}
catch
(
ClassNotFoundException
ex
)
{
return
null
;
}
catch
(
ClassCastException
ex
)
{
return
null
;
}
}
}
/* generated classes follow this pattern:
static class xS2 extends Adapter {
protected xS2(SpreadGeneric outer) { super(outer); } // to build prototype
protected xS2(SpreadGeneric outer, MethodHandle t) { super(outer, t); }
protected xS2 makeInstance(SpreadGeneric outer, MethodHandle t) { return new xS2(outer, t); }
protected Object invoke_S0(Object a0, Object a1, Object av) throws Throwable { av = super.check(av,0);
return target.<Object>invoke(a0, a1)); }
protected Object invoke_S1(Object a0, Object av) throws Throwable { av = super.check(av,1);
return target.<Object>invoke(a0,
super.select(av,0)); }
protected Object invoke_S2(Object a0, Object av) throws Throwable { av = super.check(av,1);
return target.<Object>invoke(
super.select(av,0), super.select(av,1)); }
}
// */
/*
: SHELL; n=SpreadGeneric; cp -p $n.java $n.java-; sed < $n.java- > $n.java+ -e '/{{*{{/,/}}*}}/w /tmp/genclasses.java' -e '/}}*}}/q'; (cd /tmp; javac -d . genclasses.java; java -cp . genclasses) >> $n.java+; echo '}' >> $n.java+; mv $n.java+ $n.java; mv $n.java- $n.java~
//{{{
import java.util.*;
class genclasses {
static String[][] TEMPLATES = { {
"@for@ N=0..10",
" //@each-cat@",
" static class @cat@ extends Adapter {",
" protected @cat@(SpreadGeneric outer) { super(outer); } // to build prototype",
" protected @cat@(SpreadGeneric outer, MethodHandle t) { super(outer, t); }",
" protected @cat@ makeInstance(SpreadGeneric outer, MethodHandle t) { return new @cat@(outer, t); }",
" protected Object invoke_S0(@Tvav,@Object av) throws Throwable { av = super.check(av, 0);",
" return target.<Object>invoke(@av@); }",
" //@each-S@",
" protected Object invoke_S@S@(@Tvav,@Object av) throws Throwable { av = super.check(av, @S@);",
" return target.<Object>invoke(@av,@@sv@); }",
" //@end-S@",
" }",
} };
static final String NEWLINE_INDENT = "\n ";
enum VAR {
cat, N, S, av, av_, Tvav_, sv;
public final String pattern = "@"+toString().replace('_','.')+"@";
public String binding = toString();
static void makeBindings(boolean topLevel, int outargs, int spread) {
int inargs = outargs - spread;
VAR.cat.binding = "S"+outargs;
VAR.N.binding = String.valueOf(outargs); // outgoing arg count
VAR.S.binding = String.valueOf(spread); // spread count
String[] av = new String[inargs];
String[] Tvav = new String[inargs];
for (int i = 0; i < inargs; i++) {
av[i] = arg(i);
Tvav[i] = param("Object", av[i]);
}
VAR.av.binding = comma(av);
VAR.av_.binding = comma(av, ", ");
VAR.Tvav_.binding = comma(Tvav, ", ");
String[] sv = new String[spread];
for (int i = 0; i < spread; i++) {
String spc = "";
if (i % 4 == 0) spc = NEWLINE_INDENT;
sv[i] = spc+"super.select(av,"+i+")";
}
VAR.sv.binding = comma(sv);
}
static String arg(int i) { return "a"+i; }
static String param(String t, String a) { return t+" "+a; }
static String comma(String[] v) { return comma(v, ""); }
static String comma(String[] v, String sep) {
if (v.length == 0) return "";
String res = v[0];
for (int i = 1; i < v.length; i++) res += ", "+v[i];
return res + sep;
}
static String transform(String string) {
for (VAR var : values())
string = string.replaceAll(var.pattern, var.binding);
return string;
}
}
static String[] stringsIn(String[] strings, int beg, int end) {
return Arrays.copyOfRange(strings, beg, Math.min(end, strings.length));
}
static String[] stringsBefore(String[] strings, int pos) {
return stringsIn(strings, 0, pos);
}
static String[] stringsAfter(String[] strings, int pos) {
return stringsIn(strings, pos, strings.length);
}
static int indexAfter(String[] strings, int pos, String tag) {
return Math.min(indexBefore(strings, pos, tag) + 1, strings.length);
}
static int indexBefore(String[] strings, int pos, String tag) {
for (int i = pos, end = strings.length; ; i++) {
if (i == end || strings[i].endsWith(tag)) return i;
}
}
static int MIN_ARITY, MAX_ARITY;
public static void main(String... av) {
for (String[] template : TEMPLATES) {
int forLinesLimit = indexBefore(template, 0, "@each-cat@");
String[] forLines = stringsBefore(template, forLinesLimit);
template = stringsAfter(template, forLinesLimit);
for (String forLine : forLines)
expandTemplate(forLine, template);
}
}
static void expandTemplate(String forLine, String[] template) {
String[] params = forLine.split("[^0-9]+");
if (params[0].length() == 0) params = stringsAfter(params, 1);
System.out.println("//params="+Arrays.asList(params));
int pcur = 0;
MIN_ARITY = Integer.valueOf(params[pcur++]);
MAX_ARITY = Integer.valueOf(params[pcur++]);
if (pcur != params.length) throw new RuntimeException("bad extra param: "+forLine);
for (int outargs = MIN_ARITY; outargs <= MAX_ARITY; outargs++) {
expandTemplate(template, true, outargs, 0);
}
}
static void expandTemplate(String[] template, boolean topLevel, int outargs, int spread) {
VAR.makeBindings(topLevel, outargs, spread);
for (int i = 0; i < template.length; i++) {
String line = template[i];
if (line.endsWith("@each-cat@")) {
// ignore
} else if (line.endsWith("@each-S@")) {
int blockEnd = indexAfter(template, i, "@end-S@");
String[] block = stringsIn(template, i+1, blockEnd-1);
for (int spread1 = spread+1; spread1 <= outargs; spread1++)
expandTemplate(block, false, outargs, spread1);
VAR.makeBindings(topLevel, outargs, spread);
i = blockEnd-1; continue;
} else {
System.out.println(VAR.transform(line));
}
}
}
}
//}}} */
//params=[0, 10]
static
class
S0
extends
Adapter
{
protected
S0
(
SpreadGeneric
outer
)
{
super
(
outer
);
}
// to build prototype
protected
S0
(
SpreadGeneric
outer
,
MethodHandle
t
)
{
super
(
outer
,
t
);
}
protected
S0
makeInstance
(
SpreadGeneric
outer
,
MethodHandle
t
)
{
return
new
S0
(
outer
,
t
);
}
protected
Object
invoke_S0
(
Object
av
)
throws
Throwable
{
av
=
super
.
check
(
av
,
0
);
return
target
.<
Object
>
invoke
();
}
}
static
class
S1
extends
Adapter
{
protected
S1
(
SpreadGeneric
outer
)
{
super
(
outer
);
}
// to build prototype
protected
S1
(
SpreadGeneric
outer
,
MethodHandle
t
)
{
super
(
outer
,
t
);
}
protected
S1
makeInstance
(
SpreadGeneric
outer
,
MethodHandle
t
)
{
return
new
S1
(
outer
,
t
);
}
protected
Object
invoke_S0
(
Object
a0
,
Object
av
)
throws
Throwable
{
av
=
super
.
check
(
av
,
0
);
return
target
.<
Object
>
invoke
(
a0
);
}
protected
Object
invoke_S1
(
Object
av
)
throws
Throwable
{
av
=
super
.
check
(
av
,
1
);
return
target
.<
Object
>
invoke
(
super
.
select
(
av
,
0
));
}
}
static
class
S2
extends
Adapter
{
protected
S2
(
SpreadGeneric
outer
)
{
super
(
outer
);
}
// to build prototype
protected
S2
(
SpreadGeneric
outer
,
MethodHandle
t
)
{
super
(
outer
,
t
);
}
protected
S2
makeInstance
(
SpreadGeneric
outer
,
MethodHandle
t
)
{
return
new
S2
(
outer
,
t
);
}
protected
Object
invoke_S0
(
Object
a0
,
Object
a1
,
Object
av
)
throws
Throwable
{
av
=
super
.
check
(
av
,
0
);
return
target
.<
Object
>
invoke
(
a0
,
a1
);
}
protected
Object
invoke_S1
(
Object
a0
,
Object
av
)
throws
Throwable
{
av
=
super
.
check
(
av
,
1
);
return
target
.<
Object
>
invoke
(
a0
,
super
.
select
(
av
,
0
));
}
protected
Object
invoke_S2
(
Object
av
)
throws
Throwable
{
av
=
super
.
check
(
av
,
2
);
return
target
.<
Object
>
invoke
(
super
.
select
(
av
,
0
),
super
.
select
(
av
,
1
));
}
}
static
class
S3
extends
Adapter
{
protected
S3
(
SpreadGeneric
outer
)
{
super
(
outer
);
}
// to build prototype
protected
S3
(
SpreadGeneric
outer
,
MethodHandle
t
)
{
super
(
outer
,
t
);
}
protected
S3
makeInstance
(
SpreadGeneric
outer
,
MethodHandle
t
)
{
return
new
S3
(
outer
,
t
);
}
protected
Object
invoke_S0
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
av
)
throws
Throwable
{
av
=
super
.
check
(
av
,
0
);
return
target
.<
Object
>
invoke
(
a0
,
a1
,
a2
);
}
protected
Object
invoke_S1
(
Object
a0
,
Object
a1
,
Object
av
)
throws
Throwable
{
av
=
super
.
check
(
av
,
1
);
return
target
.<
Object
>
invoke
(
a0
,
a1
,
super
.
select
(
av
,
0
));
}
protected
Object
invoke_S2
(
Object
a0
,
Object
av
)
throws
Throwable
{
av
=
super
.
check
(
av
,
2
);
return
target
.<
Object
>
invoke
(
a0
,
super
.
select
(
av
,
0
),
super
.
select
(
av
,
1
));
}
protected
Object
invoke_S3
(
Object
av
)
throws
Throwable
{
av
=
super
.
check
(
av
,
3
);
return
target
.<
Object
>
invoke
(
super
.
select
(
av
,
0
),
super
.
select
(
av
,
1
),
super
.
select
(
av
,
2
));
}
}
static
class
S4
extends
Adapter
{
protected
S4
(
SpreadGeneric
outer
)
{
super
(
outer
);
}
// to build prototype
protected
S4
(
SpreadGeneric
outer
,
MethodHandle
t
)
{
super
(
outer
,
t
);
}
protected
S4
makeInstance
(
SpreadGeneric
outer
,
MethodHandle
t
)
{
return
new
S4
(
outer
,
t
);
}
protected
Object
invoke_S0
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
av
)
throws
Throwable
{
av
=
super
.
check
(
av
,
0
);
return
target
.<
Object
>
invoke
(
a0
,
a1
,
a2
,
a3
);
}
protected
Object
invoke_S1
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
av
)
throws
Throwable
{
av
=
super
.
check
(
av
,
1
);
return
target
.<
Object
>
invoke
(
a0
,
a1
,
a2
,
super
.
select
(
av
,
0
));
}
protected
Object
invoke_S2
(
Object
a0
,
Object
a1
,
Object
av
)
throws
Throwable
{
av
=
super
.
check
(
av
,
2
);
return
target
.<
Object
>
invoke
(
a0
,
a1
,
super
.
select
(
av
,
0
),
super
.
select
(
av
,
1
));
}
protected
Object
invoke_S3
(
Object
a0
,
Object
av
)
throws
Throwable
{
av
=
super
.
check
(
av
,
3
);
return
target
.<
Object
>
invoke
(
a0
,
super
.
select
(
av
,
0
),
super
.
select
(
av
,
1
),
super
.
select
(
av
,
2
));
}
protected
Object
invoke_S4
(
Object
av
)
throws
Throwable
{
av
=
super
.
check
(
av
,
4
);
return
target
.<
Object
>
invoke
(
super
.
select
(
av
,
0
),
super
.
select
(
av
,
1
),
super
.
select
(
av
,
2
),
super
.
select
(
av
,
3
));
}
}
static
class
S5
extends
Adapter
{
protected
S5
(
SpreadGeneric
outer
)
{
super
(
outer
);
}
// to build prototype
protected
S5
(
SpreadGeneric
outer
,
MethodHandle
t
)
{
super
(
outer
,
t
);
}
protected
S5
makeInstance
(
SpreadGeneric
outer
,
MethodHandle
t
)
{
return
new
S5
(
outer
,
t
);
}
protected
Object
invoke_S0
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
av
)
throws
Throwable
{
av
=
super
.
check
(
av
,
0
);
return
target
.<
Object
>
invoke
(
a0
,
a1
,
a2
,
a3
,
a4
);
}
protected
Object
invoke_S1
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
av
)
throws
Throwable
{
av
=
super
.
check
(
av
,
1
);
return
target
.<
Object
>
invoke
(
a0
,
a1
,
a2
,
a3
,
super
.
select
(
av
,
0
));
}
protected
Object
invoke_S2
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
av
)
throws
Throwable
{
av
=
super
.
check
(
av
,
2
);
return
target
.<
Object
>
invoke
(
a0
,
a1
,
a2
,
super
.
select
(
av
,
0
),
super
.
select
(
av
,
1
));
}
protected
Object
invoke_S3
(
Object
a0
,
Object
a1
,
Object
av
)
throws
Throwable
{
av
=
super
.
check
(
av
,
3
);
return
target
.<
Object
>
invoke
(
a0
,
a1
,
super
.
select
(
av
,
0
),
super
.
select
(
av
,
1
),
super
.
select
(
av
,
2
));
}
protected
Object
invoke_S4
(
Object
a0
,
Object
av
)
throws
Throwable
{
av
=
super
.
check
(
av
,
4
);
return
target
.<
Object
>
invoke
(
a0
,
super
.
select
(
av
,
0
),
super
.
select
(
av
,
1
),
super
.
select
(
av
,
2
),
super
.
select
(
av
,
3
));
}
protected
Object
invoke_S5
(
Object
av
)
throws
Throwable
{
av
=
super
.
check
(
av
,
5
);
return
target
.<
Object
>
invoke
(
super
.
select
(
av
,
0
),
super
.
select
(
av
,
1
),
super
.
select
(
av
,
2
),
super
.
select
(
av
,
3
),
super
.
select
(
av
,
4
));
}
}
static
class
S6
extends
Adapter
{
protected
S6
(
SpreadGeneric
outer
)
{
super
(
outer
);
}
// to build prototype
protected
S6
(
SpreadGeneric
outer
,
MethodHandle
t
)
{
super
(
outer
,
t
);
}
protected
S6
makeInstance
(
SpreadGeneric
outer
,
MethodHandle
t
)
{
return
new
S6
(
outer
,
t
);
}
protected
Object
invoke_S0
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
av
)
throws
Throwable
{
av
=
super
.
check
(
av
,
0
);
return
target
.<
Object
>
invoke
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
);
}
protected
Object
invoke_S1
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
av
)
throws
Throwable
{
av
=
super
.
check
(
av
,
1
);
return
target
.<
Object
>
invoke
(
a0
,
a1
,
a2
,
a3
,
a4
,
super
.
select
(
av
,
0
));
}
protected
Object
invoke_S2
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
av
)
throws
Throwable
{
av
=
super
.
check
(
av
,
2
);
return
target
.<
Object
>
invoke
(
a0
,
a1
,
a2
,
a3
,
super
.
select
(
av
,
0
),
super
.
select
(
av
,
1
));
}
protected
Object
invoke_S3
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
av
)
throws
Throwable
{
av
=
super
.
check
(
av
,
3
);
return
target
.<
Object
>
invoke
(
a0
,
a1
,
a2
,
super
.
select
(
av
,
0
),
super
.
select
(
av
,
1
),
super
.
select
(
av
,
2
));
}
protected
Object
invoke_S4
(
Object
a0
,
Object
a1
,
Object
av
)
throws
Throwable
{
av
=
super
.
check
(
av
,
4
);
return
target
.<
Object
>
invoke
(
a0
,
a1
,
super
.
select
(
av
,
0
),
super
.
select
(
av
,
1
),
super
.
select
(
av
,
2
),
super
.
select
(
av
,
3
));
}
protected
Object
invoke_S5
(
Object
a0
,
Object
av
)
throws
Throwable
{
av
=
super
.
check
(
av
,
5
);
return
target
.<
Object
>
invoke
(
a0
,
super
.
select
(
av
,
0
),
super
.
select
(
av
,
1
),
super
.
select
(
av
,
2
),
super
.
select
(
av
,
3
),
super
.
select
(
av
,
4
));
}
protected
Object
invoke_S6
(
Object
av
)
throws
Throwable
{
av
=
super
.
check
(
av
,
6
);
return
target
.<
Object
>
invoke
(
super
.
select
(
av
,
0
),
super
.
select
(
av
,
1
),
super
.
select
(
av
,
2
),
super
.
select
(
av
,
3
),
super
.
select
(
av
,
4
),
super
.
select
(
av
,
5
));
}
}
static
class
S7
extends
Adapter
{
protected
S7
(
SpreadGeneric
outer
)
{
super
(
outer
);
}
// to build prototype
protected
S7
(
SpreadGeneric
outer
,
MethodHandle
t
)
{
super
(
outer
,
t
);
}
protected
S7
makeInstance
(
SpreadGeneric
outer
,
MethodHandle
t
)
{
return
new
S7
(
outer
,
t
);
}
protected
Object
invoke_S0
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
a6
,
Object
av
)
throws
Throwable
{
av
=
super
.
check
(
av
,
0
);
return
target
.<
Object
>
invoke
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
);
}
protected
Object
invoke_S1
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
av
)
throws
Throwable
{
av
=
super
.
check
(
av
,
1
);
return
target
.<
Object
>
invoke
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
super
.
select
(
av
,
0
));
}
protected
Object
invoke_S2
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
av
)
throws
Throwable
{
av
=
super
.
check
(
av
,
2
);
return
target
.<
Object
>
invoke
(
a0
,
a1
,
a2
,
a3
,
a4
,
super
.
select
(
av
,
0
),
super
.
select
(
av
,
1
));
}
protected
Object
invoke_S3
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
av
)
throws
Throwable
{
av
=
super
.
check
(
av
,
3
);
return
target
.<
Object
>
invoke
(
a0
,
a1
,
a2
,
a3
,
super
.
select
(
av
,
0
),
super
.
select
(
av
,
1
),
super
.
select
(
av
,
2
));
}
protected
Object
invoke_S4
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
av
)
throws
Throwable
{
av
=
super
.
check
(
av
,
4
);
return
target
.<
Object
>
invoke
(
a0
,
a1
,
a2
,
super
.
select
(
av
,
0
),
super
.
select
(
av
,
1
),
super
.
select
(
av
,
2
),
super
.
select
(
av
,
3
));
}
protected
Object
invoke_S5
(
Object
a0
,
Object
a1
,
Object
av
)
throws
Throwable
{
av
=
super
.
check
(
av
,
5
);
return
target
.<
Object
>
invoke
(
a0
,
a1
,
super
.
select
(
av
,
0
),
super
.
select
(
av
,
1
),
super
.
select
(
av
,
2
),
super
.
select
(
av
,
3
),
super
.
select
(
av
,
4
));
}
protected
Object
invoke_S6
(
Object
a0
,
Object
av
)
throws
Throwable
{
av
=
super
.
check
(
av
,
6
);
return
target
.<
Object
>
invoke
(
a0
,
super
.
select
(
av
,
0
),
super
.
select
(
av
,
1
),
super
.
select
(
av
,
2
),
super
.
select
(
av
,
3
),
super
.
select
(
av
,
4
),
super
.
select
(
av
,
5
));
}
protected
Object
invoke_S7
(
Object
av
)
throws
Throwable
{
av
=
super
.
check
(
av
,
7
);
return
target
.<
Object
>
invoke
(
super
.
select
(
av
,
0
),
super
.
select
(
av
,
1
),
super
.
select
(
av
,
2
),
super
.
select
(
av
,
3
),
super
.
select
(
av
,
4
),
super
.
select
(
av
,
5
),
super
.
select
(
av
,
6
));
}
}
static
class
S8
extends
Adapter
{
protected
S8
(
SpreadGeneric
outer
)
{
super
(
outer
);
}
// to build prototype
protected
S8
(
SpreadGeneric
outer
,
MethodHandle
t
)
{
super
(
outer
,
t
);
}
protected
S8
makeInstance
(
SpreadGeneric
outer
,
MethodHandle
t
)
{
return
new
S8
(
outer
,
t
);
}
protected
Object
invoke_S0
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
a6
,
Object
a7
,
Object
av
)
throws
Throwable
{
av
=
super
.
check
(
av
,
0
);
return
target
.<
Object
>
invoke
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
);
}
protected
Object
invoke_S1
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
a6
,
Object
av
)
throws
Throwable
{
av
=
super
.
check
(
av
,
1
);
return
target
.<
Object
>
invoke
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
super
.
select
(
av
,
0
));
}
protected
Object
invoke_S2
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
av
)
throws
Throwable
{
av
=
super
.
check
(
av
,
2
);
return
target
.<
Object
>
invoke
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
super
.
select
(
av
,
0
),
super
.
select
(
av
,
1
));
}
protected
Object
invoke_S3
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
av
)
throws
Throwable
{
av
=
super
.
check
(
av
,
3
);
return
target
.<
Object
>
invoke
(
a0
,
a1
,
a2
,
a3
,
a4
,
super
.
select
(
av
,
0
),
super
.
select
(
av
,
1
),
super
.
select
(
av
,
2
));
}
protected
Object
invoke_S4
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
av
)
throws
Throwable
{
av
=
super
.
check
(
av
,
4
);
return
target
.<
Object
>
invoke
(
a0
,
a1
,
a2
,
a3
,
super
.
select
(
av
,
0
),
super
.
select
(
av
,
1
),
super
.
select
(
av
,
2
),
super
.
select
(
av
,
3
));
}
protected
Object
invoke_S5
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
av
)
throws
Throwable
{
av
=
super
.
check
(
av
,
5
);
return
target
.<
Object
>
invoke
(
a0
,
a1
,
a2
,
super
.
select
(
av
,
0
),
super
.
select
(
av
,
1
),
super
.
select
(
av
,
2
),
super
.
select
(
av
,
3
),
super
.
select
(
av
,
4
));
}
protected
Object
invoke_S6
(
Object
a0
,
Object
a1
,
Object
av
)
throws
Throwable
{
av
=
super
.
check
(
av
,
6
);
return
target
.<
Object
>
invoke
(
a0
,
a1
,
super
.
select
(
av
,
0
),
super
.
select
(
av
,
1
),
super
.
select
(
av
,
2
),
super
.
select
(
av
,
3
),
super
.
select
(
av
,
4
),
super
.
select
(
av
,
5
));
}
protected
Object
invoke_S7
(
Object
a0
,
Object
av
)
throws
Throwable
{
av
=
super
.
check
(
av
,
7
);
return
target
.<
Object
>
invoke
(
a0
,
super
.
select
(
av
,
0
),
super
.
select
(
av
,
1
),
super
.
select
(
av
,
2
),
super
.
select
(
av
,
3
),
super
.
select
(
av
,
4
),
super
.
select
(
av
,
5
),
super
.
select
(
av
,
6
));
}
protected
Object
invoke_S8
(
Object
av
)
throws
Throwable
{
av
=
super
.
check
(
av
,
8
);
return
target
.<
Object
>
invoke
(
super
.
select
(
av
,
0
),
super
.
select
(
av
,
1
),
super
.
select
(
av
,
2
),
super
.
select
(
av
,
3
),
super
.
select
(
av
,
4
),
super
.
select
(
av
,
5
),
super
.
select
(
av
,
6
),
super
.
select
(
av
,
7
));
}
}
static
class
S9
extends
Adapter
{
protected
S9
(
SpreadGeneric
outer
)
{
super
(
outer
);
}
// to build prototype
protected
S9
(
SpreadGeneric
outer
,
MethodHandle
t
)
{
super
(
outer
,
t
);
}
protected
S9
makeInstance
(
SpreadGeneric
outer
,
MethodHandle
t
)
{
return
new
S9
(
outer
,
t
);
}
protected
Object
invoke_S0
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
a6
,
Object
a7
,
Object
a8
,
Object
av
)
throws
Throwable
{
av
=
super
.
check
(
av
,
0
);
return
target
.<
Object
>
invoke
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
);
}
protected
Object
invoke_S1
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
a6
,
Object
a7
,
Object
av
)
throws
Throwable
{
av
=
super
.
check
(
av
,
1
);
return
target
.<
Object
>
invoke
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
super
.
select
(
av
,
0
));
}
protected
Object
invoke_S2
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
a6
,
Object
av
)
throws
Throwable
{
av
=
super
.
check
(
av
,
2
);
return
target
.<
Object
>
invoke
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
super
.
select
(
av
,
0
),
super
.
select
(
av
,
1
));
}
protected
Object
invoke_S3
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
av
)
throws
Throwable
{
av
=
super
.
check
(
av
,
3
);
return
target
.<
Object
>
invoke
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
super
.
select
(
av
,
0
),
super
.
select
(
av
,
1
),
super
.
select
(
av
,
2
));
}
protected
Object
invoke_S4
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
av
)
throws
Throwable
{
av
=
super
.
check
(
av
,
4
);
return
target
.<
Object
>
invoke
(
a0
,
a1
,
a2
,
a3
,
a4
,
super
.
select
(
av
,
0
),
super
.
select
(
av
,
1
),
super
.
select
(
av
,
2
),
super
.
select
(
av
,
3
));
}
protected
Object
invoke_S5
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
av
)
throws
Throwable
{
av
=
super
.
check
(
av
,
5
);
return
target
.<
Object
>
invoke
(
a0
,
a1
,
a2
,
a3
,
super
.
select
(
av
,
0
),
super
.
select
(
av
,
1
),
super
.
select
(
av
,
2
),
super
.
select
(
av
,
3
),
super
.
select
(
av
,
4
));
}
protected
Object
invoke_S6
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
av
)
throws
Throwable
{
av
=
super
.
check
(
av
,
6
);
return
target
.<
Object
>
invoke
(
a0
,
a1
,
a2
,
super
.
select
(
av
,
0
),
super
.
select
(
av
,
1
),
super
.
select
(
av
,
2
),
super
.
select
(
av
,
3
),
super
.
select
(
av
,
4
),
super
.
select
(
av
,
5
));
}
protected
Object
invoke_S7
(
Object
a0
,
Object
a1
,
Object
av
)
throws
Throwable
{
av
=
super
.
check
(
av
,
7
);
return
target
.<
Object
>
invoke
(
a0
,
a1
,
super
.
select
(
av
,
0
),
super
.
select
(
av
,
1
),
super
.
select
(
av
,
2
),
super
.
select
(
av
,
3
),
super
.
select
(
av
,
4
),
super
.
select
(
av
,
5
),
super
.
select
(
av
,
6
));
}
protected
Object
invoke_S8
(
Object
a0
,
Object
av
)
throws
Throwable
{
av
=
super
.
check
(
av
,
8
);
return
target
.<
Object
>
invoke
(
a0
,
super
.
select
(
av
,
0
),
super
.
select
(
av
,
1
),
super
.
select
(
av
,
2
),
super
.
select
(
av
,
3
),
super
.
select
(
av
,
4
),
super
.
select
(
av
,
5
),
super
.
select
(
av
,
6
),
super
.
select
(
av
,
7
));
}
protected
Object
invoke_S9
(
Object
av
)
throws
Throwable
{
av
=
super
.
check
(
av
,
9
);
return
target
.<
Object
>
invoke
(
super
.
select
(
av
,
0
),
super
.
select
(
av
,
1
),
super
.
select
(
av
,
2
),
super
.
select
(
av
,
3
),
super
.
select
(
av
,
4
),
super
.
select
(
av
,
5
),
super
.
select
(
av
,
6
),
super
.
select
(
av
,
7
),
super
.
select
(
av
,
8
));
}
}
static
class
S10
extends
Adapter
{
protected
S10
(
SpreadGeneric
outer
)
{
super
(
outer
);
}
// to build prototype
protected
S10
(
SpreadGeneric
outer
,
MethodHandle
t
)
{
super
(
outer
,
t
);
}
protected
S10
makeInstance
(
SpreadGeneric
outer
,
MethodHandle
t
)
{
return
new
S10
(
outer
,
t
);
}
protected
Object
invoke_S0
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
a6
,
Object
a7
,
Object
a8
,
Object
a9
,
Object
av
)
throws
Throwable
{
av
=
super
.
check
(
av
,
0
);
return
target
.<
Object
>
invoke
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
,
a9
);
}
protected
Object
invoke_S1
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
a6
,
Object
a7
,
Object
a8
,
Object
av
)
throws
Throwable
{
av
=
super
.
check
(
av
,
1
);
return
target
.<
Object
>
invoke
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
,
super
.
select
(
av
,
0
));
}
protected
Object
invoke_S2
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
a6
,
Object
a7
,
Object
av
)
throws
Throwable
{
av
=
super
.
check
(
av
,
2
);
return
target
.<
Object
>
invoke
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
super
.
select
(
av
,
0
),
super
.
select
(
av
,
1
));
}
protected
Object
invoke_S3
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
a6
,
Object
av
)
throws
Throwable
{
av
=
super
.
check
(
av
,
3
);
return
target
.<
Object
>
invoke
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
super
.
select
(
av
,
0
),
super
.
select
(
av
,
1
),
super
.
select
(
av
,
2
));
}
protected
Object
invoke_S4
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
av
)
throws
Throwable
{
av
=
super
.
check
(
av
,
4
);
return
target
.<
Object
>
invoke
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
super
.
select
(
av
,
0
),
super
.
select
(
av
,
1
),
super
.
select
(
av
,
2
),
super
.
select
(
av
,
3
));
}
protected
Object
invoke_S5
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
av
)
throws
Throwable
{
av
=
super
.
check
(
av
,
5
);
return
target
.<
Object
>
invoke
(
a0
,
a1
,
a2
,
a3
,
a4
,
super
.
select
(
av
,
0
),
super
.
select
(
av
,
1
),
super
.
select
(
av
,
2
),
super
.
select
(
av
,
3
),
super
.
select
(
av
,
4
));
}
protected
Object
invoke_S6
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
av
)
throws
Throwable
{
av
=
super
.
check
(
av
,
6
);
return
target
.<
Object
>
invoke
(
a0
,
a1
,
a2
,
a3
,
super
.
select
(
av
,
0
),
super
.
select
(
av
,
1
),
super
.
select
(
av
,
2
),
super
.
select
(
av
,
3
),
super
.
select
(
av
,
4
),
super
.
select
(
av
,
5
));
}
protected
Object
invoke_S7
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
av
)
throws
Throwable
{
av
=
super
.
check
(
av
,
7
);
return
target
.<
Object
>
invoke
(
a0
,
a1
,
a2
,
super
.
select
(
av
,
0
),
super
.
select
(
av
,
1
),
super
.
select
(
av
,
2
),
super
.
select
(
av
,
3
),
super
.
select
(
av
,
4
),
super
.
select
(
av
,
5
),
super
.
select
(
av
,
6
));
}
protected
Object
invoke_S8
(
Object
a0
,
Object
a1
,
Object
av
)
throws
Throwable
{
av
=
super
.
check
(
av
,
8
);
return
target
.<
Object
>
invoke
(
a0
,
a1
,
super
.
select
(
av
,
0
),
super
.
select
(
av
,
1
),
super
.
select
(
av
,
2
),
super
.
select
(
av
,
3
),
super
.
select
(
av
,
4
),
super
.
select
(
av
,
5
),
super
.
select
(
av
,
6
),
super
.
select
(
av
,
7
));
}
protected
Object
invoke_S9
(
Object
a0
,
Object
av
)
throws
Throwable
{
av
=
super
.
check
(
av
,
9
);
return
target
.<
Object
>
invoke
(
a0
,
super
.
select
(
av
,
0
),
super
.
select
(
av
,
1
),
super
.
select
(
av
,
2
),
super
.
select
(
av
,
3
),
super
.
select
(
av
,
4
),
super
.
select
(
av
,
5
),
super
.
select
(
av
,
6
),
super
.
select
(
av
,
7
),
super
.
select
(
av
,
8
));
}
protected
Object
invoke_S10
(
Object
av
)
throws
Throwable
{
av
=
super
.
check
(
av
,
10
);
return
target
.<
Object
>
invoke
(
super
.
select
(
av
,
0
),
super
.
select
(
av
,
1
),
super
.
select
(
av
,
2
),
super
.
select
(
av
,
3
),
super
.
select
(
av
,
4
),
super
.
select
(
av
,
5
),
super
.
select
(
av
,
6
),
super
.
select
(
av
,
7
),
super
.
select
(
av
,
8
),
super
.
select
(
av
,
9
));
}
}
}
src/share/classes/sun/dyn/ToGeneric.java
浏览文件 @
8992d5c6
...
@@ -34,6 +34,7 @@ import java.lang.reflect.Constructor;
...
@@ -34,6 +34,7 @@ import java.lang.reflect.Constructor;
import
java.lang.reflect.InvocationTargetException
;
import
java.lang.reflect.InvocationTargetException
;
import
sun.dyn.util.ValueConversions
;
import
sun.dyn.util.ValueConversions
;
import
sun.dyn.util.Wrapper
;
import
sun.dyn.util.Wrapper
;
import
static
sun
.
dyn
.
MemberName
.
newIllegalArgumentException
;
/**
/**
* Adapters which mediate between incoming calls which are not generic
* Adapters which mediate between incoming calls which are not generic
...
@@ -68,7 +69,7 @@ class ToGeneric {
...
@@ -68,7 +69,7 @@ class ToGeneric {
// conversion which unboxes a primitive return value
// conversion which unboxes a primitive return value
private
final
MethodHandle
returnConversion
;
private
final
MethodHandle
returnConversion
;
/** Compute and cache information common to all
collecting
adapters
/** Compute and cache information common to all
generifying (boxing)
adapters
* that implement members of the erasure-family of the given erased type.
* that implement members of the erasure-family of the given erased type.
*/
*/
private
ToGeneric
(
MethodType
entryType
)
{
private
ToGeneric
(
MethodType
entryType
)
{
...
@@ -111,30 +112,48 @@ class ToGeneric {
...
@@ -111,30 +112,48 @@ class ToGeneric {
// primitive arguments according to their "raw" types int/long
// primitive arguments according to their "raw" types int/long
MethodType
intsAtEnd
=
MethodTypeImpl
.
of
(
primsAtEnd
).
primsAsInts
();
MethodType
intsAtEnd
=
MethodTypeImpl
.
of
(
primsAtEnd
).
primsAsInts
();
ad
=
findAdapter
(
rawEntryTypeInit
=
intsAtEnd
);
ad
=
findAdapter
(
rawEntryTypeInit
=
intsAtEnd
);
if
(
ad
==
null
)
{
MethodHandle
rawEntryPoint
;
if
(
ad
!=
null
)
{
rawEntryPoint
=
ad
.
prototypeEntryPoint
();
}
else
{
// Perhaps the adapter is available only for longs.
// Perhaps the adapter is available only for longs.
// If so, we can use it, but there will have to be a little
// If so, we can use it, but there will have to be a little
// more stack motion on each call.
// more stack motion on each call.
MethodType
longsAtEnd
=
MethodTypeImpl
.
of
(
primsAtEnd
).
primsAsLongs
();
MethodType
longsAtEnd
=
MethodTypeImpl
.
of
(
primsAtEnd
).
primsAsLongs
();
ad
=
findAdapter
(
rawEntryTypeInit
=
longsAtEnd
);
ad
=
findAdapter
(
rawEntryTypeInit
=
longsAtEnd
);
if
(
ad
==
null
)
{
if
(
ad
!=
null
)
{
MethodType
eptWithLongs
=
longsAtEnd
.
insertParameterTypes
(
0
,
ad
.
getClass
());
MethodType
eptWithInts
=
intsAtEnd
.
insertParameterTypes
(
0
,
ad
.
getClass
());
rawEntryPoint
=
ad
.
prototypeEntryPoint
();
MethodType
midType
=
eptWithLongs
;
// will change longs to ints
for
(
int
i
=
0
,
nargs
=
midType
.
parameterCount
();
i
<
nargs
;
i
++)
{
if
(
midType
.
parameterType
(
i
)
!=
eptWithInts
.
parameterType
(
i
))
{
assert
(
midType
.
parameterType
(
i
)
==
long
.
class
);
assert
(
eptWithInts
.
parameterType
(
i
)
==
int
.
class
);
MethodType
nextType
=
midType
.
changeParameterType
(
i
,
int
.
class
);
rawEntryPoint
=
MethodHandle
.
convertArguments
(
Access
.
TOKEN
,
rawEntryPoint
,
nextType
,
midType
,
null
);
midType
=
nextType
;
}
}
assert
(
midType
==
eptWithInts
);
}
else
{
// If there is no statically compiled adapter,
// If there is no statically compiled adapter,
// build one by means of dynamic bytecode generation.
// build one by means of dynamic bytecode generation.
ad
=
buildAdapterFromBytecodes
(
rawEntryTypeInit
=
intsAtEnd
);
ad
=
buildAdapterFromBytecodes
(
rawEntryTypeInit
=
intsAtEnd
);
rawEntryPoint
=
ad
.
prototypeEntryPoint
();
}
}
}
}
MethodHandle
rawEntryPoint
=
ad
.
prototypeEntryPoint
();
MethodType
tepType
=
entryType
.
insertParameterTypes
(
0
,
ad
.
getClass
());
MethodType
tepType
=
entryType
.
insertParameterType
(
0
,
ad
.
getClass
());
this
.
entryPoint
=
this
.
entryPoint
=
AdapterMethodHandle
.
makeR
awRetypeOnly
(
Access
.
TOKEN
,
tepType
,
rawEntryPoint
);
AdapterMethodHandle
.
makeR
etypeRaw
(
Access
.
TOKEN
,
tepType
,
rawEntryPoint
);
if
(
this
.
entryPoint
==
null
)
if
(
this
.
entryPoint
==
null
)
throw
new
UnsupportedOperationException
(
"cannot retype to "
+
entryType
throw
new
UnsupportedOperationException
(
"cannot retype to "
+
entryType
+
" from "
+
rawEntryPoint
.
type
().
dropParameterType
(
0
));
+
" from "
+
rawEntryPoint
.
type
().
dropParameterType
s
(
0
,
1
));
this
.
returnConversion
=
computeReturnConversion
(
entryType
,
rawEntryTypeInit
,
false
);
this
.
returnConversion
=
computeReturnConversion
(
entryType
,
rawEntryTypeInit
,
false
);
this
.
rawEntryType
=
rawEntryTypeInit
;
this
.
rawEntryType
=
rawEntryTypeInit
;
this
.
adapter
=
ad
;
this
.
adapter
=
ad
;
this
.
invoker
=
makeRawArgumentFilter
(
invoker0
,
this
.
invoker
=
makeRawArgumentFilter
(
invoker0
,
rawEntryTypeInit
,
entryType
);
rawEntryPoint
.
type
().
dropParameterType
(
0
),
entryType
);
}
}
/** A generic argument list will be created by a call of type 'raw'.
/** A generic argument list will be created by a call of type 'raw'.
...
@@ -157,8 +176,8 @@ class ToGeneric {
...
@@ -157,8 +176,8 @@ class ToGeneric {
if
(
filteredInvoker
==
null
)
throw
new
UnsupportedOperationException
(
"NYI"
);
if
(
filteredInvoker
==
null
)
throw
new
UnsupportedOperationException
(
"NYI"
);
}
}
MethodHandle
reboxer
=
ValueConversions
.
rebox
(
dst
,
false
);
MethodHandle
reboxer
=
ValueConversions
.
rebox
(
dst
,
false
);
FilterGeneric
gen
=
new
FilterGeneric
(
filteredInvoker
.
type
(),
(
short
)(
1
+
i
),
(
short
)
1
,
'R'
);
filteredInvoker
=
FilterGeneric
.
makeArgumentFilter
(
1
+
i
,
reboxer
,
filteredInvoker
);
filteredInvoker
=
gen
.
makeInstance
(
reboxer
,
filteredInvoker
);
if
(
filteredInvoker
==
null
)
throw
new
InternalError
(
);
}
}
if
(
filteredInvoker
==
null
)
return
invoker
;
if
(
filteredInvoker
==
null
)
return
invoker
;
return
AdapterMethodHandle
.
makeRetypeOnly
(
Access
.
TOKEN
,
invoker
.
type
(),
filteredInvoker
);
return
AdapterMethodHandle
.
makeRetypeOnly
(
Access
.
TOKEN
,
invoker
.
type
(),
filteredInvoker
);
...
@@ -209,9 +228,9 @@ class ToGeneric {
...
@@ -209,9 +228,9 @@ class ToGeneric {
if
(
convert
==
null
)
if
(
convert
==
null
)
convert
=
computeReturnConversion
(
type
,
rawEntryType
,
true
);
convert
=
computeReturnConversion
(
type
,
rawEntryType
,
true
);
// retype erased reference arguments (the cast makes it safe to do this)
// retype erased reference arguments (the cast makes it safe to do this)
MethodType
tepType
=
type
.
insertParameterType
(
0
,
adapter
.
getClass
());
MethodType
tepType
=
type
.
insertParameterType
s
(
0
,
adapter
.
getClass
());
MethodHandle
typedEntryPoint
=
MethodHandle
typedEntryPoint
=
AdapterMethodHandle
.
makeR
awRetypeOnly
(
Access
.
TOKEN
,
tepType
,
entryPoint
);
AdapterMethodHandle
.
makeR
etypeRaw
(
Access
.
TOKEN
,
tepType
,
entryPoint
);
return
adapter
.
makeInstance
(
typedEntryPoint
,
invoker
,
convert
,
genericTarget
);
return
adapter
.
makeInstance
(
typedEntryPoint
,
invoker
,
convert
,
genericTarget
);
}
}
...
@@ -225,7 +244,7 @@ class ToGeneric {
...
@@ -225,7 +244,7 @@ class ToGeneric {
public
static
MethodHandle
make
(
MethodType
type
,
MethodHandle
genericTarget
)
{
public
static
MethodHandle
make
(
MethodType
type
,
MethodHandle
genericTarget
)
{
MethodType
gtype
=
genericTarget
.
type
();
MethodType
gtype
=
genericTarget
.
type
();
if
(
type
.
generic
()
!=
gtype
)
if
(
type
.
generic
()
!=
gtype
)
throw
new
IllegalArgumentException
(
);
throw
new
IllegalArgumentException
(
"type must be generic"
);
if
(
type
==
gtype
)
return
genericTarget
;
if
(
type
==
gtype
)
return
genericTarget
;
return
ToGeneric
.
of
(
type
).
makeInstance
(
type
,
genericTarget
);
return
ToGeneric
.
of
(
type
).
makeInstance
(
type
,
genericTarget
);
}
}
...
@@ -283,7 +302,10 @@ class ToGeneric {
...
@@ -283,7 +302,10 @@ class ToGeneric {
try
{
try
{
return
ctor
.
newInstance
(
entryPoint
);
return
ctor
.
newInstance
(
entryPoint
);
}
catch
(
IllegalArgumentException
ex
)
{
}
catch
(
IllegalArgumentException
ex
)
{
}
catch
(
InvocationTargetException
ex
)
{
}
catch
(
InvocationTargetException
wex
)
{
Throwable
ex
=
wex
.
getTargetException
();
if
(
ex
instanceof
Error
)
throw
(
Error
)
ex
;
if
(
ex
instanceof
RuntimeException
)
throw
(
RuntimeException
)
ex
;
}
catch
(
InstantiationException
ex
)
{
}
catch
(
InstantiationException
ex
)
{
}
catch
(
IllegalAccessException
ex
)
{
}
catch
(
IllegalAccessException
ex
)
{
}
}
...
@@ -317,6 +339,11 @@ class ToGeneric {
...
@@ -317,6 +339,11 @@ class ToGeneric {
protected
final
MethodHandle
target
;
// Object... -> Object
protected
final
MethodHandle
target
;
// Object... -> Object
protected
final
MethodHandle
convert
;
// Object -> R
protected
final
MethodHandle
convert
;
// Object -> R
@Override
public
String
toString
()
{
return
target
.
toString
();
}
protected
boolean
isPrototype
()
{
return
target
==
null
;
}
protected
boolean
isPrototype
()
{
return
target
==
null
;
}
/* Prototype constructor. */
/* Prototype constructor. */
protected
Adapter
(
MethodHandle
entryPoint
)
{
protected
Adapter
(
MethodHandle
entryPoint
)
{
...
@@ -344,33 +371,33 @@ class ToGeneric {
...
@@ -344,33 +371,33 @@ class ToGeneric {
// { return new ThisType(entryPoint, convert, target); }
// { return new ThisType(entryPoint, convert, target); }
// Code to run when the arguments (<= 4) have all been boxed.
// Code to run when the arguments (<= 4) have all been boxed.
protected
Object
target
()
{
return
invoker
.<
Object
>
invoke
(
target
);
}
protected
Object
target
()
throws
Throwable
{
return
invoker
.<
Object
>
invoke
(
target
);
}
protected
Object
target
(
Object
a0
)
{
return
invoker
.<
Object
>
invoke
(
target
,
a0
);
}
protected
Object
target
(
Object
a0
)
throws
Throwable
{
return
invoker
.<
Object
>
invoke
(
target
,
a0
);
}
protected
Object
target
(
Object
a0
,
Object
a1
)
protected
Object
target
(
Object
a0
,
Object
a1
)
{
return
invoker
.<
Object
>
invoke
(
target
,
a0
,
a1
);
}
throws
Throwable
{
return
invoker
.<
Object
>
invoke
(
target
,
a0
,
a1
);
}
protected
Object
target
(
Object
a0
,
Object
a1
,
Object
a2
)
protected
Object
target
(
Object
a0
,
Object
a1
,
Object
a2
)
{
return
invoker
.<
Object
>
invoke
(
target
,
a0
,
a1
,
a2
);
}
throws
Throwable
{
return
invoker
.<
Object
>
invoke
(
target
,
a0
,
a1
,
a2
);
}
protected
Object
target
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
)
protected
Object
target
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
)
{
return
invoker
.<
Object
>
invoke
(
target
,
a0
,
a1
,
a2
,
a3
);
}
throws
Throwable
{
return
invoker
.<
Object
>
invoke
(
target
,
a0
,
a1
,
a2
,
a3
);
}
/*
/*
protected Object target_0(Object... av) { return invoker.<Object>invoke(target, av); }
protected Object target_0(Object... av)
throws Throwable
{ return invoker.<Object>invoke(target, av); }
protected Object target_1(Object a0, Object... av)
protected Object target_1(Object a0, Object... av)
{ return invoker.<Object>invoke(target, a0, (Object)av); }
throws Throwable
{ return invoker.<Object>invoke(target, a0, (Object)av); }
protected Object target_2(Object a0, Object a1, Object... av)
protected Object target_2(Object a0, Object a1, Object... av)
{ return invoker.<Object>invoke(target, a0, a1, (Object)av); }
throws Throwable
{ return invoker.<Object>invoke(target, a0, a1, (Object)av); }
protected Object target_3(Object a0, Object a1, Object a2, Object... av)
protected Object target_3(Object a0, Object a1, Object a2, Object... av)
{ return invoker.<Object>invoke(target, a0, a1, a2, (Object)av); }
throws Throwable
{ return invoker.<Object>invoke(target, a0, a1, a2, (Object)av); }
protected Object target_4(Object a0, Object a1, Object a2, Object a3, Object... av)
protected Object target_4(Object a0, Object a1, Object a2, Object a3, Object... av)
{ return invoker.<Object>invoke(target, a0, a1, a2, a3, (Object)av); }
throws Throwable
{ return invoker.<Object>invoke(target, a0, a1, a2, a3, (Object)av); }
// */
// */
// (For more than 4 arguments, generate the code in the adapter itself.)
// (For more than 4 arguments, generate the code in the adapter itself.)
// Code to run when the generic target has finished and produced a value.
// Code to run when the generic target has finished and produced a value.
protected
Object
return_L
(
Object
res
)
{
return
convert
.<
Object
>
invoke
(
res
);
}
protected
Object
return_L
(
Object
res
)
throws
Throwable
{
return
convert
.<
Object
>
invoke
(
res
);
}
protected
int
return_I
(
Object
res
)
{
return
convert
.<
int
>
invoke
(
res
);
}
protected
int
return_I
(
Object
res
)
throws
Throwable
{
return
convert
.<
int
>
invoke
(
res
);
}
protected
long
return_J
(
Object
res
)
{
return
convert
.<
long
>
invoke
(
res
);
}
protected
long
return_J
(
Object
res
)
throws
Throwable
{
return
convert
.<
long
>
invoke
(
res
);
}
protected
float
return_F
(
Object
res
)
{
return
convert
.<
float
>
invoke
(
res
);
}
protected
float
return_F
(
Object
res
)
throws
Throwable
{
return
convert
.<
float
>
invoke
(
res
);
}
protected
double
return_D
(
Object
res
)
{
return
convert
.<
double
>
invoke
(
res
);
}
protected
double
return_D
(
Object
res
)
throws
Throwable
{
return
convert
.<
double
>
invoke
(
res
);
}
static
private
final
String
CLASS_PREFIX
;
// "sun.dyn.ToGeneric$"
static
private
final
String
CLASS_PREFIX
;
// "sun.dyn.ToGeneric$"
static
{
static
{
...
@@ -397,25 +424,25 @@ class ToGeneric {
...
@@ -397,25 +424,25 @@ class ToGeneric {
protected A1(MethodHandle entryPoint) { super(entryPoint); } // to build prototype
protected A1(MethodHandle entryPoint) { super(entryPoint); } // to build prototype
protected A1(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t) { super(e, i, c, t); }
protected A1(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t) { super(e, i, c, t); }
protected A1 makeInstance(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t) { return new A1(e, i, c, t); }
protected A1 makeInstance(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t) { return new A1(e, i, c, t); }
protected Object target(Object a0) { return invoker.<Object>invoke(target, a0); }
protected Object target(Object a0)
throws Throwable
{ return invoker.<Object>invoke(target, a0); }
protected Object targetA1(Object a0) { return target(a0); }
protected Object targetA1(Object a0)
throws Throwable
{ return target(a0); }
protected Object targetA1(int a0) { return target(a0); }
protected Object targetA1(int a0)
throws Throwable
{ return target(a0); }
protected Object targetA1(long a0) { return target(a0); }
protected Object targetA1(long a0)
throws Throwable
{ return target(a0); }
protected Object invoke_L(Object a0) { return return_L(targetA1(a0)); }
protected Object invoke_L(Object a0)
throws Throwable
{ return return_L(targetA1(a0)); }
protected int invoke_I(Object a0) { return return_I(targetA1(a0)); }
protected int invoke_I(Object a0)
throws Throwable
{ return return_I(targetA1(a0)); }
protected long invoke_J(Object a0) { return return_J(targetA1(a0)); }
protected long invoke_J(Object a0)
throws Throwable
{ return return_J(targetA1(a0)); }
protected float invoke_F(Object a0) { return return_F(targetA1(a0)); }
protected float invoke_F(Object a0)
throws Throwable
{ return return_F(targetA1(a0)); }
protected double invoke_D(Object a0) { return return_D(targetA1(a0)); }
protected double invoke_D(Object a0)
throws Throwable
{ return return_D(targetA1(a0)); }
protected Object invoke_L(int a0) { return return_L(targetA1(a0)); }
protected Object invoke_L(int a0)
throws Throwable
{ return return_L(targetA1(a0)); }
protected int invoke_I(int a0) { return return_I(targetA1(a0)); }
protected int invoke_I(int a0)
throws Throwable
{ return return_I(targetA1(a0)); }
protected long invoke_J(int a0) { return return_J(targetA1(a0)); }
protected long invoke_J(int a0)
throws Throwable
{ return return_J(targetA1(a0)); }
protected float invoke_F(int a0) { return return_F(targetA1(a0)); }
protected float invoke_F(int a0)
throws Throwable
{ return return_F(targetA1(a0)); }
protected double invoke_D(int a0) { return return_D(targetA1(a0)); }
protected double invoke_D(int a0)
throws Throwable
{ return return_D(targetA1(a0)); }
protected Object invoke_L(long a0) { return return_L(targetA1(a0)); }
protected Object invoke_L(long a0)
throws Throwable
{ return return_L(targetA1(a0)); }
protected int invoke_I(long a0) { return return_I(targetA1(a0)); }
protected int invoke_I(long a0)
throws Throwable
{ return return_I(targetA1(a0)); }
protected long invoke_J(long a0) { return return_J(targetA1(a0)); }
protected long invoke_J(long a0)
throws Throwable
{ return return_J(targetA1(a0)); }
protected float invoke_F(long a0) { return return_F(targetA1(a0)); }
protected float invoke_F(long a0)
throws Throwable
{ return return_F(targetA1(a0)); }
protected double invoke_D(long a0) { return return_D(targetA1(a0)); }
protected double invoke_D(long a0)
throws Throwable
{ return return_D(targetA1(a0)); }
}
}
// */
// */
...
@@ -435,13 +462,13 @@ class genclasses {
...
@@ -435,13 +462,13 @@ class genclasses {
" protected @cat@(MethodHandle entryPoint) { super(entryPoint); } // to build prototype",
" protected @cat@(MethodHandle entryPoint) { super(entryPoint); } // to build prototype",
" protected @cat@(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t) { super(e, i, c, t); }",
" protected @cat@(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t) { super(e, i, c, t); }",
" protected @cat@ makeInstance(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t) { return new @cat@(e, i, c, t); }",
" protected @cat@ makeInstance(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t) { return new @cat@(e, i, c, t); }",
" protected Object target(@Ovav@) { return invoker.<Object>invoke(target, @av@); }",
" protected Object target(@Ovav@)
throws Throwable
{ return invoker.<Object>invoke(target, @av@); }",
" //@each-Tv@",
" //@each-Tv@",
" protected Object target@cat@(@Tvav@) { return target(@av@); }",
" protected Object target@cat@(@Tvav@)
throws Throwable
{ return target(@av@); }",
" //@end-Tv@",
" //@end-Tv@",
" //@each-Tv@",
" //@each-Tv@",
" //@each-R@",
" //@each-R@",
" protected @R@ invoke_@Rc@(@Tvav@) { return return_@Rc@(target@cat@(@av@)); }",
" protected @R@ invoke_@Rc@(@Tvav@)
throws Throwable
{ return return_@Rc@(target@cat@(@av@)); }",
" //@end-R@",
" //@end-R@",
" //@end-Tv@",
" //@end-Tv@",
" }",
" }",
...
@@ -595,424 +622,424 @@ class genclasses {
...
@@ -595,424 +622,424 @@ class genclasses {
protected
A0
(
MethodHandle
entryPoint
)
{
super
(
entryPoint
);
}
// to build prototype
protected
A0
(
MethodHandle
entryPoint
)
{
super
(
entryPoint
);
}
// to build prototype
protected
A0
(
MethodHandle
e
,
MethodHandle
i
,
MethodHandle
c
,
MethodHandle
t
)
{
super
(
e
,
i
,
c
,
t
);
}
protected
A0
(
MethodHandle
e
,
MethodHandle
i
,
MethodHandle
c
,
MethodHandle
t
)
{
super
(
e
,
i
,
c
,
t
);
}
protected
A0
makeInstance
(
MethodHandle
e
,
MethodHandle
i
,
MethodHandle
c
,
MethodHandle
t
)
{
return
new
A0
(
e
,
i
,
c
,
t
);
}
protected
A0
makeInstance
(
MethodHandle
e
,
MethodHandle
i
,
MethodHandle
c
,
MethodHandle
t
)
{
return
new
A0
(
e
,
i
,
c
,
t
);
}
protected
Object
target
()
{
return
invoker
.<
Object
>
invoke
(
target
);
}
protected
Object
target
()
throws
Throwable
{
return
invoker
.<
Object
>
invoke
(
target
);
}
protected
Object
targetA0
()
{
return
target
();
}
protected
Object
targetA0
()
throws
Throwable
{
return
target
();
}
protected
Object
invoke_L
()
{
return
return_L
(
targetA0
());
}
protected
Object
invoke_L
()
throws
Throwable
{
return
return_L
(
targetA0
());
}
protected
int
invoke_I
()
{
return
return_I
(
targetA0
());
}
protected
int
invoke_I
()
throws
Throwable
{
return
return_I
(
targetA0
());
}
protected
long
invoke_J
()
{
return
return_J
(
targetA0
());
}
protected
long
invoke_J
()
throws
Throwable
{
return
return_J
(
targetA0
());
}
protected
float
invoke_F
()
{
return
return_F
(
targetA0
());
}
protected
float
invoke_F
()
throws
Throwable
{
return
return_F
(
targetA0
());
}
protected
double
invoke_D
()
{
return
return_D
(
targetA0
());
}
protected
double
invoke_D
()
throws
Throwable
{
return
return_D
(
targetA0
());
}
}
}
static
class
A1
extends
Adapter
{
static
class
A1
extends
Adapter
{
protected
A1
(
MethodHandle
entryPoint
)
{
super
(
entryPoint
);
}
// to build prototype
protected
A1
(
MethodHandle
entryPoint
)
{
super
(
entryPoint
);
}
// to build prototype
protected
A1
(
MethodHandle
e
,
MethodHandle
i
,
MethodHandle
c
,
MethodHandle
t
)
{
super
(
e
,
i
,
c
,
t
);
}
protected
A1
(
MethodHandle
e
,
MethodHandle
i
,
MethodHandle
c
,
MethodHandle
t
)
{
super
(
e
,
i
,
c
,
t
);
}
protected
A1
makeInstance
(
MethodHandle
e
,
MethodHandle
i
,
MethodHandle
c
,
MethodHandle
t
)
{
return
new
A1
(
e
,
i
,
c
,
t
);
}
protected
A1
makeInstance
(
MethodHandle
e
,
MethodHandle
i
,
MethodHandle
c
,
MethodHandle
t
)
{
return
new
A1
(
e
,
i
,
c
,
t
);
}
protected
Object
target
(
Object
a0
)
{
return
invoker
.<
Object
>
invoke
(
target
,
a0
);
}
protected
Object
target
(
Object
a0
)
throws
Throwable
{
return
invoker
.<
Object
>
invoke
(
target
,
a0
);
}
protected
Object
targetA1
(
Object
a0
)
{
return
target
(
a0
);
}
protected
Object
targetA1
(
Object
a0
)
throws
Throwable
{
return
target
(
a0
);
}
protected
Object
targetA1
(
int
a0
)
{
return
target
(
a0
);
}
protected
Object
targetA1
(
int
a0
)
throws
Throwable
{
return
target
(
a0
);
}
protected
Object
targetA1
(
long
a0
)
{
return
target
(
a0
);
}
protected
Object
targetA1
(
long
a0
)
throws
Throwable
{
return
target
(
a0
);
}
protected
Object
invoke_L
(
Object
a0
)
{
return
return_L
(
targetA1
(
a0
));
}
protected
Object
invoke_L
(
Object
a0
)
throws
Throwable
{
return
return_L
(
targetA1
(
a0
));
}
protected
int
invoke_I
(
Object
a0
)
{
return
return_I
(
targetA1
(
a0
));
}
protected
int
invoke_I
(
Object
a0
)
throws
Throwable
{
return
return_I
(
targetA1
(
a0
));
}
protected
long
invoke_J
(
Object
a0
)
{
return
return_J
(
targetA1
(
a0
));
}
protected
long
invoke_J
(
Object
a0
)
throws
Throwable
{
return
return_J
(
targetA1
(
a0
));
}
protected
float
invoke_F
(
Object
a0
)
{
return
return_F
(
targetA1
(
a0
));
}
protected
float
invoke_F
(
Object
a0
)
throws
Throwable
{
return
return_F
(
targetA1
(
a0
));
}
protected
double
invoke_D
(
Object
a0
)
{
return
return_D
(
targetA1
(
a0
));
}
protected
double
invoke_D
(
Object
a0
)
throws
Throwable
{
return
return_D
(
targetA1
(
a0
));
}
protected
Object
invoke_L
(
int
a0
)
{
return
return_L
(
targetA1
(
a0
));
}
protected
Object
invoke_L
(
int
a0
)
throws
Throwable
{
return
return_L
(
targetA1
(
a0
));
}
protected
int
invoke_I
(
int
a0
)
{
return
return_I
(
targetA1
(
a0
));
}
protected
int
invoke_I
(
int
a0
)
throws
Throwable
{
return
return_I
(
targetA1
(
a0
));
}
protected
long
invoke_J
(
int
a0
)
{
return
return_J
(
targetA1
(
a0
));
}
protected
long
invoke_J
(
int
a0
)
throws
Throwable
{
return
return_J
(
targetA1
(
a0
));
}
protected
float
invoke_F
(
int
a0
)
{
return
return_F
(
targetA1
(
a0
));
}
protected
float
invoke_F
(
int
a0
)
throws
Throwable
{
return
return_F
(
targetA1
(
a0
));
}
protected
double
invoke_D
(
int
a0
)
{
return
return_D
(
targetA1
(
a0
));
}
protected
double
invoke_D
(
int
a0
)
throws
Throwable
{
return
return_D
(
targetA1
(
a0
));
}
protected
Object
invoke_L
(
long
a0
)
{
return
return_L
(
targetA1
(
a0
));
}
protected
Object
invoke_L
(
long
a0
)
throws
Throwable
{
return
return_L
(
targetA1
(
a0
));
}
protected
int
invoke_I
(
long
a0
)
{
return
return_I
(
targetA1
(
a0
));
}
protected
int
invoke_I
(
long
a0
)
throws
Throwable
{
return
return_I
(
targetA1
(
a0
));
}
protected
long
invoke_J
(
long
a0
)
{
return
return_J
(
targetA1
(
a0
));
}
protected
long
invoke_J
(
long
a0
)
throws
Throwable
{
return
return_J
(
targetA1
(
a0
));
}
protected
float
invoke_F
(
long
a0
)
{
return
return_F
(
targetA1
(
a0
));
}
protected
float
invoke_F
(
long
a0
)
throws
Throwable
{
return
return_F
(
targetA1
(
a0
));
}
protected
double
invoke_D
(
long
a0
)
{
return
return_D
(
targetA1
(
a0
));
}
protected
double
invoke_D
(
long
a0
)
throws
Throwable
{
return
return_D
(
targetA1
(
a0
));
}
}
}
static
class
A2
extends
Adapter
{
static
class
A2
extends
Adapter
{
protected
A2
(
MethodHandle
entryPoint
)
{
super
(
entryPoint
);
}
// to build prototype
protected
A2
(
MethodHandle
entryPoint
)
{
super
(
entryPoint
);
}
// to build prototype
protected
A2
(
MethodHandle
e
,
MethodHandle
i
,
MethodHandle
c
,
MethodHandle
t
)
{
super
(
e
,
i
,
c
,
t
);
}
protected
A2
(
MethodHandle
e
,
MethodHandle
i
,
MethodHandle
c
,
MethodHandle
t
)
{
super
(
e
,
i
,
c
,
t
);
}
protected
A2
makeInstance
(
MethodHandle
e
,
MethodHandle
i
,
MethodHandle
c
,
MethodHandle
t
)
{
return
new
A2
(
e
,
i
,
c
,
t
);
}
protected
A2
makeInstance
(
MethodHandle
e
,
MethodHandle
i
,
MethodHandle
c
,
MethodHandle
t
)
{
return
new
A2
(
e
,
i
,
c
,
t
);
}
protected
Object
target
(
Object
a0
,
Object
a1
)
{
return
invoker
.<
Object
>
invoke
(
target
,
a0
,
a1
);
}
protected
Object
target
(
Object
a0
,
Object
a1
)
throws
Throwable
{
return
invoker
.<
Object
>
invoke
(
target
,
a0
,
a1
);
}
protected
Object
targetA2
(
Object
a0
,
Object
a1
)
{
return
target
(
a0
,
a1
);
}
protected
Object
targetA2
(
Object
a0
,
Object
a1
)
throws
Throwable
{
return
target
(
a0
,
a1
);
}
protected
Object
targetA2
(
Object
a0
,
int
a1
)
{
return
target
(
a0
,
a1
);
}
protected
Object
targetA2
(
Object
a0
,
int
a1
)
throws
Throwable
{
return
target
(
a0
,
a1
);
}
protected
Object
targetA2
(
int
a0
,
int
a1
)
{
return
target
(
a0
,
a1
);
}
protected
Object
targetA2
(
int
a0
,
int
a1
)
throws
Throwable
{
return
target
(
a0
,
a1
);
}
protected
Object
targetA2
(
Object
a0
,
long
a1
)
{
return
target
(
a0
,
a1
);
}
protected
Object
targetA2
(
Object
a0
,
long
a1
)
throws
Throwable
{
return
target
(
a0
,
a1
);
}
protected
Object
targetA2
(
long
a0
,
long
a1
)
{
return
target
(
a0
,
a1
);
}
protected
Object
targetA2
(
long
a0
,
long
a1
)
throws
Throwable
{
return
target
(
a0
,
a1
);
}
protected
Object
invoke_L
(
Object
a0
,
Object
a1
)
{
return
return_L
(
targetA2
(
a0
,
a1
));
}
protected
Object
invoke_L
(
Object
a0
,
Object
a1
)
throws
Throwable
{
return
return_L
(
targetA2
(
a0
,
a1
));
}
protected
int
invoke_I
(
Object
a0
,
Object
a1
)
{
return
return_I
(
targetA2
(
a0
,
a1
));
}
protected
int
invoke_I
(
Object
a0
,
Object
a1
)
throws
Throwable
{
return
return_I
(
targetA2
(
a0
,
a1
));
}
protected
long
invoke_J
(
Object
a0
,
Object
a1
)
{
return
return_J
(
targetA2
(
a0
,
a1
));
}
protected
long
invoke_J
(
Object
a0
,
Object
a1
)
throws
Throwable
{
return
return_J
(
targetA2
(
a0
,
a1
));
}
protected
float
invoke_F
(
Object
a0
,
Object
a1
)
{
return
return_F
(
targetA2
(
a0
,
a1
));
}
protected
float
invoke_F
(
Object
a0
,
Object
a1
)
throws
Throwable
{
return
return_F
(
targetA2
(
a0
,
a1
));
}
protected
double
invoke_D
(
Object
a0
,
Object
a1
)
{
return
return_D
(
targetA2
(
a0
,
a1
));
}
protected
double
invoke_D
(
Object
a0
,
Object
a1
)
throws
Throwable
{
return
return_D
(
targetA2
(
a0
,
a1
));
}
protected
Object
invoke_L
(
Object
a0
,
int
a1
)
{
return
return_L
(
targetA2
(
a0
,
a1
));
}
protected
Object
invoke_L
(
Object
a0
,
int
a1
)
throws
Throwable
{
return
return_L
(
targetA2
(
a0
,
a1
));
}
protected
int
invoke_I
(
Object
a0
,
int
a1
)
{
return
return_I
(
targetA2
(
a0
,
a1
));
}
protected
int
invoke_I
(
Object
a0
,
int
a1
)
throws
Throwable
{
return
return_I
(
targetA2
(
a0
,
a1
));
}
protected
long
invoke_J
(
Object
a0
,
int
a1
)
{
return
return_J
(
targetA2
(
a0
,
a1
));
}
protected
long
invoke_J
(
Object
a0
,
int
a1
)
throws
Throwable
{
return
return_J
(
targetA2
(
a0
,
a1
));
}
protected
float
invoke_F
(
Object
a0
,
int
a1
)
{
return
return_F
(
targetA2
(
a0
,
a1
));
}
protected
float
invoke_F
(
Object
a0
,
int
a1
)
throws
Throwable
{
return
return_F
(
targetA2
(
a0
,
a1
));
}
protected
double
invoke_D
(
Object
a0
,
int
a1
)
{
return
return_D
(
targetA2
(
a0
,
a1
));
}
protected
double
invoke_D
(
Object
a0
,
int
a1
)
throws
Throwable
{
return
return_D
(
targetA2
(
a0
,
a1
));
}
protected
Object
invoke_L
(
int
a0
,
int
a1
)
{
return
return_L
(
targetA2
(
a0
,
a1
));
}
protected
Object
invoke_L
(
int
a0
,
int
a1
)
throws
Throwable
{
return
return_L
(
targetA2
(
a0
,
a1
));
}
protected
int
invoke_I
(
int
a0
,
int
a1
)
{
return
return_I
(
targetA2
(
a0
,
a1
));
}
protected
int
invoke_I
(
int
a0
,
int
a1
)
throws
Throwable
{
return
return_I
(
targetA2
(
a0
,
a1
));
}
protected
long
invoke_J
(
int
a0
,
int
a1
)
{
return
return_J
(
targetA2
(
a0
,
a1
));
}
protected
long
invoke_J
(
int
a0
,
int
a1
)
throws
Throwable
{
return
return_J
(
targetA2
(
a0
,
a1
));
}
protected
float
invoke_F
(
int
a0
,
int
a1
)
{
return
return_F
(
targetA2
(
a0
,
a1
));
}
protected
float
invoke_F
(
int
a0
,
int
a1
)
throws
Throwable
{
return
return_F
(
targetA2
(
a0
,
a1
));
}
protected
double
invoke_D
(
int
a0
,
int
a1
)
{
return
return_D
(
targetA2
(
a0
,
a1
));
}
protected
double
invoke_D
(
int
a0
,
int
a1
)
throws
Throwable
{
return
return_D
(
targetA2
(
a0
,
a1
));
}
protected
Object
invoke_L
(
Object
a0
,
long
a1
)
{
return
return_L
(
targetA2
(
a0
,
a1
));
}
protected
Object
invoke_L
(
Object
a0
,
long
a1
)
throws
Throwable
{
return
return_L
(
targetA2
(
a0
,
a1
));
}
protected
int
invoke_I
(
Object
a0
,
long
a1
)
{
return
return_I
(
targetA2
(
a0
,
a1
));
}
protected
int
invoke_I
(
Object
a0
,
long
a1
)
throws
Throwable
{
return
return_I
(
targetA2
(
a0
,
a1
));
}
protected
long
invoke_J
(
Object
a0
,
long
a1
)
{
return
return_J
(
targetA2
(
a0
,
a1
));
}
protected
long
invoke_J
(
Object
a0
,
long
a1
)
throws
Throwable
{
return
return_J
(
targetA2
(
a0
,
a1
));
}
protected
float
invoke_F
(
Object
a0
,
long
a1
)
{
return
return_F
(
targetA2
(
a0
,
a1
));
}
protected
float
invoke_F
(
Object
a0
,
long
a1
)
throws
Throwable
{
return
return_F
(
targetA2
(
a0
,
a1
));
}
protected
double
invoke_D
(
Object
a0
,
long
a1
)
{
return
return_D
(
targetA2
(
a0
,
a1
));
}
protected
double
invoke_D
(
Object
a0
,
long
a1
)
throws
Throwable
{
return
return_D
(
targetA2
(
a0
,
a1
));
}
protected
Object
invoke_L
(
long
a0
,
long
a1
)
{
return
return_L
(
targetA2
(
a0
,
a1
));
}
protected
Object
invoke_L
(
long
a0
,
long
a1
)
throws
Throwable
{
return
return_L
(
targetA2
(
a0
,
a1
));
}
protected
int
invoke_I
(
long
a0
,
long
a1
)
{
return
return_I
(
targetA2
(
a0
,
a1
));
}
protected
int
invoke_I
(
long
a0
,
long
a1
)
throws
Throwable
{
return
return_I
(
targetA2
(
a0
,
a1
));
}
protected
long
invoke_J
(
long
a0
,
long
a1
)
{
return
return_J
(
targetA2
(
a0
,
a1
));
}
protected
long
invoke_J
(
long
a0
,
long
a1
)
throws
Throwable
{
return
return_J
(
targetA2
(
a0
,
a1
));
}
protected
float
invoke_F
(
long
a0
,
long
a1
)
{
return
return_F
(
targetA2
(
a0
,
a1
));
}
protected
float
invoke_F
(
long
a0
,
long
a1
)
throws
Throwable
{
return
return_F
(
targetA2
(
a0
,
a1
));
}
protected
double
invoke_D
(
long
a0
,
long
a1
)
{
return
return_D
(
targetA2
(
a0
,
a1
));
}
protected
double
invoke_D
(
long
a0
,
long
a1
)
throws
Throwable
{
return
return_D
(
targetA2
(
a0
,
a1
));
}
}
}
static
class
A3
extends
Adapter
{
static
class
A3
extends
Adapter
{
protected
A3
(
MethodHandle
entryPoint
)
{
super
(
entryPoint
);
}
// to build prototype
protected
A3
(
MethodHandle
entryPoint
)
{
super
(
entryPoint
);
}
// to build prototype
protected
A3
(
MethodHandle
e
,
MethodHandle
i
,
MethodHandle
c
,
MethodHandle
t
)
{
super
(
e
,
i
,
c
,
t
);
}
protected
A3
(
MethodHandle
e
,
MethodHandle
i
,
MethodHandle
c
,
MethodHandle
t
)
{
super
(
e
,
i
,
c
,
t
);
}
protected
A3
makeInstance
(
MethodHandle
e
,
MethodHandle
i
,
MethodHandle
c
,
MethodHandle
t
)
{
return
new
A3
(
e
,
i
,
c
,
t
);
}
protected
A3
makeInstance
(
MethodHandle
e
,
MethodHandle
i
,
MethodHandle
c
,
MethodHandle
t
)
{
return
new
A3
(
e
,
i
,
c
,
t
);
}
protected
Object
target
(
Object
a0
,
Object
a1
,
Object
a2
)
{
return
invoker
.<
Object
>
invoke
(
target
,
a0
,
a1
,
a2
);
}
protected
Object
target
(
Object
a0
,
Object
a1
,
Object
a2
)
throws
Throwable
{
return
invoker
.<
Object
>
invoke
(
target
,
a0
,
a1
,
a2
);
}
protected
Object
targetA3
(
Object
a0
,
Object
a1
,
Object
a2
)
{
return
target
(
a0
,
a1
,
a2
);
}
protected
Object
targetA3
(
Object
a0
,
Object
a1
,
Object
a2
)
throws
Throwable
{
return
target
(
a0
,
a1
,
a2
);
}
protected
Object
targetA3
(
Object
a0
,
Object
a1
,
int
a2
)
{
return
target
(
a0
,
a1
,
a2
);
}
protected
Object
targetA3
(
Object
a0
,
Object
a1
,
int
a2
)
throws
Throwable
{
return
target
(
a0
,
a1
,
a2
);
}
protected
Object
targetA3
(
Object
a0
,
int
a1
,
int
a2
)
{
return
target
(
a0
,
a1
,
a2
);
}
protected
Object
targetA3
(
Object
a0
,
int
a1
,
int
a2
)
throws
Throwable
{
return
target
(
a0
,
a1
,
a2
);
}
protected
Object
targetA3
(
int
a0
,
int
a1
,
int
a2
)
{
return
target
(
a0
,
a1
,
a2
);
}
protected
Object
targetA3
(
int
a0
,
int
a1
,
int
a2
)
throws
Throwable
{
return
target
(
a0
,
a1
,
a2
);
}
protected
Object
targetA3
(
Object
a0
,
Object
a1
,
long
a2
)
{
return
target
(
a0
,
a1
,
a2
);
}
protected
Object
targetA3
(
Object
a0
,
Object
a1
,
long
a2
)
throws
Throwable
{
return
target
(
a0
,
a1
,
a2
);
}
protected
Object
targetA3
(
Object
a0
,
long
a1
,
long
a2
)
{
return
target
(
a0
,
a1
,
a2
);
}
protected
Object
targetA3
(
Object
a0
,
long
a1
,
long
a2
)
throws
Throwable
{
return
target
(
a0
,
a1
,
a2
);
}
protected
Object
targetA3
(
long
a0
,
long
a1
,
long
a2
)
{
return
target
(
a0
,
a1
,
a2
);
}
protected
Object
targetA3
(
long
a0
,
long
a1
,
long
a2
)
throws
Throwable
{
return
target
(
a0
,
a1
,
a2
);
}
protected
Object
invoke_L
(
Object
a0
,
Object
a1
,
Object
a2
)
{
return
return_L
(
targetA3
(
a0
,
a1
,
a2
));
}
protected
Object
invoke_L
(
Object
a0
,
Object
a1
,
Object
a2
)
throws
Throwable
{
return
return_L
(
targetA3
(
a0
,
a1
,
a2
));
}
protected
int
invoke_I
(
Object
a0
,
Object
a1
,
Object
a2
)
{
return
return_I
(
targetA3
(
a0
,
a1
,
a2
));
}
protected
int
invoke_I
(
Object
a0
,
Object
a1
,
Object
a2
)
throws
Throwable
{
return
return_I
(
targetA3
(
a0
,
a1
,
a2
));
}
protected
long
invoke_J
(
Object
a0
,
Object
a1
,
Object
a2
)
{
return
return_J
(
targetA3
(
a0
,
a1
,
a2
));
}
protected
long
invoke_J
(
Object
a0
,
Object
a1
,
Object
a2
)
throws
Throwable
{
return
return_J
(
targetA3
(
a0
,
a1
,
a2
));
}
protected
float
invoke_F
(
Object
a0
,
Object
a1
,
Object
a2
)
{
return
return_F
(
targetA3
(
a0
,
a1
,
a2
));
}
protected
float
invoke_F
(
Object
a0
,
Object
a1
,
Object
a2
)
throws
Throwable
{
return
return_F
(
targetA3
(
a0
,
a1
,
a2
));
}
protected
double
invoke_D
(
Object
a0
,
Object
a1
,
Object
a2
)
{
return
return_D
(
targetA3
(
a0
,
a1
,
a2
));
}
protected
double
invoke_D
(
Object
a0
,
Object
a1
,
Object
a2
)
throws
Throwable
{
return
return_D
(
targetA3
(
a0
,
a1
,
a2
));
}
protected
Object
invoke_L
(
Object
a0
,
Object
a1
,
int
a2
)
{
return
return_L
(
targetA3
(
a0
,
a1
,
a2
));
}
protected
Object
invoke_L
(
Object
a0
,
Object
a1
,
int
a2
)
throws
Throwable
{
return
return_L
(
targetA3
(
a0
,
a1
,
a2
));
}
protected
int
invoke_I
(
Object
a0
,
Object
a1
,
int
a2
)
{
return
return_I
(
targetA3
(
a0
,
a1
,
a2
));
}
protected
int
invoke_I
(
Object
a0
,
Object
a1
,
int
a2
)
throws
Throwable
{
return
return_I
(
targetA3
(
a0
,
a1
,
a2
));
}
protected
long
invoke_J
(
Object
a0
,
Object
a1
,
int
a2
)
{
return
return_J
(
targetA3
(
a0
,
a1
,
a2
));
}
protected
long
invoke_J
(
Object
a0
,
Object
a1
,
int
a2
)
throws
Throwable
{
return
return_J
(
targetA3
(
a0
,
a1
,
a2
));
}
protected
float
invoke_F
(
Object
a0
,
Object
a1
,
int
a2
)
{
return
return_F
(
targetA3
(
a0
,
a1
,
a2
));
}
protected
float
invoke_F
(
Object
a0
,
Object
a1
,
int
a2
)
throws
Throwable
{
return
return_F
(
targetA3
(
a0
,
a1
,
a2
));
}
protected
double
invoke_D
(
Object
a0
,
Object
a1
,
int
a2
)
{
return
return_D
(
targetA3
(
a0
,
a1
,
a2
));
}
protected
double
invoke_D
(
Object
a0
,
Object
a1
,
int
a2
)
throws
Throwable
{
return
return_D
(
targetA3
(
a0
,
a1
,
a2
));
}
protected
Object
invoke_L
(
Object
a0
,
int
a1
,
int
a2
)
{
return
return_L
(
targetA3
(
a0
,
a1
,
a2
));
}
protected
Object
invoke_L
(
Object
a0
,
int
a1
,
int
a2
)
throws
Throwable
{
return
return_L
(
targetA3
(
a0
,
a1
,
a2
));
}
protected
int
invoke_I
(
Object
a0
,
int
a1
,
int
a2
)
{
return
return_I
(
targetA3
(
a0
,
a1
,
a2
));
}
protected
int
invoke_I
(
Object
a0
,
int
a1
,
int
a2
)
throws
Throwable
{
return
return_I
(
targetA3
(
a0
,
a1
,
a2
));
}
protected
long
invoke_J
(
Object
a0
,
int
a1
,
int
a2
)
{
return
return_J
(
targetA3
(
a0
,
a1
,
a2
));
}
protected
long
invoke_J
(
Object
a0
,
int
a1
,
int
a2
)
throws
Throwable
{
return
return_J
(
targetA3
(
a0
,
a1
,
a2
));
}
protected
float
invoke_F
(
Object
a0
,
int
a1
,
int
a2
)
{
return
return_F
(
targetA3
(
a0
,
a1
,
a2
));
}
protected
float
invoke_F
(
Object
a0
,
int
a1
,
int
a2
)
throws
Throwable
{
return
return_F
(
targetA3
(
a0
,
a1
,
a2
));
}
protected
double
invoke_D
(
Object
a0
,
int
a1
,
int
a2
)
{
return
return_D
(
targetA3
(
a0
,
a1
,
a2
));
}
protected
double
invoke_D
(
Object
a0
,
int
a1
,
int
a2
)
throws
Throwable
{
return
return_D
(
targetA3
(
a0
,
a1
,
a2
));
}
protected
Object
invoke_L
(
int
a0
,
int
a1
,
int
a2
)
{
return
return_L
(
targetA3
(
a0
,
a1
,
a2
));
}
protected
Object
invoke_L
(
int
a0
,
int
a1
,
int
a2
)
throws
Throwable
{
return
return_L
(
targetA3
(
a0
,
a1
,
a2
));
}
protected
int
invoke_I
(
int
a0
,
int
a1
,
int
a2
)
{
return
return_I
(
targetA3
(
a0
,
a1
,
a2
));
}
protected
int
invoke_I
(
int
a0
,
int
a1
,
int
a2
)
throws
Throwable
{
return
return_I
(
targetA3
(
a0
,
a1
,
a2
));
}
protected
long
invoke_J
(
int
a0
,
int
a1
,
int
a2
)
{
return
return_J
(
targetA3
(
a0
,
a1
,
a2
));
}
protected
long
invoke_J
(
int
a0
,
int
a1
,
int
a2
)
throws
Throwable
{
return
return_J
(
targetA3
(
a0
,
a1
,
a2
));
}
protected
float
invoke_F
(
int
a0
,
int
a1
,
int
a2
)
{
return
return_F
(
targetA3
(
a0
,
a1
,
a2
));
}
protected
float
invoke_F
(
int
a0
,
int
a1
,
int
a2
)
throws
Throwable
{
return
return_F
(
targetA3
(
a0
,
a1
,
a2
));
}
protected
double
invoke_D
(
int
a0
,
int
a1
,
int
a2
)
{
return
return_D
(
targetA3
(
a0
,
a1
,
a2
));
}
protected
double
invoke_D
(
int
a0
,
int
a1
,
int
a2
)
throws
Throwable
{
return
return_D
(
targetA3
(
a0
,
a1
,
a2
));
}
protected
Object
invoke_L
(
Object
a0
,
Object
a1
,
long
a2
)
{
return
return_L
(
targetA3
(
a0
,
a1
,
a2
));
}
protected
Object
invoke_L
(
Object
a0
,
Object
a1
,
long
a2
)
throws
Throwable
{
return
return_L
(
targetA3
(
a0
,
a1
,
a2
));
}
protected
int
invoke_I
(
Object
a0
,
Object
a1
,
long
a2
)
{
return
return_I
(
targetA3
(
a0
,
a1
,
a2
));
}
protected
int
invoke_I
(
Object
a0
,
Object
a1
,
long
a2
)
throws
Throwable
{
return
return_I
(
targetA3
(
a0
,
a1
,
a2
));
}
protected
long
invoke_J
(
Object
a0
,
Object
a1
,
long
a2
)
{
return
return_J
(
targetA3
(
a0
,
a1
,
a2
));
}
protected
long
invoke_J
(
Object
a0
,
Object
a1
,
long
a2
)
throws
Throwable
{
return
return_J
(
targetA3
(
a0
,
a1
,
a2
));
}
protected
float
invoke_F
(
Object
a0
,
Object
a1
,
long
a2
)
{
return
return_F
(
targetA3
(
a0
,
a1
,
a2
));
}
protected
float
invoke_F
(
Object
a0
,
Object
a1
,
long
a2
)
throws
Throwable
{
return
return_F
(
targetA3
(
a0
,
a1
,
a2
));
}
protected
double
invoke_D
(
Object
a0
,
Object
a1
,
long
a2
)
{
return
return_D
(
targetA3
(
a0
,
a1
,
a2
));
}
protected
double
invoke_D
(
Object
a0
,
Object
a1
,
long
a2
)
throws
Throwable
{
return
return_D
(
targetA3
(
a0
,
a1
,
a2
));
}
protected
Object
invoke_L
(
Object
a0
,
long
a1
,
long
a2
)
{
return
return_L
(
targetA3
(
a0
,
a1
,
a2
));
}
protected
Object
invoke_L
(
Object
a0
,
long
a1
,
long
a2
)
throws
Throwable
{
return
return_L
(
targetA3
(
a0
,
a1
,
a2
));
}
protected
int
invoke_I
(
Object
a0
,
long
a1
,
long
a2
)
{
return
return_I
(
targetA3
(
a0
,
a1
,
a2
));
}
protected
int
invoke_I
(
Object
a0
,
long
a1
,
long
a2
)
throws
Throwable
{
return
return_I
(
targetA3
(
a0
,
a1
,
a2
));
}
protected
long
invoke_J
(
Object
a0
,
long
a1
,
long
a2
)
{
return
return_J
(
targetA3
(
a0
,
a1
,
a2
));
}
protected
long
invoke_J
(
Object
a0
,
long
a1
,
long
a2
)
throws
Throwable
{
return
return_J
(
targetA3
(
a0
,
a1
,
a2
));
}
protected
float
invoke_F
(
Object
a0
,
long
a1
,
long
a2
)
{
return
return_F
(
targetA3
(
a0
,
a1
,
a2
));
}
protected
float
invoke_F
(
Object
a0
,
long
a1
,
long
a2
)
throws
Throwable
{
return
return_F
(
targetA3
(
a0
,
a1
,
a2
));
}
protected
double
invoke_D
(
Object
a0
,
long
a1
,
long
a2
)
{
return
return_D
(
targetA3
(
a0
,
a1
,
a2
));
}
protected
double
invoke_D
(
Object
a0
,
long
a1
,
long
a2
)
throws
Throwable
{
return
return_D
(
targetA3
(
a0
,
a1
,
a2
));
}
protected
Object
invoke_L
(
long
a0
,
long
a1
,
long
a2
)
{
return
return_L
(
targetA3
(
a0
,
a1
,
a2
));
}
protected
Object
invoke_L
(
long
a0
,
long
a1
,
long
a2
)
throws
Throwable
{
return
return_L
(
targetA3
(
a0
,
a1
,
a2
));
}
protected
int
invoke_I
(
long
a0
,
long
a1
,
long
a2
)
{
return
return_I
(
targetA3
(
a0
,
a1
,
a2
));
}
protected
int
invoke_I
(
long
a0
,
long
a1
,
long
a2
)
throws
Throwable
{
return
return_I
(
targetA3
(
a0
,
a1
,
a2
));
}
protected
long
invoke_J
(
long
a0
,
long
a1
,
long
a2
)
{
return
return_J
(
targetA3
(
a0
,
a1
,
a2
));
}
protected
long
invoke_J
(
long
a0
,
long
a1
,
long
a2
)
throws
Throwable
{
return
return_J
(
targetA3
(
a0
,
a1
,
a2
));
}
protected
float
invoke_F
(
long
a0
,
long
a1
,
long
a2
)
{
return
return_F
(
targetA3
(
a0
,
a1
,
a2
));
}
protected
float
invoke_F
(
long
a0
,
long
a1
,
long
a2
)
throws
Throwable
{
return
return_F
(
targetA3
(
a0
,
a1
,
a2
));
}
protected
double
invoke_D
(
long
a0
,
long
a1
,
long
a2
)
{
return
return_D
(
targetA3
(
a0
,
a1
,
a2
));
}
protected
double
invoke_D
(
long
a0
,
long
a1
,
long
a2
)
throws
Throwable
{
return
return_D
(
targetA3
(
a0
,
a1
,
a2
));
}
}
}
//params=[4, 5, 2, 99, 99, 99]
//params=[4, 5, 2, 99, 99, 99]
static
class
A4
extends
Adapter
{
static
class
A4
extends
Adapter
{
protected
A4
(
MethodHandle
entryPoint
)
{
super
(
entryPoint
);
}
// to build prototype
protected
A4
(
MethodHandle
entryPoint
)
{
super
(
entryPoint
);
}
// to build prototype
protected
A4
(
MethodHandle
e
,
MethodHandle
i
,
MethodHandle
c
,
MethodHandle
t
)
{
super
(
e
,
i
,
c
,
t
);
}
protected
A4
(
MethodHandle
e
,
MethodHandle
i
,
MethodHandle
c
,
MethodHandle
t
)
{
super
(
e
,
i
,
c
,
t
);
}
protected
A4
makeInstance
(
MethodHandle
e
,
MethodHandle
i
,
MethodHandle
c
,
MethodHandle
t
)
{
return
new
A4
(
e
,
i
,
c
,
t
);
}
protected
A4
makeInstance
(
MethodHandle
e
,
MethodHandle
i
,
MethodHandle
c
,
MethodHandle
t
)
{
return
new
A4
(
e
,
i
,
c
,
t
);
}
protected
Object
target
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
)
{
return
invoker
.<
Object
>
invoke
(
target
,
a0
,
a1
,
a2
,
a3
);
}
protected
Object
target
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
)
throws
Throwable
{
return
invoker
.<
Object
>
invoke
(
target
,
a0
,
a1
,
a2
,
a3
);
}
protected
Object
targetA4
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
)
{
return
target
(
a0
,
a1
,
a2
,
a3
);
}
protected
Object
targetA4
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
)
throws
Throwable
{
return
target
(
a0
,
a1
,
a2
,
a3
);
}
protected
Object
targetA4
(
Object
a0
,
Object
a1
,
Object
a2
,
int
a3
)
{
return
target
(
a0
,
a1
,
a2
,
a3
);
}
protected
Object
targetA4
(
Object
a0
,
Object
a1
,
Object
a2
,
int
a3
)
throws
Throwable
{
return
target
(
a0
,
a1
,
a2
,
a3
);
}
protected
Object
targetA4
(
Object
a0
,
Object
a1
,
int
a2
,
int
a3
)
{
return
target
(
a0
,
a1
,
a2
,
a3
);
}
protected
Object
targetA4
(
Object
a0
,
Object
a1
,
int
a2
,
int
a3
)
throws
Throwable
{
return
target
(
a0
,
a1
,
a2
,
a3
);
}
protected
Object
targetA4
(
Object
a0
,
int
a1
,
int
a2
,
int
a3
)
{
return
target
(
a0
,
a1
,
a2
,
a3
);
}
protected
Object
targetA4
(
Object
a0
,
int
a1
,
int
a2
,
int
a3
)
throws
Throwable
{
return
target
(
a0
,
a1
,
a2
,
a3
);
}
protected
Object
targetA4
(
int
a0
,
int
a1
,
int
a2
,
int
a3
)
{
return
target
(
a0
,
a1
,
a2
,
a3
);
}
protected
Object
targetA4
(
int
a0
,
int
a1
,
int
a2
,
int
a3
)
throws
Throwable
{
return
target
(
a0
,
a1
,
a2
,
a3
);
}
protected
Object
targetA4
(
Object
a0
,
Object
a1
,
Object
a2
,
long
a3
)
{
return
target
(
a0
,
a1
,
a2
,
a3
);
}
protected
Object
targetA4
(
Object
a0
,
Object
a1
,
Object
a2
,
long
a3
)
throws
Throwable
{
return
target
(
a0
,
a1
,
a2
,
a3
);
}
protected
Object
targetA4
(
Object
a0
,
Object
a1
,
long
a2
,
long
a3
)
{
return
target
(
a0
,
a1
,
a2
,
a3
);
}
protected
Object
targetA4
(
Object
a0
,
Object
a1
,
long
a2
,
long
a3
)
throws
Throwable
{
return
target
(
a0
,
a1
,
a2
,
a3
);
}
protected
Object
targetA4
(
Object
a0
,
long
a1
,
long
a2
,
long
a3
)
{
return
target
(
a0
,
a1
,
a2
,
a3
);
}
protected
Object
targetA4
(
Object
a0
,
long
a1
,
long
a2
,
long
a3
)
throws
Throwable
{
return
target
(
a0
,
a1
,
a2
,
a3
);
}
protected
Object
targetA4
(
long
a0
,
long
a1
,
long
a2
,
long
a3
)
{
return
target
(
a0
,
a1
,
a2
,
a3
);
}
protected
Object
targetA4
(
long
a0
,
long
a1
,
long
a2
,
long
a3
)
throws
Throwable
{
return
target
(
a0
,
a1
,
a2
,
a3
);
}
protected
Object
invoke_L
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
)
{
return
return_L
(
targetA4
(
a0
,
a1
,
a2
,
a3
));
}
protected
Object
invoke_L
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
)
throws
Throwable
{
return
return_L
(
targetA4
(
a0
,
a1
,
a2
,
a3
));
}
protected
int
invoke_I
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
)
{
return
return_I
(
targetA4
(
a0
,
a1
,
a2
,
a3
));
}
protected
int
invoke_I
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
)
throws
Throwable
{
return
return_I
(
targetA4
(
a0
,
a1
,
a2
,
a3
));
}
protected
long
invoke_J
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
)
{
return
return_J
(
targetA4
(
a0
,
a1
,
a2
,
a3
));
}
protected
long
invoke_J
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
)
throws
Throwable
{
return
return_J
(
targetA4
(
a0
,
a1
,
a2
,
a3
));
}
protected
Object
invoke_L
(
Object
a0
,
Object
a1
,
Object
a2
,
int
a3
)
{
return
return_L
(
targetA4
(
a0
,
a1
,
a2
,
a3
));
}
protected
Object
invoke_L
(
Object
a0
,
Object
a1
,
Object
a2
,
int
a3
)
throws
Throwable
{
return
return_L
(
targetA4
(
a0
,
a1
,
a2
,
a3
));
}
protected
int
invoke_I
(
Object
a0
,
Object
a1
,
Object
a2
,
int
a3
)
{
return
return_I
(
targetA4
(
a0
,
a1
,
a2
,
a3
));
}
protected
int
invoke_I
(
Object
a0
,
Object
a1
,
Object
a2
,
int
a3
)
throws
Throwable
{
return
return_I
(
targetA4
(
a0
,
a1
,
a2
,
a3
));
}
protected
long
invoke_J
(
Object
a0
,
Object
a1
,
Object
a2
,
int
a3
)
{
return
return_J
(
targetA4
(
a0
,
a1
,
a2
,
a3
));
}
protected
long
invoke_J
(
Object
a0
,
Object
a1
,
Object
a2
,
int
a3
)
throws
Throwable
{
return
return_J
(
targetA4
(
a0
,
a1
,
a2
,
a3
));
}
protected
Object
invoke_L
(
Object
a0
,
Object
a1
,
int
a2
,
int
a3
)
{
return
return_L
(
targetA4
(
a0
,
a1
,
a2
,
a3
));
}
protected
Object
invoke_L
(
Object
a0
,
Object
a1
,
int
a2
,
int
a3
)
throws
Throwable
{
return
return_L
(
targetA4
(
a0
,
a1
,
a2
,
a3
));
}
protected
int
invoke_I
(
Object
a0
,
Object
a1
,
int
a2
,
int
a3
)
{
return
return_I
(
targetA4
(
a0
,
a1
,
a2
,
a3
));
}
protected
int
invoke_I
(
Object
a0
,
Object
a1
,
int
a2
,
int
a3
)
throws
Throwable
{
return
return_I
(
targetA4
(
a0
,
a1
,
a2
,
a3
));
}
protected
long
invoke_J
(
Object
a0
,
Object
a1
,
int
a2
,
int
a3
)
{
return
return_J
(
targetA4
(
a0
,
a1
,
a2
,
a3
));
}
protected
long
invoke_J
(
Object
a0
,
Object
a1
,
int
a2
,
int
a3
)
throws
Throwable
{
return
return_J
(
targetA4
(
a0
,
a1
,
a2
,
a3
));
}
protected
Object
invoke_L
(
Object
a0
,
int
a1
,
int
a2
,
int
a3
)
{
return
return_L
(
targetA4
(
a0
,
a1
,
a2
,
a3
));
}
protected
Object
invoke_L
(
Object
a0
,
int
a1
,
int
a2
,
int
a3
)
throws
Throwable
{
return
return_L
(
targetA4
(
a0
,
a1
,
a2
,
a3
));
}
protected
int
invoke_I
(
Object
a0
,
int
a1
,
int
a2
,
int
a3
)
{
return
return_I
(
targetA4
(
a0
,
a1
,
a2
,
a3
));
}
protected
int
invoke_I
(
Object
a0
,
int
a1
,
int
a2
,
int
a3
)
throws
Throwable
{
return
return_I
(
targetA4
(
a0
,
a1
,
a2
,
a3
));
}
protected
long
invoke_J
(
Object
a0
,
int
a1
,
int
a2
,
int
a3
)
{
return
return_J
(
targetA4
(
a0
,
a1
,
a2
,
a3
));
}
protected
long
invoke_J
(
Object
a0
,
int
a1
,
int
a2
,
int
a3
)
throws
Throwable
{
return
return_J
(
targetA4
(
a0
,
a1
,
a2
,
a3
));
}
protected
Object
invoke_L
(
int
a0
,
int
a1
,
int
a2
,
int
a3
)
{
return
return_L
(
targetA4
(
a0
,
a1
,
a2
,
a3
));
}
protected
Object
invoke_L
(
int
a0
,
int
a1
,
int
a2
,
int
a3
)
throws
Throwable
{
return
return_L
(
targetA4
(
a0
,
a1
,
a2
,
a3
));
}
protected
int
invoke_I
(
int
a0
,
int
a1
,
int
a2
,
int
a3
)
{
return
return_I
(
targetA4
(
a0
,
a1
,
a2
,
a3
));
}
protected
int
invoke_I
(
int
a0
,
int
a1
,
int
a2
,
int
a3
)
throws
Throwable
{
return
return_I
(
targetA4
(
a0
,
a1
,
a2
,
a3
));
}
protected
long
invoke_J
(
int
a0
,
int
a1
,
int
a2
,
int
a3
)
{
return
return_J
(
targetA4
(
a0
,
a1
,
a2
,
a3
));
}
protected
long
invoke_J
(
int
a0
,
int
a1
,
int
a2
,
int
a3
)
throws
Throwable
{
return
return_J
(
targetA4
(
a0
,
a1
,
a2
,
a3
));
}
protected
Object
invoke_L
(
Object
a0
,
Object
a1
,
Object
a2
,
long
a3
)
{
return
return_L
(
targetA4
(
a0
,
a1
,
a2
,
a3
));
}
protected
Object
invoke_L
(
Object
a0
,
Object
a1
,
Object
a2
,
long
a3
)
throws
Throwable
{
return
return_L
(
targetA4
(
a0
,
a1
,
a2
,
a3
));
}
protected
int
invoke_I
(
Object
a0
,
Object
a1
,
Object
a2
,
long
a3
)
{
return
return_I
(
targetA4
(
a0
,
a1
,
a2
,
a3
));
}
protected
int
invoke_I
(
Object
a0
,
Object
a1
,
Object
a2
,
long
a3
)
throws
Throwable
{
return
return_I
(
targetA4
(
a0
,
a1
,
a2
,
a3
));
}
protected
long
invoke_J
(
Object
a0
,
Object
a1
,
Object
a2
,
long
a3
)
{
return
return_J
(
targetA4
(
a0
,
a1
,
a2
,
a3
));
}
protected
long
invoke_J
(
Object
a0
,
Object
a1
,
Object
a2
,
long
a3
)
throws
Throwable
{
return
return_J
(
targetA4
(
a0
,
a1
,
a2
,
a3
));
}
protected
Object
invoke_L
(
Object
a0
,
Object
a1
,
long
a2
,
long
a3
)
{
return
return_L
(
targetA4
(
a0
,
a1
,
a2
,
a3
));
}
protected
Object
invoke_L
(
Object
a0
,
Object
a1
,
long
a2
,
long
a3
)
throws
Throwable
{
return
return_L
(
targetA4
(
a0
,
a1
,
a2
,
a3
));
}
protected
int
invoke_I
(
Object
a0
,
Object
a1
,
long
a2
,
long
a3
)
{
return
return_I
(
targetA4
(
a0
,
a1
,
a2
,
a3
));
}
protected
int
invoke_I
(
Object
a0
,
Object
a1
,
long
a2
,
long
a3
)
throws
Throwable
{
return
return_I
(
targetA4
(
a0
,
a1
,
a2
,
a3
));
}
protected
long
invoke_J
(
Object
a0
,
Object
a1
,
long
a2
,
long
a3
)
{
return
return_J
(
targetA4
(
a0
,
a1
,
a2
,
a3
));
}
protected
long
invoke_J
(
Object
a0
,
Object
a1
,
long
a2
,
long
a3
)
throws
Throwable
{
return
return_J
(
targetA4
(
a0
,
a1
,
a2
,
a3
));
}
protected
Object
invoke_L
(
Object
a0
,
long
a1
,
long
a2
,
long
a3
)
{
return
return_L
(
targetA4
(
a0
,
a1
,
a2
,
a3
));
}
protected
Object
invoke_L
(
Object
a0
,
long
a1
,
long
a2
,
long
a3
)
throws
Throwable
{
return
return_L
(
targetA4
(
a0
,
a1
,
a2
,
a3
));
}
protected
int
invoke_I
(
Object
a0
,
long
a1
,
long
a2
,
long
a3
)
{
return
return_I
(
targetA4
(
a0
,
a1
,
a2
,
a3
));
}
protected
int
invoke_I
(
Object
a0
,
long
a1
,
long
a2
,
long
a3
)
throws
Throwable
{
return
return_I
(
targetA4
(
a0
,
a1
,
a2
,
a3
));
}
protected
long
invoke_J
(
Object
a0
,
long
a1
,
long
a2
,
long
a3
)
{
return
return_J
(
targetA4
(
a0
,
a1
,
a2
,
a3
));
}
protected
long
invoke_J
(
Object
a0
,
long
a1
,
long
a2
,
long
a3
)
throws
Throwable
{
return
return_J
(
targetA4
(
a0
,
a1
,
a2
,
a3
));
}
protected
Object
invoke_L
(
long
a0
,
long
a1
,
long
a2
,
long
a3
)
{
return
return_L
(
targetA4
(
a0
,
a1
,
a2
,
a3
));
}
protected
Object
invoke_L
(
long
a0
,
long
a1
,
long
a2
,
long
a3
)
throws
Throwable
{
return
return_L
(
targetA4
(
a0
,
a1
,
a2
,
a3
));
}
protected
int
invoke_I
(
long
a0
,
long
a1
,
long
a2
,
long
a3
)
{
return
return_I
(
targetA4
(
a0
,
a1
,
a2
,
a3
));
}
protected
int
invoke_I
(
long
a0
,
long
a1
,
long
a2
,
long
a3
)
throws
Throwable
{
return
return_I
(
targetA4
(
a0
,
a1
,
a2
,
a3
));
}
protected
long
invoke_J
(
long
a0
,
long
a1
,
long
a2
,
long
a3
)
{
return
return_J
(
targetA4
(
a0
,
a1
,
a2
,
a3
));
}
protected
long
invoke_J
(
long
a0
,
long
a1
,
long
a2
,
long
a3
)
throws
Throwable
{
return
return_J
(
targetA4
(
a0
,
a1
,
a2
,
a3
));
}
}
}
static
class
A5
extends
Adapter
{
static
class
A5
extends
Adapter
{
protected
A5
(
MethodHandle
entryPoint
)
{
super
(
entryPoint
);
}
// to build prototype
protected
A5
(
MethodHandle
entryPoint
)
{
super
(
entryPoint
);
}
// to build prototype
protected
A5
(
MethodHandle
e
,
MethodHandle
i
,
MethodHandle
c
,
MethodHandle
t
)
{
super
(
e
,
i
,
c
,
t
);
}
protected
A5
(
MethodHandle
e
,
MethodHandle
i
,
MethodHandle
c
,
MethodHandle
t
)
{
super
(
e
,
i
,
c
,
t
);
}
protected
A5
makeInstance
(
MethodHandle
e
,
MethodHandle
i
,
MethodHandle
c
,
MethodHandle
t
)
{
return
new
A5
(
e
,
i
,
c
,
t
);
}
protected
A5
makeInstance
(
MethodHandle
e
,
MethodHandle
i
,
MethodHandle
c
,
MethodHandle
t
)
{
return
new
A5
(
e
,
i
,
c
,
t
);
}
protected
Object
target
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
)
{
return
invoker
.<
Object
>
invoke
(
target
,
a0
,
a1
,
a2
,
a3
,
a4
);
}
protected
Object
target
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
)
throws
Throwable
{
return
invoker
.<
Object
>
invoke
(
target
,
a0
,
a1
,
a2
,
a3
,
a4
);
}
protected
Object
targetA5
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
)
{
return
target
(
a0
,
a1
,
a2
,
a3
,
a4
);
}
protected
Object
targetA5
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
)
throws
Throwable
{
return
target
(
a0
,
a1
,
a2
,
a3
,
a4
);
}
protected
Object
targetA5
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
int
a4
)
{
return
target
(
a0
,
a1
,
a2
,
a3
,
a4
);
}
protected
Object
targetA5
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
int
a4
)
throws
Throwable
{
return
target
(
a0
,
a1
,
a2
,
a3
,
a4
);
}
protected
Object
targetA5
(
Object
a0
,
Object
a1
,
Object
a2
,
int
a3
,
int
a4
)
{
return
target
(
a0
,
a1
,
a2
,
a3
,
a4
);
}
protected
Object
targetA5
(
Object
a0
,
Object
a1
,
Object
a2
,
int
a3
,
int
a4
)
throws
Throwable
{
return
target
(
a0
,
a1
,
a2
,
a3
,
a4
);
}
protected
Object
targetA5
(
Object
a0
,
Object
a1
,
int
a2
,
int
a3
,
int
a4
)
{
return
target
(
a0
,
a1
,
a2
,
a3
,
a4
);
}
protected
Object
targetA5
(
Object
a0
,
Object
a1
,
int
a2
,
int
a3
,
int
a4
)
throws
Throwable
{
return
target
(
a0
,
a1
,
a2
,
a3
,
a4
);
}
protected
Object
targetA5
(
Object
a0
,
int
a1
,
int
a2
,
int
a3
,
int
a4
)
{
return
target
(
a0
,
a1
,
a2
,
a3
,
a4
);
}
protected
Object
targetA5
(
Object
a0
,
int
a1
,
int
a2
,
int
a3
,
int
a4
)
throws
Throwable
{
return
target
(
a0
,
a1
,
a2
,
a3
,
a4
);
}
protected
Object
targetA5
(
int
a0
,
int
a1
,
int
a2
,
int
a3
,
int
a4
)
{
return
target
(
a0
,
a1
,
a2
,
a3
,
a4
);
}
protected
Object
targetA5
(
int
a0
,
int
a1
,
int
a2
,
int
a3
,
int
a4
)
throws
Throwable
{
return
target
(
a0
,
a1
,
a2
,
a3
,
a4
);
}
protected
Object
targetA5
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
long
a4
)
{
return
target
(
a0
,
a1
,
a2
,
a3
,
a4
);
}
protected
Object
targetA5
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
long
a4
)
throws
Throwable
{
return
target
(
a0
,
a1
,
a2
,
a3
,
a4
);
}
protected
Object
targetA5
(
Object
a0
,
Object
a1
,
Object
a2
,
long
a3
,
long
a4
)
{
return
target
(
a0
,
a1
,
a2
,
a3
,
a4
);
}
protected
Object
targetA5
(
Object
a0
,
Object
a1
,
Object
a2
,
long
a3
,
long
a4
)
throws
Throwable
{
return
target
(
a0
,
a1
,
a2
,
a3
,
a4
);
}
protected
Object
targetA5
(
Object
a0
,
Object
a1
,
long
a2
,
long
a3
,
long
a4
)
{
return
target
(
a0
,
a1
,
a2
,
a3
,
a4
);
}
protected
Object
targetA5
(
Object
a0
,
Object
a1
,
long
a2
,
long
a3
,
long
a4
)
throws
Throwable
{
return
target
(
a0
,
a1
,
a2
,
a3
,
a4
);
}
protected
Object
targetA5
(
Object
a0
,
long
a1
,
long
a2
,
long
a3
,
long
a4
)
{
return
target
(
a0
,
a1
,
a2
,
a3
,
a4
);
}
protected
Object
targetA5
(
Object
a0
,
long
a1
,
long
a2
,
long
a3
,
long
a4
)
throws
Throwable
{
return
target
(
a0
,
a1
,
a2
,
a3
,
a4
);
}
protected
Object
targetA5
(
long
a0
,
long
a1
,
long
a2
,
long
a3
,
long
a4
)
{
return
target
(
a0
,
a1
,
a2
,
a3
,
a4
);
}
protected
Object
targetA5
(
long
a0
,
long
a1
,
long
a2
,
long
a3
,
long
a4
)
throws
Throwable
{
return
target
(
a0
,
a1
,
a2
,
a3
,
a4
);
}
protected
Object
invoke_L
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
)
{
return
return_L
(
targetA5
(
a0
,
a1
,
a2
,
a3
,
a4
));
}
protected
Object
invoke_L
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
)
throws
Throwable
{
return
return_L
(
targetA5
(
a0
,
a1
,
a2
,
a3
,
a4
));
}
protected
int
invoke_I
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
)
{
return
return_I
(
targetA5
(
a0
,
a1
,
a2
,
a3
,
a4
));
}
protected
int
invoke_I
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
)
throws
Throwable
{
return
return_I
(
targetA5
(
a0
,
a1
,
a2
,
a3
,
a4
));
}
protected
long
invoke_J
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
)
{
return
return_J
(
targetA5
(
a0
,
a1
,
a2
,
a3
,
a4
));
}
protected
long
invoke_J
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
)
throws
Throwable
{
return
return_J
(
targetA5
(
a0
,
a1
,
a2
,
a3
,
a4
));
}
protected
Object
invoke_L
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
int
a4
)
{
return
return_L
(
targetA5
(
a0
,
a1
,
a2
,
a3
,
a4
));
}
protected
Object
invoke_L
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
int
a4
)
throws
Throwable
{
return
return_L
(
targetA5
(
a0
,
a1
,
a2
,
a3
,
a4
));
}
protected
int
invoke_I
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
int
a4
)
{
return
return_I
(
targetA5
(
a0
,
a1
,
a2
,
a3
,
a4
));
}
protected
int
invoke_I
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
int
a4
)
throws
Throwable
{
return
return_I
(
targetA5
(
a0
,
a1
,
a2
,
a3
,
a4
));
}
protected
long
invoke_J
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
int
a4
)
{
return
return_J
(
targetA5
(
a0
,
a1
,
a2
,
a3
,
a4
));
}
protected
long
invoke_J
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
int
a4
)
throws
Throwable
{
return
return_J
(
targetA5
(
a0
,
a1
,
a2
,
a3
,
a4
));
}
protected
Object
invoke_L
(
Object
a0
,
Object
a1
,
Object
a2
,
int
a3
,
int
a4
)
{
return
return_L
(
targetA5
(
a0
,
a1
,
a2
,
a3
,
a4
));
}
protected
Object
invoke_L
(
Object
a0
,
Object
a1
,
Object
a2
,
int
a3
,
int
a4
)
throws
Throwable
{
return
return_L
(
targetA5
(
a0
,
a1
,
a2
,
a3
,
a4
));
}
protected
int
invoke_I
(
Object
a0
,
Object
a1
,
Object
a2
,
int
a3
,
int
a4
)
{
return
return_I
(
targetA5
(
a0
,
a1
,
a2
,
a3
,
a4
));
}
protected
int
invoke_I
(
Object
a0
,
Object
a1
,
Object
a2
,
int
a3
,
int
a4
)
throws
Throwable
{
return
return_I
(
targetA5
(
a0
,
a1
,
a2
,
a3
,
a4
));
}
protected
long
invoke_J
(
Object
a0
,
Object
a1
,
Object
a2
,
int
a3
,
int
a4
)
{
return
return_J
(
targetA5
(
a0
,
a1
,
a2
,
a3
,
a4
));
}
protected
long
invoke_J
(
Object
a0
,
Object
a1
,
Object
a2
,
int
a3
,
int
a4
)
throws
Throwable
{
return
return_J
(
targetA5
(
a0
,
a1
,
a2
,
a3
,
a4
));
}
protected
Object
invoke_L
(
Object
a0
,
Object
a1
,
int
a2
,
int
a3
,
int
a4
)
{
return
return_L
(
targetA5
(
a0
,
a1
,
a2
,
a3
,
a4
));
}
protected
Object
invoke_L
(
Object
a0
,
Object
a1
,
int
a2
,
int
a3
,
int
a4
)
throws
Throwable
{
return
return_L
(
targetA5
(
a0
,
a1
,
a2
,
a3
,
a4
));
}
protected
int
invoke_I
(
Object
a0
,
Object
a1
,
int
a2
,
int
a3
,
int
a4
)
{
return
return_I
(
targetA5
(
a0
,
a1
,
a2
,
a3
,
a4
));
}
protected
int
invoke_I
(
Object
a0
,
Object
a1
,
int
a2
,
int
a3
,
int
a4
)
throws
Throwable
{
return
return_I
(
targetA5
(
a0
,
a1
,
a2
,
a3
,
a4
));
}
protected
long
invoke_J
(
Object
a0
,
Object
a1
,
int
a2
,
int
a3
,
int
a4
)
{
return
return_J
(
targetA5
(
a0
,
a1
,
a2
,
a3
,
a4
));
}
protected
long
invoke_J
(
Object
a0
,
Object
a1
,
int
a2
,
int
a3
,
int
a4
)
throws
Throwable
{
return
return_J
(
targetA5
(
a0
,
a1
,
a2
,
a3
,
a4
));
}
protected
Object
invoke_L
(
Object
a0
,
int
a1
,
int
a2
,
int
a3
,
int
a4
)
{
return
return_L
(
targetA5
(
a0
,
a1
,
a2
,
a3
,
a4
));
}
protected
Object
invoke_L
(
Object
a0
,
int
a1
,
int
a2
,
int
a3
,
int
a4
)
throws
Throwable
{
return
return_L
(
targetA5
(
a0
,
a1
,
a2
,
a3
,
a4
));
}
protected
int
invoke_I
(
Object
a0
,
int
a1
,
int
a2
,
int
a3
,
int
a4
)
{
return
return_I
(
targetA5
(
a0
,
a1
,
a2
,
a3
,
a4
));
}
protected
int
invoke_I
(
Object
a0
,
int
a1
,
int
a2
,
int
a3
,
int
a4
)
throws
Throwable
{
return
return_I
(
targetA5
(
a0
,
a1
,
a2
,
a3
,
a4
));
}
protected
long
invoke_J
(
Object
a0
,
int
a1
,
int
a2
,
int
a3
,
int
a4
)
{
return
return_J
(
targetA5
(
a0
,
a1
,
a2
,
a3
,
a4
));
}
protected
long
invoke_J
(
Object
a0
,
int
a1
,
int
a2
,
int
a3
,
int
a4
)
throws
Throwable
{
return
return_J
(
targetA5
(
a0
,
a1
,
a2
,
a3
,
a4
));
}
protected
Object
invoke_L
(
int
a0
,
int
a1
,
int
a2
,
int
a3
,
int
a4
)
{
return
return_L
(
targetA5
(
a0
,
a1
,
a2
,
a3
,
a4
));
}
protected
Object
invoke_L
(
int
a0
,
int
a1
,
int
a2
,
int
a3
,
int
a4
)
throws
Throwable
{
return
return_L
(
targetA5
(
a0
,
a1
,
a2
,
a3
,
a4
));
}
protected
int
invoke_I
(
int
a0
,
int
a1
,
int
a2
,
int
a3
,
int
a4
)
{
return
return_I
(
targetA5
(
a0
,
a1
,
a2
,
a3
,
a4
));
}
protected
int
invoke_I
(
int
a0
,
int
a1
,
int
a2
,
int
a3
,
int
a4
)
throws
Throwable
{
return
return_I
(
targetA5
(
a0
,
a1
,
a2
,
a3
,
a4
));
}
protected
long
invoke_J
(
int
a0
,
int
a1
,
int
a2
,
int
a3
,
int
a4
)
{
return
return_J
(
targetA5
(
a0
,
a1
,
a2
,
a3
,
a4
));
}
protected
long
invoke_J
(
int
a0
,
int
a1
,
int
a2
,
int
a3
,
int
a4
)
throws
Throwable
{
return
return_J
(
targetA5
(
a0
,
a1
,
a2
,
a3
,
a4
));
}
protected
Object
invoke_L
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
long
a4
)
{
return
return_L
(
targetA5
(
a0
,
a1
,
a2
,
a3
,
a4
));
}
protected
Object
invoke_L
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
long
a4
)
throws
Throwable
{
return
return_L
(
targetA5
(
a0
,
a1
,
a2
,
a3
,
a4
));
}
protected
int
invoke_I
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
long
a4
)
{
return
return_I
(
targetA5
(
a0
,
a1
,
a2
,
a3
,
a4
));
}
protected
int
invoke_I
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
long
a4
)
throws
Throwable
{
return
return_I
(
targetA5
(
a0
,
a1
,
a2
,
a3
,
a4
));
}
protected
long
invoke_J
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
long
a4
)
{
return
return_J
(
targetA5
(
a0
,
a1
,
a2
,
a3
,
a4
));
}
protected
long
invoke_J
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
long
a4
)
throws
Throwable
{
return
return_J
(
targetA5
(
a0
,
a1
,
a2
,
a3
,
a4
));
}
protected
Object
invoke_L
(
Object
a0
,
Object
a1
,
Object
a2
,
long
a3
,
long
a4
)
{
return
return_L
(
targetA5
(
a0
,
a1
,
a2
,
a3
,
a4
));
}
protected
Object
invoke_L
(
Object
a0
,
Object
a1
,
Object
a2
,
long
a3
,
long
a4
)
throws
Throwable
{
return
return_L
(
targetA5
(
a0
,
a1
,
a2
,
a3
,
a4
));
}
protected
int
invoke_I
(
Object
a0
,
Object
a1
,
Object
a2
,
long
a3
,
long
a4
)
{
return
return_I
(
targetA5
(
a0
,
a1
,
a2
,
a3
,
a4
));
}
protected
int
invoke_I
(
Object
a0
,
Object
a1
,
Object
a2
,
long
a3
,
long
a4
)
throws
Throwable
{
return
return_I
(
targetA5
(
a0
,
a1
,
a2
,
a3
,
a4
));
}
protected
long
invoke_J
(
Object
a0
,
Object
a1
,
Object
a2
,
long
a3
,
long
a4
)
{
return
return_J
(
targetA5
(
a0
,
a1
,
a2
,
a3
,
a4
));
}
protected
long
invoke_J
(
Object
a0
,
Object
a1
,
Object
a2
,
long
a3
,
long
a4
)
throws
Throwable
{
return
return_J
(
targetA5
(
a0
,
a1
,
a2
,
a3
,
a4
));
}
protected
Object
invoke_L
(
Object
a0
,
Object
a1
,
long
a2
,
long
a3
,
long
a4
)
{
return
return_L
(
targetA5
(
a0
,
a1
,
a2
,
a3
,
a4
));
}
protected
Object
invoke_L
(
Object
a0
,
Object
a1
,
long
a2
,
long
a3
,
long
a4
)
throws
Throwable
{
return
return_L
(
targetA5
(
a0
,
a1
,
a2
,
a3
,
a4
));
}
protected
int
invoke_I
(
Object
a0
,
Object
a1
,
long
a2
,
long
a3
,
long
a4
)
{
return
return_I
(
targetA5
(
a0
,
a1
,
a2
,
a3
,
a4
));
}
protected
int
invoke_I
(
Object
a0
,
Object
a1
,
long
a2
,
long
a3
,
long
a4
)
throws
Throwable
{
return
return_I
(
targetA5
(
a0
,
a1
,
a2
,
a3
,
a4
));
}
protected
long
invoke_J
(
Object
a0
,
Object
a1
,
long
a2
,
long
a3
,
long
a4
)
{
return
return_J
(
targetA5
(
a0
,
a1
,
a2
,
a3
,
a4
));
}
protected
long
invoke_J
(
Object
a0
,
Object
a1
,
long
a2
,
long
a3
,
long
a4
)
throws
Throwable
{
return
return_J
(
targetA5
(
a0
,
a1
,
a2
,
a3
,
a4
));
}
protected
Object
invoke_L
(
Object
a0
,
long
a1
,
long
a2
,
long
a3
,
long
a4
)
{
return
return_L
(
targetA5
(
a0
,
a1
,
a2
,
a3
,
a4
));
}
protected
Object
invoke_L
(
Object
a0
,
long
a1
,
long
a2
,
long
a3
,
long
a4
)
throws
Throwable
{
return
return_L
(
targetA5
(
a0
,
a1
,
a2
,
a3
,
a4
));
}
protected
int
invoke_I
(
Object
a0
,
long
a1
,
long
a2
,
long
a3
,
long
a4
)
{
return
return_I
(
targetA5
(
a0
,
a1
,
a2
,
a3
,
a4
));
}
protected
int
invoke_I
(
Object
a0
,
long
a1
,
long
a2
,
long
a3
,
long
a4
)
throws
Throwable
{
return
return_I
(
targetA5
(
a0
,
a1
,
a2
,
a3
,
a4
));
}
protected
long
invoke_J
(
Object
a0
,
long
a1
,
long
a2
,
long
a3
,
long
a4
)
{
return
return_J
(
targetA5
(
a0
,
a1
,
a2
,
a3
,
a4
));
}
protected
long
invoke_J
(
Object
a0
,
long
a1
,
long
a2
,
long
a3
,
long
a4
)
throws
Throwable
{
return
return_J
(
targetA5
(
a0
,
a1
,
a2
,
a3
,
a4
));
}
protected
Object
invoke_L
(
long
a0
,
long
a1
,
long
a2
,
long
a3
,
long
a4
)
{
return
return_L
(
targetA5
(
a0
,
a1
,
a2
,
a3
,
a4
));
}
protected
Object
invoke_L
(
long
a0
,
long
a1
,
long
a2
,
long
a3
,
long
a4
)
throws
Throwable
{
return
return_L
(
targetA5
(
a0
,
a1
,
a2
,
a3
,
a4
));
}
protected
int
invoke_I
(
long
a0
,
long
a1
,
long
a2
,
long
a3
,
long
a4
)
{
return
return_I
(
targetA5
(
a0
,
a1
,
a2
,
a3
,
a4
));
}
protected
int
invoke_I
(
long
a0
,
long
a1
,
long
a2
,
long
a3
,
long
a4
)
throws
Throwable
{
return
return_I
(
targetA5
(
a0
,
a1
,
a2
,
a3
,
a4
));
}
protected
long
invoke_J
(
long
a0
,
long
a1
,
long
a2
,
long
a3
,
long
a4
)
{
return
return_J
(
targetA5
(
a0
,
a1
,
a2
,
a3
,
a4
));
}
protected
long
invoke_J
(
long
a0
,
long
a1
,
long
a2
,
long
a3
,
long
a4
)
throws
Throwable
{
return
return_J
(
targetA5
(
a0
,
a1
,
a2
,
a3
,
a4
));
}
}
}
//params=[6, 10, 2, 99, 0, 99]
//params=[6, 10, 2, 99, 0, 99]
static
class
A6
extends
Adapter
{
static
class
A6
extends
Adapter
{
protected
A6
(
MethodHandle
entryPoint
)
{
super
(
entryPoint
);
}
// to build prototype
protected
A6
(
MethodHandle
entryPoint
)
{
super
(
entryPoint
);
}
// to build prototype
protected
A6
(
MethodHandle
e
,
MethodHandle
i
,
MethodHandle
c
,
MethodHandle
t
)
{
super
(
e
,
i
,
c
,
t
);
}
protected
A6
(
MethodHandle
e
,
MethodHandle
i
,
MethodHandle
c
,
MethodHandle
t
)
{
super
(
e
,
i
,
c
,
t
);
}
protected
A6
makeInstance
(
MethodHandle
e
,
MethodHandle
i
,
MethodHandle
c
,
MethodHandle
t
)
{
return
new
A6
(
e
,
i
,
c
,
t
);
}
protected
A6
makeInstance
(
MethodHandle
e
,
MethodHandle
i
,
MethodHandle
c
,
MethodHandle
t
)
{
return
new
A6
(
e
,
i
,
c
,
t
);
}
protected
Object
target
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
)
{
return
invoker
.<
Object
>
invoke
(
target
,
a0
,
a1
,
a2
,
a3
,
a4
,
a5
);
}
protected
Object
target
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
)
throws
Throwable
{
return
invoker
.<
Object
>
invoke
(
target
,
a0
,
a1
,
a2
,
a3
,
a4
,
a5
);
}
protected
Object
targetA6
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
)
{
return
target
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
);
}
protected
Object
targetA6
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
)
throws
Throwable
{
return
target
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
);
}
protected
Object
targetA6
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
long
a5
)
{
return
target
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
);
}
protected
Object
targetA6
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
long
a5
)
throws
Throwable
{
return
target
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
);
}
protected
Object
targetA6
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
long
a4
,
long
a5
)
{
return
target
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
);
}
protected
Object
targetA6
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
long
a4
,
long
a5
)
throws
Throwable
{
return
target
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
);
}
protected
Object
targetA6
(
Object
a0
,
Object
a1
,
Object
a2
,
long
a3
,
long
a4
,
long
a5
)
{
return
target
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
);
}
protected
Object
targetA6
(
Object
a0
,
Object
a1
,
Object
a2
,
long
a3
,
long
a4
,
long
a5
)
throws
Throwable
{
return
target
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
);
}
protected
Object
targetA6
(
Object
a0
,
Object
a1
,
long
a2
,
long
a3
,
long
a4
,
long
a5
)
{
return
target
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
);
}
protected
Object
targetA6
(
Object
a0
,
Object
a1
,
long
a2
,
long
a3
,
long
a4
,
long
a5
)
throws
Throwable
{
return
target
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
);
}
protected
Object
targetA6
(
Object
a0
,
long
a1
,
long
a2
,
long
a3
,
long
a4
,
long
a5
)
{
return
target
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
);
}
protected
Object
targetA6
(
Object
a0
,
long
a1
,
long
a2
,
long
a3
,
long
a4
,
long
a5
)
throws
Throwable
{
return
target
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
);
}
protected
Object
targetA6
(
long
a0
,
long
a1
,
long
a2
,
long
a3
,
long
a4
,
long
a5
)
{
return
target
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
);
}
protected
Object
targetA6
(
long
a0
,
long
a1
,
long
a2
,
long
a3
,
long
a4
,
long
a5
)
throws
Throwable
{
return
target
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
);
}
protected
Object
invoke_L
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
)
{
return
return_L
(
targetA6
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
));
}
protected
Object
invoke_L
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
)
throws
Throwable
{
return
return_L
(
targetA6
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
));
}
protected
int
invoke_I
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
)
{
return
return_I
(
targetA6
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
));
}
protected
int
invoke_I
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
)
throws
Throwable
{
return
return_I
(
targetA6
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
));
}
protected
long
invoke_J
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
)
{
return
return_J
(
targetA6
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
));
}
protected
long
invoke_J
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
)
throws
Throwable
{
return
return_J
(
targetA6
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
));
}
protected
Object
invoke_L
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
long
a5
)
{
return
return_L
(
targetA6
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
));
}
protected
Object
invoke_L
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
long
a5
)
throws
Throwable
{
return
return_L
(
targetA6
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
));
}
protected
int
invoke_I
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
long
a5
)
{
return
return_I
(
targetA6
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
));
}
protected
int
invoke_I
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
long
a5
)
throws
Throwable
{
return
return_I
(
targetA6
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
));
}
protected
long
invoke_J
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
long
a5
)
{
return
return_J
(
targetA6
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
));
}
protected
long
invoke_J
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
long
a5
)
throws
Throwable
{
return
return_J
(
targetA6
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
));
}
protected
Object
invoke_L
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
long
a4
,
long
a5
)
{
return
return_L
(
targetA6
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
));
}
protected
Object
invoke_L
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
long
a4
,
long
a5
)
throws
Throwable
{
return
return_L
(
targetA6
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
));
}
protected
int
invoke_I
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
long
a4
,
long
a5
)
{
return
return_I
(
targetA6
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
));
}
protected
int
invoke_I
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
long
a4
,
long
a5
)
throws
Throwable
{
return
return_I
(
targetA6
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
));
}
protected
long
invoke_J
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
long
a4
,
long
a5
)
{
return
return_J
(
targetA6
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
));
}
protected
long
invoke_J
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
long
a4
,
long
a5
)
throws
Throwable
{
return
return_J
(
targetA6
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
));
}
protected
Object
invoke_L
(
Object
a0
,
Object
a1
,
Object
a2
,
long
a3
,
long
a4
,
long
a5
)
{
return
return_L
(
targetA6
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
));
}
protected
Object
invoke_L
(
Object
a0
,
Object
a1
,
Object
a2
,
long
a3
,
long
a4
,
long
a5
)
throws
Throwable
{
return
return_L
(
targetA6
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
));
}
protected
int
invoke_I
(
Object
a0
,
Object
a1
,
Object
a2
,
long
a3
,
long
a4
,
long
a5
)
{
return
return_I
(
targetA6
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
));
}
protected
int
invoke_I
(
Object
a0
,
Object
a1
,
Object
a2
,
long
a3
,
long
a4
,
long
a5
)
throws
Throwable
{
return
return_I
(
targetA6
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
));
}
protected
long
invoke_J
(
Object
a0
,
Object
a1
,
Object
a2
,
long
a3
,
long
a4
,
long
a5
)
{
return
return_J
(
targetA6
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
));
}
protected
long
invoke_J
(
Object
a0
,
Object
a1
,
Object
a2
,
long
a3
,
long
a4
,
long
a5
)
throws
Throwable
{
return
return_J
(
targetA6
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
));
}
protected
Object
invoke_L
(
Object
a0
,
Object
a1
,
long
a2
,
long
a3
,
long
a4
,
long
a5
)
{
return
return_L
(
targetA6
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
));
}
protected
Object
invoke_L
(
Object
a0
,
Object
a1
,
long
a2
,
long
a3
,
long
a4
,
long
a5
)
throws
Throwable
{
return
return_L
(
targetA6
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
));
}
protected
int
invoke_I
(
Object
a0
,
Object
a1
,
long
a2
,
long
a3
,
long
a4
,
long
a5
)
{
return
return_I
(
targetA6
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
));
}
protected
int
invoke_I
(
Object
a0
,
Object
a1
,
long
a2
,
long
a3
,
long
a4
,
long
a5
)
throws
Throwable
{
return
return_I
(
targetA6
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
));
}
protected
long
invoke_J
(
Object
a0
,
Object
a1
,
long
a2
,
long
a3
,
long
a4
,
long
a5
)
{
return
return_J
(
targetA6
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
));
}
protected
long
invoke_J
(
Object
a0
,
Object
a1
,
long
a2
,
long
a3
,
long
a4
,
long
a5
)
throws
Throwable
{
return
return_J
(
targetA6
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
));
}
protected
Object
invoke_L
(
Object
a0
,
long
a1
,
long
a2
,
long
a3
,
long
a4
,
long
a5
)
{
return
return_L
(
targetA6
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
));
}
protected
Object
invoke_L
(
Object
a0
,
long
a1
,
long
a2
,
long
a3
,
long
a4
,
long
a5
)
throws
Throwable
{
return
return_L
(
targetA6
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
));
}
protected
int
invoke_I
(
Object
a0
,
long
a1
,
long
a2
,
long
a3
,
long
a4
,
long
a5
)
{
return
return_I
(
targetA6
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
));
}
protected
int
invoke_I
(
Object
a0
,
long
a1
,
long
a2
,
long
a3
,
long
a4
,
long
a5
)
throws
Throwable
{
return
return_I
(
targetA6
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
));
}
protected
long
invoke_J
(
Object
a0
,
long
a1
,
long
a2
,
long
a3
,
long
a4
,
long
a5
)
{
return
return_J
(
targetA6
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
));
}
protected
long
invoke_J
(
Object
a0
,
long
a1
,
long
a2
,
long
a3
,
long
a4
,
long
a5
)
throws
Throwable
{
return
return_J
(
targetA6
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
));
}
protected
Object
invoke_L
(
long
a0
,
long
a1
,
long
a2
,
long
a3
,
long
a4
,
long
a5
)
{
return
return_L
(
targetA6
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
));
}
protected
Object
invoke_L
(
long
a0
,
long
a1
,
long
a2
,
long
a3
,
long
a4
,
long
a5
)
throws
Throwable
{
return
return_L
(
targetA6
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
));
}
protected
int
invoke_I
(
long
a0
,
long
a1
,
long
a2
,
long
a3
,
long
a4
,
long
a5
)
{
return
return_I
(
targetA6
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
));
}
protected
int
invoke_I
(
long
a0
,
long
a1
,
long
a2
,
long
a3
,
long
a4
,
long
a5
)
throws
Throwable
{
return
return_I
(
targetA6
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
));
}
protected
long
invoke_J
(
long
a0
,
long
a1
,
long
a2
,
long
a3
,
long
a4
,
long
a5
)
{
return
return_J
(
targetA6
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
));
}
protected
long
invoke_J
(
long
a0
,
long
a1
,
long
a2
,
long
a3
,
long
a4
,
long
a5
)
throws
Throwable
{
return
return_J
(
targetA6
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
));
}
}
}
static
class
A7
extends
Adapter
{
static
class
A7
extends
Adapter
{
protected
A7
(
MethodHandle
entryPoint
)
{
super
(
entryPoint
);
}
// to build prototype
protected
A7
(
MethodHandle
entryPoint
)
{
super
(
entryPoint
);
}
// to build prototype
protected
A7
(
MethodHandle
e
,
MethodHandle
i
,
MethodHandle
c
,
MethodHandle
t
)
{
super
(
e
,
i
,
c
,
t
);
}
protected
A7
(
MethodHandle
e
,
MethodHandle
i
,
MethodHandle
c
,
MethodHandle
t
)
{
super
(
e
,
i
,
c
,
t
);
}
protected
A7
makeInstance
(
MethodHandle
e
,
MethodHandle
i
,
MethodHandle
c
,
MethodHandle
t
)
{
return
new
A7
(
e
,
i
,
c
,
t
);
}
protected
A7
makeInstance
(
MethodHandle
e
,
MethodHandle
i
,
MethodHandle
c
,
MethodHandle
t
)
{
return
new
A7
(
e
,
i
,
c
,
t
);
}
protected
Object
target
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
a6
)
{
return
invoker
.<
Object
>
invoke
(
target
,
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
);
}
protected
Object
target
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
a6
)
throws
Throwable
{
return
invoker
.<
Object
>
invoke
(
target
,
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
);
}
protected
Object
targetA7
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
a6
)
{
return
target
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
);
}
protected
Object
targetA7
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
a6
)
throws
Throwable
{
return
target
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
);
}
protected
Object
targetA7
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
long
a6
)
{
return
target
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
);
}
protected
Object
targetA7
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
long
a6
)
throws
Throwable
{
return
target
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
);
}
protected
Object
targetA7
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
long
a5
,
long
a6
)
{
return
target
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
);
}
protected
Object
targetA7
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
long
a5
,
long
a6
)
throws
Throwable
{
return
target
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
);
}
protected
Object
targetA7
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
long
a4
,
long
a5
,
long
a6
)
{
return
target
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
);
}
protected
Object
targetA7
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
long
a4
,
long
a5
,
long
a6
)
throws
Throwable
{
return
target
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
);
}
protected
Object
targetA7
(
Object
a0
,
Object
a1
,
Object
a2
,
long
a3
,
long
a4
,
long
a5
,
long
a6
)
{
return
target
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
);
}
protected
Object
targetA7
(
Object
a0
,
Object
a1
,
Object
a2
,
long
a3
,
long
a4
,
long
a5
,
long
a6
)
throws
Throwable
{
return
target
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
);
}
protected
Object
targetA7
(
Object
a0
,
Object
a1
,
long
a2
,
long
a3
,
long
a4
,
long
a5
,
long
a6
)
{
return
target
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
);
}
protected
Object
targetA7
(
Object
a0
,
Object
a1
,
long
a2
,
long
a3
,
long
a4
,
long
a5
,
long
a6
)
throws
Throwable
{
return
target
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
);
}
protected
Object
targetA7
(
Object
a0
,
long
a1
,
long
a2
,
long
a3
,
long
a4
,
long
a5
,
long
a6
)
{
return
target
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
);
}
protected
Object
targetA7
(
Object
a0
,
long
a1
,
long
a2
,
long
a3
,
long
a4
,
long
a5
,
long
a6
)
throws
Throwable
{
return
target
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
);
}
protected
Object
targetA7
(
long
a0
,
long
a1
,
long
a2
,
long
a3
,
long
a4
,
long
a5
,
long
a6
)
{
return
target
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
);
}
protected
Object
targetA7
(
long
a0
,
long
a1
,
long
a2
,
long
a3
,
long
a4
,
long
a5
,
long
a6
)
throws
Throwable
{
return
target
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
);
}
protected
Object
invoke_L
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
a6
)
{
return
return_L
(
targetA7
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
));
}
protected
Object
invoke_L
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
a6
)
throws
Throwable
{
return
return_L
(
targetA7
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
));
}
protected
int
invoke_I
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
a6
)
{
return
return_I
(
targetA7
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
));
}
protected
int
invoke_I
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
a6
)
throws
Throwable
{
return
return_I
(
targetA7
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
));
}
protected
long
invoke_J
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
a6
)
{
return
return_J
(
targetA7
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
));
}
protected
long
invoke_J
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
a6
)
throws
Throwable
{
return
return_J
(
targetA7
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
));
}
protected
Object
invoke_L
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
long
a6
)
{
return
return_L
(
targetA7
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
));
}
protected
Object
invoke_L
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
long
a6
)
throws
Throwable
{
return
return_L
(
targetA7
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
));
}
protected
int
invoke_I
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
long
a6
)
{
return
return_I
(
targetA7
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
));
}
protected
int
invoke_I
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
long
a6
)
throws
Throwable
{
return
return_I
(
targetA7
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
));
}
protected
long
invoke_J
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
long
a6
)
{
return
return_J
(
targetA7
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
));
}
protected
long
invoke_J
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
long
a6
)
throws
Throwable
{
return
return_J
(
targetA7
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
));
}
protected
Object
invoke_L
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
long
a5
,
long
a6
)
{
return
return_L
(
targetA7
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
));
}
protected
Object
invoke_L
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
long
a5
,
long
a6
)
throws
Throwable
{
return
return_L
(
targetA7
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
));
}
protected
int
invoke_I
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
long
a5
,
long
a6
)
{
return
return_I
(
targetA7
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
));
}
protected
int
invoke_I
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
long
a5
,
long
a6
)
throws
Throwable
{
return
return_I
(
targetA7
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
));
}
protected
long
invoke_J
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
long
a5
,
long
a6
)
{
return
return_J
(
targetA7
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
));
}
protected
long
invoke_J
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
long
a5
,
long
a6
)
throws
Throwable
{
return
return_J
(
targetA7
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
));
}
protected
Object
invoke_L
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
long
a4
,
long
a5
,
long
a6
)
{
return
return_L
(
targetA7
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
));
}
protected
Object
invoke_L
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
long
a4
,
long
a5
,
long
a6
)
throws
Throwable
{
return
return_L
(
targetA7
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
));
}
protected
int
invoke_I
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
long
a4
,
long
a5
,
long
a6
)
{
return
return_I
(
targetA7
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
));
}
protected
int
invoke_I
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
long
a4
,
long
a5
,
long
a6
)
throws
Throwable
{
return
return_I
(
targetA7
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
));
}
protected
long
invoke_J
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
long
a4
,
long
a5
,
long
a6
)
{
return
return_J
(
targetA7
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
));
}
protected
long
invoke_J
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
long
a4
,
long
a5
,
long
a6
)
throws
Throwable
{
return
return_J
(
targetA7
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
));
}
protected
Object
invoke_L
(
Object
a0
,
Object
a1
,
Object
a2
,
long
a3
,
long
a4
,
long
a5
,
long
a6
)
{
return
return_L
(
targetA7
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
));
}
protected
Object
invoke_L
(
Object
a0
,
Object
a1
,
Object
a2
,
long
a3
,
long
a4
,
long
a5
,
long
a6
)
throws
Throwable
{
return
return_L
(
targetA7
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
));
}
protected
int
invoke_I
(
Object
a0
,
Object
a1
,
Object
a2
,
long
a3
,
long
a4
,
long
a5
,
long
a6
)
{
return
return_I
(
targetA7
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
));
}
protected
int
invoke_I
(
Object
a0
,
Object
a1
,
Object
a2
,
long
a3
,
long
a4
,
long
a5
,
long
a6
)
throws
Throwable
{
return
return_I
(
targetA7
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
));
}
protected
long
invoke_J
(
Object
a0
,
Object
a1
,
Object
a2
,
long
a3
,
long
a4
,
long
a5
,
long
a6
)
{
return
return_J
(
targetA7
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
));
}
protected
long
invoke_J
(
Object
a0
,
Object
a1
,
Object
a2
,
long
a3
,
long
a4
,
long
a5
,
long
a6
)
throws
Throwable
{
return
return_J
(
targetA7
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
));
}
protected
Object
invoke_L
(
Object
a0
,
Object
a1
,
long
a2
,
long
a3
,
long
a4
,
long
a5
,
long
a6
)
{
return
return_L
(
targetA7
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
));
}
protected
Object
invoke_L
(
Object
a0
,
Object
a1
,
long
a2
,
long
a3
,
long
a4
,
long
a5
,
long
a6
)
throws
Throwable
{
return
return_L
(
targetA7
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
));
}
protected
int
invoke_I
(
Object
a0
,
Object
a1
,
long
a2
,
long
a3
,
long
a4
,
long
a5
,
long
a6
)
{
return
return_I
(
targetA7
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
));
}
protected
int
invoke_I
(
Object
a0
,
Object
a1
,
long
a2
,
long
a3
,
long
a4
,
long
a5
,
long
a6
)
throws
Throwable
{
return
return_I
(
targetA7
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
));
}
protected
long
invoke_J
(
Object
a0
,
Object
a1
,
long
a2
,
long
a3
,
long
a4
,
long
a5
,
long
a6
)
{
return
return_J
(
targetA7
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
));
}
protected
long
invoke_J
(
Object
a0
,
Object
a1
,
long
a2
,
long
a3
,
long
a4
,
long
a5
,
long
a6
)
throws
Throwable
{
return
return_J
(
targetA7
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
));
}
protected
Object
invoke_L
(
Object
a0
,
long
a1
,
long
a2
,
long
a3
,
long
a4
,
long
a5
,
long
a6
)
{
return
return_L
(
targetA7
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
));
}
protected
Object
invoke_L
(
Object
a0
,
long
a1
,
long
a2
,
long
a3
,
long
a4
,
long
a5
,
long
a6
)
throws
Throwable
{
return
return_L
(
targetA7
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
));
}
protected
int
invoke_I
(
Object
a0
,
long
a1
,
long
a2
,
long
a3
,
long
a4
,
long
a5
,
long
a6
)
{
return
return_I
(
targetA7
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
));
}
protected
int
invoke_I
(
Object
a0
,
long
a1
,
long
a2
,
long
a3
,
long
a4
,
long
a5
,
long
a6
)
throws
Throwable
{
return
return_I
(
targetA7
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
));
}
protected
long
invoke_J
(
Object
a0
,
long
a1
,
long
a2
,
long
a3
,
long
a4
,
long
a5
,
long
a6
)
{
return
return_J
(
targetA7
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
));
}
protected
long
invoke_J
(
Object
a0
,
long
a1
,
long
a2
,
long
a3
,
long
a4
,
long
a5
,
long
a6
)
throws
Throwable
{
return
return_J
(
targetA7
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
));
}
protected
Object
invoke_L
(
long
a0
,
long
a1
,
long
a2
,
long
a3
,
long
a4
,
long
a5
,
long
a6
)
{
return
return_L
(
targetA7
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
));
}
protected
Object
invoke_L
(
long
a0
,
long
a1
,
long
a2
,
long
a3
,
long
a4
,
long
a5
,
long
a6
)
throws
Throwable
{
return
return_L
(
targetA7
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
));
}
protected
int
invoke_I
(
long
a0
,
long
a1
,
long
a2
,
long
a3
,
long
a4
,
long
a5
,
long
a6
)
{
return
return_I
(
targetA7
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
));
}
protected
int
invoke_I
(
long
a0
,
long
a1
,
long
a2
,
long
a3
,
long
a4
,
long
a5
,
long
a6
)
throws
Throwable
{
return
return_I
(
targetA7
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
));
}
protected
long
invoke_J
(
long
a0
,
long
a1
,
long
a2
,
long
a3
,
long
a4
,
long
a5
,
long
a6
)
{
return
return_J
(
targetA7
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
));
}
protected
long
invoke_J
(
long
a0
,
long
a1
,
long
a2
,
long
a3
,
long
a4
,
long
a5
,
long
a6
)
throws
Throwable
{
return
return_J
(
targetA7
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
));
}
}
}
static
class
A8
extends
Adapter
{
static
class
A8
extends
Adapter
{
protected
A8
(
MethodHandle
entryPoint
)
{
super
(
entryPoint
);
}
// to build prototype
protected
A8
(
MethodHandle
entryPoint
)
{
super
(
entryPoint
);
}
// to build prototype
protected
A8
(
MethodHandle
e
,
MethodHandle
i
,
MethodHandle
c
,
MethodHandle
t
)
{
super
(
e
,
i
,
c
,
t
);
}
protected
A8
(
MethodHandle
e
,
MethodHandle
i
,
MethodHandle
c
,
MethodHandle
t
)
{
super
(
e
,
i
,
c
,
t
);
}
protected
A8
makeInstance
(
MethodHandle
e
,
MethodHandle
i
,
MethodHandle
c
,
MethodHandle
t
)
{
return
new
A8
(
e
,
i
,
c
,
t
);
}
protected
A8
makeInstance
(
MethodHandle
e
,
MethodHandle
i
,
MethodHandle
c
,
MethodHandle
t
)
{
return
new
A8
(
e
,
i
,
c
,
t
);
}
protected
Object
target
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
a6
,
Object
a7
)
{
return
invoker
.<
Object
>
invoke
(
target
,
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
);
}
protected
Object
target
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
a6
,
Object
a7
)
throws
Throwable
{
return
invoker
.<
Object
>
invoke
(
target
,
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
);
}
protected
Object
targetA8
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
a6
,
Object
a7
)
{
return
target
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
);
}
protected
Object
targetA8
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
a6
,
Object
a7
)
throws
Throwable
{
return
target
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
);
}
protected
Object
targetA8
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
a6
,
long
a7
)
{
return
target
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
);
}
protected
Object
targetA8
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
a6
,
long
a7
)
throws
Throwable
{
return
target
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
);
}
protected
Object
targetA8
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
long
a6
,
long
a7
)
{
return
target
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
);
}
protected
Object
targetA8
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
long
a6
,
long
a7
)
throws
Throwable
{
return
target
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
);
}
protected
Object
targetA8
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
long
a5
,
long
a6
,
long
a7
)
{
return
target
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
);
}
protected
Object
targetA8
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
long
a5
,
long
a6
,
long
a7
)
throws
Throwable
{
return
target
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
);
}
protected
Object
targetA8
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
long
a4
,
long
a5
,
long
a6
,
long
a7
)
{
return
target
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
);
}
protected
Object
targetA8
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
long
a4
,
long
a5
,
long
a6
,
long
a7
)
throws
Throwable
{
return
target
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
);
}
protected
Object
targetA8
(
Object
a0
,
Object
a1
,
Object
a2
,
long
a3
,
long
a4
,
long
a5
,
long
a6
,
long
a7
)
{
return
target
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
);
}
protected
Object
targetA8
(
Object
a0
,
Object
a1
,
Object
a2
,
long
a3
,
long
a4
,
long
a5
,
long
a6
,
long
a7
)
throws
Throwable
{
return
target
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
);
}
protected
Object
targetA8
(
Object
a0
,
Object
a1
,
long
a2
,
long
a3
,
long
a4
,
long
a5
,
long
a6
,
long
a7
)
{
return
target
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
);
}
protected
Object
targetA8
(
Object
a0
,
Object
a1
,
long
a2
,
long
a3
,
long
a4
,
long
a5
,
long
a6
,
long
a7
)
throws
Throwable
{
return
target
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
);
}
protected
Object
targetA8
(
Object
a0
,
long
a1
,
long
a2
,
long
a3
,
long
a4
,
long
a5
,
long
a6
,
long
a7
)
{
return
target
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
);
}
protected
Object
targetA8
(
Object
a0
,
long
a1
,
long
a2
,
long
a3
,
long
a4
,
long
a5
,
long
a6
,
long
a7
)
throws
Throwable
{
return
target
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
);
}
protected
Object
targetA8
(
long
a0
,
long
a1
,
long
a2
,
long
a3
,
long
a4
,
long
a5
,
long
a6
,
long
a7
)
{
return
target
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
);
}
protected
Object
targetA8
(
long
a0
,
long
a1
,
long
a2
,
long
a3
,
long
a4
,
long
a5
,
long
a6
,
long
a7
)
throws
Throwable
{
return
target
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
);
}
protected
Object
invoke_L
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
a6
,
Object
a7
)
{
return
return_L
(
targetA8
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
));
}
protected
Object
invoke_L
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
a6
,
Object
a7
)
throws
Throwable
{
return
return_L
(
targetA8
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
));
}
protected
int
invoke_I
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
a6
,
Object
a7
)
{
return
return_I
(
targetA8
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
));
}
protected
int
invoke_I
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
a6
,
Object
a7
)
throws
Throwable
{
return
return_I
(
targetA8
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
));
}
protected
long
invoke_J
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
a6
,
Object
a7
)
{
return
return_J
(
targetA8
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
));
}
protected
long
invoke_J
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
a6
,
Object
a7
)
throws
Throwable
{
return
return_J
(
targetA8
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
));
}
protected
Object
invoke_L
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
a6
,
long
a7
)
{
return
return_L
(
targetA8
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
));
}
protected
Object
invoke_L
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
a6
,
long
a7
)
throws
Throwable
{
return
return_L
(
targetA8
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
));
}
protected
int
invoke_I
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
a6
,
long
a7
)
{
return
return_I
(
targetA8
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
));
}
protected
int
invoke_I
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
a6
,
long
a7
)
throws
Throwable
{
return
return_I
(
targetA8
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
));
}
protected
long
invoke_J
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
a6
,
long
a7
)
{
return
return_J
(
targetA8
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
));
}
protected
long
invoke_J
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
a6
,
long
a7
)
throws
Throwable
{
return
return_J
(
targetA8
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
));
}
protected
Object
invoke_L
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
long
a6
,
long
a7
)
{
return
return_L
(
targetA8
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
));
}
protected
Object
invoke_L
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
long
a6
,
long
a7
)
throws
Throwable
{
return
return_L
(
targetA8
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
));
}
protected
int
invoke_I
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
long
a6
,
long
a7
)
{
return
return_I
(
targetA8
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
));
}
protected
int
invoke_I
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
long
a6
,
long
a7
)
throws
Throwable
{
return
return_I
(
targetA8
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
));
}
protected
long
invoke_J
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
long
a6
,
long
a7
)
{
return
return_J
(
targetA8
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
));
}
protected
long
invoke_J
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
long
a6
,
long
a7
)
throws
Throwable
{
return
return_J
(
targetA8
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
));
}
protected
Object
invoke_L
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
long
a5
,
long
a6
,
long
a7
)
{
return
return_L
(
targetA8
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
));
}
protected
Object
invoke_L
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
long
a5
,
long
a6
,
long
a7
)
throws
Throwable
{
return
return_L
(
targetA8
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
));
}
protected
int
invoke_I
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
long
a5
,
long
a6
,
long
a7
)
{
return
return_I
(
targetA8
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
));
}
protected
int
invoke_I
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
long
a5
,
long
a6
,
long
a7
)
throws
Throwable
{
return
return_I
(
targetA8
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
));
}
protected
long
invoke_J
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
long
a5
,
long
a6
,
long
a7
)
{
return
return_J
(
targetA8
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
));
}
protected
long
invoke_J
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
long
a5
,
long
a6
,
long
a7
)
throws
Throwable
{
return
return_J
(
targetA8
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
));
}
protected
Object
invoke_L
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
long
a4
,
long
a5
,
long
a6
,
long
a7
)
{
return
return_L
(
targetA8
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
));
}
protected
Object
invoke_L
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
long
a4
,
long
a5
,
long
a6
,
long
a7
)
throws
Throwable
{
return
return_L
(
targetA8
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
));
}
protected
int
invoke_I
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
long
a4
,
long
a5
,
long
a6
,
long
a7
)
{
return
return_I
(
targetA8
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
));
}
protected
int
invoke_I
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
long
a4
,
long
a5
,
long
a6
,
long
a7
)
throws
Throwable
{
return
return_I
(
targetA8
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
));
}
protected
long
invoke_J
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
long
a4
,
long
a5
,
long
a6
,
long
a7
)
{
return
return_J
(
targetA8
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
));
}
protected
long
invoke_J
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
long
a4
,
long
a5
,
long
a6
,
long
a7
)
throws
Throwable
{
return
return_J
(
targetA8
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
));
}
protected
Object
invoke_L
(
Object
a0
,
Object
a1
,
Object
a2
,
long
a3
,
long
a4
,
long
a5
,
long
a6
,
long
a7
)
{
return
return_L
(
targetA8
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
));
}
protected
Object
invoke_L
(
Object
a0
,
Object
a1
,
Object
a2
,
long
a3
,
long
a4
,
long
a5
,
long
a6
,
long
a7
)
throws
Throwable
{
return
return_L
(
targetA8
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
));
}
protected
int
invoke_I
(
Object
a0
,
Object
a1
,
Object
a2
,
long
a3
,
long
a4
,
long
a5
,
long
a6
,
long
a7
)
{
return
return_I
(
targetA8
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
));
}
protected
int
invoke_I
(
Object
a0
,
Object
a1
,
Object
a2
,
long
a3
,
long
a4
,
long
a5
,
long
a6
,
long
a7
)
throws
Throwable
{
return
return_I
(
targetA8
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
));
}
protected
long
invoke_J
(
Object
a0
,
Object
a1
,
Object
a2
,
long
a3
,
long
a4
,
long
a5
,
long
a6
,
long
a7
)
{
return
return_J
(
targetA8
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
));
}
protected
long
invoke_J
(
Object
a0
,
Object
a1
,
Object
a2
,
long
a3
,
long
a4
,
long
a5
,
long
a6
,
long
a7
)
throws
Throwable
{
return
return_J
(
targetA8
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
));
}
protected
Object
invoke_L
(
Object
a0
,
Object
a1
,
long
a2
,
long
a3
,
long
a4
,
long
a5
,
long
a6
,
long
a7
)
{
return
return_L
(
targetA8
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
));
}
protected
Object
invoke_L
(
Object
a0
,
Object
a1
,
long
a2
,
long
a3
,
long
a4
,
long
a5
,
long
a6
,
long
a7
)
throws
Throwable
{
return
return_L
(
targetA8
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
));
}
protected
int
invoke_I
(
Object
a0
,
Object
a1
,
long
a2
,
long
a3
,
long
a4
,
long
a5
,
long
a6
,
long
a7
)
{
return
return_I
(
targetA8
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
));
}
protected
int
invoke_I
(
Object
a0
,
Object
a1
,
long
a2
,
long
a3
,
long
a4
,
long
a5
,
long
a6
,
long
a7
)
throws
Throwable
{
return
return_I
(
targetA8
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
));
}
protected
long
invoke_J
(
Object
a0
,
Object
a1
,
long
a2
,
long
a3
,
long
a4
,
long
a5
,
long
a6
,
long
a7
)
{
return
return_J
(
targetA8
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
));
}
protected
long
invoke_J
(
Object
a0
,
Object
a1
,
long
a2
,
long
a3
,
long
a4
,
long
a5
,
long
a6
,
long
a7
)
throws
Throwable
{
return
return_J
(
targetA8
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
));
}
protected
Object
invoke_L
(
Object
a0
,
long
a1
,
long
a2
,
long
a3
,
long
a4
,
long
a5
,
long
a6
,
long
a7
)
{
return
return_L
(
targetA8
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
));
}
protected
Object
invoke_L
(
Object
a0
,
long
a1
,
long
a2
,
long
a3
,
long
a4
,
long
a5
,
long
a6
,
long
a7
)
throws
Throwable
{
return
return_L
(
targetA8
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
));
}
protected
int
invoke_I
(
Object
a0
,
long
a1
,
long
a2
,
long
a3
,
long
a4
,
long
a5
,
long
a6
,
long
a7
)
{
return
return_I
(
targetA8
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
));
}
protected
int
invoke_I
(
Object
a0
,
long
a1
,
long
a2
,
long
a3
,
long
a4
,
long
a5
,
long
a6
,
long
a7
)
throws
Throwable
{
return
return_I
(
targetA8
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
));
}
protected
long
invoke_J
(
Object
a0
,
long
a1
,
long
a2
,
long
a3
,
long
a4
,
long
a5
,
long
a6
,
long
a7
)
{
return
return_J
(
targetA8
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
));
}
protected
long
invoke_J
(
Object
a0
,
long
a1
,
long
a2
,
long
a3
,
long
a4
,
long
a5
,
long
a6
,
long
a7
)
throws
Throwable
{
return
return_J
(
targetA8
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
));
}
protected
Object
invoke_L
(
long
a0
,
long
a1
,
long
a2
,
long
a3
,
long
a4
,
long
a5
,
long
a6
,
long
a7
)
{
return
return_L
(
targetA8
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
));
}
protected
Object
invoke_L
(
long
a0
,
long
a1
,
long
a2
,
long
a3
,
long
a4
,
long
a5
,
long
a6
,
long
a7
)
throws
Throwable
{
return
return_L
(
targetA8
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
));
}
protected
int
invoke_I
(
long
a0
,
long
a1
,
long
a2
,
long
a3
,
long
a4
,
long
a5
,
long
a6
,
long
a7
)
{
return
return_I
(
targetA8
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
));
}
protected
int
invoke_I
(
long
a0
,
long
a1
,
long
a2
,
long
a3
,
long
a4
,
long
a5
,
long
a6
,
long
a7
)
throws
Throwable
{
return
return_I
(
targetA8
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
));
}
protected
long
invoke_J
(
long
a0
,
long
a1
,
long
a2
,
long
a3
,
long
a4
,
long
a5
,
long
a6
,
long
a7
)
{
return
return_J
(
targetA8
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
));
}
protected
long
invoke_J
(
long
a0
,
long
a1
,
long
a2
,
long
a3
,
long
a4
,
long
a5
,
long
a6
,
long
a7
)
throws
Throwable
{
return
return_J
(
targetA8
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
));
}
}
}
static
class
A9
extends
Adapter
{
static
class
A9
extends
Adapter
{
protected
A9
(
MethodHandle
entryPoint
)
{
super
(
entryPoint
);
}
// to build prototype
protected
A9
(
MethodHandle
entryPoint
)
{
super
(
entryPoint
);
}
// to build prototype
protected
A9
(
MethodHandle
e
,
MethodHandle
i
,
MethodHandle
c
,
MethodHandle
t
)
{
super
(
e
,
i
,
c
,
t
);
}
protected
A9
(
MethodHandle
e
,
MethodHandle
i
,
MethodHandle
c
,
MethodHandle
t
)
{
super
(
e
,
i
,
c
,
t
);
}
protected
A9
makeInstance
(
MethodHandle
e
,
MethodHandle
i
,
MethodHandle
c
,
MethodHandle
t
)
{
return
new
A9
(
e
,
i
,
c
,
t
);
}
protected
A9
makeInstance
(
MethodHandle
e
,
MethodHandle
i
,
MethodHandle
c
,
MethodHandle
t
)
{
return
new
A9
(
e
,
i
,
c
,
t
);
}
protected
Object
target
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
a6
,
Object
a7
,
Object
a8
)
{
return
invoker
.<
Object
>
invoke
(
target
,
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
);
}
protected
Object
target
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
a6
,
Object
a7
,
Object
a8
)
throws
Throwable
{
return
invoker
.<
Object
>
invoke
(
target
,
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
);
}
protected
Object
targetA9
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
a6
,
Object
a7
,
Object
a8
)
{
return
target
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
);
}
protected
Object
targetA9
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
a6
,
Object
a7
,
Object
a8
)
throws
Throwable
{
return
target
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
);
}
protected
Object
targetA9
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
a6
,
Object
a7
,
long
a8
)
{
return
target
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
);
}
protected
Object
targetA9
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
a6
,
Object
a7
,
long
a8
)
throws
Throwable
{
return
target
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
);
}
protected
Object
targetA9
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
a6
,
long
a7
,
long
a8
)
{
return
target
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
);
}
protected
Object
targetA9
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
a6
,
long
a7
,
long
a8
)
throws
Throwable
{
return
target
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
);
}
protected
Object
targetA9
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
long
a6
,
long
a7
,
long
a8
)
{
return
target
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
);
}
protected
Object
targetA9
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
long
a6
,
long
a7
,
long
a8
)
throws
Throwable
{
return
target
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
);
}
protected
Object
targetA9
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
long
a5
,
long
a6
,
long
a7
,
long
a8
)
{
return
target
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
);
}
protected
Object
targetA9
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
long
a5
,
long
a6
,
long
a7
,
long
a8
)
throws
Throwable
{
return
target
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
);
}
protected
Object
targetA9
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
long
a4
,
long
a5
,
long
a6
,
long
a7
,
long
a8
)
{
return
target
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
);
}
protected
Object
targetA9
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
long
a4
,
long
a5
,
long
a6
,
long
a7
,
long
a8
)
throws
Throwable
{
return
target
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
);
}
protected
Object
targetA9
(
Object
a0
,
Object
a1
,
Object
a2
,
long
a3
,
long
a4
,
long
a5
,
long
a6
,
long
a7
,
long
a8
)
{
return
target
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
);
}
protected
Object
targetA9
(
Object
a0
,
Object
a1
,
Object
a2
,
long
a3
,
long
a4
,
long
a5
,
long
a6
,
long
a7
,
long
a8
)
throws
Throwable
{
return
target
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
);
}
protected
Object
targetA9
(
Object
a0
,
Object
a1
,
long
a2
,
long
a3
,
long
a4
,
long
a5
,
long
a6
,
long
a7
,
long
a8
)
{
return
target
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
);
}
protected
Object
targetA9
(
Object
a0
,
Object
a1
,
long
a2
,
long
a3
,
long
a4
,
long
a5
,
long
a6
,
long
a7
,
long
a8
)
throws
Throwable
{
return
target
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
);
}
protected
Object
targetA9
(
Object
a0
,
long
a1
,
long
a2
,
long
a3
,
long
a4
,
long
a5
,
long
a6
,
long
a7
,
long
a8
)
{
return
target
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
);
}
protected
Object
targetA9
(
Object
a0
,
long
a1
,
long
a2
,
long
a3
,
long
a4
,
long
a5
,
long
a6
,
long
a7
,
long
a8
)
throws
Throwable
{
return
target
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
);
}
protected
Object
targetA9
(
long
a0
,
long
a1
,
long
a2
,
long
a3
,
long
a4
,
long
a5
,
long
a6
,
long
a7
,
long
a8
)
{
return
target
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
);
}
protected
Object
targetA9
(
long
a0
,
long
a1
,
long
a2
,
long
a3
,
long
a4
,
long
a5
,
long
a6
,
long
a7
,
long
a8
)
throws
Throwable
{
return
target
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
);
}
protected
Object
invoke_L
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
a6
,
Object
a7
,
Object
a8
)
{
return
return_L
(
targetA9
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
));
}
protected
Object
invoke_L
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
a6
,
Object
a7
,
Object
a8
)
throws
Throwable
{
return
return_L
(
targetA9
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
));
}
protected
int
invoke_I
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
a6
,
Object
a7
,
Object
a8
)
{
return
return_I
(
targetA9
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
));
}
protected
int
invoke_I
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
a6
,
Object
a7
,
Object
a8
)
throws
Throwable
{
return
return_I
(
targetA9
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
));
}
protected
long
invoke_J
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
a6
,
Object
a7
,
Object
a8
)
{
return
return_J
(
targetA9
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
));
}
protected
long
invoke_J
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
a6
,
Object
a7
,
Object
a8
)
throws
Throwable
{
return
return_J
(
targetA9
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
));
}
protected
Object
invoke_L
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
a6
,
Object
a7
,
long
a8
)
{
return
return_L
(
targetA9
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
));
}
protected
Object
invoke_L
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
a6
,
Object
a7
,
long
a8
)
throws
Throwable
{
return
return_L
(
targetA9
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
));
}
protected
int
invoke_I
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
a6
,
Object
a7
,
long
a8
)
{
return
return_I
(
targetA9
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
));
}
protected
int
invoke_I
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
a6
,
Object
a7
,
long
a8
)
throws
Throwable
{
return
return_I
(
targetA9
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
));
}
protected
long
invoke_J
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
a6
,
Object
a7
,
long
a8
)
{
return
return_J
(
targetA9
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
));
}
protected
long
invoke_J
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
a6
,
Object
a7
,
long
a8
)
throws
Throwable
{
return
return_J
(
targetA9
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
));
}
protected
Object
invoke_L
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
a6
,
long
a7
,
long
a8
)
{
return
return_L
(
targetA9
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
));
}
protected
Object
invoke_L
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
a6
,
long
a7
,
long
a8
)
throws
Throwable
{
return
return_L
(
targetA9
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
));
}
protected
int
invoke_I
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
a6
,
long
a7
,
long
a8
)
{
return
return_I
(
targetA9
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
));
}
protected
int
invoke_I
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
a6
,
long
a7
,
long
a8
)
throws
Throwable
{
return
return_I
(
targetA9
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
));
}
protected
long
invoke_J
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
a6
,
long
a7
,
long
a8
)
{
return
return_J
(
targetA9
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
));
}
protected
long
invoke_J
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
a6
,
long
a7
,
long
a8
)
throws
Throwable
{
return
return_J
(
targetA9
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
));
}
protected
Object
invoke_L
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
long
a6
,
long
a7
,
long
a8
)
{
return
return_L
(
targetA9
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
));
}
protected
Object
invoke_L
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
long
a6
,
long
a7
,
long
a8
)
throws
Throwable
{
return
return_L
(
targetA9
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
));
}
protected
int
invoke_I
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
long
a6
,
long
a7
,
long
a8
)
{
return
return_I
(
targetA9
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
));
}
protected
int
invoke_I
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
long
a6
,
long
a7
,
long
a8
)
throws
Throwable
{
return
return_I
(
targetA9
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
));
}
protected
long
invoke_J
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
long
a6
,
long
a7
,
long
a8
)
{
return
return_J
(
targetA9
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
));
}
protected
long
invoke_J
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
long
a6
,
long
a7
,
long
a8
)
throws
Throwable
{
return
return_J
(
targetA9
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
));
}
protected
Object
invoke_L
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
long
a5
,
long
a6
,
long
a7
,
long
a8
)
{
return
return_L
(
targetA9
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
));
}
protected
Object
invoke_L
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
long
a5
,
long
a6
,
long
a7
,
long
a8
)
throws
Throwable
{
return
return_L
(
targetA9
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
));
}
protected
int
invoke_I
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
long
a5
,
long
a6
,
long
a7
,
long
a8
)
{
return
return_I
(
targetA9
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
));
}
protected
int
invoke_I
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
long
a5
,
long
a6
,
long
a7
,
long
a8
)
throws
Throwable
{
return
return_I
(
targetA9
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
));
}
protected
long
invoke_J
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
long
a5
,
long
a6
,
long
a7
,
long
a8
)
{
return
return_J
(
targetA9
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
));
}
protected
long
invoke_J
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
long
a5
,
long
a6
,
long
a7
,
long
a8
)
throws
Throwable
{
return
return_J
(
targetA9
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
));
}
protected
Object
invoke_L
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
long
a4
,
long
a5
,
long
a6
,
long
a7
,
long
a8
)
{
return
return_L
(
targetA9
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
));
}
protected
Object
invoke_L
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
long
a4
,
long
a5
,
long
a6
,
long
a7
,
long
a8
)
throws
Throwable
{
return
return_L
(
targetA9
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
));
}
protected
int
invoke_I
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
long
a4
,
long
a5
,
long
a6
,
long
a7
,
long
a8
)
{
return
return_I
(
targetA9
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
));
}
protected
int
invoke_I
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
long
a4
,
long
a5
,
long
a6
,
long
a7
,
long
a8
)
throws
Throwable
{
return
return_I
(
targetA9
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
));
}
protected
long
invoke_J
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
long
a4
,
long
a5
,
long
a6
,
long
a7
,
long
a8
)
{
return
return_J
(
targetA9
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
));
}
protected
long
invoke_J
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
long
a4
,
long
a5
,
long
a6
,
long
a7
,
long
a8
)
throws
Throwable
{
return
return_J
(
targetA9
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
));
}
protected
Object
invoke_L
(
Object
a0
,
Object
a1
,
Object
a2
,
long
a3
,
long
a4
,
long
a5
,
long
a6
,
long
a7
,
long
a8
)
{
return
return_L
(
targetA9
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
));
}
protected
Object
invoke_L
(
Object
a0
,
Object
a1
,
Object
a2
,
long
a3
,
long
a4
,
long
a5
,
long
a6
,
long
a7
,
long
a8
)
throws
Throwable
{
return
return_L
(
targetA9
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
));
}
protected
int
invoke_I
(
Object
a0
,
Object
a1
,
Object
a2
,
long
a3
,
long
a4
,
long
a5
,
long
a6
,
long
a7
,
long
a8
)
{
return
return_I
(
targetA9
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
));
}
protected
int
invoke_I
(
Object
a0
,
Object
a1
,
Object
a2
,
long
a3
,
long
a4
,
long
a5
,
long
a6
,
long
a7
,
long
a8
)
throws
Throwable
{
return
return_I
(
targetA9
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
));
}
protected
long
invoke_J
(
Object
a0
,
Object
a1
,
Object
a2
,
long
a3
,
long
a4
,
long
a5
,
long
a6
,
long
a7
,
long
a8
)
{
return
return_J
(
targetA9
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
));
}
protected
long
invoke_J
(
Object
a0
,
Object
a1
,
Object
a2
,
long
a3
,
long
a4
,
long
a5
,
long
a6
,
long
a7
,
long
a8
)
throws
Throwable
{
return
return_J
(
targetA9
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
));
}
protected
Object
invoke_L
(
Object
a0
,
Object
a1
,
long
a2
,
long
a3
,
long
a4
,
long
a5
,
long
a6
,
long
a7
,
long
a8
)
{
return
return_L
(
targetA9
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
));
}
protected
Object
invoke_L
(
Object
a0
,
Object
a1
,
long
a2
,
long
a3
,
long
a4
,
long
a5
,
long
a6
,
long
a7
,
long
a8
)
throws
Throwable
{
return
return_L
(
targetA9
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
));
}
protected
int
invoke_I
(
Object
a0
,
Object
a1
,
long
a2
,
long
a3
,
long
a4
,
long
a5
,
long
a6
,
long
a7
,
long
a8
)
{
return
return_I
(
targetA9
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
));
}
protected
int
invoke_I
(
Object
a0
,
Object
a1
,
long
a2
,
long
a3
,
long
a4
,
long
a5
,
long
a6
,
long
a7
,
long
a8
)
throws
Throwable
{
return
return_I
(
targetA9
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
));
}
protected
long
invoke_J
(
Object
a0
,
Object
a1
,
long
a2
,
long
a3
,
long
a4
,
long
a5
,
long
a6
,
long
a7
,
long
a8
)
{
return
return_J
(
targetA9
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
));
}
protected
long
invoke_J
(
Object
a0
,
Object
a1
,
long
a2
,
long
a3
,
long
a4
,
long
a5
,
long
a6
,
long
a7
,
long
a8
)
throws
Throwable
{
return
return_J
(
targetA9
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
));
}
protected
Object
invoke_L
(
Object
a0
,
long
a1
,
long
a2
,
long
a3
,
long
a4
,
long
a5
,
long
a6
,
long
a7
,
long
a8
)
{
return
return_L
(
targetA9
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
));
}
protected
Object
invoke_L
(
Object
a0
,
long
a1
,
long
a2
,
long
a3
,
long
a4
,
long
a5
,
long
a6
,
long
a7
,
long
a8
)
throws
Throwable
{
return
return_L
(
targetA9
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
));
}
protected
int
invoke_I
(
Object
a0
,
long
a1
,
long
a2
,
long
a3
,
long
a4
,
long
a5
,
long
a6
,
long
a7
,
long
a8
)
{
return
return_I
(
targetA9
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
));
}
protected
int
invoke_I
(
Object
a0
,
long
a1
,
long
a2
,
long
a3
,
long
a4
,
long
a5
,
long
a6
,
long
a7
,
long
a8
)
throws
Throwable
{
return
return_I
(
targetA9
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
));
}
protected
long
invoke_J
(
Object
a0
,
long
a1
,
long
a2
,
long
a3
,
long
a4
,
long
a5
,
long
a6
,
long
a7
,
long
a8
)
{
return
return_J
(
targetA9
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
));
}
protected
long
invoke_J
(
Object
a0
,
long
a1
,
long
a2
,
long
a3
,
long
a4
,
long
a5
,
long
a6
,
long
a7
,
long
a8
)
throws
Throwable
{
return
return_J
(
targetA9
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
));
}
protected
Object
invoke_L
(
long
a0
,
long
a1
,
long
a2
,
long
a3
,
long
a4
,
long
a5
,
long
a6
,
long
a7
,
long
a8
)
{
return
return_L
(
targetA9
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
));
}
protected
Object
invoke_L
(
long
a0
,
long
a1
,
long
a2
,
long
a3
,
long
a4
,
long
a5
,
long
a6
,
long
a7
,
long
a8
)
throws
Throwable
{
return
return_L
(
targetA9
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
));
}
protected
int
invoke_I
(
long
a0
,
long
a1
,
long
a2
,
long
a3
,
long
a4
,
long
a5
,
long
a6
,
long
a7
,
long
a8
)
{
return
return_I
(
targetA9
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
));
}
protected
int
invoke_I
(
long
a0
,
long
a1
,
long
a2
,
long
a3
,
long
a4
,
long
a5
,
long
a6
,
long
a7
,
long
a8
)
throws
Throwable
{
return
return_I
(
targetA9
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
));
}
protected
long
invoke_J
(
long
a0
,
long
a1
,
long
a2
,
long
a3
,
long
a4
,
long
a5
,
long
a6
,
long
a7
,
long
a8
)
{
return
return_J
(
targetA9
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
));
}
protected
long
invoke_J
(
long
a0
,
long
a1
,
long
a2
,
long
a3
,
long
a4
,
long
a5
,
long
a6
,
long
a7
,
long
a8
)
throws
Throwable
{
return
return_J
(
targetA9
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
));
}
}
}
static
class
A10
extends
Adapter
{
static
class
A10
extends
Adapter
{
protected
A10
(
MethodHandle
entryPoint
)
{
super
(
entryPoint
);
}
// to build prototype
protected
A10
(
MethodHandle
entryPoint
)
{
super
(
entryPoint
);
}
// to build prototype
protected
A10
(
MethodHandle
e
,
MethodHandle
i
,
MethodHandle
c
,
MethodHandle
t
)
{
super
(
e
,
i
,
c
,
t
);
}
protected
A10
(
MethodHandle
e
,
MethodHandle
i
,
MethodHandle
c
,
MethodHandle
t
)
{
super
(
e
,
i
,
c
,
t
);
}
protected
A10
makeInstance
(
MethodHandle
e
,
MethodHandle
i
,
MethodHandle
c
,
MethodHandle
t
)
{
return
new
A10
(
e
,
i
,
c
,
t
);
}
protected
A10
makeInstance
(
MethodHandle
e
,
MethodHandle
i
,
MethodHandle
c
,
MethodHandle
t
)
{
return
new
A10
(
e
,
i
,
c
,
t
);
}
protected
Object
target
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
a6
,
Object
a7
,
Object
a8
,
Object
a9
)
{
return
invoker
.<
Object
>
invoke
(
target
,
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
,
a9
);
}
protected
Object
target
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
a6
,
Object
a7
,
Object
a8
,
Object
a9
)
throws
Throwable
{
return
invoker
.<
Object
>
invoke
(
target
,
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
,
a9
);
}
protected
Object
targetA10
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
a6
,
Object
a7
,
Object
a8
,
Object
a9
)
{
return
target
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
,
a9
);
}
protected
Object
targetA10
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
a6
,
Object
a7
,
Object
a8
,
Object
a9
)
throws
Throwable
{
return
target
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
,
a9
);
}
protected
Object
targetA10
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
a6
,
Object
a7
,
Object
a8
,
long
a9
)
{
return
target
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
,
a9
);
}
protected
Object
targetA10
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
a6
,
Object
a7
,
Object
a8
,
long
a9
)
throws
Throwable
{
return
target
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
,
a9
);
}
protected
Object
targetA10
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
a6
,
Object
a7
,
long
a8
,
long
a9
)
{
return
target
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
,
a9
);
}
protected
Object
targetA10
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
a6
,
Object
a7
,
long
a8
,
long
a9
)
throws
Throwable
{
return
target
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
,
a9
);
}
protected
Object
targetA10
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
a6
,
long
a7
,
long
a8
,
long
a9
)
{
return
target
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
,
a9
);
}
protected
Object
targetA10
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
a6
,
long
a7
,
long
a8
,
long
a9
)
throws
Throwable
{
return
target
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
,
a9
);
}
protected
Object
targetA10
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
long
a6
,
long
a7
,
long
a8
,
long
a9
)
{
return
target
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
,
a9
);
}
protected
Object
targetA10
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
long
a6
,
long
a7
,
long
a8
,
long
a9
)
throws
Throwable
{
return
target
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
,
a9
);
}
protected
Object
targetA10
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
long
a5
,
long
a6
,
long
a7
,
long
a8
,
long
a9
)
{
return
target
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
,
a9
);
}
protected
Object
targetA10
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
long
a5
,
long
a6
,
long
a7
,
long
a8
,
long
a9
)
throws
Throwable
{
return
target
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
,
a9
);
}
protected
Object
targetA10
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
long
a4
,
long
a5
,
long
a6
,
long
a7
,
long
a8
,
long
a9
)
{
return
target
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
,
a9
);
}
protected
Object
targetA10
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
long
a4
,
long
a5
,
long
a6
,
long
a7
,
long
a8
,
long
a9
)
throws
Throwable
{
return
target
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
,
a9
);
}
protected
Object
targetA10
(
Object
a0
,
Object
a1
,
Object
a2
,
long
a3
,
long
a4
,
long
a5
,
long
a6
,
long
a7
,
long
a8
,
long
a9
)
{
return
target
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
,
a9
);
}
protected
Object
targetA10
(
Object
a0
,
Object
a1
,
Object
a2
,
long
a3
,
long
a4
,
long
a5
,
long
a6
,
long
a7
,
long
a8
,
long
a9
)
throws
Throwable
{
return
target
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
,
a9
);
}
protected
Object
targetA10
(
Object
a0
,
Object
a1
,
long
a2
,
long
a3
,
long
a4
,
long
a5
,
long
a6
,
long
a7
,
long
a8
,
long
a9
)
{
return
target
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
,
a9
);
}
protected
Object
targetA10
(
Object
a0
,
Object
a1
,
long
a2
,
long
a3
,
long
a4
,
long
a5
,
long
a6
,
long
a7
,
long
a8
,
long
a9
)
throws
Throwable
{
return
target
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
,
a9
);
}
protected
Object
targetA10
(
Object
a0
,
long
a1
,
long
a2
,
long
a3
,
long
a4
,
long
a5
,
long
a6
,
long
a7
,
long
a8
,
long
a9
)
{
return
target
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
,
a9
);
}
protected
Object
targetA10
(
Object
a0
,
long
a1
,
long
a2
,
long
a3
,
long
a4
,
long
a5
,
long
a6
,
long
a7
,
long
a8
,
long
a9
)
throws
Throwable
{
return
target
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
,
a9
);
}
protected
Object
targetA10
(
long
a0
,
long
a1
,
long
a2
,
long
a3
,
long
a4
,
long
a5
,
long
a6
,
long
a7
,
long
a8
,
long
a9
)
{
return
target
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
,
a9
);
}
protected
Object
targetA10
(
long
a0
,
long
a1
,
long
a2
,
long
a3
,
long
a4
,
long
a5
,
long
a6
,
long
a7
,
long
a8
,
long
a9
)
throws
Throwable
{
return
target
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
,
a9
);
}
protected
Object
invoke_L
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
a6
,
Object
a7
,
Object
a8
,
Object
a9
)
{
return
return_L
(
targetA10
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
,
a9
));
}
protected
Object
invoke_L
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
a6
,
Object
a7
,
Object
a8
,
Object
a9
)
throws
Throwable
{
return
return_L
(
targetA10
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
,
a9
));
}
protected
int
invoke_I
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
a6
,
Object
a7
,
Object
a8
,
Object
a9
)
{
return
return_I
(
targetA10
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
,
a9
));
}
protected
int
invoke_I
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
a6
,
Object
a7
,
Object
a8
,
Object
a9
)
throws
Throwable
{
return
return_I
(
targetA10
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
,
a9
));
}
protected
long
invoke_J
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
a6
,
Object
a7
,
Object
a8
,
Object
a9
)
{
return
return_J
(
targetA10
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
,
a9
));
}
protected
long
invoke_J
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
a6
,
Object
a7
,
Object
a8
,
Object
a9
)
throws
Throwable
{
return
return_J
(
targetA10
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
,
a9
));
}
protected
Object
invoke_L
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
a6
,
Object
a7
,
Object
a8
,
long
a9
)
{
return
return_L
(
targetA10
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
,
a9
));
}
protected
Object
invoke_L
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
a6
,
Object
a7
,
Object
a8
,
long
a9
)
throws
Throwable
{
return
return_L
(
targetA10
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
,
a9
));
}
protected
int
invoke_I
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
a6
,
Object
a7
,
Object
a8
,
long
a9
)
{
return
return_I
(
targetA10
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
,
a9
));
}
protected
int
invoke_I
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
a6
,
Object
a7
,
Object
a8
,
long
a9
)
throws
Throwable
{
return
return_I
(
targetA10
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
,
a9
));
}
protected
long
invoke_J
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
a6
,
Object
a7
,
Object
a8
,
long
a9
)
{
return
return_J
(
targetA10
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
,
a9
));
}
protected
long
invoke_J
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
a6
,
Object
a7
,
Object
a8
,
long
a9
)
throws
Throwable
{
return
return_J
(
targetA10
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
,
a9
));
}
protected
Object
invoke_L
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
a6
,
Object
a7
,
long
a8
,
long
a9
)
{
return
return_L
(
targetA10
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
,
a9
));
}
protected
Object
invoke_L
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
a6
,
Object
a7
,
long
a8
,
long
a9
)
throws
Throwable
{
return
return_L
(
targetA10
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
,
a9
));
}
protected
int
invoke_I
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
a6
,
Object
a7
,
long
a8
,
long
a9
)
{
return
return_I
(
targetA10
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
,
a9
));
}
protected
int
invoke_I
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
a6
,
Object
a7
,
long
a8
,
long
a9
)
throws
Throwable
{
return
return_I
(
targetA10
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
,
a9
));
}
protected
long
invoke_J
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
a6
,
Object
a7
,
long
a8
,
long
a9
)
{
return
return_J
(
targetA10
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
,
a9
));
}
protected
long
invoke_J
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
a6
,
Object
a7
,
long
a8
,
long
a9
)
throws
Throwable
{
return
return_J
(
targetA10
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
,
a9
));
}
protected
Object
invoke_L
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
a6
,
long
a7
,
long
a8
,
long
a9
)
{
return
return_L
(
targetA10
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
,
a9
));
}
protected
Object
invoke_L
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
a6
,
long
a7
,
long
a8
,
long
a9
)
throws
Throwable
{
return
return_L
(
targetA10
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
,
a9
));
}
protected
int
invoke_I
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
a6
,
long
a7
,
long
a8
,
long
a9
)
{
return
return_I
(
targetA10
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
,
a9
));
}
protected
int
invoke_I
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
a6
,
long
a7
,
long
a8
,
long
a9
)
throws
Throwable
{
return
return_I
(
targetA10
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
,
a9
));
}
protected
long
invoke_J
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
a6
,
long
a7
,
long
a8
,
long
a9
)
{
return
return_J
(
targetA10
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
,
a9
));
}
protected
long
invoke_J
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
a6
,
long
a7
,
long
a8
,
long
a9
)
throws
Throwable
{
return
return_J
(
targetA10
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
,
a9
));
}
protected
Object
invoke_L
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
long
a6
,
long
a7
,
long
a8
,
long
a9
)
{
return
return_L
(
targetA10
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
,
a9
));
}
protected
Object
invoke_L
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
long
a6
,
long
a7
,
long
a8
,
long
a9
)
throws
Throwable
{
return
return_L
(
targetA10
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
,
a9
));
}
protected
int
invoke_I
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
long
a6
,
long
a7
,
long
a8
,
long
a9
)
{
return
return_I
(
targetA10
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
,
a9
));
}
protected
int
invoke_I
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
long
a6
,
long
a7
,
long
a8
,
long
a9
)
throws
Throwable
{
return
return_I
(
targetA10
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
,
a9
));
}
protected
long
invoke_J
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
long
a6
,
long
a7
,
long
a8
,
long
a9
)
{
return
return_J
(
targetA10
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
,
a9
));
}
protected
long
invoke_J
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
long
a6
,
long
a7
,
long
a8
,
long
a9
)
throws
Throwable
{
return
return_J
(
targetA10
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
,
a9
));
}
protected
Object
invoke_L
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
long
a5
,
long
a6
,
long
a7
,
long
a8
,
long
a9
)
{
return
return_L
(
targetA10
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
,
a9
));
}
protected
Object
invoke_L
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
long
a5
,
long
a6
,
long
a7
,
long
a8
,
long
a9
)
throws
Throwable
{
return
return_L
(
targetA10
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
,
a9
));
}
protected
int
invoke_I
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
long
a5
,
long
a6
,
long
a7
,
long
a8
,
long
a9
)
{
return
return_I
(
targetA10
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
,
a9
));
}
protected
int
invoke_I
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
long
a5
,
long
a6
,
long
a7
,
long
a8
,
long
a9
)
throws
Throwable
{
return
return_I
(
targetA10
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
,
a9
));
}
protected
long
invoke_J
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
long
a5
,
long
a6
,
long
a7
,
long
a8
,
long
a9
)
{
return
return_J
(
targetA10
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
,
a9
));
}
protected
long
invoke_J
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
long
a5
,
long
a6
,
long
a7
,
long
a8
,
long
a9
)
throws
Throwable
{
return
return_J
(
targetA10
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
,
a9
));
}
protected
Object
invoke_L
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
long
a4
,
long
a5
,
long
a6
,
long
a7
,
long
a8
,
long
a9
)
{
return
return_L
(
targetA10
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
,
a9
));
}
protected
Object
invoke_L
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
long
a4
,
long
a5
,
long
a6
,
long
a7
,
long
a8
,
long
a9
)
throws
Throwable
{
return
return_L
(
targetA10
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
,
a9
));
}
protected
int
invoke_I
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
long
a4
,
long
a5
,
long
a6
,
long
a7
,
long
a8
,
long
a9
)
{
return
return_I
(
targetA10
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
,
a9
));
}
protected
int
invoke_I
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
long
a4
,
long
a5
,
long
a6
,
long
a7
,
long
a8
,
long
a9
)
throws
Throwable
{
return
return_I
(
targetA10
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
,
a9
));
}
protected
long
invoke_J
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
long
a4
,
long
a5
,
long
a6
,
long
a7
,
long
a8
,
long
a9
)
{
return
return_J
(
targetA10
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
,
a9
));
}
protected
long
invoke_J
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
long
a4
,
long
a5
,
long
a6
,
long
a7
,
long
a8
,
long
a9
)
throws
Throwable
{
return
return_J
(
targetA10
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
,
a9
));
}
protected
Object
invoke_L
(
Object
a0
,
Object
a1
,
Object
a2
,
long
a3
,
long
a4
,
long
a5
,
long
a6
,
long
a7
,
long
a8
,
long
a9
)
{
return
return_L
(
targetA10
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
,
a9
));
}
protected
Object
invoke_L
(
Object
a0
,
Object
a1
,
Object
a2
,
long
a3
,
long
a4
,
long
a5
,
long
a6
,
long
a7
,
long
a8
,
long
a9
)
throws
Throwable
{
return
return_L
(
targetA10
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
,
a9
));
}
protected
int
invoke_I
(
Object
a0
,
Object
a1
,
Object
a2
,
long
a3
,
long
a4
,
long
a5
,
long
a6
,
long
a7
,
long
a8
,
long
a9
)
{
return
return_I
(
targetA10
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
,
a9
));
}
protected
int
invoke_I
(
Object
a0
,
Object
a1
,
Object
a2
,
long
a3
,
long
a4
,
long
a5
,
long
a6
,
long
a7
,
long
a8
,
long
a9
)
throws
Throwable
{
return
return_I
(
targetA10
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
,
a9
));
}
protected
long
invoke_J
(
Object
a0
,
Object
a1
,
Object
a2
,
long
a3
,
long
a4
,
long
a5
,
long
a6
,
long
a7
,
long
a8
,
long
a9
)
{
return
return_J
(
targetA10
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
,
a9
));
}
protected
long
invoke_J
(
Object
a0
,
Object
a1
,
Object
a2
,
long
a3
,
long
a4
,
long
a5
,
long
a6
,
long
a7
,
long
a8
,
long
a9
)
throws
Throwable
{
return
return_J
(
targetA10
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
,
a9
));
}
protected
Object
invoke_L
(
Object
a0
,
Object
a1
,
long
a2
,
long
a3
,
long
a4
,
long
a5
,
long
a6
,
long
a7
,
long
a8
,
long
a9
)
{
return
return_L
(
targetA10
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
,
a9
));
}
protected
Object
invoke_L
(
Object
a0
,
Object
a1
,
long
a2
,
long
a3
,
long
a4
,
long
a5
,
long
a6
,
long
a7
,
long
a8
,
long
a9
)
throws
Throwable
{
return
return_L
(
targetA10
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
,
a9
));
}
protected
int
invoke_I
(
Object
a0
,
Object
a1
,
long
a2
,
long
a3
,
long
a4
,
long
a5
,
long
a6
,
long
a7
,
long
a8
,
long
a9
)
{
return
return_I
(
targetA10
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
,
a9
));
}
protected
int
invoke_I
(
Object
a0
,
Object
a1
,
long
a2
,
long
a3
,
long
a4
,
long
a5
,
long
a6
,
long
a7
,
long
a8
,
long
a9
)
throws
Throwable
{
return
return_I
(
targetA10
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
,
a9
));
}
protected
long
invoke_J
(
Object
a0
,
Object
a1
,
long
a2
,
long
a3
,
long
a4
,
long
a5
,
long
a6
,
long
a7
,
long
a8
,
long
a9
)
{
return
return_J
(
targetA10
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
,
a9
));
}
protected
long
invoke_J
(
Object
a0
,
Object
a1
,
long
a2
,
long
a3
,
long
a4
,
long
a5
,
long
a6
,
long
a7
,
long
a8
,
long
a9
)
throws
Throwable
{
return
return_J
(
targetA10
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
,
a9
));
}
protected
Object
invoke_L
(
Object
a0
,
long
a1
,
long
a2
,
long
a3
,
long
a4
,
long
a5
,
long
a6
,
long
a7
,
long
a8
,
long
a9
)
{
return
return_L
(
targetA10
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
,
a9
));
}
protected
Object
invoke_L
(
Object
a0
,
long
a1
,
long
a2
,
long
a3
,
long
a4
,
long
a5
,
long
a6
,
long
a7
,
long
a8
,
long
a9
)
throws
Throwable
{
return
return_L
(
targetA10
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
,
a9
));
}
protected
int
invoke_I
(
Object
a0
,
long
a1
,
long
a2
,
long
a3
,
long
a4
,
long
a5
,
long
a6
,
long
a7
,
long
a8
,
long
a9
)
{
return
return_I
(
targetA10
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
,
a9
));
}
protected
int
invoke_I
(
Object
a0
,
long
a1
,
long
a2
,
long
a3
,
long
a4
,
long
a5
,
long
a6
,
long
a7
,
long
a8
,
long
a9
)
throws
Throwable
{
return
return_I
(
targetA10
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
,
a9
));
}
protected
long
invoke_J
(
Object
a0
,
long
a1
,
long
a2
,
long
a3
,
long
a4
,
long
a5
,
long
a6
,
long
a7
,
long
a8
,
long
a9
)
{
return
return_J
(
targetA10
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
,
a9
));
}
protected
long
invoke_J
(
Object
a0
,
long
a1
,
long
a2
,
long
a3
,
long
a4
,
long
a5
,
long
a6
,
long
a7
,
long
a8
,
long
a9
)
throws
Throwable
{
return
return_J
(
targetA10
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
,
a9
));
}
protected
Object
invoke_L
(
long
a0
,
long
a1
,
long
a2
,
long
a3
,
long
a4
,
long
a5
,
long
a6
,
long
a7
,
long
a8
,
long
a9
)
{
return
return_L
(
targetA10
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
,
a9
));
}
protected
Object
invoke_L
(
long
a0
,
long
a1
,
long
a2
,
long
a3
,
long
a4
,
long
a5
,
long
a6
,
long
a7
,
long
a8
,
long
a9
)
throws
Throwable
{
return
return_L
(
targetA10
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
,
a9
));
}
protected
int
invoke_I
(
long
a0
,
long
a1
,
long
a2
,
long
a3
,
long
a4
,
long
a5
,
long
a6
,
long
a7
,
long
a8
,
long
a9
)
{
return
return_I
(
targetA10
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
,
a9
));
}
protected
int
invoke_I
(
long
a0
,
long
a1
,
long
a2
,
long
a3
,
long
a4
,
long
a5
,
long
a6
,
long
a7
,
long
a8
,
long
a9
)
throws
Throwable
{
return
return_I
(
targetA10
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
,
a9
));
}
protected
long
invoke_J
(
long
a0
,
long
a1
,
long
a2
,
long
a3
,
long
a4
,
long
a5
,
long
a6
,
long
a7
,
long
a8
,
long
a9
)
{
return
return_J
(
targetA10
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
,
a9
));
}
protected
long
invoke_J
(
long
a0
,
long
a1
,
long
a2
,
long
a3
,
long
a4
,
long
a5
,
long
a6
,
long
a7
,
long
a8
,
long
a9
)
throws
Throwable
{
return
return_J
(
targetA10
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
,
a9
));
}
}
}
}
}
src/share/classes/sun/dyn/empty/Empty.java
浏览文件 @
8992d5c6
...
@@ -29,6 +29,10 @@ package sun.dyn.empty;
...
@@ -29,6 +29,10 @@ package sun.dyn.empty;
* An empty class in an empty package.
* An empty class in an empty package.
* Used as a proxy for unprivileged code, since making access checks
* Used as a proxy for unprivileged code, since making access checks
* against it will only succeed against public methods in public types.
* against it will only succeed against public methods in public types.
* <p>
* This class also stands (internally to sun.dyn) for the type of a
* value that cannot be produced, because the expression of this type
* always returns abnormally. (Cf. Nothing in the closures proposal.)
* @author jrose
* @author jrose
*/
*/
public
class
Empty
{
public
class
Empty
{
...
...
src/share/classes/sun/dyn/util/Bytecode
Signature
.java
→
src/share/classes/sun/dyn/util/Bytecode
Descriptor
.java
浏览文件 @
8992d5c6
...
@@ -33,9 +33,9 @@ import java.util.List;
...
@@ -33,9 +33,9 @@ import java.util.List;
* Utility routines for dealing with bytecode-level signatures.
* Utility routines for dealing with bytecode-level signatures.
* @author jrose
* @author jrose
*/
*/
public
class
Bytecode
Signature
{
public
class
Bytecode
Descriptor
{
private
Bytecode
Signature
()
{
}
// cannot instantiate
private
Bytecode
Descriptor
()
{
}
// cannot instantiate
public
static
List
<
Class
<?>>
parseMethod
(
String
bytecodeSignature
,
ClassLoader
loader
)
{
public
static
List
<
Class
<?>>
parseMethod
(
String
bytecodeSignature
,
ClassLoader
loader
)
{
return
parseMethod
(
bytecodeSignature
,
0
,
bytecodeSignature
.
length
(),
loader
);
return
parseMethod
(
bytecodeSignature
,
0
,
bytecodeSignature
.
length
(),
loader
);
...
...
src/share/classes/sun/dyn/util/BytecodeName.java
浏览文件 @
8992d5c6
...
@@ -298,6 +298,8 @@ public class BytecodeName {
...
@@ -298,6 +298,8 @@ public class BytecodeName {
* The name {@code <init>} will be parsed into { '<', "init", '>'}}
* The name {@code <init>} will be parsed into { '<', "init", '>'}}
* The name {@code foo/bar$:baz} will be parsed into
* The name {@code foo/bar$:baz} will be parsed into
* {@code {"foo", '/', "bar", '$', ':', "baz"}}.
* {@code {"foo", '/', "bar", '$', ':', "baz"}}.
* The name {@code ::\=:foo:\=bar\!baz} will be parsed into
* {@code {':', ':', "", ':', "foo", ':', "bar:baz"}}.
*/
*/
public
static
Object
[]
parseBytecodeName
(
String
s
)
{
public
static
Object
[]
parseBytecodeName
(
String
s
)
{
int
slen
=
s
.
length
();
int
slen
=
s
.
length
();
...
@@ -315,7 +317,7 @@ public class BytecodeName {
...
@@ -315,7 +317,7 @@ public class BytecodeName {
if
(
lasti
<
i
)
{
if
(
lasti
<
i
)
{
// normal component
// normal component
if
(
pass
!=
0
)
if
(
pass
!=
0
)
res
[
fillp
]
=
s
.
substring
(
lasti
,
i
);
res
[
fillp
]
=
toSourceName
(
s
.
substring
(
lasti
,
i
)
);
fillp
++;
fillp
++;
lasti
=
i
+
1
;
lasti
=
i
+
1
;
}
}
...
@@ -323,13 +325,14 @@ public class BytecodeName {
...
@@ -323,13 +325,14 @@ public class BytecodeName {
if
(
pass
!=
0
)
if
(
pass
!=
0
)
res
[
fillp
]
=
DANGEROUS_CHARS_CA
[
whichDC
];
res
[
fillp
]
=
DANGEROUS_CHARS_CA
[
whichDC
];
fillp
++;
fillp
++;
lasti
=
i
+
1
;
}
}
}
}
if
(
pass
!=
0
)
break
;
if
(
pass
!=
0
)
break
;
// between passes, build the result array
// between passes, build the result array
res
=
new
String
[
fillp
];
res
=
new
Object
[
fillp
];
if
(
fillp
<=
1
)
{
if
(
fillp
<=
1
&&
lasti
==
0
)
{
if
(
fillp
!=
0
)
res
[
0
]
=
s
;
if
(
fillp
!=
0
)
res
[
0
]
=
toSourceName
(
s
)
;
break
;
break
;
}
}
}
}
...
@@ -348,9 +351,19 @@ public class BytecodeName {
...
@@ -348,9 +351,19 @@ public class BytecodeName {
* @throws NullPointerException if any component is null
* @throws NullPointerException if any component is null
*/
*/
public
static
String
unparseBytecodeName
(
Object
[]
components
)
{
public
static
String
unparseBytecodeName
(
Object
[]
components
)
{
for
(
Object
c
:
components
)
{
Object
[]
components0
=
components
;
if
(
c
instanceof
String
)
for
(
int
i
=
0
;
i
<
components
.
length
;
i
++)
{
checkSafeBytecodeName
((
String
)
c
);
// may fail
Object
c
=
components
[
i
];
if
(
c
instanceof
String
)
{
String
mc
=
toBytecodeName
((
String
)
c
);
if
(
i
==
0
&&
components
.
length
==
1
)
return
mc
;
// usual case
if
((
Object
)
mc
!=
c
)
{
if
(
components
==
components0
)
components
=
components
.
clone
();
components
[
i
]
=
c
=
mc
;
}
}
}
}
return
appendAll
(
components
);
return
appendAll
(
components
);
}
}
...
@@ -381,6 +394,14 @@ public class BytecodeName {
...
@@ -381,6 +394,14 @@ public class BytecodeName {
* If the bytecode name contains dangerous characters,
* If the bytecode name contains dangerous characters,
* assume that they are being used as punctuation,
* assume that they are being used as punctuation,
* and pass them through unchanged.
* and pass them through unchanged.
* Non-empty runs of non-dangerous characters are demangled
* if necessary, and the resulting names are quoted if
* they are not already valid Java identifiers, or if
* they contain a dangerous character (i.e., dollar sign "$").
* Single quotes are used when quoting.
* Within quoted names, embedded single quotes and backslashes
* are further escaped by prepended backslashes.
*
* @param s the original bytecode name (which may be qualified)
* @param s the original bytecode name (which may be qualified)
* @return a human-readable presentation
* @return a human-readable presentation
*/
*/
...
@@ -389,10 +410,10 @@ public class BytecodeName {
...
@@ -389,10 +410,10 @@ public class BytecodeName {
for
(
int
i
=
0
;
i
<
components
.
length
;
i
++)
{
for
(
int
i
=
0
;
i
<
components
.
length
;
i
++)
{
if
(!(
components
[
i
]
instanceof
String
))
if
(!(
components
[
i
]
instanceof
String
))
continue
;
continue
;
String
c
=
(
String
)
components
[
i
];
String
sn
=
(
String
)
components
[
i
];
//
pretty up the name by demangling it
//
note that the name is already demangled!
String
sn
=
toSourceName
(
c
);
//sn = toSourceName(sn
);
if
(
(
Object
)
sn
!=
c
||
!
isJavaIdent
(
sn
)
)
{
if
(
!
isJavaIdent
(
sn
)
||
sn
.
indexOf
(
'$'
)
>=
0
)
{
components
[
i
]
=
quoteDisplay
(
sn
);
components
[
i
]
=
quoteDisplay
(
sn
);
}
}
}
}
...
@@ -401,10 +422,10 @@ public class BytecodeName {
...
@@ -401,10 +422,10 @@ public class BytecodeName {
private
static
boolean
isJavaIdent
(
String
s
)
{
private
static
boolean
isJavaIdent
(
String
s
)
{
int
slen
=
s
.
length
();
int
slen
=
s
.
length
();
if
(
slen
==
0
)
return
false
;
if
(
slen
==
0
)
return
false
;
if
(!
Character
.
is
Unicode
IdentifierStart
(
s
.
charAt
(
0
)))
if
(!
Character
.
is
Java
IdentifierStart
(
s
.
charAt
(
0
)))
return
false
;
return
false
;
for
(
int
i
=
1
;
i
<
slen
;
i
++)
{
for
(
int
i
=
1
;
i
<
slen
;
i
++)
{
if
(!
Character
.
is
UnicodeIdentifierPart
(
s
.
charAt
(
0
)))
if
(!
Character
.
is
JavaIdentifierPart
(
s
.
charAt
(
i
)))
return
false
;
return
false
;
}
}
return
true
;
return
true
;
...
@@ -602,110 +623,5 @@ public class BytecodeName {
...
@@ -602,110 +623,5 @@ public class BytecodeName {
return
-
1
;
return
-
1
;
}
}
// test driver
static
void
main
(
String
[]
av
)
{
// If verbose is enabled, quietly check everything.
// Otherwise, print the output for the user to check.
boolean
verbose
=
false
;
int
maxlen
=
0
;
while
(
av
.
length
>
0
&&
av
[
0
].
startsWith
(
"-"
))
{
String
flag
=
av
[
0
].
intern
();
av
=
java
.
util
.
Arrays
.
copyOfRange
(
av
,
1
,
av
.
length
);
// Java 1.6 or later
if
(
flag
==
"-"
||
flag
==
"--"
)
break
;
else
if
(
flag
==
"-q"
)
verbose
=
false
;
else
if
(
flag
==
"-v"
)
verbose
=
true
;
else
if
(
flag
.
startsWith
(
"-l"
))
maxlen
=
Integer
.
valueOf
(
flag
.
substring
(
2
));
else
throw
new
Error
(
"Illegal flag argument: "
+
flag
);
}
if
(
maxlen
==
0
)
maxlen
=
(
verbose
?
2
:
4
);
if
(
verbose
)
System
.
out
.
println
(
"Note: maxlen = "
+
maxlen
);
switch
(
av
.
length
)
{
case
0
:
av
=
new
String
[]
{
DANGEROUS_CHARS
.
substring
(
0
)
+
REPLACEMENT_CHARS
.
substring
(
0
,
1
)
+
NULL_ESCAPE
+
"x"
};
// and fall through:
case
1
:
char
[]
cv
=
av
[
0
].
toCharArray
();
av
=
new
String
[
cv
.
length
];
int
avp
=
0
;
for
(
char
c
:
cv
)
{
String
s
=
String
.
valueOf
(
c
);
if
(
c
==
'x'
)
s
=
"foo"
;
// tradition...
av
[
avp
++]
=
s
;
}
}
if
(
verbose
)
System
.
out
.
println
(
"Note: Verbose output mode enabled. Use '-q' to suppress."
);
Tester
t
=
new
Tester
();
t
.
maxlen
=
maxlen
;
t
.
verbose
=
verbose
;
t
.
tokens
=
av
;
t
.
test
(
""
,
0
);
}
static
class
Tester
{
boolean
verbose
;
int
maxlen
;
java
.
util
.
Map
<
String
,
String
>
map
=
new
java
.
util
.
HashMap
<
String
,
String
>();
String
[]
tokens
;
void
test
(
String
stringSoFar
,
int
tokensSoFar
)
{
test
(
stringSoFar
);
if
(
tokensSoFar
<=
maxlen
)
{
for
(
String
token
:
tokens
)
{
if
(
token
.
length
()
==
0
)
continue
;
// skip empty tokens
if
(
stringSoFar
.
indexOf
(
token
)
!=
stringSoFar
.
lastIndexOf
(
token
))
continue
;
// there are already two occs. of this token
if
(
token
.
charAt
(
0
)
==
ESCAPE_C
&&
token
.
length
()
==
1
&&
maxlen
<
4
)
test
(
stringSoFar
+
token
,
tokensSoFar
);
// want lots of \'s
else
if
(
tokensSoFar
<
maxlen
)
test
(
stringSoFar
+
token
,
tokensSoFar
+
1
);
}
}
}
void
test
(
String
s
)
{
// for small batches, do not test the null string
if
(
s
.
length
()
==
0
&&
maxlen
>=
1
&&
maxlen
<=
2
)
return
;
String
bn
=
testSourceName
(
s
);
if
(
bn
==
null
)
return
;
if
(
bn
==
s
)
{
//if (verbose) System.out.println(s+" == id");
}
else
{
if
(
verbose
)
System
.
out
.
println
(
s
+
" => "
+
bn
+
" "
+
toDisplayName
(
bn
));
String
bnbn
=
testSourceName
(
bn
);
if
(
bnbn
==
null
)
return
;
if
(
verbose
)
System
.
out
.
println
(
bn
+
" => "
+
bnbn
+
" "
+
toDisplayName
(
bnbn
));
/*
String bn3 = testSourceName(bnbn);
if (bn3 == null) return;
if (verbose) System.out.println(bnbn+" => "+bn3);
*/
}
}
String
testSourceName
(
String
s
)
{
if
(
map
.
containsKey
(
s
))
return
null
;
String
bn
=
toBytecodeName
(
s
);
map
.
put
(
s
,
bn
);
String
sn
=
toSourceName
(
bn
);
if
(!
sn
.
equals
(
s
))
{
String
bad
=
(
s
+
" => "
+
bn
+
" != "
+
sn
);
if
(!
verbose
)
throw
new
Error
(
"Bad mangling: "
+
bad
);
System
.
out
.
println
(
"*** "
+
bad
);
return
null
;
}
return
bn
;
}
}
}
}
src/share/classes/sun/dyn/util/ValueConversions.java
浏览文件 @
8992d5c6
...
@@ -27,7 +27,10 @@ package sun.dyn.util;
...
@@ -27,7 +27,10 @@ package sun.dyn.util;
import
java.dyn.*
;
import
java.dyn.*
;
import
java.dyn.MethodHandles.Lookup
;
import
java.dyn.MethodHandles.Lookup
;
import
java.util.ArrayList
;
import
java.util.Arrays
;
import
java.util.EnumMap
;
import
java.util.EnumMap
;
import
java.util.List
;
import
sun.dyn.Access
;
import
sun.dyn.Access
;
import
sun.dyn.AdapterMethodHandle
;
import
sun.dyn.AdapterMethodHandle
;
import
sun.dyn.MethodHandleImpl
;
import
sun.dyn.MethodHandleImpl
;
...
@@ -37,6 +40,7 @@ public class ValueConversions {
...
@@ -37,6 +40,7 @@ public class ValueConversions {
private
static
final
Lookup
IMPL_LOOKUP
=
MethodHandleImpl
.
getLookup
(
IMPL_TOKEN
);
private
static
final
Lookup
IMPL_LOOKUP
=
MethodHandleImpl
.
getLookup
(
IMPL_TOKEN
);
private
static
EnumMap
<
Wrapper
,
MethodHandle
>[]
newWrapperCaches
(
int
n
)
{
private
static
EnumMap
<
Wrapper
,
MethodHandle
>[]
newWrapperCaches
(
int
n
)
{
@SuppressWarnings
(
"unchecked"
)
EnumMap
<
Wrapper
,
MethodHandle
>[]
caches
EnumMap
<
Wrapper
,
MethodHandle
>[]
caches
=
(
EnumMap
<
Wrapper
,
MethodHandle
>[])
new
EnumMap
[
n
];
// unchecked warning expected here
=
(
EnumMap
<
Wrapper
,
MethodHandle
>[])
new
EnumMap
[
n
];
// unchecked warning expected here
for
(
int
i
=
0
;
i
<
n
;
i
++)
for
(
int
i
=
0
;
i
<
n
;
i
++)
...
@@ -114,7 +118,7 @@ public class ValueConversions {
...
@@ -114,7 +118,7 @@ public class ValueConversions {
}
}
private
static
MethodType
unboxType
(
Wrapper
wrap
,
boolean
raw
)
{
private
static
MethodType
unboxType
(
Wrapper
wrap
,
boolean
raw
)
{
return
MethodType
.
m
ak
e
(
rawWrapper
(
wrap
,
raw
).
primitiveType
(),
wrap
.
wrapperType
());
return
MethodType
.
m
ethodTyp
e
(
rawWrapper
(
wrap
,
raw
).
primitiveType
(),
wrap
.
wrapperType
());
}
}
private
static
final
EnumMap
<
Wrapper
,
MethodHandle
>[]
private
static
final
EnumMap
<
Wrapper
,
MethodHandle
>[]
...
@@ -240,7 +244,7 @@ public class ValueConversions {
...
@@ -240,7 +244,7 @@ public class ValueConversions {
private
static
MethodType
boxType
(
Wrapper
wrap
,
boolean
raw
)
{
private
static
MethodType
boxType
(
Wrapper
wrap
,
boolean
raw
)
{
// be exact, since return casts are hard to compose
// be exact, since return casts are hard to compose
Class
<?>
boxType
=
wrap
.
wrapperType
();
Class
<?>
boxType
=
wrap
.
wrapperType
();
return
MethodType
.
m
ak
e
(
boxType
,
rawWrapper
(
wrap
,
raw
).
primitiveType
());
return
MethodType
.
m
ethodTyp
e
(
boxType
,
rawWrapper
(
wrap
,
raw
).
primitiveType
());
}
}
private
static
Wrapper
rawWrapper
(
Wrapper
wrap
,
boolean
raw
)
{
private
static
Wrapper
rawWrapper
(
Wrapper
wrap
,
boolean
raw
)
{
...
@@ -305,29 +309,47 @@ public class ValueConversions {
...
@@ -305,29 +309,47 @@ public class ValueConversions {
/// Kludges for when raw values get accidentally boxed.
/// Kludges for when raw values get accidentally boxed.
static
int
unboxRawInteger
(
Object
x
)
{
if
(
x
instanceof
Integer
)
return
unboxInteger
(
x
);
else
return
(
int
)
unboxLong
(
x
);
}
static
Integer
reboxRawInteger
(
Object
x
)
{
if
(
x
instanceof
Integer
)
return
(
Integer
)
x
;
else
return
(
int
)
unboxLong
(
x
);
}
static
Byte
reboxRawByte
(
Object
x
)
{
static
Byte
reboxRawByte
(
Object
x
)
{
if
(
x
instanceof
Byte
)
return
(
Byte
)
x
;
if
(
x
instanceof
Byte
)
return
(
Byte
)
x
;
return
boxByteRaw
(
unboxInteger
(
x
));
return
boxByteRaw
(
unbox
Raw
Integer
(
x
));
}
}
static
Short
reboxRawShort
(
Object
x
)
{
static
Short
reboxRawShort
(
Object
x
)
{
if
(
x
instanceof
Short
)
return
(
Short
)
x
;
if
(
x
instanceof
Short
)
return
(
Short
)
x
;
return
boxShortRaw
(
unboxInteger
(
x
));
return
boxShortRaw
(
unbox
Raw
Integer
(
x
));
}
}
static
Boolean
reboxRawBoolean
(
Object
x
)
{
static
Boolean
reboxRawBoolean
(
Object
x
)
{
if
(
x
instanceof
Boolean
)
return
(
Boolean
)
x
;
if
(
x
instanceof
Boolean
)
return
(
Boolean
)
x
;
return
boxBooleanRaw
(
unboxInteger
(
x
));
return
boxBooleanRaw
(
unbox
Raw
Integer
(
x
));
}
}
static
Character
reboxRawCharacter
(
Object
x
)
{
static
Character
reboxRawCharacter
(
Object
x
)
{
if
(
x
instanceof
Character
)
return
(
Character
)
x
;
if
(
x
instanceof
Character
)
return
(
Character
)
x
;
return
boxCharacterRaw
(
unboxInteger
(
x
));
return
boxCharacterRaw
(
unbox
Raw
Integer
(
x
));
}
}
static
Float
reboxRawFloat
(
Object
x
)
{
static
Float
reboxRawFloat
(
Object
x
)
{
if
(
x
instanceof
Float
)
return
(
Float
)
x
;
if
(
x
instanceof
Float
)
return
(
Float
)
x
;
return
boxFloatRaw
(
unboxInteger
(
x
));
return
boxFloatRaw
(
unboxRawInteger
(
x
));
}
static
Long
reboxRawLong
(
Object
x
)
{
return
(
Long
)
x
;
//never a rebox
}
}
static
Double
reboxRawDouble
(
Object
x
)
{
static
Double
reboxRawDouble
(
Object
x
)
{
...
@@ -337,12 +359,21 @@ public class ValueConversions {
...
@@ -337,12 +359,21 @@ public class ValueConversions {
private
static
MethodType
reboxType
(
Wrapper
wrap
)
{
private
static
MethodType
reboxType
(
Wrapper
wrap
)
{
Class
<?>
boxType
=
wrap
.
wrapperType
();
Class
<?>
boxType
=
wrap
.
wrapperType
();
return
MethodType
.
m
ak
e
(
boxType
,
Object
.
class
);
return
MethodType
.
m
ethodTyp
e
(
boxType
,
Object
.
class
);
}
}
private
static
final
EnumMap
<
Wrapper
,
MethodHandle
>[]
private
static
final
EnumMap
<
Wrapper
,
MethodHandle
>[]
REBOX_CONVERSIONS
=
newWrapperCaches
(
2
);
REBOX_CONVERSIONS
=
newWrapperCaches
(
2
);
/**
* Becase we normalize primitive types to reduce the number of signatures,
* primitives are sometimes manipulated under an "erased" type,
* either int (for types other than long/double) or long (for all types).
* When the erased primitive value is then boxed into an Integer or Long,
* the final boxed primitive is sometimes required. This transformation
* is called a "rebox". It takes an Integer or Long and produces some
* other boxed value.
*/
public
static
MethodHandle
rebox
(
Wrapper
wrap
,
boolean
exact
)
{
public
static
MethodHandle
rebox
(
Wrapper
wrap
,
boolean
exact
)
{
EnumMap
<
Wrapper
,
MethodHandle
>
cache
=
REBOX_CONVERSIONS
[
exact
?
1
:
0
];
EnumMap
<
Wrapper
,
MethodHandle
>
cache
=
REBOX_CONVERSIONS
[
exact
?
1
:
0
];
MethodHandle
mh
=
cache
.
get
(
wrap
);
MethodHandle
mh
=
cache
.
get
(
wrap
);
...
@@ -355,9 +386,6 @@ public class ValueConversions {
...
@@ -355,9 +386,6 @@ public class ValueConversions {
mh
=
IDENTITY
;
break
;
mh
=
IDENTITY
;
break
;
case
VOID:
case
VOID:
throw
new
IllegalArgumentException
(
"cannot rebox a void"
);
throw
new
IllegalArgumentException
(
"cannot rebox a void"
);
case
INT:
case
LONG:
mh
=
cast
(
wrap
.
wrapperType
(),
exact
);
break
;
}
}
if
(
mh
!=
null
)
{
if
(
mh
!=
null
)
{
cache
.
put
(
wrap
,
mh
);
cache
.
put
(
wrap
,
mh
);
...
@@ -384,13 +412,21 @@ public class ValueConversions {
...
@@ -384,13 +412,21 @@ public class ValueConversions {
/// Width-changing conversions between int and long.
/// Width-changing conversions between int and long.
static
long
widenInt
(
int
x
)
{
static
long
widenInt
(
int
x
)
{
return
x
;
return
(
long
)
x
;
}
static
Long
widenBoxedInt
(
Integer
x
)
{
return
(
long
)(
int
)
x
;
}
}
static
int
narrowLong
(
long
x
)
{
static
int
narrowLong
(
long
x
)
{
return
(
int
)
x
;
return
(
int
)
x
;
}
}
static
Integer
narrowBoxedLong
(
Long
x
)
{
return
(
int
)(
long
)
x
;
}
/// Constant functions
/// Constant functions
static
void
ignore
(
Object
x
)
{
static
void
ignore
(
Object
x
)
{
...
@@ -432,7 +468,7 @@ public class ValueConversions {
...
@@ -432,7 +468,7 @@ public class ValueConversions {
return
mh
;
return
mh
;
}
}
// slow path
// slow path
MethodType
type
=
MethodType
.
m
ak
e
(
wrap
.
primitiveType
());
MethodType
type
=
MethodType
.
m
ethodTyp
e
(
wrap
.
primitiveType
());
switch
(
wrap
)
{
switch
(
wrap
)
{
case
VOID:
case
VOID:
mh
=
EMPTY
;
mh
=
EMPTY
;
...
@@ -500,11 +536,11 @@ public class ValueConversions {
...
@@ -500,11 +536,11 @@ public class ValueConversions {
private
static
final
MethodHandle
IDENTITY
,
CAST_REFERENCE
,
ALWAYS_NULL
,
ALWAYS_ZERO
,
ZERO_OBJECT
,
IGNORE
,
EMPTY
;
private
static
final
MethodHandle
IDENTITY
,
CAST_REFERENCE
,
ALWAYS_NULL
,
ALWAYS_ZERO
,
ZERO_OBJECT
,
IGNORE
,
EMPTY
;
static
{
static
{
try
{
try
{
MethodType
idType
=
MethodType
.
makeGeneric
(
1
);
MethodType
idType
=
MethodType
.
genericMethodType
(
1
);
MethodType
castType
=
idType
.
insertParameterType
(
0
,
Class
.
class
);
MethodType
castType
=
idType
.
insertParameterType
s
(
0
,
Class
.
class
);
MethodType
alwaysZeroType
=
idType
.
changeReturnType
(
int
.
class
);
MethodType
alwaysZeroType
=
idType
.
changeReturnType
(
int
.
class
);
MethodType
ignoreType
=
idType
.
changeReturnType
(
void
.
class
);
MethodType
ignoreType
=
idType
.
changeReturnType
(
void
.
class
);
MethodType
zeroObjectType
=
MethodType
.
makeGeneric
(
0
);
MethodType
zeroObjectType
=
MethodType
.
genericMethodType
(
0
);
IDENTITY
=
IMPL_LOOKUP
.
findStatic
(
ValueConversions
.
class
,
"identity"
,
idType
);
IDENTITY
=
IMPL_LOOKUP
.
findStatic
(
ValueConversions
.
class
,
"identity"
,
idType
);
//CAST_REFERENCE = IMPL_LOOKUP.findVirtual(Class.class, "cast", idType);
//CAST_REFERENCE = IMPL_LOOKUP.findVirtual(Class.class, "cast", idType);
CAST_REFERENCE
=
IMPL_LOOKUP
.
findStatic
(
ValueConversions
.
class
,
"castReference"
,
castType
);
CAST_REFERENCE
=
IMPL_LOOKUP
.
findStatic
(
ValueConversions
.
class
,
"castReference"
,
castType
);
...
@@ -512,7 +548,7 @@ public class ValueConversions {
...
@@ -512,7 +548,7 @@ public class ValueConversions {
ALWAYS_ZERO
=
IMPL_LOOKUP
.
findStatic
(
ValueConversions
.
class
,
"alwaysZero"
,
alwaysZeroType
);
ALWAYS_ZERO
=
IMPL_LOOKUP
.
findStatic
(
ValueConversions
.
class
,
"alwaysZero"
,
alwaysZeroType
);
ZERO_OBJECT
=
IMPL_LOOKUP
.
findStatic
(
ValueConversions
.
class
,
"zeroObject"
,
zeroObjectType
);
ZERO_OBJECT
=
IMPL_LOOKUP
.
findStatic
(
ValueConversions
.
class
,
"zeroObject"
,
zeroObjectType
);
IGNORE
=
IMPL_LOOKUP
.
findStatic
(
ValueConversions
.
class
,
"ignore"
,
ignoreType
);
IGNORE
=
IMPL_LOOKUP
.
findStatic
(
ValueConversions
.
class
,
"ignore"
,
ignoreType
);
EMPTY
=
IMPL_LOOKUP
.
findStatic
(
ValueConversions
.
class
,
"empty"
,
ignoreType
.
dropParameterType
(
0
));
EMPTY
=
IMPL_LOOKUP
.
findStatic
(
ValueConversions
.
class
,
"empty"
,
ignoreType
.
dropParameterType
s
(
0
,
1
));
}
catch
(
RuntimeException
ex
)
{
}
catch
(
RuntimeException
ex
)
{
throw
ex
;
throw
ex
;
}
}
...
@@ -543,10 +579,10 @@ public class ValueConversions {
...
@@ -543,10 +579,10 @@ public class ValueConversions {
else
if
(
VerifyType
.
isNullType
(
type
))
else
if
(
VerifyType
.
isNullType
(
type
))
mh
=
ALWAYS_NULL
;
mh
=
ALWAYS_NULL
;
else
else
mh
=
MethodHandles
.
insertArgument
(
CAST_REFERENCE
,
0
,
type
);
mh
=
MethodHandles
.
insertArgument
s
(
CAST_REFERENCE
,
0
,
type
);
if
(
exact
)
{
if
(
exact
)
{
MethodType
xmt
=
MethodType
.
m
ak
e
(
type
,
Object
.
class
);
MethodType
xmt
=
MethodType
.
m
ethodTyp
e
(
type
,
Object
.
class
);
mh
=
AdapterMethodHandle
.
makeR
awRetypeOnly
(
IMPL_TOKEN
,
xmt
,
mh
);
mh
=
AdapterMethodHandle
.
makeR
etypeRaw
(
IMPL_TOKEN
,
xmt
,
mh
);
}
}
if
(
cache
!=
null
)
if
(
cache
!=
null
)
cache
.
put
(
wrap
,
mh
);
cache
.
put
(
wrap
,
mh
);
...
@@ -560,4 +596,127 @@ public class ValueConversions {
...
@@ -560,4 +596,127 @@ public class ValueConversions {
private
static
MethodHandle
retype
(
MethodType
type
,
MethodHandle
mh
)
{
private
static
MethodHandle
retype
(
MethodType
type
,
MethodHandle
mh
)
{
return
AdapterMethodHandle
.
makeRetypeOnly
(
IMPL_TOKEN
,
type
,
mh
);
return
AdapterMethodHandle
.
makeRetypeOnly
(
IMPL_TOKEN
,
type
,
mh
);
}
}
private
static
final
Object
[]
NO_ARGS_ARRAY
=
{};
private
static
Object
[]
makeArray
(
Object
...
args
)
{
return
args
;
}
private
static
Object
[]
array
()
{
return
NO_ARGS_ARRAY
;
}
private
static
Object
[]
array
(
Object
a0
)
{
return
makeArray
(
a0
);
}
private
static
Object
[]
array
(
Object
a0
,
Object
a1
)
{
return
makeArray
(
a0
,
a1
);
}
private
static
Object
[]
array
(
Object
a0
,
Object
a1
,
Object
a2
)
{
return
makeArray
(
a0
,
a1
,
a2
);
}
private
static
Object
[]
array
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
)
{
return
makeArray
(
a0
,
a1
,
a2
,
a3
);
}
private
static
Object
[]
array
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
)
{
return
makeArray
(
a0
,
a1
,
a2
,
a3
,
a4
);
}
private
static
Object
[]
array
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
)
{
return
makeArray
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
);
}
private
static
Object
[]
array
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
a6
)
{
return
makeArray
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
);
}
private
static
Object
[]
array
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
a6
,
Object
a7
)
{
return
makeArray
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
);
}
private
static
Object
[]
array
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
a6
,
Object
a7
,
Object
a8
)
{
return
makeArray
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
);
}
private
static
Object
[]
array
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
a6
,
Object
a7
,
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
>();
MethodHandles
.
Lookup
lookup
=
IMPL_LOOKUP
;
for
(;;)
{
int
nargs
=
arrays
.
size
();
MethodType
type
=
MethodType
.
genericMethodType
(
nargs
).
changeReturnType
(
Object
[].
class
);
String
name
=
"array"
;
MethodHandle
array
=
null
;
try
{
array
=
lookup
.
findStatic
(
ValueConversions
.
class
,
name
,
type
);
}
catch
(
NoAccessException
ex
)
{
}
if
(
array
==
null
)
break
;
arrays
.
add
(
array
);
}
assert
(
arrays
.
size
()
==
11
);
// current number of methods
return
arrays
.
toArray
(
new
MethodHandle
[
0
]);
}
static
final
MethodHandle
[]
ARRAYS
=
makeArrays
();
/** Return a method handle that takes the indicated number of Object
* arguments and returns an Object array of them, as if for varargs.
*/
public
static
MethodHandle
varargsArray
(
int
nargs
)
{
if
(
nargs
<
ARRAYS
.
length
)
return
ARRAYS
[
nargs
];
// else need to spin bytecode or do something else fancy
throw
new
UnsupportedOperationException
(
"NYI"
);
}
private
static
final
List
<
Object
>
NO_ARGS_LIST
=
Arrays
.
asList
(
NO_ARGS_ARRAY
);
private
static
List
<
Object
>
makeList
(
Object
...
args
)
{
return
Arrays
.
asList
(
args
);
}
private
static
List
<
Object
>
list
()
{
return
NO_ARGS_LIST
;
}
private
static
List
<
Object
>
list
(
Object
a0
)
{
return
makeList
(
a0
);
}
private
static
List
<
Object
>
list
(
Object
a0
,
Object
a1
)
{
return
makeList
(
a0
,
a1
);
}
private
static
List
<
Object
>
list
(
Object
a0
,
Object
a1
,
Object
a2
)
{
return
makeList
(
a0
,
a1
,
a2
);
}
private
static
List
<
Object
>
list
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
)
{
return
makeList
(
a0
,
a1
,
a2
,
a3
);
}
private
static
List
<
Object
>
list
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
)
{
return
makeList
(
a0
,
a1
,
a2
,
a3
,
a4
);
}
private
static
List
<
Object
>
list
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
)
{
return
makeList
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
);
}
private
static
List
<
Object
>
list
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
a6
)
{
return
makeList
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
);
}
private
static
List
<
Object
>
list
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
a6
,
Object
a7
)
{
return
makeList
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
);
}
private
static
List
<
Object
>
list
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
a6
,
Object
a7
,
Object
a8
)
{
return
makeList
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
);
}
private
static
List
<
Object
>
list
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
a6
,
Object
a7
,
Object
a8
,
Object
a9
)
{
return
makeList
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
,
a9
);
}
static
MethodHandle
[]
makeLists
()
{
ArrayList
<
MethodHandle
>
arrays
=
new
ArrayList
<
MethodHandle
>();
MethodHandles
.
Lookup
lookup
=
IMPL_LOOKUP
;
for
(;;)
{
int
nargs
=
arrays
.
size
();
MethodType
type
=
MethodType
.
genericMethodType
(
nargs
).
changeReturnType
(
List
.
class
);
String
name
=
"list"
;
MethodHandle
array
=
null
;
try
{
array
=
lookup
.
findStatic
(
ValueConversions
.
class
,
name
,
type
);
}
catch
(
NoAccessException
ex
)
{
}
if
(
array
==
null
)
break
;
arrays
.
add
(
array
);
}
assert
(
arrays
.
size
()
==
11
);
// current number of methods
return
arrays
.
toArray
(
new
MethodHandle
[
0
]);
}
static
final
MethodHandle
[]
LISTS
=
makeLists
();
/** Return a method handle that takes the indicated number of Object
* arguments and returns List.
*/
public
static
MethodHandle
varargsList
(
int
nargs
)
{
if
(
nargs
<
LISTS
.
length
)
return
LISTS
[
nargs
];
// else need to spin bytecode or do something else fancy
throw
new
UnsupportedOperationException
(
"NYI"
);
}
}
}
src/share/classes/sun/dyn/util/VerifyAccess.java
浏览文件 @
8992d5c6
...
@@ -26,8 +26,12 @@
...
@@ -26,8 +26,12 @@
package
sun.dyn.util
;
package
sun.dyn.util
;
import
java.dyn.LinkagePermission
;
import
java.dyn.LinkagePermission
;
import
java.dyn.MethodHandles.Lookup
;
import
java.dyn.NoAccessException
;
import
java.lang.reflect.Modifier
;
import
java.lang.reflect.Modifier
;
import
sun.dyn.Access
;
import
sun.dyn.MemberName
;
import
sun.dyn.MethodHandleImpl
;
import
sun.dyn.empty.Empty
;
/**
/**
* This class centralizes information about the JVM's linkage access control.
* This class centralizes information about the JVM's linkage access control.
...
@@ -45,21 +49,21 @@ public class VerifyAccess {
...
@@ -45,21 +49,21 @@ public class VerifyAccess {
* <p>
* <p>
* Some circumstances require an additional check on the
* Some circumstances require an additional check on the
* leading parameter (the receiver) of the method, if it is non-static.
* leading parameter (the receiver) of the method, if it is non-static.
* In the case of {@code invokespecial} ({@code
doDispatch} is fals
e),
* In the case of {@code invokespecial} ({@code
isSpecialInvoke} is tru
e),
* the leading parameter must be the accessing class or a subclass.
* the leading parameter must be the accessing class or a subclass.
* In the case of a call to a {@code protected} method outside the same
* In the case of a call to a {@code protected} method outside the same
* package, the same constraint applies.
* package, the same constraint applies.
* @param m the proposed callee
* @param m the proposed callee
* @param
doDispatch if false, a non-static m will be invoked as if by
{@code invokespecial}
* @param
isSpecialInvoke if true, a non-static method m is checked as if for
{@code invokespecial}
* @param lookupClass the class for which the access check is being made
* @param lookupClass the class for which the access check is being made
* @return null if the method is not accessible, else a receiver type constraint, else {@code Object.class}
* @return null if the method is not accessible, else a receiver type constraint, else {@code Object.class}
*/
*/
public
static
Class
<?>
isAccessible
(
Class
<?>
defc
,
int
mods
,
public
static
Class
<?>
isAccessible
(
Class
<?>
defc
,
int
mods
,
boolean
doDispatch
,
Class
<?>
lookupClass
)
{
Class
<?>
lookupClass
,
boolean
isSpecialInvoke
)
{
if
(!
isAccessible
(
defc
,
lookupClass
))
if
(!
isAccessible
(
defc
,
lookupClass
))
return
null
;
return
null
;
Class
<?>
constraint
=
Object
.
class
;
Class
<?>
constraint
=
Object
.
class
;
if
(
!
doDispatch
&&
!
Modifier
.
isStatic
(
mods
))
{
if
(
isSpecialInvoke
&&
!
Modifier
.
isStatic
(
mods
))
{
constraint
=
lookupClass
;
constraint
=
lookupClass
;
}
}
if
(
Modifier
.
isPublic
(
mods
))
if
(
Modifier
.
isPublic
(
mods
))
...
@@ -166,4 +170,38 @@ public class VerifyAccess {
...
@@ -166,4 +170,38 @@ public class VerifyAccess {
if
(
isSamePackage
(
requestingClass
,
subjectClass
))
return
;
if
(
isSamePackage
(
requestingClass
,
subjectClass
))
return
;
security
.
checkPermission
(
new
LinkagePermission
(
permissionName
,
requestingClass
));
security
.
checkPermission
(
new
LinkagePermission
(
permissionName
,
requestingClass
));
}
}
private
static
RuntimeException
checkNameFailed
(
MemberName
self
,
Lookup
lookup
,
String
comment
)
{
return
new
NoAccessException
(
"cannot access from "
+
lookup
+
": "
+
self
.
toString
()+
": "
+
comment
);
}
public
static
void
checkName
(
MemberName
self
,
Lookup
lookup
)
{
Class
<?>
lc
=
lookup
.
lookupClass
();
if
(
lc
==
null
)
return
;
// lookup is privileged
Class
<?>
dc
=
self
.
getDeclaringClass
();
int
samepkg
=
0
;
// First check the containing class. Must be public or local.
if
(!
Modifier
.
isPublic
(
dc
.
getModifiers
()))
{
if
(
lc
!=
Empty
.
class
)
samepkg
=
(
isSamePackage
(
dc
,
lc
)
?
1
:
-
1
);
if
(
samepkg
<=
0
)
throw
checkNameFailed
(
self
,
lookup
,
"class is not public"
);
}
// At this point dc is known to be accessible.
if
(
self
.
isPublic
())
{
return
;
}
else
if
(
lc
==
Empty
.
class
)
{
throw
checkNameFailed
(
self
,
lookup
,
"member is not public"
);
}
else
if
(
self
.
isProtected
())
{
if
(
dc
.
isAssignableFrom
(
lc
))
return
;
}
else
if
(
self
.
isPrivate
())
{
if
(
isSamePackageMember
(
dc
,
lc
))
return
;
throw
checkNameFailed
(
self
,
lookup
,
"member is private"
);
}
// Fall-through handles the package-private and protected cases.
if
(
samepkg
==
0
)
samepkg
=
(
isSamePackage
(
dc
,
lc
)
?
1
:
-
1
);
if
(
samepkg
>
0
)
return
;
throw
checkNameFailed
(
self
,
lookup
,
self
.
isProtected
()
?
"member is protected"
:
"member is private to package"
);
}
}
}
src/share/classes/sun/dyn/util/VerifyType.java
浏览文件 @
8992d5c6
...
@@ -26,6 +26,7 @@
...
@@ -26,6 +26,7 @@
package
sun.dyn.util
;
package
sun.dyn.util
;
import
java.dyn.MethodType
;
import
java.dyn.MethodType
;
import
sun.dyn.empty.Empty
;
/**
/**
* This class centralizes information about the JVM verifier
* This class centralizes information about the JVM verifier
...
@@ -73,29 +74,28 @@ public class VerifyType {
...
@@ -73,29 +74,28 @@ public class VerifyType {
}
}
/**
/**
* Is the given type either java.lang.Void or java.lang.Null?
* Is the given type java.lang.Null or an equivalent null-only type?
* These types serve as markers for bare nulls and therefore
* may be promoted to any type. This is secure, since
*/
*/
public
static
boolean
isNullType
(
Class
<?>
type
)
{
public
static
boolean
isNullType
(
Class
<?>
type
)
{
if
(
type
==
null
)
return
false
;
if
(
type
==
null
)
return
false
;
return
type
==
NULL_CLASS_1
||
type
==
NULL_CLASS_2
;
return
type
==
NULL_CLASS
// This one may also be used as a null type.
// TO DO: Decide if we really want to legitimize it here.
// Probably we do, unless java.lang.Null really makes it into Java 7
//|| type == Void.class
// Locally known null-only class:
||
type
==
Empty
.
class
;
}
}
private
static
final
Class
<?>
NULL_CLASS
_1
,
NULL_CLASS_2
;
private
static
final
Class
<?>
NULL_CLASS
;
static
{
static
{
Class
<?>
nullClass
1
=
null
,
nullClass2
=
null
;
Class
<?>
nullClass
=
null
;
try
{
try
{
nullClass
1
=
Class
.
forName
(
"java.lang.Null"
);
nullClass
=
Class
.
forName
(
"java.lang.Null"
);
}
catch
(
ClassNotFoundException
ex
)
{
}
catch
(
ClassNotFoundException
ex
)
{
// OK, we'll cope
// OK, we'll cope
}
}
NULL_CLASS_1
=
nullClass1
;
NULL_CLASS
=
nullClass
;
// This one may also be used as a null type.
// TO DO: Decide if we really want to legitimize it here.
// Probably we do, unless java.lang.Null really makes it into Java 7
nullClass2
=
Void
.
class
;
NULL_CLASS_2
=
nullClass2
;
}
}
/**
/**
...
@@ -191,6 +191,11 @@ public class VerifyType {
...
@@ -191,6 +191,11 @@ public class VerifyType {
// to be captured as a garbage int.
// to be captured as a garbage int.
// Caller promises that the actual value will be disregarded.
// Caller promises that the actual value will be disregarded.
return
dst
==
int
.
class
?
1
:
0
;
return
dst
==
int
.
class
?
1
:
0
;
if
(
isNullType
(
src
))
// Special permission for raw conversions: allow a null
// to be reinterpreted as anything. For objects, it is safe,
// and for primitives you get a garbage value (probably zero).
return
1
;
if
(!
src
.
isPrimitive
())
if
(!
src
.
isPrimitive
())
return
0
;
return
0
;
Wrapper
sw
=
Wrapper
.
forPrimitiveType
(
src
);
Wrapper
sw
=
Wrapper
.
forPrimitiveType
(
src
);
...
...
src/share/classes/sun/dyn/util/Wrapper.java
浏览文件 @
8992d5c6
...
@@ -141,13 +141,19 @@ public enum Wrapper {
...
@@ -141,13 +141,19 @@ public enum Wrapper {
* @throws IllegalArgumentException for unexpected types
* @throws IllegalArgumentException for unexpected types
*/
*/
public
static
Wrapper
forPrimitiveType
(
Class
<?>
type
)
{
public
static
Wrapper
forPrimitiveType
(
Class
<?>
type
)
{
Wrapper
w
=
findPrimitiveType
(
type
);
if
(
w
!=
null
)
return
w
;
if
(
type
.
isPrimitive
())
throw
new
InternalError
();
// redo hash function
throw
newIllegalArgumentException
(
"not primitive: "
+
type
);
}
static
Wrapper
findPrimitiveType
(
Class
<?>
type
)
{
Wrapper
w
=
FROM_PRIM
[
hashPrim
(
type
)];
Wrapper
w
=
FROM_PRIM
[
hashPrim
(
type
)];
if
(
w
!=
null
&&
w
.
primitiveType
==
type
)
{
if
(
w
!=
null
&&
w
.
primitiveType
==
type
)
{
return
w
;
return
w
;
}
}
if
(
type
.
isPrimitive
())
return
null
;
throw
new
InternalError
();
// redo hash function
throw
newIllegalArgumentException
(
"not primitive: "
+
type
);
}
}
/** Return the wrapper that wraps values into the given wrapper type.
/** Return the wrapper that wraps values into the given wrapper type.
...
@@ -160,7 +166,7 @@ public enum Wrapper {
...
@@ -160,7 +166,7 @@ public enum Wrapper {
Wrapper
w
=
findWrapperType
(
type
);
Wrapper
w
=
findWrapperType
(
type
);
if
(
w
!=
null
)
return
w
;
if
(
w
!=
null
)
return
w
;
for
(
Wrapper
x
:
values
())
for
(
Wrapper
x
:
values
())
if
(
w
.
wrapperType
==
type
)
if
(
x
.
wrapperType
==
type
)
throw
new
InternalError
();
// redo hash function
throw
new
InternalError
();
// redo hash function
throw
newIllegalArgumentException
(
"not wrapper: "
+
type
);
throw
newIllegalArgumentException
(
"not wrapper: "
+
type
);
}
}
...
@@ -244,8 +250,10 @@ public enum Wrapper {
...
@@ -244,8 +250,10 @@ public enum Wrapper {
public
Class
<?>
wrapperType
()
{
return
wrapperType
;
}
public
Class
<?>
wrapperType
()
{
return
wrapperType
;
}
/** What is the wrapper type for this wrapper?
/** What is the wrapper type for this wrapper?
*
T
he example type must be the wrapper type,
*
Otherwise, t
he example type must be the wrapper type,
* or the corresponding primitive type.
* or the corresponding primitive type.
* (For {@code OBJECT}, the example type can be any non-primitive,
* and is normalized to {@code Object.class}.)
* The resulting class type has the same type parameter.
* The resulting class type has the same type parameter.
*/
*/
public
<
T
>
Class
<
T
>
wrapperType
(
Class
<
T
>
exampleType
)
{
public
<
T
>
Class
<
T
>
wrapperType
(
Class
<
T
>
exampleType
)
{
...
@@ -290,6 +298,16 @@ public enum Wrapper {
...
@@ -290,6 +298,16 @@ public enum Wrapper {
return
type
.
isPrimitive
();
return
type
.
isPrimitive
();
}
}
/** What is the bytecode signature character for this type?
* All non-primitives, including array types, report as 'L', the signature character for references.
*/
public
static
char
basicTypeChar
(
Class
<?>
type
)
{
if
(!
type
.
isPrimitive
())
return
'L'
;
else
return
forPrimitiveType
(
type
).
basicTypeChar
();
}
/** What is the bytecode signature character for this wrapper's
/** What is the bytecode signature character for this wrapper's
* primitive type?
* primitive type?
*/
*/
...
@@ -309,7 +327,7 @@ public enum Wrapper {
...
@@ -309,7 +327,7 @@ public enum Wrapper {
/** Cast a wrapped value to the given type, which may be either a primitive or wrapper type.
/** Cast a wrapped value to the given type, which may be either a primitive or wrapper type.
* Performs standard primitive conversions, including truncation and float conversions.
* Performs standard primitive conversions, including truncation and float conversions.
* The given type must be compatible with this wrapper. That is, it must either
* The given type must be compatible with this wrapper. That is, it must either
* be the wrapper type (or a subtype, in the case of {@code OBJECT} or else
* be the wrapper type (or a subtype, in the case of {@code OBJECT}
)
or else
* it must be the wrapper's primitive type.
* it must be the wrapper's primitive type.
* @throws ClassCastException if the given type is not compatible with this wrapper
* @throws ClassCastException if the given type is not compatible with this wrapper
*/
*/
...
@@ -326,9 +344,17 @@ public enum Wrapper {
...
@@ -326,9 +344,17 @@ public enum Wrapper {
* If the target type is a primitive, change it to a wrapper.
* If the target type is a primitive, change it to a wrapper.
*/
*/
static
<
T
>
Class
<
T
>
forceType
(
Class
<?>
type
,
Class
<
T
>
exampleType
)
{
static
<
T
>
Class
<
T
>
forceType
(
Class
<?>
type
,
Class
<
T
>
exampleType
)
{
boolean
z
=
(
type
==
exampleType
||
type
.
isPrimitive
()
&&
forPrimitiveType
(
type
)
==
findWrapperType
(
exampleType
)
||
exampleType
.
isPrimitive
()
&&
forPrimitiveType
(
exampleType
)
==
findWrapperType
(
type
)
||
type
==
Object
.
class
&&
!
exampleType
.
isPrimitive
());
if
(!
z
)
System
.
out
.
println
(
type
+
" <= "
+
exampleType
);
assert
(
type
==
exampleType
||
assert
(
type
==
exampleType
||
type
==
asWrapperType
(
exampleType
)
||
type
.
isPrimitive
()
&&
forPrimitiveType
(
type
)
==
findWrapperType
(
exampleType
)
||
type
==
Object
.
class
&&
exampleType
.
isInterface
());
exampleType
.
isPrimitive
()
&&
forPrimitiveType
(
exampleType
)
==
findWrapperType
(
type
)
||
type
==
Object
.
class
&&
!
exampleType
.
isPrimitive
());
@SuppressWarnings
(
"unchecked"
)
Class
<
T
>
result
=
(
Class
<
T
>)
type
;
// unchecked warning is expected here
Class
<
T
>
result
=
(
Class
<
T
>)
type
;
// unchecked warning is expected here
return
result
;
return
result
;
}
}
...
...
test/java/dyn/MethodHandlesTest.java
0 → 100644
浏览文件 @
8992d5c6
/*
* Copyright 2009 Sun Microsystems, Inc. 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. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
/* @test
* @summary unit tests for java.dyn.MethodHandles
* @compile -XDinvokedynamic MethodHandlesTest.java
* @run junit/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableInvokeDynamic jdk.java.dyn.MethodHandlesTest
*/
package
jdk.java.dyn
;
import
java.dyn.*
;
import
java.dyn.MethodHandles.Lookup
;
import
java.lang.reflect.*
;
import
java.util.*
;
import
java.util.logging.Level
;
import
java.util.logging.Logger
;
import
org.junit.*
;
import
static
org
.
junit
.
Assert
.*;
/**
*
* @author jrose
*/
public
class
MethodHandlesTest
{
// How much output?
static
int
verbosity
=
1
;
// Set this true during development if you want to fast-forward to
// a particular new, non-working test. Tests which are known to
// work (or have recently worked) test this flag and return on true.
static
boolean
CAN_SKIP_WORKING
=
false
;
//static { CAN_SKIP_WORKING = true; }
// Set true to test more calls. If false, some tests are just
// lookups, without exercising the actual method handle.
static
boolean
DO_MORE_CALLS
=
false
;
@Test
public
void
testFirst
()
throws
Throwable
{
verbosity
+=
9
;
try
{
// left blank for debugging
}
finally
{
verbosity
-=
9
;
}
}
// current failures
@Test
@Ignore
(
"failure in call to makeRawRetypeOnly in ToGeneric"
)
public
void
testFail_1
()
throws
Throwable
{
testSpreadArguments
(
int
.
class
,
0
,
6
);
}
@Test
@Ignore
(
"failure in JVM when expanding the stack"
)
public
void
testFail_2
()
throws
Throwable
{
// if CONV_OP_IMPLEMENTED_MASK includes OP_SPREAD_ARGS, this crashes:
testSpreadArguments
(
Object
.
class
,
0
,
2
);
}
@Test
@Ignore
(
"IllArgEx failure in call to ToGeneric.make"
)
public
void
testFail_3
()
throws
Throwable
{
testSpreadArguments
(
int
.
class
,
1
,
2
);
}
@Test
@Ignore
(
"IllArgEx failure in call to ToGeneric.make"
)
public
void
testFail_4
()
throws
Throwable
{
testCollectArguments
(
int
.
class
,
1
,
2
);
}
@Test
@Ignore
(
"cannot collect leading primitive types"
)
public
void
testFail_5
()
throws
Throwable
{
testInvokers
(
MethodType
.
genericMethodType
(
2
).
changeParameterType
(
0
,
int
.
class
));
}
@Test
@Ignore
(
"should not insert arguments beyond MethodHandlePushLimit"
)
public
void
testFail_6
()
throws
Throwable
{
testInsertArguments
(
0
,
0
,
MAX_ARG_INCREASE
+
1
);
}
static
final
int
MAX_ARG_INCREASE
=
3
;
public
MethodHandlesTest
()
{
}
String
testName
;
int
posTests
,
negTests
;
@After
public
void
printCounts
()
{
if
(
verbosity
>=
1
&&
(
posTests
|
negTests
)
!=
0
)
{
System
.
out
.
println
();
if
(
posTests
!=
0
)
System
.
out
.
println
(
"=== "
+
testName
+
": "
+
posTests
+
" positive test cases run"
);
if
(
negTests
!=
0
)
System
.
out
.
println
(
"=== "
+
testName
+
": "
+
negTests
+
" negative test cases run"
);
}
}
void
countTest
(
boolean
positive
)
{
if
(
positive
)
++
posTests
;
else
++
negTests
;
}
void
countTest
()
{
countTest
(
true
);
}
void
startTest
(
String
name
)
{
if
(
testName
!=
null
)
printCounts
();
if
(
verbosity
>=
0
)
System
.
out
.
println
(
name
);
posTests
=
negTests
=
0
;
testName
=
name
;
}
@BeforeClass
public
static
void
setUpClass
()
throws
Exception
{
calledLog
.
clear
();
calledLog
.
add
(
null
);
nextArg
=
1000000
;
}
@AfterClass
public
static
void
tearDownClass
()
throws
Exception
{
}
static
List
<
Object
>
calledLog
=
new
ArrayList
<
Object
>();
static
Object
logEntry
(
String
name
,
Object
...
args
)
{
return
Arrays
.
asList
(
name
,
Arrays
.
asList
(
args
));
}
static
Object
called
(
String
name
,
Object
...
args
)
{
Object
entry
=
logEntry
(
name
,
args
);
calledLog
.
add
(
entry
);
return
entry
;
}
static
void
assertCalled
(
String
name
,
Object
...
args
)
{
Object
expected
=
logEntry
(
name
,
args
);
Object
actual
=
calledLog
.
get
(
calledLog
.
size
()
-
1
);
if
(
expected
.
equals
(
actual
))
return
;
System
.
out
.
println
(
"assertCalled "
+
name
+
":"
);
System
.
out
.
println
(
"expected: "
+
expected
);
System
.
out
.
println
(
"actual: "
+
actual
);
System
.
out
.
println
(
"ex. types: "
+
getClasses
(
expected
));
System
.
out
.
println
(
"act. types: "
+
getClasses
(
actual
));
assertEquals
(
"previous method call types"
,
expected
,
actual
);
assertEquals
(
"previous method call"
,
expected
,
actual
);
}
static
void
printCalled
(
MethodHandle
target
,
String
name
,
Object
...
args
)
{
if
(
verbosity
>=
2
)
System
.
out
.
println
(
"calling "
+
logEntry
(
name
,
args
)+
" on "
+
target
);
}
static
Object
castToWrapper
(
Object
value
,
Class
<?>
dst
)
{
Object
wrap
=
null
;
if
(
value
instanceof
Number
)
wrap
=
castToWrapperOrNull
(((
Number
)
value
).
longValue
(),
dst
);
if
(
value
instanceof
Character
)
wrap
=
castToWrapperOrNull
((
char
)(
Character
)
value
,
dst
);
if
(
wrap
!=
null
)
return
wrap
;
return
dst
.
cast
(
value
);
}
static
Object
castToWrapperOrNull
(
long
value
,
Class
<?>
dst
)
{
if
(
dst
==
int
.
class
||
dst
==
Integer
.
class
)
return
(
int
)(
value
);
if
(
dst
==
long
.
class
||
dst
==
Long
.
class
)
return
(
long
)(
value
);
if
(
dst
==
char
.
class
||
dst
==
Character
.
class
)
return
(
char
)(
value
);
if
(
dst
==
short
.
class
||
dst
==
Short
.
class
)
return
(
short
)(
value
);
if
(
dst
==
float
.
class
||
dst
==
Float
.
class
)
return
(
float
)(
value
);
if
(
dst
==
double
.
class
||
dst
==
Double
.
class
)
return
(
double
)(
value
);
if
(
dst
==
byte
.
class
||
dst
==
Byte
.
class
)
return
(
byte
)(
value
);
if
(
dst
==
boolean
.
class
||
dst
==
boolean
.
class
)
return
((
value
%
29
)
&
1
)
==
0
;
return
null
;
}
static
int
nextArg
;
static
Object
randomArg
(
Class
<?>
param
)
{
Object
wrap
=
castToWrapperOrNull
(
nextArg
,
param
);
if
(
wrap
!=
null
)
{
nextArg
++;
return
wrap
;
}
// import sun.dyn.util.Wrapper;
// Wrapper wrap = Wrapper.forBasicType(dst);
// if (wrap == Wrapper.OBJECT && Wrapper.isWrapperType(dst))
// wrap = Wrapper.forWrapperType(dst);
// if (wrap != Wrapper.OBJECT)
// return wrap.wrap(nextArg++);
if
(
param
.
isInterface
()
||
param
.
isAssignableFrom
(
String
.
class
))
return
"#"
+(
nextArg
++);
else
try
{
return
param
.
newInstance
();
}
catch
(
InstantiationException
ex
)
{
}
catch
(
IllegalAccessException
ex
)
{
}
return
null
;
// random class not Object, String, Integer, etc.
}
static
Object
[]
randomArgs
(
Class
<?>...
params
)
{
Object
[]
args
=
new
Object
[
params
.
length
];
for
(
int
i
=
0
;
i
<
args
.
length
;
i
++)
args
[
i
]
=
randomArg
(
params
[
i
]);
return
args
;
}
static
Object
[]
randomArgs
(
int
nargs
,
Class
<?>
param
)
{
Object
[]
args
=
new
Object
[
nargs
];
for
(
int
i
=
0
;
i
<
args
.
length
;
i
++)
args
[
i
]
=
randomArg
(
param
);
return
args
;
}
static
<
T
,
E
extends
T
>
T
[]
array
(
Class
<
T
[]>
atype
,
E
...
a
)
{
return
Arrays
.
copyOf
(
a
,
a
.
length
,
atype
);
}
static
<
T
>
T
[]
cat
(
T
[]
a
,
T
...
b
)
{
int
alen
=
a
.
length
,
blen
=
b
.
length
;
if
(
blen
==
0
)
return
a
;
T
[]
c
=
Arrays
.
copyOf
(
a
,
alen
+
blen
);
System
.
arraycopy
(
b
,
0
,
c
,
alen
,
blen
);
return
c
;
}
static
Integer
[]
boxAll
(
int
...
vx
)
{
Integer
[]
res
=
new
Integer
[
vx
.
length
];
for
(
int
i
=
0
;
i
<
res
.
length
;
i
++)
{
res
[
i
]
=
vx
[
i
];
}
return
res
;
}
static
Object
getClasses
(
Object
x
)
{
if
(
x
==
null
)
return
x
;
if
(
x
instanceof
String
)
return
x
;
// keep the name
if
(
x
instanceof
List
)
{
// recursively report classes of the list elements
Object
[]
xa
=
((
List
)
x
).
toArray
();
for
(
int
i
=
0
;
i
<
xa
.
length
;
i
++)
xa
[
i
]
=
getClasses
(
xa
[
i
]);
return
Arrays
.
asList
(
xa
);
}
return
x
.
getClass
().
getSimpleName
();
}
static
MethodHandle
changeArgTypes
(
MethodHandle
target
,
Class
<?>
argType
)
{
return
changeArgTypes
(
target
,
0
,
999
,
argType
);
}
static
MethodHandle
changeArgTypes
(
MethodHandle
target
,
int
beg
,
int
end
,
Class
<?>
argType
)
{
MethodType
targetType
=
target
.
type
();
end
=
Math
.
min
(
end
,
targetType
.
parameterCount
());
ArrayList
<
Class
<?>>
argTypes
=
new
ArrayList
<
Class
<?>>(
targetType
.
parameterList
());
Collections
.
fill
(
argTypes
.
subList
(
beg
,
end
),
argType
);
MethodType
ttype2
=
MethodType
.
methodType
(
targetType
.
returnType
(),
argTypes
);
return
MethodHandles
.
convertArguments
(
target
,
ttype2
);
}
// This lookup is good for all members in and under MethodHandlesTest.
static
final
Lookup
PRIVATE
=
MethodHandles
.
lookup
();
// This lookup is good for package-private members but not private ones.
static
final
Lookup
PACKAGE
=
PackageSibling
.
lookup
();
// This lookup is good only for public members.
static
final
Lookup
PUBLIC
=
MethodHandles
.
publicLookup
();
// Subject methods...
static
class
Example
implements
IntExample
{
final
String
name
;
public
Example
()
{
name
=
"Example#"
+(
nextArg
++);
}
protected
Example
(
String
name
)
{
this
.
name
=
name
;
}
protected
Example
(
int
x
)
{
this
();
called
(
"protected <init>"
,
this
,
x
);
}
@Override
public
String
toString
()
{
return
name
;
}
public
void
v0
()
{
called
(
"v0"
,
this
);
}
void
pkg_v0
()
{
called
(
"pkg_v0"
,
this
);
}
private
void
pri_v0
()
{
called
(
"pri_v0"
,
this
);
}
public
static
void
s0
()
{
called
(
"s0"
);
}
static
void
pkg_s0
()
{
called
(
"pkg_s0"
);
}
private
static
void
pri_s0
()
{
called
(
"pri_s0"
);
}
public
Object
v1
(
Object
x
)
{
return
called
(
"v1"
,
this
,
x
);
}
public
Object
v2
(
Object
x
,
Object
y
)
{
return
called
(
"v2"
,
this
,
x
,
y
);
}
public
Object
v2
(
Object
x
,
int
y
)
{
return
called
(
"v2"
,
this
,
x
,
y
);
}
public
Object
v2
(
int
x
,
Object
y
)
{
return
called
(
"v2"
,
this
,
x
,
y
);
}
public
Object
v2
(
int
x
,
int
y
)
{
return
called
(
"v2"
,
this
,
x
,
y
);
}
public
static
Object
s1
(
Object
x
)
{
return
called
(
"s1"
,
x
);
}
public
static
Object
s2
(
int
x
)
{
return
called
(
"s2"
,
x
);
}
public
static
Object
s3
(
long
x
)
{
return
called
(
"s3"
,
x
);
}
public
static
Object
s4
(
int
x
,
int
y
)
{
return
called
(
"s4"
,
x
,
y
);
}
public
static
Object
s5
(
long
x
,
int
y
)
{
return
called
(
"s5"
,
x
,
y
);
}
public
static
Object
s6
(
int
x
,
long
y
)
{
return
called
(
"s6"
,
x
,
y
);
}
public
static
Object
s7
(
float
x
,
double
y
)
{
return
called
(
"s7"
,
x
,
y
);
}
}
public
static
class
PubExample
extends
Example
{
}
static
class
SubExample
extends
Example
{
@Override
public
void
v0
()
{
called
(
"Sub/v0"
,
this
);
}
@Override
void
pkg_v0
()
{
called
(
"Sub/pkg_v0"
,
this
);
}
private
SubExample
(
int
x
)
{
called
(
"<init>"
,
this
,
x
);
}
public
SubExample
()
{
super
(
"SubExample#"
+(
nextArg
++));
}
}
public
static
interface
IntExample
{
public
void
v0
();
static
class
Impl
implements
IntExample
{
public
void
v0
()
{
called
(
"Int/v0"
,
this
);
}
final
String
name
;
public
Impl
()
{
name
=
"Example#"
+(
nextArg
++);
}
}
}
static
final
Object
[][][]
ACCESS_CASES
=
{
{
{
false
,
PUBLIC
},
{
false
,
PACKAGE
},
{
false
,
PRIVATE
}
},
{
{
false
,
PUBLIC
},
{
false
,
PACKAGE
},
{
true
,
PRIVATE
}
},
{
{
false
,
PUBLIC
},
{
true
,
PACKAGE
},
{
true
,
PRIVATE
}
},
{
{
true
,
PUBLIC
},
{
true
,
PACKAGE
},
{
true
,
PRIVATE
}
},
};
static
Object
[][]
accessCases
(
Class
<?>
defc
,
String
name
)
{
if
(
name
.
contains
(
"pri_"
))
{
return
ACCESS_CASES
[
1
];
// PRIVATE only
}
else
if
(
name
.
contains
(
"pkg_"
))
{
return
ACCESS_CASES
[
2
];
// not PUBLIC
}
else
{
assertTrue
(
name
.
indexOf
(
'_'
)
<
0
);
boolean
pubc
=
Modifier
.
isPublic
(
defc
.
getModifiers
());
if
(
pubc
)
return
ACCESS_CASES
[
3
];
// all access levels
return
ACCESS_CASES
[
2
];
// PACKAGE but not PUBLIC
}
}
@Test
public
void
testFindStatic
()
throws
Throwable
{
if
(
CAN_SKIP_WORKING
)
return
;
startTest
(
"findStatic"
);
testFindStatic
(
PubExample
.
class
,
void
.
class
,
"s0"
);
testFindStatic
(
Example
.
class
,
void
.
class
,
"s0"
);
testFindStatic
(
Example
.
class
,
void
.
class
,
"pkg_s0"
);
testFindStatic
(
Example
.
class
,
void
.
class
,
"pri_s0"
);
testFindStatic
(
Example
.
class
,
Object
.
class
,
"s1"
,
Object
.
class
);
testFindStatic
(
Example
.
class
,
Object
.
class
,
"s2"
,
int
.
class
);
testFindStatic
(
Example
.
class
,
Object
.
class
,
"s3"
,
long
.
class
);
testFindStatic
(
Example
.
class
,
Object
.
class
,
"s4"
,
int
.
class
,
int
.
class
);
testFindStatic
(
Example
.
class
,
Object
.
class
,
"s5"
,
long
.
class
,
int
.
class
);
testFindStatic
(
Example
.
class
,
Object
.
class
,
"s6"
,
int
.
class
,
long
.
class
);
testFindStatic
(
Example
.
class
,
Object
.
class
,
"s7"
,
float
.
class
,
double
.
class
);
testFindStatic
(
false
,
PRIVATE
,
Example
.
class
,
void
.
class
,
"bogus"
);
}
void
testFindStatic
(
Class
<?>
defc
,
Class
<?>
ret
,
String
name
,
Class
<?>...
params
)
throws
Throwable
{
for
(
Object
[]
ac
:
accessCases
(
defc
,
name
))
{
testFindStatic
((
Boolean
)
ac
[
0
],
(
Lookup
)
ac
[
1
],
defc
,
ret
,
name
,
params
);
}
}
void
testFindStatic
(
Lookup
lookup
,
Class
<?>
defc
,
Class
<?>
ret
,
String
name
,
Class
<?>...
params
)
throws
Throwable
{
testFindStatic
(
true
,
lookup
,
defc
,
ret
,
name
,
params
);
}
void
testFindStatic
(
boolean
positive
,
Lookup
lookup
,
Class
<?>
defc
,
Class
<?>
ret
,
String
name
,
Class
<?>...
params
)
throws
Throwable
{
countTest
(
positive
);
MethodType
type
=
MethodType
.
methodType
(
ret
,
params
);
MethodHandle
target
=
null
;
RuntimeException
noAccess
=
null
;
try
{
target
=
lookup
.
findStatic
(
defc
,
name
,
type
);
}
catch
(
NoAccessException
ex
)
{
noAccess
=
ex
;
}
if
(
verbosity
>=
2
)
System
.
out
.
println
(
"findStatic "
+
lookup
+
": "
+
defc
+
"."
+
name
+
"/"
+
type
+
" => "
+
target
+(
noAccess
==
null
?
""
:
" !! "
+
noAccess
));
if
(
positive
&&
noAccess
!=
null
)
throw
noAccess
;
assertEquals
(
positive
?
"positive test"
:
"negative test erroneously passed"
,
positive
,
target
!=
null
);
if
(!
positive
)
return
;
// negative test failed as expected
assertEquals
(
type
,
target
.
type
());
assertTrue
(
target
.
toString
().
contains
(
name
));
// rough check
if
(!
DO_MORE_CALLS
&&
lookup
!=
PRIVATE
)
return
;
Object
[]
args
=
randomArgs
(
params
);
printCalled
(
target
,
name
,
args
);
target
.
invokeVarargs
(
args
);
assertCalled
(
name
,
args
);
System
.
out
.
print
(
':'
);
}
@Test
public
void
testFindVirtual
()
throws
Throwable
{
if
(
CAN_SKIP_WORKING
)
return
;
startTest
(
"findVirtual"
);
testFindVirtual
(
Example
.
class
,
void
.
class
,
"v0"
);
testFindVirtual
(
Example
.
class
,
void
.
class
,
"pkg_v0"
);
testFindVirtual
(
Example
.
class
,
void
.
class
,
"pri_v0"
);
testFindVirtual
(
Example
.
class
,
Object
.
class
,
"v1"
,
Object
.
class
);
testFindVirtual
(
Example
.
class
,
Object
.
class
,
"v2"
,
Object
.
class
,
Object
.
class
);
testFindVirtual
(
Example
.
class
,
Object
.
class
,
"v2"
,
Object
.
class
,
int
.
class
);
testFindVirtual
(
Example
.
class
,
Object
.
class
,
"v2"
,
int
.
class
,
Object
.
class
);
testFindVirtual
(
Example
.
class
,
Object
.
class
,
"v2"
,
int
.
class
,
int
.
class
);
testFindVirtual
(
false
,
PRIVATE
,
Example
.
class
,
Example
.
class
,
void
.
class
,
"bogus"
);
// test dispatch
testFindVirtual
(
SubExample
.
class
,
SubExample
.
class
,
void
.
class
,
"Sub/v0"
);
testFindVirtual
(
SubExample
.
class
,
Example
.
class
,
void
.
class
,
"Sub/v0"
);
testFindVirtual
(
SubExample
.
class
,
IntExample
.
class
,
void
.
class
,
"Sub/v0"
);
testFindVirtual
(
SubExample
.
class
,
SubExample
.
class
,
void
.
class
,
"Sub/pkg_v0"
);
testFindVirtual
(
SubExample
.
class
,
Example
.
class
,
void
.
class
,
"Sub/pkg_v0"
);
testFindVirtual
(
Example
.
class
,
IntExample
.
class
,
void
.
class
,
"v0"
);
testFindVirtual
(
IntExample
.
Impl
.
class
,
IntExample
.
class
,
void
.
class
,
"Int/v0"
);
}
void
testFindVirtual
(
Class
<?>
defc
,
Class
<?>
ret
,
String
name
,
Class
<?>...
params
)
throws
Throwable
{
Class
<?>
rcvc
=
defc
;
testFindVirtual
(
rcvc
,
defc
,
ret
,
name
,
params
);
}
void
testFindVirtual
(
Class
<?>
rcvc
,
Class
<?>
defc
,
Class
<?>
ret
,
String
name
,
Class
<?>...
params
)
throws
Throwable
{
for
(
Object
[]
ac
:
accessCases
(
defc
,
name
))
{
testFindVirtual
((
Boolean
)
ac
[
0
],
(
Lookup
)
ac
[
1
],
rcvc
,
defc
,
ret
,
name
,
params
);
}
}
void
testFindVirtual
(
Lookup
lookup
,
Class
<?>
rcvc
,
Class
<?>
defc
,
Class
<?>
ret
,
String
name
,
Class
<?>...
params
)
throws
Throwable
{
testFindVirtual
(
true
,
lookup
,
rcvc
,
defc
,
ret
,
name
,
params
);
}
void
testFindVirtual
(
boolean
positive
,
Lookup
lookup
,
Class
<?>
rcvc
,
Class
<?>
defc
,
Class
<?>
ret
,
String
name
,
Class
<?>...
params
)
throws
Throwable
{
countTest
(
positive
);
String
methodName
=
name
.
substring
(
1
+
name
.
indexOf
(
'/'
));
// foo/bar => foo
MethodType
type
=
MethodType
.
methodType
(
ret
,
params
);
MethodHandle
target
=
null
;
RuntimeException
noAccess
=
null
;
try
{
target
=
lookup
.
findVirtual
(
defc
,
methodName
,
type
);
}
catch
(
NoAccessException
ex
)
{
noAccess
=
ex
;
}
if
(
verbosity
>=
2
)
System
.
out
.
println
(
"findVirtual "
+
lookup
+
": "
+
defc
+
"."
+
name
+
"/"
+
type
+
" => "
+
target
+(
noAccess
==
null
?
""
:
" !! "
+
noAccess
));
if
(
positive
&&
noAccess
!=
null
)
throw
noAccess
;
assertEquals
(
positive
?
"positive test"
:
"negative test erroneously passed"
,
positive
,
target
!=
null
);
if
(!
positive
)
return
;
// negative test failed as expected
Class
<?>[]
paramsWithSelf
=
cat
(
array
(
Class
[].
class
,
(
Class
)
defc
),
params
);
MethodType
typeWithSelf
=
MethodType
.
methodType
(
ret
,
paramsWithSelf
);
MethodType
ttype
=
target
.
type
();
ttype
=
ttype
.
changeParameterType
(
0
,
defc
);
// FIXME: test this
assertEquals
(
typeWithSelf
,
ttype
);
assertTrue
(
target
.
toString
().
contains
(
methodName
));
// rough check
if
(!
DO_MORE_CALLS
&&
lookup
!=
PRIVATE
)
return
;
Object
[]
argsWithSelf
=
randomArgs
(
paramsWithSelf
);
if
(
rcvc
!=
defc
)
argsWithSelf
[
0
]
=
randomArg
(
rcvc
);
printCalled
(
target
,
name
,
argsWithSelf
);
target
.
invokeVarargs
(
argsWithSelf
);
assertCalled
(
name
,
argsWithSelf
);
System
.
out
.
print
(
':'
);
}
@Test
public
void
testFindSpecial
()
throws
Throwable
{
if
(
CAN_SKIP_WORKING
)
return
;
startTest
(
"findSpecial"
);
testFindSpecial
(
Example
.
class
,
void
.
class
,
"v0"
);
testFindSpecial
(
Example
.
class
,
void
.
class
,
"pkg_v0"
);
testFindSpecial
(
false
,
PRIVATE
,
Example
.
class
,
void
.
class
,
"<init>"
,
int
.
class
);
testFindSpecial
(
false
,
PRIVATE
,
Example
.
class
,
void
.
class
,
"bogus"
);
}
void
testFindSpecial
(
Class
<?>
defc
,
Class
<?>
ret
,
String
name
,
Class
<?>...
params
)
throws
Throwable
{
testFindSpecial
(
true
,
PRIVATE
,
defc
,
ret
,
name
,
params
);
testFindSpecial
(
false
,
PACKAGE
,
defc
,
ret
,
name
,
params
);
testFindSpecial
(
false
,
PUBLIC
,
defc
,
ret
,
name
,
params
);
}
void
testFindSpecial
(
boolean
positive
,
Lookup
lookup
,
Class
<?>
defc
,
Class
<?>
ret
,
String
name
,
Class
<?>...
params
)
throws
Throwable
{
countTest
(
positive
);
MethodType
type
=
MethodType
.
methodType
(
ret
,
params
);
MethodHandle
target
=
null
;
RuntimeException
noAccess
=
null
;
try
{
target
=
lookup
.
findSpecial
(
defc
,
name
,
type
,
defc
);
}
catch
(
NoAccessException
ex
)
{
noAccess
=
ex
;
}
if
(
verbosity
>=
2
)
System
.
out
.
println
(
"findSpecial "
+
defc
+
"."
+
name
+
"/"
+
type
+
" => "
+
target
+(
noAccess
==
null
?
""
:
" !! "
+
noAccess
));
if
(
positive
&&
noAccess
!=
null
)
throw
noAccess
;
assertEquals
(
positive
?
"positive test"
:
"negative test erroneously passed"
,
positive
,
target
!=
null
);
if
(!
positive
)
return
;
// negative test failed as expected
Class
<?>[]
paramsWithSelf
=
cat
(
array
(
Class
[].
class
,
(
Class
)
defc
),
params
);
MethodType
typeWithSelf
=
MethodType
.
methodType
(
ret
,
paramsWithSelf
);
MethodType
ttype
=
target
.
type
();
ttype
=
ttype
.
changeParameterType
(
0
,
defc
);
// FIXME: test this
assertEquals
(
typeWithSelf
,
ttype
);
assertTrue
(
target
.
toString
().
contains
(
name
));
// rough check
if
(!
DO_MORE_CALLS
&&
lookup
!=
PRIVATE
)
return
;
Object
[]
args
=
randomArgs
(
paramsWithSelf
);
printCalled
(
target
,
name
,
args
);
target
.
invokeVarargs
(
args
);
assertCalled
(
name
,
args
);
System
.
out
.
print
(
':'
);
}
@Test
public
void
testBind
()
throws
Throwable
{
if
(
CAN_SKIP_WORKING
)
return
;
startTest
(
"bind"
);
testBind
(
Example
.
class
,
void
.
class
,
"v0"
);
testBind
(
Example
.
class
,
void
.
class
,
"pkg_v0"
);
testBind
(
Example
.
class
,
void
.
class
,
"pri_v0"
);
testBind
(
Example
.
class
,
Object
.
class
,
"v1"
,
Object
.
class
);
testBind
(
Example
.
class
,
Object
.
class
,
"v2"
,
Object
.
class
,
Object
.
class
);
testBind
(
Example
.
class
,
Object
.
class
,
"v2"
,
Object
.
class
,
int
.
class
);
testBind
(
Example
.
class
,
Object
.
class
,
"v2"
,
int
.
class
,
Object
.
class
);
testBind
(
Example
.
class
,
Object
.
class
,
"v2"
,
int
.
class
,
int
.
class
);
testBind
(
false
,
PRIVATE
,
Example
.
class
,
void
.
class
,
"bogus"
);
testBind
(
SubExample
.
class
,
void
.
class
,
"Sub/v0"
);
testBind
(
SubExample
.
class
,
void
.
class
,
"Sub/pkg_v0"
);
testBind
(
IntExample
.
Impl
.
class
,
void
.
class
,
"Int/v0"
);
}
void
testBind
(
Class
<?>
defc
,
Class
<?>
ret
,
String
name
,
Class
<?>...
params
)
throws
Throwable
{
for
(
Object
[]
ac
:
accessCases
(
defc
,
name
))
{
testBind
((
Boolean
)
ac
[
0
],
(
Lookup
)
ac
[
1
],
defc
,
ret
,
name
,
params
);
}
}
void
testBind
(
boolean
positive
,
Lookup
lookup
,
Class
<?>
defc
,
Class
<?>
ret
,
String
name
,
Class
<?>...
params
)
throws
Throwable
{
countTest
(
positive
);
String
methodName
=
name
.
substring
(
1
+
name
.
indexOf
(
'/'
));
// foo/bar => foo
MethodType
type
=
MethodType
.
methodType
(
ret
,
params
);
Object
receiver
=
randomArg
(
defc
);
MethodHandle
target
=
null
;
RuntimeException
noAccess
=
null
;
try
{
target
=
lookup
.
bind
(
receiver
,
methodName
,
type
);
}
catch
(
NoAccessException
ex
)
{
noAccess
=
ex
;
}
if
(
verbosity
>=
2
)
System
.
out
.
println
(
"bind "
+
receiver
+
"."
+
name
+
"/"
+
type
+
" => "
+
target
+(
noAccess
==
null
?
""
:
" !! "
+
noAccess
));
if
(
positive
&&
noAccess
!=
null
)
throw
noAccess
;
assertEquals
(
positive
?
"positive test"
:
"negative test erroneously passed"
,
positive
,
target
!=
null
);
if
(!
positive
)
return
;
// negative test failed as expected
assertEquals
(
type
,
target
.
type
());
Object
[]
args
=
randomArgs
(
params
);
printCalled
(
target
,
name
,
args
);
target
.
invokeVarargs
(
args
);
Object
[]
argsWithReceiver
=
cat
(
array
(
Object
[].
class
,
receiver
),
args
);
assertCalled
(
name
,
argsWithReceiver
);
System
.
out
.
print
(
':'
);
}
@Test
public
void
testUnreflect
()
throws
Throwable
{
if
(
CAN_SKIP_WORKING
)
return
;
startTest
(
"unreflect"
);
testUnreflect
(
Example
.
class
,
true
,
void
.
class
,
"s0"
);
testUnreflect
(
Example
.
class
,
true
,
void
.
class
,
"pkg_s0"
);
testUnreflect
(
Example
.
class
,
true
,
void
.
class
,
"pri_s0"
);
testUnreflect
(
Example
.
class
,
true
,
Object
.
class
,
"s1"
,
Object
.
class
);
testUnreflect
(
Example
.
class
,
true
,
Object
.
class
,
"s2"
,
int
.
class
);
//testUnreflect(Example.class, true, Object.class, "s3", long.class);
//testUnreflect(Example.class, true, Object.class, "s4", int.class, int.class);
//testUnreflect(Example.class, true, Object.class, "s5", long.class, int.class);
//testUnreflect(Example.class, true, Object.class, "s6", int.class, long.class);
testUnreflect
(
Example
.
class
,
false
,
void
.
class
,
"v0"
);
testUnreflect
(
Example
.
class
,
false
,
void
.
class
,
"pkg_v0"
);
testUnreflect
(
Example
.
class
,
false
,
void
.
class
,
"pri_v0"
);
testUnreflect
(
Example
.
class
,
false
,
Object
.
class
,
"v1"
,
Object
.
class
);
testUnreflect
(
Example
.
class
,
false
,
Object
.
class
,
"v2"
,
Object
.
class
,
Object
.
class
);
testUnreflect
(
Example
.
class
,
false
,
Object
.
class
,
"v2"
,
Object
.
class
,
int
.
class
);
testUnreflect
(
Example
.
class
,
false
,
Object
.
class
,
"v2"
,
int
.
class
,
Object
.
class
);
testUnreflect
(
Example
.
class
,
false
,
Object
.
class
,
"v2"
,
int
.
class
,
int
.
class
);
}
void
testUnreflect
(
Class
<?>
defc
,
boolean
isStatic
,
Class
<?>
ret
,
String
name
,
Class
<?>...
params
)
throws
Throwable
{
for
(
Object
[]
ac
:
accessCases
(
defc
,
name
))
{
testUnreflect
((
Boolean
)
ac
[
0
],
(
Lookup
)
ac
[
1
],
defc
,
isStatic
,
ret
,
name
,
params
);
}
}
void
testUnreflect
(
boolean
positive
,
Lookup
lookup
,
Class
<?>
defc
,
boolean
isStatic
,
Class
<?>
ret
,
String
name
,
Class
<?>...
params
)
throws
Throwable
{
countTest
(
positive
);
MethodType
type
=
MethodType
.
methodType
(
ret
,
params
);
Method
rmethod
=
null
;
MethodHandle
target
=
null
;
RuntimeException
noAccess
=
null
;
try
{
rmethod
=
defc
.
getDeclaredMethod
(
name
,
params
);
}
catch
(
NoSuchMethodException
ex
)
{
throw
new
NoAccessException
(
ex
);
}
assertEquals
(
isStatic
,
Modifier
.
isStatic
(
rmethod
.
getModifiers
()));
try
{
target
=
lookup
.
unreflect
(
rmethod
);
}
catch
(
NoAccessException
ex
)
{
noAccess
=
ex
;
}
if
(
verbosity
>=
2
)
System
.
out
.
println
(
"unreflect "
+
defc
+
"."
+
name
+
"/"
+
type
+
" => "
+
target
+(
noAccess
==
null
?
""
:
" !! "
+
noAccess
));
if
(
positive
&&
noAccess
!=
null
)
throw
noAccess
;
assertEquals
(
positive
?
"positive test"
:
"negative test erroneously passed"
,
positive
,
target
!=
null
);
if
(!
positive
)
return
;
// negative test failed as expected
Class
<?>[]
paramsMaybeWithSelf
=
params
;
if
(!
isStatic
)
{
paramsMaybeWithSelf
=
cat
(
array
(
Class
[].
class
,
(
Class
)
defc
),
params
);
}
MethodType
typeMaybeWithSelf
=
MethodType
.
methodType
(
ret
,
paramsMaybeWithSelf
);
MethodType
ttype
=
target
.
type
();
if
(!
isStatic
)
ttype
=
ttype
.
changeParameterType
(
0
,
defc
);
// FIXME: test this
assertEquals
(
typeMaybeWithSelf
,
ttype
);
Object
[]
argsMaybeWithSelf
=
randomArgs
(
paramsMaybeWithSelf
);
printCalled
(
target
,
name
,
argsMaybeWithSelf
);
target
.
invokeVarargs
(
argsMaybeWithSelf
);
assertCalled
(
name
,
argsMaybeWithSelf
);
System
.
out
.
print
(
':'
);
}
@Test
@Ignore
(
"unimplemented"
)
public
void
testUnreflectSpecial
()
throws
Throwable
{
Lookup
lookup
=
PRIVATE
;
// FIXME: test more lookups than this one
startTest
(
"unreflectSpecial"
);
Method
m
=
null
;
MethodHandle
expResult
=
null
;
MethodHandle
result
=
lookup
.
unreflectSpecial
(
m
,
Example
.
class
);
assertEquals
(
expResult
,
result
);
fail
(
"The test case is a prototype."
);
}
public
static
class
HasFields
{
boolean
fZ
=
false
;
byte
fB
=
(
byte
)
'B'
;
short
fS
=
(
short
)
'S'
;
char
fC
=
'C'
;
int
fI
=
'I'
;
long
fJ
=
'J'
;
float
fF
=
'F'
;
double
fD
=
'D'
;
static
boolean
sZ
=
true
;
static
byte
sB
=
1
+(
byte
)
'B'
;
static
short
sS
=
1
+(
short
)
'S'
;
static
char
sC
=
1
+
'C'
;
static
int
sI
=
1
+
'I'
;
static
long
sJ
=
1
+
'J'
;
static
float
sF
=
1
+
'F'
;
static
double
sD
=
1
+
'D'
;
Object
fL
=
'L'
;
String
fR
=
"R"
;
static
Object
sL
=
'M'
;
static
String
sR
=
"S"
;
static
final
Object
[][]
CASES
;
static
{
ArrayList
<
Object
[]>
cases
=
new
ArrayList
<
Object
[]>();
Object
types
[][]
=
{
{
'L'
,
Object
.
class
},
{
'R'
,
String
.
class
},
{
'I'
,
int
.
class
},
{
'J'
,
long
.
class
},
{
'F'
,
float
.
class
},
{
'D'
,
double
.
class
},
{
'Z'
,
boolean
.
class
},
{
'B'
,
byte
.
class
},
{
'S'
,
short
.
class
},
{
'C'
,
char
.
class
},
};
HasFields
fields
=
new
HasFields
();
for
(
Object
[]
t
:
types
)
{
for
(
int
kind
=
0
;
kind
<=
1
;
kind
++)
{
boolean
isStatic
=
(
kind
!=
0
);
char
btc
=
(
Character
)
t
[
0
];
String
name
=
(
isStatic
?
"s"
:
"f"
)
+
btc
;
Class
<?>
type
=
(
Class
<?>)
t
[
1
];
Object
value
;
Field
field
;
try
{
field
=
HasFields
.
class
.
getDeclaredField
(
name
);
}
catch
(
Exception
ex
)
{
throw
new
InternalError
(
"no field HasFields."
+
name
);
}
try
{
value
=
field
.
get
(
fields
);
}
catch
(
Exception
ex
)
{
throw
new
InternalError
(
"cannot fetch field HasFields."
+
name
);
}
if
(
type
==
float
.
class
)
{
float
v
=
'F'
;
if
(
isStatic
)
v
++;
assert
(
value
.
equals
(
v
));
}
assert
(
name
.
equals
(
field
.
getName
()));
assert
(
type
.
equals
(
field
.
getType
()));
assert
(
isStatic
==
(
Modifier
.
isStatic
(
field
.
getModifiers
())));
cases
.
add
(
new
Object
[]{
field
,
value
});
}
}
CASES
=
cases
.
toArray
(
new
Object
[
0
][]);
}
}
@Test
public
void
testUnreflectGetter
()
throws
Throwable
{
Lookup
lookup
=
PRIVATE
;
// FIXME: test more lookups than this one
startTest
(
"unreflectGetter"
);
for
(
Object
[]
c
:
HasFields
.
CASES
)
{
Field
f
=
(
Field
)
c
[
0
];
Object
value
=
c
[
1
];
Class
<?>
type
=
f
.
getType
();
if
(
type
.
isPrimitive
()
&&
type
!=
int
.
class
)
continue
;
//FIXME
testUnreflectGetter
(
lookup
,
f
,
type
,
value
);
}
}
public
void
testUnreflectGetter
(
MethodHandles
.
Lookup
lookup
,
Field
f
,
Class
<?>
type
,
Object
value
)
throws
Throwable
{
countTest
(
true
);
boolean
isStatic
=
Modifier
.
isStatic
(
f
.
getModifiers
());
MethodType
expType
=
MethodType
.
methodType
(
type
,
HasFields
.
class
);
if
(
isStatic
)
expType
=
expType
.
dropParameterTypes
(
0
,
1
);
MethodHandle
mh
=
lookup
.
unreflectGetter
(
f
);
assertSame
(
mh
.
type
(),
expType
);
assertEquals
(
mh
.
toString
(),
f
.
getName
());
HasFields
fields
=
new
HasFields
();
Object
sawValue
;
Class
<?>
rtype
=
type
;
if
(
type
!=
int
.
class
)
rtype
=
Object
.
class
;
mh
=
MethodHandles
.
convertArguments
(
mh
,
mh
.
type
().
generic
().
changeReturnType
(
rtype
));
Object
expValue
=
value
;
for
(
int
i
=
0
;
i
<=
1
;
i
++)
{
if
(
isStatic
)
{
if
(
type
==
int
.
class
)
sawValue
=
mh
.<
int
>
invoke
();
// do these exactly
else
sawValue
=
mh
.
invoke
();
}
else
{
if
(
type
==
int
.
class
)
sawValue
=
mh
.<
int
>
invoke
((
Object
)
fields
);
else
sawValue
=
mh
.
invoke
((
Object
)
fields
);
}
assertEquals
(
sawValue
,
expValue
);
Object
random
=
randomArg
(
type
);
f
.
set
(
fields
,
random
);
expValue
=
random
;
}
f
.
set
(
fields
,
value
);
// put it back
}
@Test
public
void
testUnreflectSetter
()
throws
Throwable
{
Lookup
lookup
=
PRIVATE
;
// FIXME: test more lookups than this one
startTest
(
"unreflectSetter"
);
for
(
Object
[]
c
:
HasFields
.
CASES
)
{
Field
f
=
(
Field
)
c
[
0
];
Object
value
=
c
[
1
];
Class
<?>
type
=
f
.
getType
();
if
(
type
.
isPrimitive
()
&&
type
!=
int
.
class
)
continue
;
//FIXME
testUnreflectSetter
(
lookup
,
f
,
type
,
value
);
}
}
public
void
testUnreflectSetter
(
MethodHandles
.
Lookup
lookup
,
Field
f
,
Class
<?>
type
,
Object
value
)
throws
Throwable
{
countTest
(
true
);
boolean
isStatic
=
Modifier
.
isStatic
(
f
.
getModifiers
());
MethodType
expType
=
MethodType
.
methodType
(
void
.
class
,
HasFields
.
class
,
type
);
if
(
isStatic
)
expType
=
expType
.
dropParameterTypes
(
0
,
1
);
MethodHandle
mh
=
lookup
.
unreflectSetter
(
f
);
assertSame
(
mh
.
type
(),
expType
);
assertEquals
(
mh
.
toString
(),
f
.
getName
());
HasFields
fields
=
new
HasFields
();
Object
sawValue
;
Class
<?>
vtype
=
type
;
if
(
type
!=
int
.
class
)
vtype
=
Object
.
class
;
int
last
=
mh
.
type
().
parameterCount
()
-
1
;
mh
=
MethodHandles
.
convertArguments
(
mh
,
mh
.
type
().
generic
().
changeReturnType
(
void
.
class
).
changeParameterType
(
last
,
vtype
));
assertEquals
(
f
.
get
(
fields
),
value
);
// clean to start with
for
(
int
i
=
0
;
i
<=
1
;
i
++)
{
Object
putValue
=
randomArg
(
type
);
if
(
isStatic
)
{
if
(
type
==
int
.
class
)
mh
.<
void
>
invoke
((
int
)(
Integer
)
putValue
);
// do these exactly
else
mh
.<
void
>
invoke
(
putValue
);
}
else
{
if
(
type
==
int
.
class
)
mh
.<
void
>
invoke
((
Object
)
fields
,
(
int
)(
Integer
)
putValue
);
else
mh
.<
void
>
invoke
((
Object
)
fields
,
putValue
);
}
assertEquals
(
f
.
get
(
fields
),
putValue
);
}
f
.
set
(
fields
,
value
);
// put it back
}
@Test
public
void
testArrayElementGetter
()
throws
Throwable
{
startTest
(
"arrayElementGetter"
);
testArrayElementGetterSetter
(
new
Object
[
10
],
false
);
testArrayElementGetterSetter
(
new
String
[
10
],
false
);
testArrayElementGetterSetter
(
new
int
[
10
],
false
);
// FIXME: Do the other primitive types.
//testArrayElementGetterSetter(new float[10], false);
}
@Test
public
void
testArrayElementSetter
()
throws
Throwable
{
startTest
(
"arrayElementSetter"
);
testArrayElementGetterSetter
(
new
Object
[
10
],
true
);
testArrayElementGetterSetter
(
new
String
[
10
],
true
);
testArrayElementGetterSetter
(
new
int
[
10
],
true
);
// FIXME: Do the other primitive types.
//testArrayElementGetterSetter(new float[10], true);
}
public
void
testArrayElementGetterSetter
(
Object
array
,
boolean
testSetter
)
throws
Throwable
{
countTest
(
true
);
Class
<?>
arrayType
=
array
.
getClass
();
Class
<?>
elemType
=
arrayType
.
getComponentType
();
MethodType
expType
=
!
testSetter
?
MethodType
.
methodType
(
elemType
,
arrayType
,
int
.
class
)
:
MethodType
.
methodType
(
void
.
class
,
arrayType
,
int
.
class
,
elemType
);
MethodHandle
mh
=
!
testSetter
?
MethodHandles
.
arrayElementGetter
(
arrayType
)
:
MethodHandles
.
arrayElementSetter
(
arrayType
);
assertSame
(
mh
.
type
(),
expType
);
//assertEquals(mh.toString(), f.getName());
Object
sawValue
,
expValue
;
List
<
Object
>
model
=
array2list
(
array
);
int
length
=
Array
.
getLength
(
array
);
for
(
int
i
=
0
;
i
<
length
;
i
++)
{
// update array element
Object
random
=
randomArg
(
elemType
);
model
.
set
(
i
,
random
);
if
(
testSetter
)
{
if
(
elemType
==
int
.
class
)
mh
.<
void
>
invoke
((
int
[])
array
,
i
,
(
int
)(
Integer
)
random
);
else
mh
.
invokeGeneric
(
array
,
i
,
random
);
assertEquals
(
model
,
array2list
(
array
));
}
else
{
Array
.
set
(
array
,
i
,
random
);
}
// observe array element
sawValue
=
Array
.
get
(
array
,
i
);
if
(!
testSetter
)
{
expValue
=
sawValue
;
if
(
elemType
==
int
.
class
)
sawValue
=
mh
.<
int
>
invoke
((
int
[])
array
,
i
);
else
sawValue
=
mh
.
invokeGeneric
(
array
,
i
);
assertEquals
(
sawValue
,
expValue
);
assertEquals
(
model
,
array2list
(
array
));
}
}
}
List
<
Object
>
array2list
(
Object
array
)
{
int
length
=
Array
.
getLength
(
array
);
ArrayList
<
Object
>
model
=
new
ArrayList
<
Object
>(
length
);
for
(
int
i
=
0
;
i
<
length
;
i
++)
model
.
add
(
Array
.
get
(
array
,
i
));
return
model
;
}
static
class
Callee
{
static
Object
id
()
{
return
called
(
"id"
);
}
static
Object
id
(
Object
x
)
{
return
called
(
"id"
,
x
);
}
static
Object
id
(
Object
x
,
Object
y
)
{
return
called
(
"id"
,
x
,
y
);
}
static
Object
id
(
Object
x
,
Object
y
,
Object
z
)
{
return
called
(
"id"
,
x
,
y
,
z
);
}
static
Object
id
(
Object
...
vx
)
{
return
called
(
"id"
,
vx
);
}
static
MethodHandle
ofType
(
int
n
)
{
return
ofType
(
Object
.
class
,
n
);
}
static
MethodHandle
ofType
(
Class
<?>
rtype
,
int
n
)
{
if
(
n
==
-
1
)
return
ofType
(
MethodType
.
methodType
(
rtype
,
Object
[].
class
));
return
ofType
(
MethodType
.
genericMethodType
(
n
).
changeReturnType
(
rtype
));
}
static
MethodHandle
ofType
(
Class
<?>
rtype
,
Class
<?>...
ptypes
)
{
return
ofType
(
MethodType
.
methodType
(
rtype
,
ptypes
));
}
static
MethodHandle
ofType
(
MethodType
type
)
{
Class
<?>
rtype
=
type
.
returnType
();
String
pfx
=
""
;
if
(
rtype
!=
Object
.
class
)
pfx
=
rtype
.
getSimpleName
().
substring
(
0
,
1
).
toLowerCase
();
String
name
=
pfx
+
"id"
;
return
PRIVATE
.
findStatic
(
Callee
.
class
,
name
,
type
);
}
}
@Test
public
void
testConvertArguments
()
throws
Throwable
{
if
(
CAN_SKIP_WORKING
)
return
;
startTest
(
"convertArguments"
);
testConvert
(
Callee
.
ofType
(
1
),
null
,
"id"
,
int
.
class
);
testConvert
(
Callee
.
ofType
(
1
),
null
,
"id"
,
String
.
class
);
testConvert
(
Callee
.
ofType
(
1
),
null
,
"id"
,
Integer
.
class
);
testConvert
(
Callee
.
ofType
(
1
),
null
,
"id"
,
short
.
class
);
}
void
testConvert
(
MethodHandle
id
,
Class
<?>
rtype
,
String
name
,
Class
<?>...
params
)
throws
Throwable
{
testConvert
(
true
,
id
,
rtype
,
name
,
params
);
}
void
testConvert
(
boolean
positive
,
MethodHandle
id
,
Class
<?>
rtype
,
String
name
,
Class
<?>...
params
)
throws
Throwable
{
countTest
(
positive
);
MethodType
idType
=
id
.
type
();
if
(
rtype
==
null
)
rtype
=
idType
.
returnType
();
for
(
int
i
=
0
;
i
<
params
.
length
;
i
++)
{
if
(
params
[
i
]
==
null
)
params
[
i
]
=
idType
.
parameterType
(
i
);
}
// simulate the pairwise conversion
MethodType
newType
=
MethodType
.
methodType
(
rtype
,
params
);
Object
[]
args
=
randomArgs
(
newType
.
parameterArray
());
Object
[]
convArgs
=
args
.
clone
();
for
(
int
i
=
0
;
i
<
args
.
length
;
i
++)
{
Class
<?>
src
=
newType
.
parameterType
(
i
);
Class
<?>
dst
=
idType
.
parameterType
(
i
);
if
(
src
!=
dst
)
convArgs
[
i
]
=
castToWrapper
(
convArgs
[
i
],
dst
);
}
Object
convResult
=
id
.
invokeVarargs
(
convArgs
);
{
Class
<?>
dst
=
newType
.
returnType
();
Class
<?>
src
=
idType
.
returnType
();
if
(
src
!=
dst
)
convResult
=
castToWrapper
(
convResult
,
dst
);
}
MethodHandle
target
=
null
;
RuntimeException
error
=
null
;
try
{
target
=
MethodHandles
.
convertArguments
(
id
,
newType
);
}
catch
(
RuntimeException
ex
)
{
error
=
ex
;
}
if
(
verbosity
>=
2
)
System
.
out
.
println
(
"convert "
+
id
+
" to "
+
newType
+
" => "
+
target
+(
error
==
null
?
""
:
" !! "
+
error
));
if
(
positive
&&
error
!=
null
)
throw
error
;
assertEquals
(
positive
?
"positive test"
:
"negative test erroneously passed"
,
positive
,
target
!=
null
);
if
(!
positive
)
return
;
// negative test failed as expected
assertEquals
(
newType
,
target
.
type
());
printCalled
(
target
,
id
.
toString
(),
args
);
Object
result
=
target
.
invokeVarargs
(
args
);
assertCalled
(
name
,
convArgs
);
assertEquals
(
convResult
,
result
);
System
.
out
.
print
(
':'
);
}
@Test
public
void
testPermuteArguments
()
throws
Throwable
{
if
(
CAN_SKIP_WORKING
)
return
;
startTest
(
"permuteArguments"
);
testPermuteArguments
(
4
,
Integer
.
class
,
2
,
String
.
class
,
0
);
//testPermuteArguments(6, Integer.class, 0, null, 30);
//testPermuteArguments(4, Integer.class, 1, int.class, 6);
}
public
void
testPermuteArguments
(
int
max
,
Class
<?>
type1
,
int
t2c
,
Class
<?>
type2
,
int
dilution
)
throws
Throwable
{
if
(
verbosity
>=
1
)
System
.
out
.
println
(
"permuteArguments "
+
max
+
"*"
+
type1
.
getName
()
+(
t2c
==
0
?
""
:
"/"
+
t2c
+
"*"
+
type2
.
getName
())
+(
dilution
>
0
?
" with dilution "
+
dilution
:
""
));
int
t2pos
=
t2c
==
0
?
0
:
1
;
for
(
int
inargs
=
t2pos
+
1
;
inargs
<=
max
;
inargs
++)
{
Class
<?>[]
types
=
new
Class
<?>[
inargs
];
Arrays
.
fill
(
types
,
type1
);
if
(
t2c
!=
0
)
{
// Fill in a middle range with type2:
Arrays
.
fill
(
types
,
t2pos
,
Math
.
min
(
t2pos
+
t2c
,
inargs
),
type2
);
}
Object
[]
args
=
randomArgs
(
types
);
int
numcases
=
1
;
for
(
int
outargs
=
0
;
outargs
<=
max
;
outargs
++)
{
if
(
outargs
-
inargs
>=
MAX_ARG_INCREASE
)
continue
;
int
[]
reorder
=
new
int
[
outargs
];
int
casStep
=
dilution
+
1
;
// Avoid some common factors:
while
((
casStep
>
2
&&
casStep
%
2
==
0
&&
inargs
%
2
==
0
)
||
(
casStep
>
3
&&
casStep
%
3
==
0
&&
inargs
%
3
==
0
))
casStep
++;
for
(
int
cas
=
0
;
cas
<
numcases
;
cas
+=
casStep
)
{
for
(
int
i
=
0
,
c
=
cas
;
i
<
outargs
;
i
++)
{
reorder
[
i
]
=
c
%
inargs
;
c
/=
inargs
;
}
testPermuteArguments
(
args
,
types
,
reorder
);
}
numcases
*=
inargs
;
if
(
dilution
>
10
&&
outargs
>=
4
)
{
// Do some special patterns, which we probably missed.
// Replication of a single argument or argument pair.
for
(
int
i
=
0
;
i
<
inargs
;
i
++)
{
Arrays
.
fill
(
reorder
,
i
);
testPermuteArguments
(
args
,
types
,
reorder
);
for
(
int
d
=
1
;
d
<=
2
;
d
++)
{
if
(
i
+
d
>=
inargs
)
continue
;
for
(
int
j
=
1
;
j
<
outargs
;
j
+=
2
)
reorder
[
j
]
+=
1
;
testPermuteArguments
(
args
,
types
,
reorder
);
testPermuteArguments
(
args
,
types
,
reverse
(
reorder
));
}
}
// Repetition of a sequence of 3 or more arguments.
for
(
int
i
=
1
;
i
<
inargs
;
i
++)
{
for
(
int
len
=
3
;
len
<=
inargs
;
len
++)
{
for
(
int
j
=
0
;
j
<
outargs
;
j
++)
reorder
[
j
]
=
(
i
+
(
j
%
len
))
%
inargs
;
testPermuteArguments
(
args
,
types
,
reorder
);
testPermuteArguments
(
args
,
types
,
reverse
(
reorder
));
}
}
}
}
}
}
static
int
[]
reverse
(
int
[]
reorder
)
{
reorder
=
reorder
.
clone
();
for
(
int
i
=
0
,
imax
=
reorder
.
length
/
2
;
i
<
imax
;
i
++)
{
int
j
=
reorder
.
length
-
1
-
i
;
int
tem
=
reorder
[
i
];
reorder
[
i
]
=
reorder
[
j
];
reorder
[
j
]
=
tem
;
}
return
reorder
;
}
void
testPermuteArguments
(
Object
[]
args
,
Class
<?>[]
types
,
int
[]
reorder
)
throws
Throwable
{
countTest
();
if
(
args
==
null
&&
types
==
null
)
{
int
max
=
0
;
for
(
int
j
:
reorder
)
{
if
(
max
<
j
)
max
=
j
;
}
args
=
randomArgs
(
max
+
1
,
Integer
.
class
);
}
if
(
args
==
null
)
{
args
=
randomArgs
(
types
);
}
if
(
types
==
null
)
{
types
=
new
Class
<?>[
args
.
length
];
for
(
int
i
=
0
;
i
<
args
.
length
;
i
++)
types
[
i
]
=
args
[
i
].
getClass
();
}
int
inargs
=
args
.
length
,
outargs
=
reorder
.
length
;
assert
(
inargs
==
types
.
length
);
if
(
verbosity
>=
2
)
System
.
out
.
println
(
"permuteArguments "
+
Arrays
.
toString
(
reorder
));
Object
[]
permArgs
=
new
Object
[
outargs
];
Class
<?>[]
permTypes
=
new
Class
<?>[
outargs
];
for
(
int
i
=
0
;
i
<
outargs
;
i
++)
{
permArgs
[
i
]
=
args
[
reorder
[
i
]];
permTypes
[
i
]
=
types
[
reorder
[
i
]];
}
if
(
verbosity
>=
3
)
{
System
.
out
.
println
(
"in args: "
+
Arrays
.
asList
(
args
));
System
.
out
.
println
(
"out args: "
+
Arrays
.
asList
(
permArgs
));
System
.
out
.
println
(
"in types: "
+
Arrays
.
asList
(
types
));
System
.
out
.
println
(
"out types: "
+
Arrays
.
asList
(
permTypes
));
}
MethodType
inType
=
MethodType
.
methodType
(
Object
.
class
,
types
);
MethodType
outType
=
MethodType
.
methodType
(
Object
.
class
,
permTypes
);
MethodHandle
target
=
MethodHandles
.
convertArguments
(
ValueConversions
.
varargsList
(
outargs
),
outType
);
MethodHandle
newTarget
=
MethodHandles
.
permuteArguments
(
target
,
inType
,
reorder
);
Object
result
=
newTarget
.
invokeVarargs
(
args
);
Object
expected
=
Arrays
.
asList
(
permArgs
);
assertEquals
(
expected
,
result
);
}
@Test
public
void
testSpreadArguments
()
throws
Throwable
{
if
(
CAN_SKIP_WORKING
)
return
;
startTest
(
"spreadArguments"
);
for
(
Class
<?>
argType
:
new
Class
[]{
Object
.
class
,
Integer
.
class
,
int
.
class
})
{
if
(
verbosity
>=
2
)
System
.
out
.
println
(
"spreadArguments "
+
argType
);
for
(
int
nargs
=
0
;
nargs
<
10
;
nargs
++)
{
if
(
argType
==
int
.
class
&&
nargs
>=
6
)
continue
;
// FIXME Fail_1
for
(
int
pos
=
0
;
pos
<
nargs
;
pos
++)
{
if
(
argType
==
int
.
class
&&
pos
>
0
)
continue
;
// FIXME Fail_3
testSpreadArguments
(
argType
,
pos
,
nargs
);
}
}
}
}
public
void
testSpreadArguments
(
Class
<?>
argType
,
int
pos
,
int
nargs
)
throws
Throwable
{
countTest
();
MethodHandle
target
=
ValueConversions
.
varargsArray
(
nargs
);
MethodHandle
target2
=
changeArgTypes
(
target
,
argType
);
if
(
verbosity
>=
2
)
System
.
out
.
println
(
"spread into "
+
target2
+
" ["
+
pos
+
".."
+
nargs
+
"]"
);
Object
[]
args
=
randomArgs
(
target2
.
type
().
parameterArray
());
// make sure the target does what we think it does:
if
(
pos
==
0
&&
nargs
<
5
)
{
Object
[]
check
=
(
Object
[])
target
.
invokeVarargs
(
args
);
assertArrayEquals
(
args
,
check
);
switch
(
nargs
)
{
case
0
:
check
=
target
.<
Object
[]>
invoke
();
assertArrayEquals
(
args
,
check
);
break
;
case
1
:
check
=
target
.<
Object
[]>
invoke
(
args
[
0
]);
assertArrayEquals
(
args
,
check
);
break
;
case
2
:
check
=
target
.<
Object
[]>
invoke
(
args
[
0
],
args
[
1
]);
assertArrayEquals
(
args
,
check
);
break
;
}
}
List
<
Class
<?>>
newParams
=
new
ArrayList
<
Class
<?>>(
target2
.
type
().
parameterList
());
{
// modify newParams in place
List
<
Class
<?>>
spreadParams
=
newParams
.
subList
(
pos
,
nargs
);
spreadParams
.
clear
();
spreadParams
.
add
(
Object
[].
class
);
}
MethodType
newType
=
MethodType
.
methodType
(
Object
.
class
,
newParams
);
MethodHandle
result
=
MethodHandles
.
spreadArguments
(
target2
,
newType
);
Object
[]
returnValue
;
if
(
pos
==
0
)
{
returnValue
=
(
Object
[])
result
.
invoke
(
args
);
}
else
{
Object
[]
args1
=
Arrays
.
copyOfRange
(
args
,
0
,
pos
+
1
);
args1
[
pos
]
=
Arrays
.
copyOfRange
(
args
,
pos
,
args
.
length
);
returnValue
=
(
Object
[])
result
.
invokeVarargs
(
args1
);
}
assertArrayEquals
(
args
,
returnValue
);
}
@Test
public
void
testCollectArguments
()
throws
Throwable
{
if
(
CAN_SKIP_WORKING
)
return
;
startTest
(
"collectArguments"
);
for
(
Class
<?>
argType
:
new
Class
[]{
Object
.
class
,
Integer
.
class
,
int
.
class
})
{
if
(
verbosity
>=
2
)
System
.
out
.
println
(
"collectArguments "
+
argType
);
for
(
int
nargs
=
0
;
nargs
<
10
;
nargs
++)
{
for
(
int
pos
=
0
;
pos
<
nargs
;
pos
++)
{
if
(
argType
==
int
.
class
)
continue
;
// FIXME Fail_4
testCollectArguments
(
argType
,
pos
,
nargs
);
}
}
}
}
public
void
testCollectArguments
(
Class
<?>
argType
,
int
pos
,
int
nargs
)
throws
Throwable
{
countTest
();
// fake up a MH with the same type as the desired adapter:
MethodHandle
fake
=
ValueConversions
.
varargsArray
(
nargs
);
fake
=
changeArgTypes
(
fake
,
argType
);
MethodType
newType
=
fake
.
type
();
Object
[]
args
=
randomArgs
(
newType
.
parameterArray
());
// here is what should happen:
Object
[]
collectedArgs
=
Arrays
.
copyOfRange
(
args
,
0
,
pos
+
1
);
collectedArgs
[
pos
]
=
Arrays
.
copyOfRange
(
args
,
pos
,
args
.
length
);
// here is the MH which will witness the collected argument tail:
MethodHandle
target
=
ValueConversions
.
varargsArray
(
pos
+
1
);
target
=
changeArgTypes
(
target
,
0
,
pos
,
argType
);
target
=
changeArgTypes
(
target
,
pos
,
pos
+
1
,
Object
[].
class
);
if
(
verbosity
>=
2
)
System
.
out
.
println
(
"collect from "
+
Arrays
.
asList
(
args
)+
" ["
+
pos
+
".."
+
nargs
+
"]"
);
MethodHandle
result
=
MethodHandles
.
collectArguments
(
target
,
newType
);
Object
[]
returnValue
=
(
Object
[])
result
.
invokeVarargs
(
args
);
// assertTrue(returnValue.length == pos+1 && returnValue[pos] instanceof Object[]);
// returnValue[pos] = Arrays.asList((Object[]) returnValue[pos]);
// collectedArgs[pos] = Arrays.asList((Object[]) collectedArgs[pos]);
assertArrayEquals
(
collectedArgs
,
returnValue
);
}
@Test
public
void
testInsertArguments
()
throws
Throwable
{
if
(
CAN_SKIP_WORKING
)
return
;
startTest
(
"insertArguments"
);
for
(
int
nargs
=
0
;
nargs
<=
4
;
nargs
++)
{
for
(
int
ins
=
0
;
ins
<=
4
;
ins
++)
{
if
(
ins
>
MAX_ARG_INCREASE
)
continue
;
// FIXME Fail_6
for
(
int
pos
=
0
;
pos
<=
nargs
;
pos
++)
{
testInsertArguments
(
nargs
,
pos
,
ins
);
}
}
}
}
void
testInsertArguments
(
int
nargs
,
int
pos
,
int
ins
)
throws
Throwable
{
countTest
();
MethodHandle
target
=
ValueConversions
.
varargsArray
(
nargs
+
ins
);
Object
[]
args
=
randomArgs
(
target
.
type
().
parameterArray
());
List
<
Object
>
resList
=
Arrays
.
asList
(
args
);
List
<
Object
>
argsToPass
=
new
ArrayList
<
Object
>(
resList
);
List
<
Object
>
argsToInsert
=
argsToPass
.
subList
(
pos
,
pos
+
ins
);
if
(
verbosity
>=
2
)
System
.
out
.
println
(
"insert: "
+
argsToInsert
+
" into "
+
target
);
MethodHandle
target2
=
MethodHandles
.
insertArguments
(
target
,
pos
,
(
Object
[])
argsToInsert
.
toArray
());
argsToInsert
.
clear
();
// remove from argsToInsert
Object
res2
=
target2
.
invokeVarargs
(
argsToPass
);
Object
res2List
=
Arrays
.
asList
((
Object
[])
res2
);
if
(
verbosity
>=
2
)
System
.
out
.
println
(
"result: "
+
res2List
);
//if (!resList.equals(res2List))
// System.out.println("*** fail at n/p/i = "+nargs+"/"+pos+"/"+ins+": "+resList+" => "+res2List);
assertEquals
(
resList
,
res2List
);
}
@Test
public
void
testFilterArguments
()
throws
Throwable
{
if
(
CAN_SKIP_WORKING
)
return
;
startTest
(
"filterArguments"
);
for
(
int
nargs
=
1
;
nargs
<=
6
;
nargs
++)
{
for
(
int
pos
=
0
;
pos
<
nargs
;
pos
++)
{
testFilterArguments
(
nargs
,
pos
);
}
}
}
void
testFilterArguments
(
int
nargs
,
int
pos
)
throws
Throwable
{
countTest
();
MethodHandle
target
=
ValueConversions
.
varargsList
(
nargs
);
MethodHandle
filter
=
ValueConversions
.
varargsList
(
1
);
filter
=
MethodHandles
.
convertArguments
(
filter
,
filter
.
type
().
generic
());
Object
[]
argsToPass
=
randomArgs
(
nargs
,
Object
.
class
);
if
(
verbosity
>=
2
)
System
.
out
.
println
(
"filter "
+
target
+
" at "
+
pos
+
" with "
+
filter
);
MethodHandle
[]
filters
=
new
MethodHandle
[
pos
*
2
+
1
];
filters
[
pos
]
=
filter
;
MethodHandle
target2
=
MethodHandles
.
filterArguments
(
target
,
filters
);
// Simulate expected effect of filter on arglist:
Object
[]
filteredArgs
=
argsToPass
.
clone
();
filteredArgs
[
pos
]
=
filter
.
invoke
(
filteredArgs
[
pos
]);
List
<
Object
>
expected
=
Arrays
.
asList
(
filteredArgs
);
Object
result
=
target2
.
invokeVarargs
(
argsToPass
);
if
(
verbosity
>=
2
)
System
.
out
.
println
(
"result: "
+
result
);
if
(!
expected
.
equals
(
result
))
System
.
out
.
println
(
"*** fail at n/p = "
+
nargs
+
"/"
+
pos
+
": "
+
argsToPass
+
" => "
+
result
);
assertEquals
(
expected
,
result
);
}
@Test
public
void
testFoldArguments
()
throws
Throwable
{
if
(
CAN_SKIP_WORKING
)
return
;
startTest
(
"foldArguments"
);
for
(
int
nargs
=
0
;
nargs
<=
4
;
nargs
++)
{
for
(
int
fold
=
0
;
fold
<=
nargs
;
fold
++)
{
for
(
int
pos
=
0
;
pos
<=
nargs
;
pos
++)
{
testFoldArguments
(
nargs
,
pos
,
fold
);
}
}
}
}
void
testFoldArguments
(
int
nargs
,
int
pos
,
int
fold
)
throws
Throwable
{
if
(
pos
!=
0
)
return
;
// can fold only at pos=0 for now
countTest
();
MethodHandle
target
=
ValueConversions
.
varargsList
(
1
+
nargs
);
MethodHandle
combine
=
ValueConversions
.
varargsList
(
fold
);
List
<
Object
>
argsToPass
=
Arrays
.
asList
(
randomArgs
(
nargs
,
Object
.
class
));
if
(
verbosity
>=
2
)
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
>
argsToFold
=
expected
.
subList
(
pos
,
pos
+
fold
);
if
(
verbosity
>=
2
)
System
.
out
.
println
(
"fold: "
+
argsToFold
+
" into "
+
target2
);
Object
foldedArgs
=
combine
.
invokeVarargs
(
argsToFold
);
argsToFold
.
add
(
0
,
foldedArgs
);
Object
result
=
target2
.
invokeVarargs
(
argsToPass
);
if
(
verbosity
>=
2
)
System
.
out
.
println
(
"result: "
+
result
);
if
(!
expected
.
equals
(
result
))
System
.
out
.
println
(
"*** fail at n/p/f = "
+
nargs
+
"/"
+
pos
+
"/"
+
fold
+
": "
+
argsToPass
+
" => "
+
result
);
assertEquals
(
expected
,
result
);
}
@Test
public
void
testDropArguments
()
throws
Throwable
{
if
(
CAN_SKIP_WORKING
)
return
;
startTest
(
"dropArguments"
);
for
(
int
nargs
=
0
;
nargs
<=
4
;
nargs
++)
{
for
(
int
drop
=
1
;
drop
<=
4
;
drop
++)
{
for
(
int
pos
=
0
;
pos
<=
nargs
;
pos
++)
{
testDropArguments
(
nargs
,
pos
,
drop
);
}
}
}
}
void
testDropArguments
(
int
nargs
,
int
pos
,
int
drop
)
throws
Throwable
{
countTest
();
MethodHandle
target
=
ValueConversions
.
varargsArray
(
nargs
);
Object
[]
args
=
randomArgs
(
target
.
type
().
parameterArray
());
MethodHandle
target2
=
MethodHandles
.
dropArguments
(
target
,
pos
,
Collections
.
nCopies
(
drop
,
Object
.
class
).
toArray
(
new
Class
[
0
]));
List
<
Object
>
resList
=
Arrays
.
asList
(
args
);
List
<
Object
>
argsToDrop
=
new
ArrayList
<
Object
>(
resList
);
for
(
int
i
=
drop
;
i
>
0
;
i
--)
{
argsToDrop
.
add
(
pos
,
"blort#"
+
i
);
}
Object
res2
=
target2
.
invokeVarargs
(
argsToDrop
);
Object
res2List
=
Arrays
.
asList
((
Object
[])
res2
);
//if (!resList.equals(res2List))
// System.out.println("*** fail at n/p/d = "+nargs+"/"+pos+"/"+drop+": "+argsToDrop+" => "+res2List);
assertEquals
(
resList
,
res2List
);
}
@Test
public
void
testInvokers
()
throws
Throwable
{
if
(
CAN_SKIP_WORKING
)
return
;
startTest
(
"exactInvoker, genericInvoker, varargsInvoker, dynamicInvoker"
);
// exactInvoker, genericInvoker, varargsInvoker[0..N], dynamicInvoker
Set
<
MethodType
>
done
=
new
HashSet
<
MethodType
>();
for
(
int
i
=
0
;
i
<=
6
;
i
++)
{
MethodType
gtype
=
MethodType
.
genericMethodType
(
i
);
for
(
Class
<?>
argType
:
new
Class
[]{
Object
.
class
,
Integer
.
class
,
int
.
class
})
{
for
(
int
j
=
-
1
;
j
<
i
;
j
++)
{
MethodType
type
=
gtype
;
if
(
j
<
0
)
type
=
type
.
changeReturnType
(
argType
);
else
if
(
argType
==
void
.
class
)
continue
;
else
type
=
type
.
changeParameterType
(
j
,
argType
);
if
(
argType
.
isPrimitive
()
&&
j
!=
i
-
1
)
continue
;
// FIXME Fail_5
if
(
done
.
add
(
type
))
testInvokers
(
type
);
MethodType
vtype
=
type
.
changeReturnType
(
void
.
class
);
if
(
done
.
add
(
vtype
))
testInvokers
(
vtype
);
}
}
}
}
public
void
testInvokers
(
MethodType
type
)
throws
Throwable
{
if
(
verbosity
>=
2
)
System
.
out
.
println
(
"test invokers for "
+
type
);
int
nargs
=
type
.
parameterCount
();
boolean
testRetCode
=
type
.
returnType
()
!=
void
.
class
;
MethodHandle
target
=
PRIVATE
.
findStatic
(
MethodHandlesTest
.
class
,
"invokee"
,
MethodType
.
genericMethodType
(
0
,
true
));
target
=
MethodHandles
.
collectArguments
(
target
,
type
);
Object
[]
args
=
randomArgs
(
type
.
parameterArray
());
List
<
Object
>
targetPlusArgs
=
new
ArrayList
<
Object
>(
Arrays
.
asList
(
args
));
targetPlusArgs
.
add
(
0
,
target
);
int
code
=
(
Integer
)
invokee
(
args
);
Object
log
=
logEntry
(
"invokee"
,
args
);
assertEquals
(
log
.
hashCode
(),
code
);
assertCalled
(
"invokee"
,
args
);
MethodHandle
inv
;
Object
result
;
// exact invoker
countTest
();
calledLog
.
clear
();
inv
=
MethodHandles
.
exactInvoker
(
type
);
result
=
inv
.
invokeVarargs
(
targetPlusArgs
);
if
(
testRetCode
)
assertEquals
(
code
,
result
);
assertCalled
(
"invokee"
,
args
);
// generic invoker
countTest
();
inv
=
MethodHandles
.
genericInvoker
(
type
);
if
(
nargs
<=
3
)
{
calledLog
.
clear
();
switch
(
nargs
)
{
case
0
:
result
=
inv
.
invoke
(
target
);
break
;
case
1
:
result
=
inv
.
invoke
(
target
,
args
[
0
]);
break
;
case
2
:
result
=
inv
.
invoke
(
target
,
args
[
0
],
args
[
1
]);
break
;
case
3
:
result
=
inv
.
invoke
(
target
,
args
[
0
],
args
[
1
],
args
[
2
]);
break
;
}
if
(
testRetCode
)
assertEquals
(
code
,
result
);
assertCalled
(
"invokee"
,
args
);
}
calledLog
.
clear
();
result
=
inv
.
invokeVarargs
(
targetPlusArgs
);
if
(
testRetCode
)
assertEquals
(
code
,
result
);
assertCalled
(
"invokee"
,
args
);
// varargs invoker #0
calledLog
.
clear
();
inv
=
MethodHandles
.
varargsInvoker
(
type
,
0
);
result
=
inv
.
invoke
(
target
,
args
);
if
(
testRetCode
)
assertEquals
(
code
,
result
);
assertCalled
(
"invokee"
,
args
);
if
(
nargs
>=
1
)
{
// varargs invoker #1
calledLog
.
clear
();
inv
=
MethodHandles
.
varargsInvoker
(
type
,
1
);
result
=
inv
.
invoke
(
target
,
args
[
0
],
Arrays
.
copyOfRange
(
args
,
1
,
nargs
));
if
(
testRetCode
)
assertEquals
(
code
,
result
);
assertCalled
(
"invokee"
,
args
);
}
if
(
nargs
>=
2
)
{
// varargs invoker #2
calledLog
.
clear
();
inv
=
MethodHandles
.
varargsInvoker
(
type
,
2
);
result
=
inv
.
invoke
(
target
,
args
[
0
],
args
[
1
],
Arrays
.
copyOfRange
(
args
,
2
,
nargs
));
if
(
testRetCode
)
assertEquals
(
code
,
result
);
assertCalled
(
"invokee"
,
args
);
}
if
(
nargs
>=
3
)
{
// varargs invoker #3
calledLog
.
clear
();
inv
=
MethodHandles
.
varargsInvoker
(
type
,
3
);
result
=
inv
.
invoke
(
target
,
args
[
0
],
args
[
1
],
args
[
2
],
Arrays
.
copyOfRange
(
args
,
3
,
nargs
));
if
(
testRetCode
)
assertEquals
(
code
,
result
);
assertCalled
(
"invokee"
,
args
);
}
for
(
int
k
=
0
;
k
<=
nargs
;
k
++)
{
// varargs invoker #0..N
countTest
();
calledLog
.
clear
();
inv
=
MethodHandles
.
varargsInvoker
(
type
,
k
);
List
<
Object
>
targetPlusVarArgs
=
new
ArrayList
<
Object
>(
targetPlusArgs
);
List
<
Object
>
tailList
=
targetPlusVarArgs
.
subList
(
1
+
k
,
1
+
nargs
);
Object
[]
tail
=
tailList
.
toArray
();
tailList
.
clear
();
tailList
.
add
(
tail
);
result
=
inv
.
invokeVarargs
(
targetPlusVarArgs
);
if
(
testRetCode
)
assertEquals
(
code
,
result
);
assertCalled
(
"invokee"
,
args
);
}
// dynamic invoker
countTest
();
CallSite
site
=
new
CallSite
(
MethodHandlesTest
.
class
,
"foo"
,
type
);
inv
=
MethodHandles
.
dynamicInvoker
(
site
);
site
.
setTarget
(
target
);
calledLog
.
clear
();
result
=
inv
.
invokeVarargs
(
args
);
if
(
testRetCode
)
assertEquals
(
code
,
result
);
assertCalled
(
"invokee"
,
args
);
}
static
Object
invokee
(
Object
...
args
)
{
return
called
(
"invokee"
,
args
).
hashCode
();
}
private
static
final
String
MISSING_ARG
=
"missingArg"
;
static
Object
targetIfEquals
()
{
return
called
(
"targetIfEquals"
);
}
static
Object
fallbackIfNotEquals
()
{
return
called
(
"fallbackIfNotEquals"
);
}
static
Object
targetIfEquals
(
Object
x
)
{
assertEquals
(
x
,
MISSING_ARG
);
return
called
(
"targetIfEquals"
,
x
);
}
static
Object
fallbackIfNotEquals
(
Object
x
)
{
assertFalse
(
x
.
toString
(),
x
.
equals
(
MISSING_ARG
));
return
called
(
"fallbackIfNotEquals"
,
x
);
}
static
Object
targetIfEquals
(
Object
x
,
Object
y
)
{
assertEquals
(
x
,
y
);
return
called
(
"targetIfEquals"
,
x
,
y
);
}
static
Object
fallbackIfNotEquals
(
Object
x
,
Object
y
)
{
assertFalse
(
x
.
toString
(),
x
.
equals
(
y
));
return
called
(
"fallbackIfNotEquals"
,
x
,
y
);
}
static
Object
targetIfEquals
(
Object
x
,
Object
y
,
Object
z
)
{
assertEquals
(
x
,
y
);
return
called
(
"targetIfEquals"
,
x
,
y
,
z
);
}
static
Object
fallbackIfNotEquals
(
Object
x
,
Object
y
,
Object
z
)
{
assertFalse
(
x
.
toString
(),
x
.
equals
(
y
));
return
called
(
"fallbackIfNotEquals"
,
x
,
y
,
z
);
}
@Test
public
void
testGuardWithTest
()
throws
Throwable
{
if
(
CAN_SKIP_WORKING
)
return
;
startTest
(
"guardWithTest"
);
for
(
int
nargs
=
0
;
nargs
<=
3
;
nargs
++)
{
if
(
nargs
!=
2
)
continue
;
// FIXME: test more later
testGuardWithTest
(
nargs
,
Object
.
class
);
testGuardWithTest
(
nargs
,
String
.
class
);
}
}
void
testGuardWithTest
(
int
nargs
,
Class
<?>
argClass
)
throws
Throwable
{
countTest
();
MethodHandle
test
=
PRIVATE
.
findVirtual
(
Object
.
class
,
"equals"
,
MethodType
.
methodType
(
boolean
.
class
,
Object
.
class
));
MethodHandle
target
=
PRIVATE
.
findStatic
(
MethodHandlesTest
.
class
,
"targetIfEquals"
,
MethodType
.
genericMethodType
(
nargs
));
MethodHandle
fallback
=
PRIVATE
.
findStatic
(
MethodHandlesTest
.
class
,
"fallbackIfNotEquals"
,
MethodType
.
genericMethodType
(
nargs
));
while
(
test
.
type
().
parameterCount
()
<
nargs
)
test
=
MethodHandles
.
dropArguments
(
test
,
test
.
type
().
parameterCount
()-
1
,
Object
.
class
);
while
(
test
.
type
().
parameterCount
()
>
nargs
)
test
=
MethodHandles
.
insertArguments
(
test
,
0
,
MISSING_ARG
);
if
(
argClass
!=
Object
.
class
)
{
test
=
changeArgTypes
(
test
,
argClass
);
target
=
changeArgTypes
(
target
,
argClass
);
fallback
=
changeArgTypes
(
fallback
,
argClass
);
}
MethodHandle
mh
=
MethodHandles
.
guardWithTest
(
test
,
target
,
fallback
);
assertEquals
(
target
.
type
(),
mh
.
type
());
Object
[][]
argLists
=
{
{
},
{
"foo"
},
{
MISSING_ARG
},
{
"foo"
,
"foo"
},
{
"foo"
,
"bar"
},
{
"foo"
,
"foo"
,
"baz"
},
{
"foo"
,
"bar"
,
"baz"
}
};
for
(
Object
[]
argList
:
argLists
)
{
if
(
argList
.
length
!=
nargs
)
continue
;
boolean
equals
;
switch
(
nargs
)
{
case
0
:
equals
=
true
;
break
;
case
1
:
equals
=
MISSING_ARG
.
equals
(
argList
[
0
]);
break
;
default
:
equals
=
argList
[
0
].
equals
(
argList
[
1
]);
break
;
}
String
willCall
=
(
equals
?
"targetIfEquals"
:
"fallbackIfNotEquals"
);
if
(
verbosity
>=
2
)
System
.
out
.
println
(
logEntry
(
willCall
,
argList
));
Object
result
=
mh
.
invokeVarargs
(
argList
);
assertCalled
(
willCall
,
argList
);
}
}
@Test
public
void
testCatchException
()
throws
Throwable
{
if
(
CAN_SKIP_WORKING
)
return
;
startTest
(
"catchException"
);
for
(
int
nargs
=
2
;
nargs
<=
6
;
nargs
++)
{
for
(
int
ti
=
0
;
ti
<=
1
;
ti
++)
{
boolean
throwIt
=
(
ti
!=
0
);
testCatchException
(
int
.
class
,
new
ClassCastException
(
"testing"
),
throwIt
,
nargs
);
testCatchException
(
void
.
class
,
new
java
.
io
.
IOException
(
"testing"
),
throwIt
,
nargs
);
testCatchException
(
String
.
class
,
new
LinkageError
(
"testing"
),
throwIt
,
nargs
);
}
}
}
private
static
<
T
extends
Throwable
>
Object
throwOrReturn
(
Object
normal
,
T
exception
)
throws
T
{
if
(
exception
!=
null
)
throw
exception
;
return
normal
;
}
void
testCatchException
(
Class
<?>
returnType
,
Throwable
thrown
,
boolean
throwIt
,
int
nargs
)
throws
Throwable
{
countTest
();
if
(
verbosity
>=
2
)
System
.
out
.
println
(
"catchException rt="
+
returnType
+
" throw="
+
throwIt
+
" nargs="
+
nargs
);
Class
<?
extends
Throwable
>
exType
=
thrown
.
getClass
();
MethodHandle
throwOrReturn
=
PRIVATE
.
findStatic
(
MethodHandlesTest
.
class
,
"throwOrReturn"
,
MethodType
.
methodType
(
Object
.
class
,
Object
.
class
,
Throwable
.
class
));
MethodHandle
thrower
=
throwOrReturn
;
while
(
thrower
.
type
().
parameterCount
()
<
nargs
)
thrower
=
MethodHandles
.
dropArguments
(
thrower
,
thrower
.
type
().
parameterCount
(),
Object
.
class
);
MethodHandle
target
=
MethodHandles
.
catchException
(
thrower
,
thrown
.
getClass
(),
ValueConversions
.
varargsList
(
1
+
nargs
));
assertEquals
(
thrower
.
type
(),
target
.
type
());
//System.out.println("catching with "+target+" : "+throwOrReturn);
Object
[]
args
=
randomArgs
(
nargs
,
Object
.
class
);
args
[
1
]
=
(
throwIt
?
thrown
:
null
);
Object
returned
=
target
.
invokeVarargs
(
args
);
//System.out.println("return from "+target+" : "+returned);
if
(!
throwIt
)
{
assertSame
(
args
[
0
],
returned
);
}
else
{
List
<
Object
>
catchArgs
=
new
ArrayList
<
Object
>(
Arrays
.
asList
(
args
));
catchArgs
.
add
(
0
,
thrown
);
assertEquals
(
catchArgs
,
returned
);
}
}
@Test
public
void
testThrowException
()
throws
Throwable
{
if
(
CAN_SKIP_WORKING
)
return
;
startTest
(
"throwException"
);
testThrowException
(
int
.
class
,
new
ClassCastException
(
"testing"
));
testThrowException
(
void
.
class
,
new
java
.
io
.
IOException
(
"testing"
));
testThrowException
(
String
.
class
,
new
LinkageError
(
"testing"
));
}
void
testThrowException
(
Class
<?>
returnType
,
Throwable
thrown
)
throws
Throwable
{
countTest
();
Class
<?
extends
Throwable
>
exType
=
thrown
.
getClass
();
MethodHandle
target
=
MethodHandles
.
throwException
(
returnType
,
exType
);
//System.out.println("throwing with "+target+" : "+thrown);
MethodType
expectedType
=
MethodType
.
methodType
(
returnType
,
exType
);
assertEquals
(
expectedType
,
target
.
type
());
Throwable
caught
=
null
;
try
{
Object
res
=
target
.
invokeGeneric
(
thrown
);
fail
(
"got "
+
res
+
" instead of throwing "
+
thrown
);
}
catch
(
Throwable
ex
)
{
if
(
ex
!=
thrown
)
{
if
(
ex
instanceof
Error
)
throw
(
Error
)
ex
;
if
(
ex
instanceof
RuntimeException
)
throw
(
RuntimeException
)
ex
;
}
caught
=
ex
;
}
assertSame
(
thrown
,
caught
);
}
@Test
public
void
testCastFailure
()
throws
Throwable
{
if
(
CAN_SKIP_WORKING
)
return
;
startTest
(
"testCastFailure"
);
testCastFailure
(
"cast/argument"
,
11000
);
testCastFailure
(
"unbox/argument"
,
11000
);
testCastFailure
(
"cast/return"
,
11000
);
testCastFailure
(
"unbox/return"
,
11000
);
}
static
class
Surprise
extends
JavaMethodHandle
{
Surprise
()
{
super
(
"value"
);
}
Object
value
(
Object
x
)
{
trace
(
"value"
,
x
);
if
(
boo
!=
null
)
return
boo
;
return
x
;
}
Object
boo
;
void
boo
(
Object
x
)
{
boo
=
x
;
}
static
void
trace
(
String
x
,
Object
y
)
{
if
(
verbosity
>
8
)
System
.
out
.
println
(
x
+
"="
+
y
);
}
static
Object
refIdentity
(
Object
x
)
{
trace
(
"ref.x"
,
x
);
return
x
;
}
static
Integer
boxIdentity
(
Integer
x
)
{
trace
(
"box.x"
,
x
);
return
x
;
}
static
int
intIdentity
(
int
x
)
{
trace
(
"int.x"
,
x
);
return
x
;
}
static
MethodHandle
REF_IDENTITY
=
PRIVATE
.
findStatic
(
Surprise
.
class
,
"refIdentity"
,
MethodType
.
methodType
(
Object
.
class
,
Object
.
class
));
static
MethodHandle
BOX_IDENTITY
=
PRIVATE
.
findStatic
(
Surprise
.
class
,
"boxIdentity"
,
MethodType
.
methodType
(
Integer
.
class
,
Integer
.
class
));
static
MethodHandle
INT_IDENTITY
=
PRIVATE
.
findStatic
(
Surprise
.
class
,
"intIdentity"
,
MethodType
.
methodType
(
int
.
class
,
int
.
class
));
}
void
testCastFailure
(
String
mode
,
int
okCount
)
throws
Throwable
{
countTest
(
false
);
if
(
verbosity
>
1
)
System
.
out
.
println
(
"mode="
+
mode
);
Surprise
boo
=
new
Surprise
();
MethodHandle
identity
=
Surprise
.
REF_IDENTITY
,
surprise
=
boo
;
if
(
mode
.
endsWith
(
"/return"
))
{
if
(
mode
.
equals
(
"unbox/return"
))
{
// fail on return to ((Integer)surprise).intValue
surprise
=
MethodHandles
.
convertArguments
(
surprise
,
MethodType
.
methodType
(
int
.
class
,
Object
.
class
));
identity
=
MethodHandles
.
convertArguments
(
identity
,
MethodType
.
methodType
(
int
.
class
,
Object
.
class
));
}
else
if
(
mode
.
equals
(
"cast/return"
))
{
// fail on return to (Integer)surprise
surprise
=
MethodHandles
.
convertArguments
(
surprise
,
MethodType
.
methodType
(
Integer
.
class
,
Object
.
class
));
identity
=
MethodHandles
.
convertArguments
(
identity
,
MethodType
.
methodType
(
Integer
.
class
,
Object
.
class
));
}
}
else
if
(
mode
.
endsWith
(
"/argument"
))
{
MethodHandle
callee
=
null
;
if
(
mode
.
equals
(
"unbox/argument"
))
{
// fail on handing surprise to int argument
callee
=
Surprise
.
INT_IDENTITY
;
}
else
if
(
mode
.
equals
(
"cast/argument"
))
{
// fail on handing surprise to Integer argument
callee
=
Surprise
.
BOX_IDENTITY
;
}
if
(
callee
!=
null
)
{
callee
=
MethodHandles
.
convertArguments
(
callee
,
MethodType
.
genericMethodType
(
1
));
surprise
=
MethodHandles
.
filterArguments
(
callee
,
surprise
);
identity
=
MethodHandles
.
filterArguments
(
callee
,
identity
);
}
}
assertNotSame
(
mode
,
surprise
,
boo
);
identity
=
MethodHandles
.
convertArguments
(
identity
,
MethodType
.
genericMethodType
(
1
));
surprise
=
MethodHandles
.
convertArguments
(
surprise
,
MethodType
.
genericMethodType
(
1
));
Object
x
=
42
;
for
(
int
i
=
0
;
i
<
okCount
;
i
++)
{
Object
y
=
identity
.
invoke
(
x
);
assertEquals
(
x
,
y
);
Object
z
=
surprise
.
invoke
(
x
);
assertEquals
(
x
,
z
);
}
boo
.
boo
(
"Boo!"
);
Object
y
=
identity
.
invoke
(
x
);
assertEquals
(
x
,
y
);
try
{
Object
z
=
surprise
.
invoke
(
x
);
System
.
out
.
println
(
"Failed to throw; got z="
+
z
);
assertTrue
(
false
);
}
catch
(
Exception
ex
)
{
if
(
verbosity
>
1
)
System
.
out
.
println
(
"caught "
+
ex
);
if
(
verbosity
>
2
)
ex
.
printStackTrace
();
assertTrue
(
ex
instanceof
ClassCastException
// FIXME: accept only one of the two for any given unit test
||
ex
instanceof
WrongMethodTypeException
);
}
}
}
// Local abbreviated copy of sun.dyn.util.ValueConversions
class
ValueConversions
{
private
static
final
Lookup
IMPL_LOOKUP
=
MethodHandles
.
lookup
();
private
static
final
Object
[]
NO_ARGS_ARRAY
=
{};
private
static
Object
[]
makeArray
(
Object
...
args
)
{
return
args
;
}
private
static
Object
[]
array
()
{
return
NO_ARGS_ARRAY
;
}
private
static
Object
[]
array
(
Object
a0
)
{
return
makeArray
(
a0
);
}
private
static
Object
[]
array
(
Object
a0
,
Object
a1
)
{
return
makeArray
(
a0
,
a1
);
}
private
static
Object
[]
array
(
Object
a0
,
Object
a1
,
Object
a2
)
{
return
makeArray
(
a0
,
a1
,
a2
);
}
private
static
Object
[]
array
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
)
{
return
makeArray
(
a0
,
a1
,
a2
,
a3
);
}
private
static
Object
[]
array
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
)
{
return
makeArray
(
a0
,
a1
,
a2
,
a3
,
a4
);
}
private
static
Object
[]
array
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
)
{
return
makeArray
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
);
}
private
static
Object
[]
array
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
a6
)
{
return
makeArray
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
);
}
private
static
Object
[]
array
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
a6
,
Object
a7
)
{
return
makeArray
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
);
}
private
static
Object
[]
array
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
a6
,
Object
a7
,
Object
a8
)
{
return
makeArray
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
);
}
private
static
Object
[]
array
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
a6
,
Object
a7
,
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
>();
MethodHandles
.
Lookup
lookup
=
IMPL_LOOKUP
;
for
(;;)
{
int
nargs
=
arrays
.
size
();
MethodType
type
=
MethodType
.
genericMethodType
(
nargs
).
changeReturnType
(
Object
[].
class
);
String
name
=
"array"
;
MethodHandle
array
=
null
;
try
{
array
=
lookup
.
findStatic
(
ValueConversions
.
class
,
name
,
type
);
}
catch
(
NoAccessException
ex
)
{
}
if
(
array
==
null
)
break
;
arrays
.
add
(
array
);
}
assert
(
arrays
.
size
()
==
11
);
// current number of methods
return
arrays
.
toArray
(
new
MethodHandle
[
0
]);
}
static
final
MethodHandle
[]
ARRAYS
=
makeArrays
();
/** Return a method handle that takes the indicated number of Object
* arguments and returns an Object array of them, as if for varargs.
*/
public
static
MethodHandle
varargsArray
(
int
nargs
)
{
if
(
nargs
<
ARRAYS
.
length
)
return
ARRAYS
[
nargs
];
// else need to spin bytecode or do something else fancy
throw
new
UnsupportedOperationException
(
"NYI"
);
}
private
static
final
List
<
Object
>
NO_ARGS_LIST
=
Arrays
.
asList
(
NO_ARGS_ARRAY
);
private
static
List
<
Object
>
makeList
(
Object
...
args
)
{
return
Arrays
.
asList
(
args
);
}
private
static
List
<
Object
>
list
()
{
return
NO_ARGS_LIST
;
}
private
static
List
<
Object
>
list
(
Object
a0
)
{
return
makeList
(
a0
);
}
private
static
List
<
Object
>
list
(
Object
a0
,
Object
a1
)
{
return
makeList
(
a0
,
a1
);
}
private
static
List
<
Object
>
list
(
Object
a0
,
Object
a1
,
Object
a2
)
{
return
makeList
(
a0
,
a1
,
a2
);
}
private
static
List
<
Object
>
list
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
)
{
return
makeList
(
a0
,
a1
,
a2
,
a3
);
}
private
static
List
<
Object
>
list
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
)
{
return
makeList
(
a0
,
a1
,
a2
,
a3
,
a4
);
}
private
static
List
<
Object
>
list
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
)
{
return
makeList
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
);
}
private
static
List
<
Object
>
list
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
a6
)
{
return
makeList
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
);
}
private
static
List
<
Object
>
list
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
a6
,
Object
a7
)
{
return
makeList
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
);
}
private
static
List
<
Object
>
list
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
a6
,
Object
a7
,
Object
a8
)
{
return
makeList
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
);
}
private
static
List
<
Object
>
list
(
Object
a0
,
Object
a1
,
Object
a2
,
Object
a3
,
Object
a4
,
Object
a5
,
Object
a6
,
Object
a7
,
Object
a8
,
Object
a9
)
{
return
makeList
(
a0
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
,
a9
);
}
static
MethodHandle
[]
makeLists
()
{
ArrayList
<
MethodHandle
>
arrays
=
new
ArrayList
<
MethodHandle
>();
MethodHandles
.
Lookup
lookup
=
IMPL_LOOKUP
;
for
(;;)
{
int
nargs
=
arrays
.
size
();
MethodType
type
=
MethodType
.
genericMethodType
(
nargs
).
changeReturnType
(
List
.
class
);
String
name
=
"list"
;
MethodHandle
array
=
null
;
try
{
array
=
lookup
.
findStatic
(
ValueConversions
.
class
,
name
,
type
);
}
catch
(
NoAccessException
ex
)
{
}
if
(
array
==
null
)
break
;
arrays
.
add
(
array
);
}
assert
(
arrays
.
size
()
==
11
);
// current number of methods
return
arrays
.
toArray
(
new
MethodHandle
[
0
]);
}
static
final
MethodHandle
[]
LISTS
=
makeLists
();
/** Return a method handle that takes the indicated number of Object
* arguments and returns List.
*/
public
static
MethodHandle
varargsList
(
int
nargs
)
{
if
(
nargs
<
LISTS
.
length
)
return
LISTS
[
nargs
];
// else need to spin bytecode or do something else fancy
throw
new
UnsupportedOperationException
(
"NYI"
);
}
}
// This guy tests access from outside the same package member, but inside
// the package itself.
class
PackageSibling
{
static
Lookup
lookup
()
{
return
MethodHandles
.
lookup
();
}
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录