mirror of
https://github.com/openjdk/jdk.git
synced 2026-05-17 00:50:48 +00:00
8050166: Get rid of some package-private methods on arguments in j.l.i.MethodHandle
Reviewed-by: vlivanov, psandoz
This commit is contained in:
parent
6a177f43fb
commit
2f4b5e8534
@ -60,13 +60,12 @@ import jdk.internal.org.objectweb.asm.Type;
|
||||
// BMH API and internals
|
||||
//
|
||||
|
||||
static MethodHandle bindSingle(MethodType type, LambdaForm form, BasicType xtype, Object x) {
|
||||
static BoundMethodHandle bindSingle(MethodType type, LambdaForm form, BasicType xtype, Object x) {
|
||||
// for some type signatures, there exist pre-defined concrete BMH classes
|
||||
try {
|
||||
switch (xtype) {
|
||||
case L_TYPE:
|
||||
if (true) return bindSingle(type, form, x); // Use known fast path.
|
||||
return (BoundMethodHandle) SpeciesData.EMPTY.extendWith(L_TYPE).constructor().invokeBasic(type, form, x);
|
||||
return bindSingle(type, form, x); // Use known fast path.
|
||||
case I_TYPE:
|
||||
return (BoundMethodHandle) SpeciesData.EMPTY.extendWith(I_TYPE).constructor().invokeBasic(type, form, ValueConversions.widenSubword(x));
|
||||
case J_TYPE:
|
||||
@ -82,49 +81,40 @@ import jdk.internal.org.objectweb.asm.Type;
|
||||
}
|
||||
}
|
||||
|
||||
static MethodHandle bindSingle(MethodType type, LambdaForm form, Object x) {
|
||||
return new Species_L(type, form, x);
|
||||
static BoundMethodHandle bindSingle(MethodType type, LambdaForm form, Object x) {
|
||||
return Species_L.make(type, form, x);
|
||||
}
|
||||
|
||||
MethodHandle cloneExtend(MethodType type, LambdaForm form, BasicType xtype, Object x) {
|
||||
try {
|
||||
switch (xtype) {
|
||||
case L_TYPE: return copyWithExtendL(type, form, x);
|
||||
case I_TYPE: return copyWithExtendI(type, form, ValueConversions.widenSubword(x));
|
||||
case J_TYPE: return copyWithExtendJ(type, form, (long) x);
|
||||
case F_TYPE: return copyWithExtendF(type, form, (float) x);
|
||||
case D_TYPE: return copyWithExtendD(type, form, (double) x);
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
throw newInternalError(t);
|
||||
}
|
||||
throw newInternalError("unexpected type: " + xtype);
|
||||
}
|
||||
|
||||
@Override
|
||||
MethodHandle bindArgument(int pos, BasicType basicType, Object value) {
|
||||
@Override // there is a default binder in the super class, for 'L' types only
|
||||
/*non-public*/
|
||||
BoundMethodHandle bindArgumentL(int pos, Object value) {
|
||||
MethodType type = type().dropParameterTypes(pos, pos+1);
|
||||
LambdaForm form = internalForm().bind(1+pos, speciesData());
|
||||
return cloneExtend(type, form, basicType, value);
|
||||
return copyWithExtendL(type, form, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
MethodHandle dropArguments(MethodType srcType, int pos, int drops) {
|
||||
LambdaForm form = internalForm().addArguments(pos, srcType.parameterList().subList(pos, pos + drops));
|
||||
try {
|
||||
return copyWith(srcType, form);
|
||||
} catch (Throwable t) {
|
||||
throw newInternalError(t);
|
||||
}
|
||||
/*non-public*/
|
||||
BoundMethodHandle bindArgumentI(int pos, int value) {
|
||||
MethodType type = type().dropParameterTypes(pos, pos+1);
|
||||
LambdaForm form = internalForm().bind(1+pos, speciesData());
|
||||
return copyWithExtendI(type, form, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
MethodHandle permuteArguments(MethodType newType, int[] reorder) {
|
||||
try {
|
||||
return copyWith(newType, form.permuteArguments(1, reorder, basicTypes(newType.parameterList())));
|
||||
} catch (Throwable t) {
|
||||
throw newInternalError(t);
|
||||
}
|
||||
/*non-public*/
|
||||
BoundMethodHandle bindArgumentJ(int pos, long value) {
|
||||
MethodType type = type().dropParameterTypes(pos, pos+1);
|
||||
LambdaForm form = internalForm().bind(1+pos, speciesData());
|
||||
return copyWithExtendJ(type, form, value);
|
||||
}
|
||||
/*non-public*/
|
||||
BoundMethodHandle bindArgumentF(int pos, float value) {
|
||||
MethodType type = type().dropParameterTypes(pos, pos+1);
|
||||
LambdaForm form = internalForm().bind(1+pos, speciesData());
|
||||
return copyWithExtendF(type, form, value);
|
||||
}
|
||||
/*non-public*/
|
||||
BoundMethodHandle bindArgumentD(int pos, double value) {
|
||||
MethodType type = type().dropParameterTypes(pos, pos + 1);
|
||||
LambdaForm form = internalForm().bind(1+pos, speciesData());
|
||||
return copyWithExtendD(type, form, value);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -211,7 +211,7 @@ public class CallSite {
|
||||
public abstract MethodHandle dynamicInvoker();
|
||||
|
||||
/*non-public*/ MethodHandle makeDynamicInvoker() {
|
||||
MethodHandle getTarget = GET_TARGET.bindReceiver(this);
|
||||
MethodHandle getTarget = GET_TARGET.bindArgumentL(0, this);
|
||||
MethodHandle invoker = MethodHandles.exactInvoker(this.type());
|
||||
return MethodHandles.foldArguments(invoker, getTarget);
|
||||
}
|
||||
|
||||
@ -142,45 +142,8 @@ class DirectMethodHandle extends MethodHandle {
|
||||
return member;
|
||||
}
|
||||
|
||||
@Override
|
||||
MethodHandle bindArgument(int pos, BasicType basicType, Object value) {
|
||||
// If the member needs dispatching, do so.
|
||||
if (pos == 0 && basicType == L_TYPE) {
|
||||
DirectMethodHandle concrete = maybeRebind(value);
|
||||
if (concrete != null)
|
||||
return concrete.bindReceiver(value);
|
||||
}
|
||||
return super.bindArgument(pos, basicType, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
MethodHandle bindReceiver(Object receiver) {
|
||||
// If the member needs dispatching, do so.
|
||||
DirectMethodHandle concrete = maybeRebind(receiver);
|
||||
if (concrete != null)
|
||||
return concrete.bindReceiver(receiver);
|
||||
return super.bindReceiver(receiver);
|
||||
}
|
||||
|
||||
private static final MemberName.Factory IMPL_NAMES = MemberName.getFactory();
|
||||
|
||||
private DirectMethodHandle maybeRebind(Object receiver) {
|
||||
if (receiver != null) {
|
||||
switch (member.getReferenceKind()) {
|
||||
case REF_invokeInterface:
|
||||
case REF_invokeVirtual:
|
||||
// Pre-dispatch the member.
|
||||
Class<?> concreteClass = receiver.getClass();
|
||||
MemberName concrete = new MemberName(concreteClass, member.getName(), member.getMethodType(), REF_invokeSpecial);
|
||||
concrete = IMPL_NAMES.resolveOrNull(REF_invokeSpecial, concrete, concreteClass);
|
||||
if (concrete != null)
|
||||
return new DirectMethodHandle(type(), preparedLambdaForm(concrete), concrete);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a LF which can invoke the given method.
|
||||
* Cache and share this structure among all methods with
|
||||
|
||||
@ -774,7 +774,7 @@ public abstract class MethodHandle {
|
||||
/*non-public*/ MethodHandle asTypeUncached(MethodType newType) {
|
||||
if (!type.isConvertibleTo(newType))
|
||||
throw new WrongMethodTypeException("cannot convert "+this+" to "+newType);
|
||||
return asTypeCache = convertArguments(newType);
|
||||
return asTypeCache = MethodHandleImpl.makePairwiseConvert(this, newType, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -987,7 +987,7 @@ assertEquals("[123]", (String) longsToString.invokeExact((long)123));
|
||||
int collectArgPos = type().parameterCount()-1;
|
||||
MethodHandle target = this;
|
||||
if (arrayType != type().parameterType(collectArgPos))
|
||||
target = convertArguments(type().changeParameterType(collectArgPos, arrayType));
|
||||
target = MethodHandleImpl.makePairwiseConvert(this, type().changeParameterType(collectArgPos, arrayType), 1);
|
||||
MethodHandle collector = MethodHandleImpl.varargsArray(arrayType, arrayLength);
|
||||
return MethodHandles.collectArguments(target, collectArgPos, collector);
|
||||
}
|
||||
@ -1260,14 +1260,8 @@ assertEquals("[three, thee, tee]", asListFix.invoke((Object)argv).toString());
|
||||
* @see MethodHandles#insertArguments
|
||||
*/
|
||||
public MethodHandle bindTo(Object x) {
|
||||
Class<?> ptype;
|
||||
@SuppressWarnings("LocalVariableHidesMemberVariable")
|
||||
MethodType type = type();
|
||||
if (type.parameterCount() == 0 ||
|
||||
(ptype = type.parameterType(0)).isPrimitive())
|
||||
throw newIllegalArgumentException("no leading reference parameter", x);
|
||||
x = ptype.cast(x); // throw CCE if needed
|
||||
return bindReceiver(x);
|
||||
x = type.leadingReferenceParameter().cast(x); // throw CCE if needed
|
||||
return bindArgumentL(0, x);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1306,6 +1300,10 @@ assertEquals("[three, thee, tee]", asListFix.invoke((Object)argv).toString());
|
||||
|
||||
// Other transforms to do: convert, explicitCast, permute, drop, filter, fold, GWT, catch
|
||||
|
||||
BoundMethodHandle bindArgumentL(int pos, Object value) {
|
||||
return rebind().bindArgumentL(pos, value);
|
||||
}
|
||||
|
||||
/*non-public*/
|
||||
MethodHandle setVarargs(MemberName member) throws IllegalAccessException {
|
||||
if (!member.isVarargs()) return this;
|
||||
@ -1374,37 +1372,8 @@ assertEquals("[three, thee, tee]", asListFix.invoke((Object)argv).toString());
|
||||
//// Sub-classes can override these default implementations.
|
||||
//// All these methods assume arguments are already validated.
|
||||
|
||||
/*non-public*/ MethodHandle convertArguments(MethodType newType) {
|
||||
// Override this if it can be improved.
|
||||
return MethodHandleImpl.makePairwiseConvert(this, newType, 1);
|
||||
}
|
||||
|
||||
/*non-public*/
|
||||
MethodHandle bindArgument(int pos, BasicType basicType, Object value) {
|
||||
// Override this if it can be improved.
|
||||
return rebind().bindArgument(pos, basicType, value);
|
||||
}
|
||||
|
||||
/*non-public*/
|
||||
MethodHandle bindReceiver(Object receiver) {
|
||||
// Override this if it can be improved.
|
||||
return bindArgument(0, L_TYPE, receiver);
|
||||
}
|
||||
|
||||
/*non-public*/
|
||||
MethodHandle dropArguments(MethodType srcType, int pos, int drops) {
|
||||
// Override this if it can be improved.
|
||||
return rebind().dropArguments(srcType, pos, drops);
|
||||
}
|
||||
|
||||
/*non-public*/
|
||||
MethodHandle permuteArguments(MethodType newType, int[] reorder) {
|
||||
// Override this if it can be improved.
|
||||
return rebind().permuteArguments(newType, reorder);
|
||||
}
|
||||
|
||||
/*non-public*/
|
||||
MethodHandle rebind() {
|
||||
BoundMethodHandle rebind() {
|
||||
// Bind 'this' into a new invoker, of the known class BMH.
|
||||
MethodType type2 = type();
|
||||
LambdaForm form2 = reinvokerForm(this);
|
||||
|
||||
@ -434,27 +434,6 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
|
||||
boolean isInvokeSpecial() {
|
||||
return asFixedArity().isInvokeSpecial();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
MethodHandle bindArgument(int pos, BasicType basicType, Object value) {
|
||||
return asFixedArity().bindArgument(pos, basicType, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
MethodHandle bindReceiver(Object receiver) {
|
||||
return asFixedArity().bindReceiver(receiver);
|
||||
}
|
||||
|
||||
@Override
|
||||
MethodHandle dropArguments(MethodType srcType, int pos, int drops) {
|
||||
return asFixedArity().dropArguments(srcType, pos, drops);
|
||||
}
|
||||
|
||||
@Override
|
||||
MethodHandle permuteArguments(MethodType newType, int[] reorder) {
|
||||
return asFixedArity().permuteArguments(newType, reorder);
|
||||
}
|
||||
}
|
||||
|
||||
/** Factory method: Spread selected argument. */
|
||||
@ -794,7 +773,9 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
|
||||
assert(Throwable.class.isAssignableFrom(type.parameterType(0)));
|
||||
int arity = type.parameterCount();
|
||||
if (arity > 1) {
|
||||
return throwException(type.dropParameterTypes(1, arity)).dropArguments(type, 1, arity-1);
|
||||
MethodHandle mh = throwException(type.dropParameterTypes(1, arity));
|
||||
mh = MethodHandles.dropArguments(mh, 1, type.parameterList().subList(1, arity));
|
||||
return mh;
|
||||
}
|
||||
return makePairwiseConvert(Lazy.NF_throwException.resolvedHandle(), type, 2);
|
||||
}
|
||||
|
||||
@ -26,6 +26,7 @@
|
||||
package java.lang.invoke;
|
||||
|
||||
import java.lang.reflect.*;
|
||||
import java.util.BitSet;
|
||||
import java.util.List;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
@ -1143,7 +1144,7 @@ return mh1;
|
||||
Class<? extends Object> refc = receiver.getClass(); // may get NPE
|
||||
MemberName method = resolveOrFail(REF_invokeSpecial, refc, name, type);
|
||||
MethodHandle mh = getDirectMethodNoRestrict(REF_invokeSpecial, refc, method, findBoundCallerClass(method));
|
||||
return mh.bindReceiver(receiver).setVarargs(method);
|
||||
return mh.bindArgumentL(0, receiver).setVarargs(method);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -2086,11 +2087,55 @@ assert((int)twice.invokeExact(21) == 42);
|
||||
public static
|
||||
MethodHandle permuteArguments(MethodHandle target, MethodType newType, int... reorder) {
|
||||
reorder = reorder.clone();
|
||||
checkReorder(reorder, newType, target.type());
|
||||
return target.permuteArguments(newType, reorder);
|
||||
permuteArgumentChecks(reorder, newType, target.type());
|
||||
// first detect dropped arguments and handle them separately
|
||||
MethodHandle originalTarget = target;
|
||||
int newArity = newType.parameterCount();
|
||||
for (int dropIdx; (dropIdx = findFirstDrop(reorder, newArity)) >= 0; ) {
|
||||
// dropIdx is missing from reorder; add it in at the end
|
||||
int oldArity = reorder.length;
|
||||
target = dropArguments(target, oldArity, newType.parameterType(dropIdx));
|
||||
reorder = Arrays.copyOf(reorder, oldArity+1);
|
||||
reorder[oldArity] = dropIdx;
|
||||
}
|
||||
assert(target == originalTarget || permuteArgumentChecks(reorder, newType, target.type()));
|
||||
// Note: This may cache too many distinct LFs. Consider backing off to varargs code.
|
||||
BoundMethodHandle result = target.rebind();
|
||||
LambdaForm form = result.form.permuteArguments(1, reorder, basicTypes(newType.parameterList()));
|
||||
return result.copyWith(newType, form);
|
||||
}
|
||||
|
||||
private static void checkReorder(int[] reorder, MethodType newType, MethodType oldType) {
|
||||
/** Return the first value in [0..newArity-1] that is not present in reorder. */
|
||||
private static int findFirstDrop(int[] reorder, int newArity) {
|
||||
final int BIT_LIMIT = 63; // max number of bits in bit mask
|
||||
if (newArity < BIT_LIMIT) {
|
||||
long mask = 0;
|
||||
for (int arg : reorder) {
|
||||
assert(arg < newArity);
|
||||
mask |= (1 << arg);
|
||||
}
|
||||
if (mask == (1 << newArity) - 1) {
|
||||
assert(Long.numberOfTrailingZeros(Long.lowestOneBit(~mask)) == newArity);
|
||||
return -1;
|
||||
}
|
||||
// find first zero
|
||||
long zeroBit = Long.lowestOneBit(~mask);
|
||||
int zeroPos = Long.numberOfTrailingZeros(zeroBit);
|
||||
assert(zeroPos < newArity);
|
||||
return zeroPos;
|
||||
}
|
||||
BitSet mask = new BitSet(newArity);
|
||||
for (int arg : reorder) {
|
||||
assert(arg < newArity);
|
||||
mask.set(arg);
|
||||
}
|
||||
int zeroPos = mask.nextClearBit(0);
|
||||
if (zeroPos == newArity)
|
||||
return -1;
|
||||
return zeroPos;
|
||||
}
|
||||
|
||||
private static boolean permuteArgumentChecks(int[] reorder, MethodType newType, MethodType oldType) {
|
||||
if (newType.returnType() != oldType.returnType())
|
||||
throw newIllegalArgumentException("return types do not match",
|
||||
oldType, newType);
|
||||
@ -2108,7 +2153,7 @@ assert((int)twice.invokeExact(21) == 42);
|
||||
throw newIllegalArgumentException("parameter types do not match after reorder",
|
||||
oldType, newType);
|
||||
}
|
||||
if (!bad) return;
|
||||
if (!bad) return true;
|
||||
}
|
||||
throw newIllegalArgumentException("bad reorder array: "+Arrays.toString(reorder));
|
||||
}
|
||||
@ -2192,6 +2237,37 @@ assert((int)twice.invokeExact(21) == 42);
|
||||
public static
|
||||
MethodHandle insertArguments(MethodHandle target, int pos, Object... values) {
|
||||
int insCount = values.length;
|
||||
Class<?>[] ptypes = insertArgumentsChecks(target, insCount, pos);
|
||||
if (insCount == 0) return target;
|
||||
BoundMethodHandle result = target.rebind();
|
||||
for (int i = 0; i < insCount; i++) {
|
||||
Object value = values[i];
|
||||
Class<?> ptype = ptypes[pos+i];
|
||||
if (ptype.isPrimitive()) {
|
||||
result = insertArgumentPrimitive(result, pos, ptype, value);
|
||||
} else {
|
||||
value = ptype.cast(value); // throw CCE if needed
|
||||
result = result.bindArgumentL(pos, value);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static BoundMethodHandle insertArgumentPrimitive(BoundMethodHandle result, int pos,
|
||||
Class<?> ptype, Object value) {
|
||||
Wrapper w = Wrapper.forPrimitiveType(ptype);
|
||||
// perform unboxing and/or primitive conversion
|
||||
value = w.convert(value, ptype);
|
||||
switch (w) {
|
||||
case INT: return result.bindArgumentI(pos, (int)value);
|
||||
case LONG: return result.bindArgumentJ(pos, (long)value);
|
||||
case FLOAT: return result.bindArgumentF(pos, (float)value);
|
||||
case DOUBLE: return result.bindArgumentD(pos, (double)value);
|
||||
default: return result.bindArgumentI(pos, ValueConversions.widenSubword(value));
|
||||
}
|
||||
}
|
||||
|
||||
private static Class<?>[] insertArgumentsChecks(MethodHandle target, int insCount, int pos) throws RuntimeException {
|
||||
MethodType oldType = target.type();
|
||||
int outargs = oldType.parameterCount();
|
||||
int inargs = outargs - insCount;
|
||||
@ -2199,31 +2275,7 @@ assert((int)twice.invokeExact(21) == 42);
|
||||
throw newIllegalArgumentException("too many values to insert");
|
||||
if (pos < 0 || pos > inargs)
|
||||
throw newIllegalArgumentException("no argument type to append");
|
||||
MethodHandle result = target;
|
||||
for (int i = 0; i < insCount; i++) {
|
||||
Object value = values[i];
|
||||
Class<?> ptype = oldType.parameterType(pos+i);
|
||||
if (ptype.isPrimitive()) {
|
||||
BasicType btype = I_TYPE;
|
||||
Wrapper w = Wrapper.forPrimitiveType(ptype);
|
||||
switch (w) {
|
||||
case LONG: btype = J_TYPE; break;
|
||||
case FLOAT: btype = F_TYPE; break;
|
||||
case DOUBLE: btype = D_TYPE; break;
|
||||
}
|
||||
// perform unboxing and/or primitive conversion
|
||||
value = w.convert(value, ptype);
|
||||
result = result.bindArgument(pos, btype, value);
|
||||
continue;
|
||||
}
|
||||
value = ptype.cast(value); // throw CCE if needed
|
||||
if (pos == 0) {
|
||||
result = result.bindReceiver(value);
|
||||
} else {
|
||||
result = result.bindArgument(pos, L_TYPE, value);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
return oldType.ptypes();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -2271,18 +2323,26 @@ assertEquals("yz", (String) d0.invokeExact(123, "x", "y", "z"));
|
||||
public static
|
||||
MethodHandle dropArguments(MethodHandle target, int pos, List<Class<?>> valueTypes) {
|
||||
MethodType oldType = target.type(); // get NPE
|
||||
int dropped = dropArgumentChecks(oldType, pos, valueTypes);
|
||||
if (dropped == 0) return target;
|
||||
BoundMethodHandle result = target.rebind();
|
||||
LambdaForm lform = result.form;
|
||||
lform = lform.addArguments(pos, valueTypes);
|
||||
MethodType newType = oldType.insertParameterTypes(pos, valueTypes);
|
||||
result = result.copyWith(newType, lform);
|
||||
return result;
|
||||
}
|
||||
|
||||
private static int dropArgumentChecks(MethodType oldType, int pos, List<Class<?>> valueTypes) {
|
||||
int dropped = valueTypes.size();
|
||||
MethodType.checkSlotCount(dropped);
|
||||
if (dropped == 0) return target;
|
||||
int outargs = oldType.parameterCount();
|
||||
int inargs = outargs + dropped;
|
||||
if (pos < 0 || pos >= inargs)
|
||||
throw newIllegalArgumentException("no argument type to remove");
|
||||
ArrayList<Class<?>> ptypes = new ArrayList<>(oldType.parameterList());
|
||||
ptypes.addAll(pos, valueTypes);
|
||||
if (ptypes.size() != inargs) throw newIllegalArgumentException("valueTypes");
|
||||
MethodType newType = MethodType.methodType(oldType.returnType(), ptypes);
|
||||
return target.dropArguments(newType, pos, dropped);
|
||||
if (pos < 0 || pos > outargs)
|
||||
throw newIllegalArgumentException("no argument type to remove"
|
||||
+ Arrays.asList(oldType, pos, valueTypes, inargs, outargs)
|
||||
);
|
||||
return dropped;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -499,6 +499,17 @@ class MethodType implements java.io.Serializable {
|
||||
return this; // arguments check out; no change
|
||||
}
|
||||
|
||||
/** Return the leading parameter type, which must exist and be a reference.
|
||||
* @return the leading parameter type, after error checks
|
||||
*/
|
||||
/*non-public*/ Class<?> leadingReferenceParameter() {
|
||||
Class<?> ptype;
|
||||
if (ptypes.length == 0 ||
|
||||
(ptype = ptypes[0]).isPrimitive())
|
||||
throw newIllegalArgumentException("no leading reference parameter");
|
||||
return ptype;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds or creates a method type with some parameter types omitted.
|
||||
* Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[]) methodType}.
|
||||
|
||||
@ -25,9 +25,6 @@
|
||||
|
||||
package java.lang.invoke;
|
||||
|
||||
import static java.lang.invoke.LambdaForm.*;
|
||||
import static java.lang.invoke.LambdaForm.BasicType.*;
|
||||
|
||||
/**
|
||||
* A method handle whose behavior is determined only by its LambdaForm.
|
||||
* @author jrose
|
||||
@ -40,23 +37,4 @@ final class SimpleMethodHandle extends MethodHandle {
|
||||
/*non-public*/ static SimpleMethodHandle make(MethodType type, LambdaForm form) {
|
||||
return new SimpleMethodHandle(type, form);
|
||||
}
|
||||
|
||||
@Override
|
||||
MethodHandle bindArgument(int pos, BasicType basicType, Object value) {
|
||||
MethodType type2 = type().dropParameterTypes(pos, pos+1);
|
||||
LambdaForm form2 = internalForm().bind(1+pos, BoundMethodHandle.SpeciesData.EMPTY);
|
||||
return BoundMethodHandle.bindSingle(type2, form2, basicType, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
MethodHandle dropArguments(MethodType srcType, int pos, int drops) {
|
||||
LambdaForm newForm = internalForm().addArguments(pos, srcType.parameterList().subList(pos, pos+drops));
|
||||
return new SimpleMethodHandle(srcType, newForm);
|
||||
}
|
||||
|
||||
@Override
|
||||
MethodHandle permuteArguments(MethodType newType, int[] reorder) {
|
||||
LambdaForm form2 = internalForm().permuteArguments(1, reorder, basicTypes(newType.parameterList()));
|
||||
return new SimpleMethodHandle(newType, form2);
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user