/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/**
* Construction and caching of often-used invokers.
* @author jrose
*/
class Invokers {
// exact type (sans leading taget MH) for the outgoing call
// FIXME: Get rid of the invokers that are not useful.
// exact invoker for the outgoing call
// erased (partially untyped but with primitives) invoker for the outgoing call
// FIXME: get rid of
// FIXME: get rid of
// general invoker for the outgoing call
// general invoker for the outgoing call, uses varargs
// general invoker for the outgoing call; accepts a trailing Object[]
// invoker for an unbound callsite
/** Compute and cache information common to all collecting adapters
* that implement members of the erasure-family of the given erased type.
*/
this.targetType = targetType;
}
} else {
// At maximum arity, we cannot afford an extra mtype argument,
// so build a fully customized (non-cached) invoker form.
}
assert(checkInvoker(invoker));
return invoker;
}
assert(GENERIC_INVOKER_SLOP >= MTYPE_ARG_APPENDED);
} else {
// At maximum arity, we cannot afford an extra mtype argument,
// so build a fully customized (non-cached) invoker form.
}
assert(checkInvoker(invoker));
return invoker;
}
// Note: This is not cached here. It is cached by the calling MethodTypeForm.
assert(checkInvoker(invoker));
return invoker;
}
try {
//Lookup.findVirtual(MethodHandle.class, name, type);
} catch (ReflectiveOperationException ex) {
}
}
assert(!invoker.isVarargsCollector());
return true;
}
// FIXME: get rid of
return invoker;
}
// Factor sinvoker.invoke(mh, a) into ginvoker.asSpreader().invoke(mh, a)
// where ginvoker.invoke(mh, a*) => mh.invoke(a*).
} else {
// Cannot build a general invoker here of type ginvoker.invoke(mh, a*[254]).
// Instead, factor sinvoker.invoke(mh, a) into ainvoker.invoke(filter(mh), a)
// where filter(mh) == mh.asSpreader(Object[], spreadArgCount)
try {
} catch (ReflectiveOperationException ex) {
throw newInternalError(ex);
}
}
return vaInvoker;
}
return vaInvoker;
}
return invoker;
}
try {
} catch (ReflectiveOperationException ex) {
throw newInternalError(ex);
}
}
invoker = MethodHandles.explicitCastArguments(invoker, MethodType.methodType(targetType.returnType()));
return invoker;
}
return "Invokers"+targetType;
}
} else {
}
}
if (mtype.parameterSlotCount() <= MethodType.MAX_MH_ARITY - (MTYPE_ARG_APPENDED + GENERIC_INVOKER_SLOP)) {
} else {
}
}
boolean isCached;
if (!customized) {
isCached = true;
} else {
isCached = false; // maybe cache if mtype == mtype.basicType()
}
switch (which) {
case MethodTypeForm.LF_EX_LINKER: isLinker = true; isGeneric = false; debugName = "invokeExact_MT"; break;
case MethodTypeForm.LF_EX_INVOKER: isLinker = false; isGeneric = false; debugName = "exactInvoker"; break;
case MethodTypeForm.LF_GEN_LINKER: isLinker = true; isGeneric = true; debugName = "invoke_MT"; break;
case MethodTypeForm.LF_GEN_INVOKER: isLinker = false; isGeneric = true; debugName = "invoker"; break;
default: throw new InternalError();
}
if (isCached) {
}
// exactInvokerForm (Object,Object)Object
// link with java.lang.invoke.MethodHandle.invokeBasic(MethodHandle,Object,Object)Object/invokeSpecial
final int THIS_MH = 0;
int nameCursor = OUTARG_LIMIT;
final int CHECK_TYPE = nameCursor++;
final int LINKER_CALL = nameCursor++;
if (isLinker) {
if (!customized)
} else {
}
if (MTYPE_ARG >= INARG_LIMIT) {
// else if isLinker, then MTYPE is passed in from the caller (e.g., the JVM)
}
// Make the final call. If isGeneric, then prepend the result of type checking.
if (!isGeneric) {
// mh.invokeExact(a*):R => checkExactType(mh, TYPEOF(a*:R)); mh.invokeBasic(a*)
outCallType = mtype;
} else if (customized) {
// mh.invokeGeneric(a*):R =>
// let mt=TYPEOF(a*:R), tmh=asType(mh, mt);
// tmh.invokeBasic(a*)
outCallType = mtype;
} else {
// mh.invokeGeneric(a*):R =>
// let mt=TYPEOF(a*:R), gamh=checkGenericType(mh, mt);
// gamh.invokeBasic(mt, mh, a*)
assert(GENERIC_INVOKER_SLOP == PREPEND_COUNT);
// prepend arguments:
}
if (isLinker)
if (isCached)
return lform;
}
/*non-public*/ static
// FIXME: merge with JVM logic for throwing WMTE
}
/** Static definition of MethodHandle.invokeExact checking code. */
/*non-public*/ static
}
/** Static definition of MethodHandle.invokeGeneric checking code. */
/*non-public*/ static
//MethodType actual = mh.type();
return prepareForGenericCall(expected);
}
/**
* Returns an adapter GA for invoking a MH with type adjustments.
* The MethodType of the generic invocation site is prepended to MH
* and its arguments as follows:
* {@code (R)MH.invoke(A*) => GA.invokeBasic(TYPEOF<A*,R>, MH, A*)}
*/
// force any needed adapters to be preconstructed
try {
// Trigger adapter creation.
return gamh;
}
}
}
// exactInvokerForm (Object,Object)Object
// link with java.lang.invoke.MethodHandle.invokeBasic(MethodHandle,Object,Object)Object/invokeSpecial
final int ARG_BASE = 0;
int nameCursor = OUTARG_LIMIT;
final int LINKER_CALL = nameCursor++;
// (site.)invokedynamic(a*):R => mh = site.getTarget(); mh.invokeBasic(a*)
Object[] outArgs = Arrays.copyOfRange(names, ARG_BASE, OUTARG_LIMIT + PREPEND_COUNT, Object[].class);
// prepend MH argument:
return lform;
}
/** Static definition of MethodHandle.invokeGeneric checking code. */
/*non-public*/ static
}
// Local constant functions:
static {
try {
// bound
} catch (ReflectiveOperationException ex) {
throw newInternalError(ex);
}
}
}