/** * Replaces the types in the callSiteType parameter if more specific types * given through the arguments. This is in general the case, unless * the argument is null. */ protected static MethodType replaceWithMoreSpecificType(Object[] args, MethodType callSiteType) { for (int i=0; i<args.length; i++) { // if argument null, take the static type if (args[i]==null) continue; if (callSiteType.parameterType(i).isPrimitive()) continue; Class argClass = args[i].getClass(); callSiteType = callSiteType.changeParameterType(i, argClass); } return callSiteType; }
Class<?> instanceType = instanceFactory.get().type().returnType(); checkArgument(instanceFactory.get().type().parameterList().size() == 0, "instanceFactory should have no parameter"); checkArgument(instanceType.equals(methodHandle.type().parameterType(0)), "methodHandle is not an instance method");
public Class<?> thisType() { return isStatic() ? null : type().parameterType(0); }
public static MethodHandle arrayGet(MethodType type) { Class key = type.parameterType(0); MethodHandle res = getterMap.get(key); if (res!=null) return res; res = buildGetter(key); res = MethodHandles.explicitCastArguments(res, type); return res; }
/** * Apply a transformer as filter. * The filter may not match exactly in the types. In this case needed * additional type transformations are done by {@link MethodHandle#asType(MethodType)} */ public static MethodHandle applyUnsharpFilter(MethodHandle handle, int pos, MethodHandle transformer) { MethodType type = transformer.type(); Class given = handle.type().parameterType(pos); if (type.returnType() != given || type.parameterType(0) != given) { transformer = transformer.asType(MethodType.methodType(given, type.parameterType(0))); } return MethodHandles.filterArguments(handle, pos, transformer); }
public static MethodHandle arraySet(MethodType type) { Class key = type.parameterType(0); MethodHandle res = setterMap.get(key); if (res!=null) return res; res = buildSetter(key); res = MethodHandles.explicitCastArguments(res, type); return res; } }
/** * Gives a replacement receiver for null. * In case of the receiver being null we want to do the method * invocation on NullObject instead. */ public void correctNullReceiver() { if (args[0]!=null) return; handle = handle.bindTo(NullObject.getNullObject()); handle = MethodHandles.dropArguments(handle, 0, targetType.parameterType(0)); if (LOG_ENABLED) LOG.info("binding null object receiver and dropping old receiver"); }
private MethodHandle getMethodHandle(Method method) { MethodHandle methodHandle = methodHandle(FUNCTION_IMPLEMENTATION_ERROR, method); if (!isStatic(method.getModifiers())) { // Change type of "this" argument to Object to make sure callers won't have classloader issues methodHandle = methodHandle.asType(methodHandle.type().changeParameterType(0, Object.class)); // Re-arrange the parameters, so that the "this" parameter is after the meta parameters int[] permutedIndices = new int[methodHandle.type().parameterCount()]; permutedIndices[0] = dependencies.size(); MethodType newType = methodHandle.type().changeParameterType(dependencies.size(), methodHandle.type().parameterType(0)); for (int i = 0; i < dependencies.size(); i++) { permutedIndices[i + 1] = i; newType = newType.changeParameterType(i, methodHandle.type().parameterType(i + 1)); } for (int i = dependencies.size() + 1; i < permutedIndices.length; i++) { permutedIndices[i] = i; } methodHandle = permuteArguments(methodHandle, newType, permutedIndices); } return methodHandle; }
public CastSelector(MutableCallSite callSite, Object[] arguments) { super(callSite, Selector.class, "", CALL_TYPES.CAST, false, false, false, arguments); this.staticSourceType = callSite.type().parameterType(0); this.staticTargetType = callSite.type().returnType(); }
/** * @param f (U, S1, S2, ..., Sm)R * @param g (T1, T2, ..., Tn)U * @return (T1, T2, ..., Tn, S1, S2, ..., Sm)R */ public static MethodHandle compose(MethodHandle f, MethodHandle g) { if (f.type().parameterType(0) != g.type().returnType()) { throw new IllegalArgumentException(format("f.parameter(0) != g.return(). f: %s g: %s", f.type(), g.type())); } // Semantics: f => f // Type: (U, S1, S2, ..., Sn)R => (U, T1, T2, ..., Tm, S1, S2, ..., Sn)R MethodHandle fUTS = MethodHandles.dropArguments(f, 1, g.type().parameterList()); // Semantics: f => fg // Type: (U, T1, T2, ..., Tm, S1, S2, ..., Sn)R => (T1, T2, ..., Tm, S1, S2, ..., Sn)R return MethodHandles.foldArguments(fUTS, g); }
if (method.type().parameterCount() > 0 && method.type().parameterType(0) == ConnectorSession.class) { method = method.bindTo(session); boolean isNull = argument == null; if (isNull) { argument = Defaults.defaultValue(method.type().parameterType(actualArguments.size()));
/** * @param f (U, S1, S2, ..., Sm)R * @param g (T1, T2, ..., Tn)U * @return (T1, T2, ..., Tn, S1, S2, ..., Sm)R */ public static MethodHandle compose(MethodHandle f, MethodHandle g) { if (f.type().parameterType(0) != g.type().returnType()) { throw new IllegalArgumentException(format("f.parameter(0) != g.return(). f: %s g: %s", f.type(), g.type())); } // Semantics: f => f // Type: (U, S1, S2, ..., Sn)R => (U, T1, T2, ..., Tm, S1, S2, ..., Sn)R MethodHandle fUTS = MethodHandles.dropArguments(f, 1, g.type().parameterList()); // Semantics: f => fg // Type: (U, T1, T2, ..., Tm, S1, S2, ..., Sn)R => (T1, T2, ..., Tm, S1, S2, ..., Sn)R return MethodHandles.foldArguments(fUTS, g); }
if ((values[i] == null) && methodType.parameterType(i).isPrimitive()) { String name = procedure.getArguments().get(i).getName(); throw new PrestoException(INVALID_PROCEDURE_ARGUMENT, "Procedure argument cannot be null: " + name);
con = MethodHandles.dropArguments(con, 1, targetType.parameterType(1)); foldTargetType = foldTargetType.insertParameterTypes(0, targetType.parameterType(1));
MethodHandle method = function.getMethodHandle(); if (method.type().parameterCount() > 0 && method.type().parameterType(0) == ConnectorSession.class) { method = method.bindTo(session);
/** * Widens the operators. For math operations like a+b we generally * execute them using a conversion to certain types. If a for example * is an int and b a byte, we do the operation using integer math. This * method gives a simplified MethodType that contains the two operators * with this widening according to Groovy rules applied. That means both * parameters in the MethodType will have the same type. */ private static MethodType widenOperators(MethodType mt) { if (mt.parameterCount()==2) { Class leftType = mt.parameterType(0); Class rightType = mt.parameterType(1); if (isIntCategory(leftType) && isIntCategory(rightType)) return IIV; if (isLongCategory(leftType) && isLongCategory(rightType)) return LLV; if (isBigDecCategory(leftType) && isBigDecCategory(rightType)) return GGV; if (isDoubleCategory(leftType) && isDoubleCategory(rightType)) return DDV; return OOV; } else if (mt.parameterCount()==1) { Class leftType = mt.parameterType(0); if (isIntCategory(leftType)) return IV; if (isLongCategory(leftType)) return LV; if (isBigDecCategory(leftType)) return GV; if (isDoubleCategory(leftType)) return DV; } return mt; }
throw new IllegalArgumentException(format("f.parameterCount != 2. f: %s", f.type())); if (f.type().parameterType(0) != g.type().returnType()) { throw new IllegalArgumentException(format("f.parameter(0) != g.return. f: %s g: %s", f.type(), g.type())); if (f.type().parameterType(1) != h.type().returnType()) { throw new IllegalArgumentException(format("f.parameter(0) != h.return. f: %s h: %s", f.type(), h.type())); MethodType typeVTU = f.type().dropParameterTypes(0, 1).appendParameterTypes(h.type().parameterList()).appendParameterTypes(f.type().parameterType(0));
throw new IllegalArgumentException(format("f.parameterCount != 2. f: %s", f.type())); if (f.type().parameterType(0) != g.type().returnType()) { throw new IllegalArgumentException(format("f.parameter(0) != g.return. f: %s g: %s", f.type(), g.type())); if (f.type().parameterType(1) != h.type().returnType()) { throw new IllegalArgumentException(format("f.parameter(0) != h.return. f: %s h: %s", f.type(), h.type())); MethodType typeVTU = f.type().dropParameterTypes(0, 1).appendParameterTypes(h.type().parameterList()).appendParameterTypes(f.type().parameterType(0));
private static MethodHandle bindCallSite(MethodCallSite site) throws IllegalAccessException { MethodHandle mh = RobolectricInternals.findShadowMethodHandle(site.getTheClass(), site.getName(), site.type(), site.isStatic()); if (mh == null) { // call original code mh = site.getOriginal(); } else if (mh == ShadowWrangler.DO_NOTHING) { // no-op mh = dropArguments(mh, 0, site.type().parameterList()); } else if (!site.isStatic()) { // drop arg 0 (this) for static methods Class<?> shadowType = mh.type().parameterType(0); mh = filterArguments(mh, 0, GET_SHADOW.asType(methodType(shadowType, site.thisType()))); } try { return bindWithFallback(site, cleanStackTraces(mh), BIND_CALL_SITE); } catch (Throwable t) { // The error that bubbles up is currently not very helpful so we print any error messages // here t.printStackTrace(); System.err.println(site.getTheClass()); throw t; } }
@Override protected Object visitArithmeticUnary(ArithmeticUnaryExpression node, Object context) { Object value = process(node.getValue(), context); if (value == null) { return null; } if (value instanceof Expression) { return new ArithmeticUnaryExpression(node.getSign(), toExpression(value, type(node.getValue()))); } switch (node.getSign()) { case PLUS: return value; case MINUS: Signature operatorSignature = metadata.getFunctionRegistry().resolveOperator(OperatorType.NEGATION, types(node.getValue())); MethodHandle handle = metadata.getFunctionRegistry().getScalarFunctionImplementation(operatorSignature).getMethodHandle(); if (handle.type().parameterCount() > 0 && handle.type().parameterType(0) == ConnectorSession.class) { handle = handle.bindTo(session); } try { return handle.invokeWithArguments(value); } catch (Throwable throwable) { throwIfInstanceOf(throwable, RuntimeException.class); throwIfInstanceOf(throwable, Error.class); throw new RuntimeException(throwable.getMessage(), throwable); } } throw new UnsupportedOperationException("Unsupported unary operator: " + node.getSign()); }