Java Code Examples for java.lang.invoke.MethodHandles#collectArguments()

The following examples show how to use java.lang.invoke.MethodHandles#collectArguments() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: ValueConversions.java    From openjdk-8-source with GNU General Public License v2.0 6 votes vote down vote up
private static MethodHandle buildVarargsArray(MethodHandle newArray, MethodHandle finisher, int nargs) {
    // Build up the result mh as a sequence of fills like this:
    //   finisher(fill(fill(newArrayWA(23,x1..x10),10,x11..x20),20,x21..x23))
    // The various fill(_,10*I,___*[J]) are reusable.
    int leftLen = Math.min(nargs, LEFT_ARGS);  // absorb some arguments immediately
    int rightLen = nargs - leftLen;
    MethodHandle leftCollector = newArray.bindTo(nargs);
    leftCollector = leftCollector.asCollector(Object[].class, leftLen);
    MethodHandle mh = finisher;
    if (rightLen > 0) {
        MethodHandle rightFiller = fillToRight(LEFT_ARGS + rightLen);
        if (mh == ARRAY_IDENTITY)
            mh = rightFiller;
        else
            mh = MethodHandles.collectArguments(mh, 0, rightFiller);
    }
    if (mh == ARRAY_IDENTITY)
        mh = leftCollector;
    else
        mh = MethodHandles.collectArguments(mh, 0, leftCollector);
    return mh;
}
 
Example 2
Source File: ValueConversions.java    From openjdk-8 with GNU General Public License v2.0 6 votes vote down vote up
private static MethodHandle buildVarargsArray(MethodHandle newArray, MethodHandle finisher, int nargs) {
    // Build up the result mh as a sequence of fills like this:
    //   finisher(fill(fill(newArrayWA(23,x1..x10),10,x11..x20),20,x21..x23))
    // The various fill(_,10*I,___*[J]) are reusable.
    int leftLen = Math.min(nargs, LEFT_ARGS);  // absorb some arguments immediately
    int rightLen = nargs - leftLen;
    MethodHandle leftCollector = newArray.bindTo(nargs);
    leftCollector = leftCollector.asCollector(Object[].class, leftLen);
    MethodHandle mh = finisher;
    if (rightLen > 0) {
        MethodHandle rightFiller = fillToRight(LEFT_ARGS + rightLen);
        if (mh == ARRAY_IDENTITY)
            mh = rightFiller;
        else
            mh = MethodHandles.collectArguments(mh, 0, rightFiller);
    }
    if (mh == ARRAY_IDENTITY)
        mh = leftCollector;
    else
        mh = MethodHandles.collectArguments(mh, 0, leftCollector);
    return mh;
}
 
Example 3
Source File: NativeCalls.java    From es6draft with MIT License 6 votes vote down vote up
private static MethodHandle forSpreadCall(MethodHandle mh, MethodType type) {
    int expectedParameters = mh.type().parameterCount();
    int actualParameters = type.parameterCount();
    if (!mh.isVarargsCollector() || !mh.type().parameterType(expectedParameters - 1).equals(Object[].class)) {
        throw new WrongMethodTypeException("Not Object[] var-args collector");
    }
    if (expectedParameters > actualParameters) {
        throw new WrongMethodTypeException("Too few arguments");
    }
    if (expectedParameters < actualParameters) {
        int fixedCount = actualParameters - expectedParameters;
        int firstFixed = expectedParameters - 1;
        List<Class<?>> fixed = type.parameterList().subList(firstFixed, firstFixed + fixedCount);
        mh = MethodHandles.collectArguments(mh, firstFixed, combineArraysMH);
        mh = MethodHandles.collectArguments(mh, firstFixed, toObjectArray(fixed));
    }
    return mh.asType(type);
}
 
Example 4
Source File: ValueConversions.java    From openjdk-8-source with GNU General Public License v2.0 5 votes vote down vote up
private static MethodHandle buildFiller(int nargs) {
    if (nargs <= LEFT_ARGS)
        return ARRAY_IDENTITY;  // no args to fill; return the array unchanged
    // we need room for both mh and a in mh.invoke(a, arg*[nargs])
    final int CHUNK = LEFT_ARGS;
    int rightLen = nargs % CHUNK;
    int midLen = nargs - rightLen;
    if (rightLen == 0) {
        midLen = nargs - (rightLen = CHUNK);
        if (FILL_ARRAY_TO_RIGHT[midLen] == null) {
            // build some precursors from left to right
            for (int j = LEFT_ARGS % CHUNK; j < midLen; j += CHUNK)
                if (j > LEFT_ARGS)  fillToRight(j);
        }
    }
    if (midLen < LEFT_ARGS) rightLen = nargs - (midLen = LEFT_ARGS);
    assert(rightLen > 0);
    MethodHandle midFill = fillToRight(midLen);  // recursive fill
    MethodHandle rightFill = FILL_ARRAYS[rightLen].bindTo(midLen);  // [midLen..nargs-1]
    assert(midFill.type().parameterCount()   == 1 + midLen - LEFT_ARGS);
    assert(rightFill.type().parameterCount() == 1 + rightLen);

    // Combine the two fills:
    //   right(mid(a, x10..x19), x20..x23)
    // The final product will look like this:
    //   right(mid(newArrayLeft(24, x0..x9), x10..x19), x20..x23)
    if (midLen == LEFT_ARGS)
        return rightFill;
    else
        return MethodHandles.collectArguments(rightFill, 0, midFill);
}
 
Example 5
Source File: ValueConversions.java    From openjdk-8 with GNU General Public License v2.0 5 votes vote down vote up
private static MethodHandle buildFiller(int nargs) {
    if (nargs <= LEFT_ARGS)
        return ARRAY_IDENTITY;  // no args to fill; return the array unchanged
    // we need room for both mh and a in mh.invoke(a, arg*[nargs])
    final int CHUNK = LEFT_ARGS;
    int rightLen = nargs % CHUNK;
    int midLen = nargs - rightLen;
    if (rightLen == 0) {
        midLen = nargs - (rightLen = CHUNK);
        if (FILL_ARRAY_TO_RIGHT[midLen] == null) {
            // build some precursors from left to right
            for (int j = LEFT_ARGS % CHUNK; j < midLen; j += CHUNK)
                if (j > LEFT_ARGS)  fillToRight(j);
        }
    }
    if (midLen < LEFT_ARGS) rightLen = nargs - (midLen = LEFT_ARGS);
    assert(rightLen > 0);
    MethodHandle midFill = fillToRight(midLen);  // recursive fill
    MethodHandle rightFill = FILL_ARRAYS[rightLen].bindTo(midLen);  // [midLen..nargs-1]
    assert(midFill.type().parameterCount()   == 1 + midLen - LEFT_ARGS);
    assert(rightFill.type().parameterCount() == 1 + rightLen);

    // Combine the two fills:
    //   right(mid(a, x10..x19), x20..x23)
    // The final product will look like this:
    //   right(mid(newArrayLeft(24, x0..x9), x10..x19), x20..x23)
    if (midLen == LEFT_ARGS)
        return rightFill;
    else
        return MethodHandles.collectArguments(rightFill, 0, midFill);
}