Пример #1
0
  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);
  }
Пример #2
0
 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;
 }