6939134: JSR 292 adjustments to method handle invocation
Split MethodHandle.invoke into invokeExact and invokeGeneric Reviewed-by: twisti
This commit is contained in:
parent
9329c4986e
commit
a56ce23775
@ -230,6 +230,12 @@ public class Flags {
|
|||||||
*/
|
*/
|
||||||
public static final long PROPRIETARY = 1L<<38;
|
public static final long PROPRIETARY = 1L<<38;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Flag that marks a signature-polymorphic invoke method.
|
||||||
|
* (These occur inside java.dyn.MethodHandle.)
|
||||||
|
*/
|
||||||
|
public static final long POLYMORPHIC_SIGNATURE = 1L<<39;
|
||||||
|
|
||||||
/** Modifier masks.
|
/** Modifier masks.
|
||||||
*/
|
*/
|
||||||
public static final int
|
public static final int
|
||||||
|
@ -168,6 +168,10 @@ public enum Source {
|
|||||||
public boolean allowStringsInSwitch() {
|
public boolean allowStringsInSwitch() {
|
||||||
return compareTo(JDK1_7) >= 0;
|
return compareTo(JDK1_7) >= 0;
|
||||||
}
|
}
|
||||||
|
// JSR 292: recognize @PolymorphicSignature on java/dyn names
|
||||||
|
public boolean allowPolymorphicSignature() {
|
||||||
|
return compareTo(JDK1_7) >= 0;
|
||||||
|
}
|
||||||
public static SourceVersion toSourceVersion(Source source) {
|
public static SourceVersion toSourceVersion(Source source) {
|
||||||
switch(source) {
|
switch(source) {
|
||||||
case JDK1_2:
|
case JDK1_2:
|
||||||
|
@ -120,6 +120,7 @@ public class Symtab {
|
|||||||
public final Type cloneableType;
|
public final Type cloneableType;
|
||||||
public final Type serializableType;
|
public final Type serializableType;
|
||||||
public final Type methodHandleType;
|
public final Type methodHandleType;
|
||||||
|
public final Type polymorphicSignatureType;
|
||||||
public final Type invokeDynamicType;
|
public final Type invokeDynamicType;
|
||||||
public final Type throwableType;
|
public final Type throwableType;
|
||||||
public final Type errorType;
|
public final Type errorType;
|
||||||
@ -291,24 +292,6 @@ public class Symtab {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void synthesizeMHTypeIfMissing(final Type type) {
|
|
||||||
final Completer completer = type.tsym.completer;
|
|
||||||
if (completer != null) {
|
|
||||||
type.tsym.completer = new Completer() {
|
|
||||||
public void complete(Symbol sym) throws CompletionFailure {
|
|
||||||
try {
|
|
||||||
completer.complete(sym);
|
|
||||||
} catch (CompletionFailure e) {
|
|
||||||
sym.flags_field |= (PUBLIC | ABSTRACT);
|
|
||||||
((ClassType) sym.type).supertype_field = objectType;
|
|
||||||
// do not bother to create MH.type if not visibly declared
|
|
||||||
// this sym just accumulates invoke(...) methods
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void synthesizeBoxTypeIfMissing(final Type type) {
|
public void synthesizeBoxTypeIfMissing(final Type type) {
|
||||||
ClassSymbol sym = reader.enterClass(boxedName[type.tag]);
|
ClassSymbol sym = reader.enterClass(boxedName[type.tag]);
|
||||||
final Completer completer = sym.completer;
|
final Completer completer = sym.completer;
|
||||||
@ -426,6 +409,7 @@ public class Symtab {
|
|||||||
throwableType = enterClass("java.lang.Throwable");
|
throwableType = enterClass("java.lang.Throwable");
|
||||||
serializableType = enterClass("java.io.Serializable");
|
serializableType = enterClass("java.io.Serializable");
|
||||||
methodHandleType = enterClass("java.dyn.MethodHandle");
|
methodHandleType = enterClass("java.dyn.MethodHandle");
|
||||||
|
polymorphicSignatureType = enterClass("java.dyn.MethodHandle$PolymorphicSignature");
|
||||||
invokeDynamicType = enterClass("java.dyn.InvokeDynamic");
|
invokeDynamicType = enterClass("java.dyn.InvokeDynamic");
|
||||||
errorType = enterClass("java.lang.Error");
|
errorType = enterClass("java.lang.Error");
|
||||||
illegalArgumentExceptionType = enterClass("java.lang.IllegalArgumentException");
|
illegalArgumentExceptionType = enterClass("java.lang.IllegalArgumentException");
|
||||||
@ -463,8 +447,7 @@ public class Symtab {
|
|||||||
|
|
||||||
synthesizeEmptyInterfaceIfMissing(cloneableType);
|
synthesizeEmptyInterfaceIfMissing(cloneableType);
|
||||||
synthesizeEmptyInterfaceIfMissing(serializableType);
|
synthesizeEmptyInterfaceIfMissing(serializableType);
|
||||||
synthesizeMHTypeIfMissing(methodHandleType);
|
synthesizeEmptyInterfaceIfMissing(polymorphicSignatureType);
|
||||||
synthesizeMHTypeIfMissing(invokeDynamicType);
|
|
||||||
synthesizeBoxTypeIfMissing(doubleType);
|
synthesizeBoxTypeIfMissing(doubleType);
|
||||||
synthesizeBoxTypeIfMissing(floatType);
|
synthesizeBoxTypeIfMissing(floatType);
|
||||||
synthesizeBoxTypeIfMissing(voidType);
|
synthesizeBoxTypeIfMissing(voidType);
|
||||||
|
@ -122,7 +122,6 @@ public class Attr extends JCTree.Visitor {
|
|||||||
relax = (options.get("-retrofit") != null ||
|
relax = (options.get("-retrofit") != null ||
|
||||||
options.get("-relax") != null);
|
options.get("-relax") != null);
|
||||||
useBeforeDeclarationWarning = options.get("useBeforeDeclarationWarning") != null;
|
useBeforeDeclarationWarning = options.get("useBeforeDeclarationWarning") != null;
|
||||||
allowInvokedynamic = options.get("invokedynamic") != null;
|
|
||||||
enableSunApiLintControl = options.get("enableSunApiLintControl") != null;
|
enableSunApiLintControl = options.get("enableSunApiLintControl") != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -155,10 +154,6 @@ public class Attr extends JCTree.Visitor {
|
|||||||
*/
|
*/
|
||||||
boolean allowAnonOuterThis;
|
boolean allowAnonOuterThis;
|
||||||
|
|
||||||
/** Switch: allow invokedynamic syntax
|
|
||||||
*/
|
|
||||||
boolean allowInvokedynamic;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Switch: warn about use of variable before declaration?
|
* Switch: warn about use of variable before declaration?
|
||||||
* RFE: 6425594
|
* RFE: 6425594
|
||||||
@ -1377,9 +1372,15 @@ public class Attr extends JCTree.Visitor {
|
|||||||
// as a special case, MethodHandle.<T>invoke(abc) and InvokeDynamic.<T>foo(abc)
|
// as a special case, MethodHandle.<T>invoke(abc) and InvokeDynamic.<T>foo(abc)
|
||||||
// has type <T>, and T can be a primitive type.
|
// has type <T>, and T can be a primitive type.
|
||||||
if (tree.meth.getTag() == JCTree.SELECT && !typeargtypes.isEmpty()) {
|
if (tree.meth.getTag() == JCTree.SELECT && !typeargtypes.isEmpty()) {
|
||||||
Type selt = ((JCFieldAccess) tree.meth).selected.type;
|
JCFieldAccess mfield = (JCFieldAccess) tree.meth;
|
||||||
if ((selt == syms.methodHandleType && methName == names.invoke) || selt == syms.invokeDynamicType) {
|
if ((mfield.selected.type.tsym != null &&
|
||||||
|
(mfield.selected.type.tsym.flags() & POLYMORPHIC_SIGNATURE) != 0)
|
||||||
|
||
|
||||||
|
(mfield.sym != null &&
|
||||||
|
(mfield.sym.flags() & POLYMORPHIC_SIGNATURE) != 0)) {
|
||||||
assert types.isSameType(restype, typeargtypes.head) : mtype;
|
assert types.isSameType(restype, typeargtypes.head) : mtype;
|
||||||
|
assert mfield.selected.type == syms.methodHandleType
|
||||||
|
|| mfield.selected.type == syms.invokeDynamicType;
|
||||||
typeargtypesNonRefOK = true;
|
typeargtypesNonRefOK = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -768,6 +768,12 @@ public class MemberEnter extends JCTree.Visitor implements Completer {
|
|||||||
&& s.owner.kind != MTH
|
&& s.owner.kind != MTH
|
||||||
&& types.isSameType(c.type, syms.deprecatedType))
|
&& types.isSameType(c.type, syms.deprecatedType))
|
||||||
s.flags_field |= Flags.DEPRECATED;
|
s.flags_field |= Flags.DEPRECATED;
|
||||||
|
// Internally to java.dyn, a @PolymorphicSignature annotation
|
||||||
|
// translates to a classfile attribute.
|
||||||
|
if (!c.type.isErroneous()
|
||||||
|
&& types.isSameType(c.type, syms.polymorphicSignatureType)) {
|
||||||
|
s.flags_field |= Flags.POLYMORPHIC_SIGNATURE;
|
||||||
|
}
|
||||||
if (!annotated.add(a.type.tsym))
|
if (!annotated.add(a.type.tsym))
|
||||||
log.error(a.pos, "duplicate.annotation");
|
log.error(a.pos, "duplicate.annotation");
|
||||||
}
|
}
|
||||||
|
@ -67,7 +67,7 @@ public class Resolve {
|
|||||||
JCDiagnostic.Factory diags;
|
JCDiagnostic.Factory diags;
|
||||||
public final boolean boxingEnabled; // = source.allowBoxing();
|
public final boolean boxingEnabled; // = source.allowBoxing();
|
||||||
public final boolean varargsEnabled; // = source.allowVarargs();
|
public final boolean varargsEnabled; // = source.allowVarargs();
|
||||||
public final boolean allowInvokedynamic; // = options.get("invokedynamic");
|
public final boolean allowPolymorphicSignature;
|
||||||
private final boolean debugResolve;
|
private final boolean debugResolve;
|
||||||
|
|
||||||
public static Resolve instance(Context context) {
|
public static Resolve instance(Context context) {
|
||||||
@ -105,7 +105,7 @@ public class Resolve {
|
|||||||
varargsEnabled = source.allowVarargs();
|
varargsEnabled = source.allowVarargs();
|
||||||
Options options = Options.instance(context);
|
Options options = Options.instance(context);
|
||||||
debugResolve = options.get("debugresolve") != null;
|
debugResolve = options.get("debugresolve") != null;
|
||||||
allowInvokedynamic = options.get("invokedynamic") != null;
|
allowPolymorphicSignature = source.allowPolymorphicSignature() || options.get("invokedynamic") != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** error symbols, which are returned when resolution fails
|
/** error symbols, which are returned when resolution fails
|
||||||
@ -301,6 +301,7 @@ public class Resolve {
|
|||||||
boolean useVarargs,
|
boolean useVarargs,
|
||||||
Warner warn)
|
Warner warn)
|
||||||
throws Infer.InferenceException {
|
throws Infer.InferenceException {
|
||||||
|
assert ((m.flags() & (POLYMORPHIC_SIGNATURE|HYPOTHETICAL)) != POLYMORPHIC_SIGNATURE);
|
||||||
if (useVarargs && (m.flags() & VARARGS) == 0) return null;
|
if (useVarargs && (m.flags() & VARARGS) == 0) return null;
|
||||||
Type mt = types.memberType(site, m);
|
Type mt = types.memberType(site, m);
|
||||||
|
|
||||||
@ -575,6 +576,14 @@ public class Resolve {
|
|||||||
if (sym.kind == ERR) return bestSoFar;
|
if (sym.kind == ERR) return bestSoFar;
|
||||||
if (!sym.isInheritedIn(site.tsym, types)) return bestSoFar;
|
if (!sym.isInheritedIn(site.tsym, types)) return bestSoFar;
|
||||||
assert sym.kind < AMBIGUOUS;
|
assert sym.kind < AMBIGUOUS;
|
||||||
|
if ((sym.flags() & POLYMORPHIC_SIGNATURE) != 0 && allowPolymorphicSignature) {
|
||||||
|
assert(site.tag == CLASS);
|
||||||
|
// Never match a MethodHandle.invoke directly.
|
||||||
|
if (useVarargs | allowBoxing | operator)
|
||||||
|
return bestSoFar;
|
||||||
|
// Supply an exactly-typed implicit method instead.
|
||||||
|
sym = findPolymorphicSignatureInstance(env, sym.owner.type, sym.name, (MethodSymbol) sym, argtypes, typeargtypes);
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
if (rawInstantiate(env, site, sym, argtypes, typeargtypes,
|
if (rawInstantiate(env, site, sym, argtypes, typeargtypes,
|
||||||
allowBoxing, useVarargs, Warner.noWarnings) == null) {
|
allowBoxing, useVarargs, Warner.noWarnings) == null) {
|
||||||
@ -745,6 +754,14 @@ public class Resolve {
|
|||||||
boolean allowBoxing,
|
boolean allowBoxing,
|
||||||
boolean useVarargs,
|
boolean useVarargs,
|
||||||
boolean operator) {
|
boolean operator) {
|
||||||
|
Symbol bestSoFar = methodNotFound;
|
||||||
|
if ((site.tsym.flags() & POLYMORPHIC_SIGNATURE) != 0 &&
|
||||||
|
allowPolymorphicSignature &&
|
||||||
|
site.tag == CLASS &&
|
||||||
|
!(useVarargs | allowBoxing | operator)) {
|
||||||
|
// supply an exactly-typed implicit method in java.dyn.InvokeDynamic
|
||||||
|
bestSoFar = findPolymorphicSignatureInstance(env, site, name, null, argtypes, typeargtypes);
|
||||||
|
}
|
||||||
return findMethod(env,
|
return findMethod(env,
|
||||||
site,
|
site,
|
||||||
name,
|
name,
|
||||||
@ -752,7 +769,7 @@ public class Resolve {
|
|||||||
typeargtypes,
|
typeargtypes,
|
||||||
site.tsym.type,
|
site.tsym.type,
|
||||||
true,
|
true,
|
||||||
methodNotFound,
|
bestSoFar,
|
||||||
allowBoxing,
|
allowBoxing,
|
||||||
useVarargs,
|
useVarargs,
|
||||||
operator);
|
operator);
|
||||||
@ -896,13 +913,14 @@ public class Resolve {
|
|||||||
* @param argtypes The method's value arguments.
|
* @param argtypes The method's value arguments.
|
||||||
* @param typeargtypes The method's type arguments
|
* @param typeargtypes The method's type arguments
|
||||||
*/
|
*/
|
||||||
Symbol findImplicitMethod(Env<AttrContext> env,
|
Symbol findPolymorphicSignatureInstance(Env<AttrContext> env,
|
||||||
Type site,
|
Type site,
|
||||||
Name name,
|
Name name,
|
||||||
List<Type> argtypes,
|
MethodSymbol spMethod, // sig. poly. method or null if none
|
||||||
List<Type> typeargtypes) {
|
List<Type> argtypes,
|
||||||
assert allowInvokedynamic;
|
List<Type> typeargtypes) {
|
||||||
assert site == syms.invokeDynamicType || (site == syms.methodHandleType && name == names.invoke);
|
assert allowPolymorphicSignature;
|
||||||
|
//assert site == syms.invokeDynamicType || site == syms.methodHandleType : site;
|
||||||
ClassSymbol c = (ClassSymbol) site.tsym;
|
ClassSymbol c = (ClassSymbol) site.tsym;
|
||||||
Scope implicit = c.members().next;
|
Scope implicit = c.members().next;
|
||||||
if (implicit == null) {
|
if (implicit == null) {
|
||||||
@ -917,12 +935,22 @@ public class Resolve {
|
|||||||
return methodNotFound;
|
return methodNotFound;
|
||||||
}
|
}
|
||||||
List<Type> paramtypes = Type.map(argtypes, implicitArgType);
|
List<Type> paramtypes = Type.map(argtypes, implicitArgType);
|
||||||
|
long flags;
|
||||||
|
List<Type> exType;
|
||||||
|
if (spMethod != null) {
|
||||||
|
exType = spMethod.getThrownTypes();
|
||||||
|
flags = spMethod.flags() & AccessFlags;
|
||||||
|
} else {
|
||||||
|
// make it throw all exceptions
|
||||||
|
//assert(site == syms.invokeDynamicType);
|
||||||
|
exType = List.of(syms.throwableType);
|
||||||
|
flags = PUBLIC | STATIC;
|
||||||
|
}
|
||||||
MethodType mtype = new MethodType(paramtypes,
|
MethodType mtype = new MethodType(paramtypes,
|
||||||
restype,
|
restype,
|
||||||
List.<Type>nil(),
|
exType,
|
||||||
syms.methodClass);
|
syms.methodClass);
|
||||||
int flags = PUBLIC | ABSTRACT;
|
flags |= ABSTRACT | HYPOTHETICAL | POLYMORPHIC_SIGNATURE;
|
||||||
if (site == syms.invokeDynamicType) flags |= STATIC;
|
|
||||||
Symbol m = null;
|
Symbol m = null;
|
||||||
for (Scope.Entry e = implicit.lookup(name);
|
for (Scope.Entry e = implicit.lookup(name);
|
||||||
e.scope != null;
|
e.scope != null;
|
||||||
@ -1337,14 +1365,6 @@ public class Resolve {
|
|||||||
methodResolutionCache.put(steps.head, sym);
|
methodResolutionCache.put(steps.head, sym);
|
||||||
steps = steps.tail;
|
steps = steps.tail;
|
||||||
}
|
}
|
||||||
if (sym.kind >= AMBIGUOUS &&
|
|
||||||
allowInvokedynamic &&
|
|
||||||
(site == syms.invokeDynamicType ||
|
|
||||||
site == syms.methodHandleType && name == names.invoke)) {
|
|
||||||
// lookup failed; supply an exactly-typed implicit method
|
|
||||||
sym = findImplicitMethod(env, site, name, argtypes, typeargtypes);
|
|
||||||
env.info.varArgs = false;
|
|
||||||
}
|
|
||||||
if (sym.kind >= AMBIGUOUS) {//if nothing is found return the 'first' error
|
if (sym.kind >= AMBIGUOUS) {//if nothing is found return the 'first' error
|
||||||
MethodResolutionPhase errPhase =
|
MethodResolutionPhase errPhase =
|
||||||
firstErroneousResolutionPhase();
|
firstErroneousResolutionPhase();
|
||||||
|
@ -1098,6 +1098,12 @@ public class ClassReader implements Completer {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
new AttributeReader(names.PolymorphicSignature, V45_3/*S.B.V51*/, CLASS_OR_MEMBER_ATTRIBUTE) {
|
||||||
|
void read(Symbol sym, int attrLen) {
|
||||||
|
sym.flags_field |= POLYMORPHIC_SIGNATURE;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
// The following attributes for a Code attribute are not currently handled
|
// The following attributes for a Code attribute are not currently handled
|
||||||
// StackMapTable
|
// StackMapTable
|
||||||
|
@ -651,6 +651,13 @@ public class ClassWriter extends ClassFile {
|
|||||||
endAttr(alenIdx);
|
endAttr(alenIdx);
|
||||||
acount++;
|
acount++;
|
||||||
}
|
}
|
||||||
|
if ((flags & POLYMORPHIC_SIGNATURE) != 0) {
|
||||||
|
if (target.majorVersion < 51)
|
||||||
|
throw new AssertionError("PolymorphicSignature attributes in java/dyn must be written with -target 7 (required major version is 51, current is"+target.majorVersion+")");
|
||||||
|
int alenIdx = writeAttr(names.PolymorphicSignature);
|
||||||
|
endAttr(alenIdx);
|
||||||
|
acount++;
|
||||||
|
}
|
||||||
return acount;
|
return acount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -121,7 +121,7 @@ public class Gen extends JCTree.Visitor {
|
|||||||
: options.get("-g:vars") != null;
|
: options.get("-g:vars") != null;
|
||||||
genCrt = options.get("-Xjcov") != null;
|
genCrt = options.get("-Xjcov") != null;
|
||||||
debugCode = options.get("debugcode") != null;
|
debugCode = options.get("debugcode") != null;
|
||||||
allowInvokedynamic = options.get("invokedynamic") != null;
|
allowInvokedynamic = target.hasInvokedynamic() || options.get("invokedynamic") != null;
|
||||||
|
|
||||||
generateIproxies =
|
generateIproxies =
|
||||||
target.requiresIproxy() ||
|
target.requiresIproxy() ||
|
||||||
|
@ -281,9 +281,6 @@ public class Main {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (target.hasInvokedynamic()) {
|
|
||||||
options.put("invokedynamic", "invokedynamic");
|
|
||||||
}
|
|
||||||
|
|
||||||
// handle this here so it works even if no other options given
|
// handle this here so it works even if no other options given
|
||||||
String showClass = options.get("showClass");
|
String showClass = options.get("showClass");
|
||||||
|
@ -103,6 +103,7 @@ public class Names {
|
|||||||
public final Name RuntimeInvisibleTypeAnnotations;
|
public final Name RuntimeInvisibleTypeAnnotations;
|
||||||
public final Name RuntimeVisibleParameterAnnotations;
|
public final Name RuntimeVisibleParameterAnnotations;
|
||||||
public final Name RuntimeInvisibleParameterAnnotations;
|
public final Name RuntimeInvisibleParameterAnnotations;
|
||||||
|
public final Name PolymorphicSignature;
|
||||||
public final Name Value;
|
public final Name Value;
|
||||||
public final Name EnclosingMethod;
|
public final Name EnclosingMethod;
|
||||||
public final Name desiredAssertionStatus;
|
public final Name desiredAssertionStatus;
|
||||||
@ -115,7 +116,6 @@ public class Names {
|
|||||||
public final Name value;
|
public final Name value;
|
||||||
public final Name getMessage;
|
public final Name getMessage;
|
||||||
public final Name getClass;
|
public final Name getClass;
|
||||||
public final Name invoke;
|
|
||||||
public final Name TYPE;
|
public final Name TYPE;
|
||||||
public final Name TYPE_USE;
|
public final Name TYPE_USE;
|
||||||
public final Name TYPE_PARAMETER;
|
public final Name TYPE_PARAMETER;
|
||||||
@ -213,6 +213,7 @@ public class Names {
|
|||||||
RuntimeInvisibleTypeAnnotations = fromString("RuntimeInvisibleTypeAnnotations");
|
RuntimeInvisibleTypeAnnotations = fromString("RuntimeInvisibleTypeAnnotations");
|
||||||
RuntimeVisibleParameterAnnotations = fromString("RuntimeVisibleParameterAnnotations");
|
RuntimeVisibleParameterAnnotations = fromString("RuntimeVisibleParameterAnnotations");
|
||||||
RuntimeInvisibleParameterAnnotations = fromString("RuntimeInvisibleParameterAnnotations");
|
RuntimeInvisibleParameterAnnotations = fromString("RuntimeInvisibleParameterAnnotations");
|
||||||
|
PolymorphicSignature = fromString("PolymorphicSignature");
|
||||||
Value = fromString("Value");
|
Value = fromString("Value");
|
||||||
EnclosingMethod = fromString("EnclosingMethod");
|
EnclosingMethod = fromString("EnclosingMethod");
|
||||||
|
|
||||||
@ -227,7 +228,6 @@ public class Names {
|
|||||||
value = fromString("value");
|
value = fromString("value");
|
||||||
getMessage = fromString("getMessage");
|
getMessage = fromString("getMessage");
|
||||||
getClass = fromString("getClass");
|
getClass = fromString("getClass");
|
||||||
invoke = fromString("invoke");
|
|
||||||
|
|
||||||
TYPE = fromString("TYPE");
|
TYPE = fromString("TYPE");
|
||||||
TYPE_USE = fromString("TYPE_USE");
|
TYPE_USE = fromString("TYPE_USE");
|
||||||
|
@ -47,7 +47,7 @@ package meth;
|
|||||||
import java.dyn.InvokeDynamic;
|
import java.dyn.InvokeDynamic;
|
||||||
|
|
||||||
public class InvokeDyn {
|
public class InvokeDyn {
|
||||||
void test() {
|
void test() throws Throwable {
|
||||||
Object x = "hello";
|
Object x = "hello";
|
||||||
InvokeDynamic.greet(x, "world", 123);
|
InvokeDynamic.greet(x, "world", 123);
|
||||||
InvokeDynamic.greet(x, "mundus", 456);
|
InvokeDynamic.greet(x, "mundus", 456);
|
||||||
|
@ -48,28 +48,56 @@ public class InvokeMH {
|
|||||||
void test(MethodHandle mh_SiO,
|
void test(MethodHandle mh_SiO,
|
||||||
MethodHandle mh_vS,
|
MethodHandle mh_vS,
|
||||||
MethodHandle mh_vi,
|
MethodHandle mh_vi,
|
||||||
MethodHandle mh_vv) {
|
MethodHandle mh_vv) throws Throwable {
|
||||||
Object o; String s; int i; // for return type testing
|
Object o; String s; int i; // for return type testing
|
||||||
|
|
||||||
// next five must have sig = (String,int)Object
|
// next five must have sig = (String,int)Object
|
||||||
mh_SiO.invoke("world", 123);
|
mh_SiO.invokeExact("world", 123);
|
||||||
mh_SiO.invoke("mundus", 456);
|
mh_SiO.invokeExact("mundus", 456);
|
||||||
Object k = "kosmos";
|
Object k = "kosmos";
|
||||||
mh_SiO.invoke((String)k, 789);
|
mh_SiO.invokeExact((String)k, 789);
|
||||||
o = mh_SiO.invoke((String)null, 000);
|
o = mh_SiO.invokeExact((String)null, 000);
|
||||||
o = mh_SiO.<Object>invoke("arda", -123);
|
o = mh_SiO.<Object>invokeExact("arda", -123);
|
||||||
|
|
||||||
// sig = ()String
|
// sig = ()String
|
||||||
s = mh_vS.<String>invoke();
|
s = mh_vS.<String>invokeExact();
|
||||||
|
|
||||||
// sig = ()int
|
// sig = ()int
|
||||||
i = mh_vi.<int>invoke();
|
i = mh_vi.<int>invokeExact();
|
||||||
o = mh_vi.<int>invoke();
|
o = mh_vi.<int>invokeExact();
|
||||||
//s = mh_vi.<int>invoke(); //BAD
|
//s = mh_vi.<int>invokeExact(); //BAD
|
||||||
mh_vi.<int>invoke();
|
mh_vi.<int>invokeExact();
|
||||||
|
|
||||||
// sig = ()void
|
// sig = ()void
|
||||||
//o = mh_vv.<void>invoke(); //BAD
|
//o = mh_vv.<void>invokeExact(); //BAD
|
||||||
mh_vv.<void>invoke();
|
mh_vv.<void>invokeExact();
|
||||||
|
}
|
||||||
|
|
||||||
|
void testGen(MethodHandle mh_SiO,
|
||||||
|
MethodHandle mh_vS,
|
||||||
|
MethodHandle mh_vi,
|
||||||
|
MethodHandle mh_vv) throws Throwable {
|
||||||
|
Object o; String s; int i; // for return type testing
|
||||||
|
|
||||||
|
// next five must have sig = (*,*)*
|
||||||
|
mh_SiO.invokeGeneric((Object)"world", (Object)123);
|
||||||
|
mh_SiO.<void>invokeGeneric((Object)"mundus", (Object)456);
|
||||||
|
Object k = "kosmos";
|
||||||
|
mh_SiO.invokeGeneric(k, 789);
|
||||||
|
o = mh_SiO.invokeGeneric(null, 000);
|
||||||
|
o = mh_SiO.<Object>invokeGeneric("arda", -123);
|
||||||
|
|
||||||
|
// sig = ()String
|
||||||
|
o = mh_vS.invokeGeneric();
|
||||||
|
|
||||||
|
// sig = ()int
|
||||||
|
i = mh_vi.<int>invokeGeneric();
|
||||||
|
o = mh_vi.invokeGeneric();
|
||||||
|
//s = mh_vi.<int>invokeGeneric(); //BAD
|
||||||
|
mh_vi.<void>invokeGeneric();
|
||||||
|
|
||||||
|
// sig = ()void
|
||||||
|
//o = mh_vv.<void>invokeGeneric(); //BAD
|
||||||
|
o = mh_vv.invokeGeneric();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user