src/share/classes/java/lang/invoke/MethodHandleImpl.java
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File jdk Sdiff src/share/classes/java/lang/invoke

src/share/classes/java/lang/invoke/MethodHandleImpl.java

Print this page




 418             Class<?> arg = VerifyType.spreadArgElementType(spreadArgType, i);
 419             if (arg == null)  arg = Object.class;
 420             targetType = targetType.changeParameterType(spreadArgPos + i, arg);
 421         }
 422         target = target.asType(targetType);
 423 
 424         MethodType srcType = targetType
 425                 .replaceParameterTypes(spreadArgPos, spreadArgPos + spreadArgCount, spreadArgType);
 426         // Now build a LambdaForm.
 427         MethodType lambdaType = srcType.invokerType();
 428         Name[] names = arguments(spreadArgCount + 2, lambdaType);
 429         int nameCursor = lambdaType.parameterCount();
 430         int[] indexes = new int[targetType.parameterCount()];
 431 
 432         for (int i = 0, argIndex = 1; i < targetType.parameterCount() + 1; i++, argIndex++) {
 433             Class<?> src = lambdaType.parameterType(i);
 434             if (i == spreadArgPos) {
 435                 // Spread the array.
 436                 MethodHandle aload = MethodHandles.arrayElementGetter(spreadArgType);
 437                 Name array = names[argIndex];
 438                 names[nameCursor++] = new Name(NF_checkSpreadArgument, array, spreadArgCount);
 439                 for (int j = 0; j < spreadArgCount; i++, j++) {
 440                     indexes[i] = nameCursor;
 441                     names[nameCursor++] = new Name(aload, array, j);
 442                 }
 443             } else if (i < indexes.length) {
 444                 indexes[i] = argIndex;
 445             }
 446         }
 447         assert(nameCursor == names.length-1);  // leave room for the final call
 448 
 449         // Build argument array for the call.
 450         Name[] targetArgs = new Name[targetType.parameterCount()];
 451         for (int i = 0; i < targetType.parameterCount(); i++) {
 452             int idx = indexes[i];
 453             targetArgs[i] = names[idx];
 454         }
 455         names[names.length - 1] = new Name(target, (Object[]) targetArgs);
 456 
 457         LambdaForm form = new LambdaForm("spread", lambdaType.parameterCount(), names);
 458         return SimpleMethodHandle.make(srcType, form);


 463         // but the actual exception raised by an arity mismatch should be WMTE
 464         final boolean RAISE_RANDOM_EXCEPTIONS = true;  // FIXME: delete in JSR 292 M1
 465         if (av == null) {
 466             if (n == 0)  return;
 467             int len;
 468             if (RAISE_RANDOM_EXCEPTIONS)
 469                 len = ((Object[])av).length;  // throw NPE; but delete this after tests are fixed
 470         } else if (av instanceof Object[]) {
 471             int len = ((Object[])av).length;
 472             if (len == n)  return;
 473         } else {
 474             int len = java.lang.reflect.Array.getLength(av);
 475             if (len == n)  return;
 476         }
 477         // fall through to error:
 478         if (RAISE_RANDOM_EXCEPTIONS)
 479             throw newIllegalArgumentException("Array is not of length "+n);
 480         throw new WrongMethodTypeException("Array is not of length "+n);
 481     }
 482 
 483     private static final NamedFunction NF_checkSpreadArgument;





 484     static {
 485         try {
 486             NF_checkSpreadArgument = new NamedFunction(MethodHandleImpl.class
 487                     .getDeclaredMethod("checkSpreadArgument", Object.class, int.class));
 488             NF_checkSpreadArgument.resolve();
 489         } catch (ReflectiveOperationException ex) {
 490             throw newInternalError(ex);
 491         }
 492     }

 493 
 494     /** Factory method:  Collect or filter selected argument(s). */
 495     static MethodHandle makeCollectArguments(MethodHandle target,
 496                 MethodHandle collector, int collectArgPos, boolean retainOriginalArgs) {
 497         MethodType targetType = target.type();          // (a..., c, [b...])=>r
 498         MethodType collectorType = collector.type();    // (b...)=>c
 499         int collectArgCount = collectorType.parameterCount();
 500         Class<?> collectValType = collectorType.returnType();
 501         int collectValCount = (collectValType == void.class ? 0 : 1);
 502         MethodType srcType = targetType                 // (a..., [b...])=>r
 503                 .dropParameterTypes(collectArgPos, collectArgPos+collectValCount);
 504         if (!retainOriginalArgs) {                      // (a..., b...)=>r
 505             srcType = srcType.insertParameterTypes(collectArgPos, collectorType.parameterList());
 506         }
 507         // in  arglist: [0: ...keep1 | cpos: collect...  | cpos+cacount: keep2... ]
 508         // out arglist: [0: ...keep1 | cpos: collectVal? | cpos+cvcount: keep2... ]
 509         // out(retain): [0: ...keep1 | cpos: cV? coll... | cpos+cvc+cac: keep2... ]
 510 
 511         // Now build a LambdaForm.
 512         MethodType lambdaType = srcType.invokerType();




 418             Class<?> arg = VerifyType.spreadArgElementType(spreadArgType, i);
 419             if (arg == null)  arg = Object.class;
 420             targetType = targetType.changeParameterType(spreadArgPos + i, arg);
 421         }
 422         target = target.asType(targetType);
 423 
 424         MethodType srcType = targetType
 425                 .replaceParameterTypes(spreadArgPos, spreadArgPos + spreadArgCount, spreadArgType);
 426         // Now build a LambdaForm.
 427         MethodType lambdaType = srcType.invokerType();
 428         Name[] names = arguments(spreadArgCount + 2, lambdaType);
 429         int nameCursor = lambdaType.parameterCount();
 430         int[] indexes = new int[targetType.parameterCount()];
 431 
 432         for (int i = 0, argIndex = 1; i < targetType.parameterCount() + 1; i++, argIndex++) {
 433             Class<?> src = lambdaType.parameterType(i);
 434             if (i == spreadArgPos) {
 435                 // Spread the array.
 436                 MethodHandle aload = MethodHandles.arrayElementGetter(spreadArgType);
 437                 Name array = names[argIndex];
 438                 names[nameCursor++] = new Name(NF.checkSpreadArgument, array, spreadArgCount);
 439                 for (int j = 0; j < spreadArgCount; i++, j++) {
 440                     indexes[i] = nameCursor;
 441                     names[nameCursor++] = new Name(aload, array, j);
 442                 }
 443             } else if (i < indexes.length) {
 444                 indexes[i] = argIndex;
 445             }
 446         }
 447         assert(nameCursor == names.length-1);  // leave room for the final call
 448 
 449         // Build argument array for the call.
 450         Name[] targetArgs = new Name[targetType.parameterCount()];
 451         for (int i = 0; i < targetType.parameterCount(); i++) {
 452             int idx = indexes[i];
 453             targetArgs[i] = names[idx];
 454         }
 455         names[names.length - 1] = new Name(target, (Object[]) targetArgs);
 456 
 457         LambdaForm form = new LambdaForm("spread", lambdaType.parameterCount(), names);
 458         return SimpleMethodHandle.make(srcType, form);


 463         // but the actual exception raised by an arity mismatch should be WMTE
 464         final boolean RAISE_RANDOM_EXCEPTIONS = true;  // FIXME: delete in JSR 292 M1
 465         if (av == null) {
 466             if (n == 0)  return;
 467             int len;
 468             if (RAISE_RANDOM_EXCEPTIONS)
 469                 len = ((Object[])av).length;  // throw NPE; but delete this after tests are fixed
 470         } else if (av instanceof Object[]) {
 471             int len = ((Object[])av).length;
 472             if (len == n)  return;
 473         } else {
 474             int len = java.lang.reflect.Array.getLength(av);
 475             if (len == n)  return;
 476         }
 477         // fall through to error:
 478         if (RAISE_RANDOM_EXCEPTIONS)
 479             throw newIllegalArgumentException("Array is not of length "+n);
 480         throw new WrongMethodTypeException("Array is not of length "+n);
 481     }
 482 
 483     /**
 484      * Pre-initialized NamedFunctions for bootstrapping purposes.
 485      * Factored in an inner class to delay initialization until first usage.
 486      */
 487     private static class NF {
 488         static final NamedFunction checkSpreadArgument;
 489         static {
 490             try {
 491                 checkSpreadArgument = new NamedFunction(MethodHandleImpl.class
 492                         .getDeclaredMethod("checkSpreadArgument", Object.class, int.class));
 493                 checkSpreadArgument.resolve();
 494             } catch (ReflectiveOperationException ex) {
 495                 throw newInternalError(ex);
 496             }
 497         }
 498     }
 499 
 500     /** Factory method:  Collect or filter selected argument(s). */
 501     static MethodHandle makeCollectArguments(MethodHandle target,
 502                 MethodHandle collector, int collectArgPos, boolean retainOriginalArgs) {
 503         MethodType targetType = target.type();          // (a..., c, [b...])=>r
 504         MethodType collectorType = collector.type();    // (b...)=>c
 505         int collectArgCount = collectorType.parameterCount();
 506         Class<?> collectValType = collectorType.returnType();
 507         int collectValCount = (collectValType == void.class ? 0 : 1);
 508         MethodType srcType = targetType                 // (a..., [b...])=>r
 509                 .dropParameterTypes(collectArgPos, collectArgPos+collectValCount);
 510         if (!retainOriginalArgs) {                      // (a..., b...)=>r
 511             srcType = srcType.insertParameterTypes(collectArgPos, collectorType.parameterList());
 512         }
 513         // in  arglist: [0: ...keep1 | cpos: collect...  | cpos+cacount: keep2... ]
 514         // out arglist: [0: ...keep1 | cpos: collectVal? | cpos+cvcount: keep2... ]
 515         // out(retain): [0: ...keep1 | cpos: cV? coll... | cpos+cvc+cac: keep2... ]
 516 
 517         // Now build a LambdaForm.
 518         MethodType lambdaType = srcType.invokerType();


src/share/classes/java/lang/invoke/MethodHandleImpl.java
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File