jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleImpl.java
changeset 26466 3bbb6a284bd4
parent 26465 5ff735dd0d52
child 26467 d69abed3a07d
equal deleted inserted replaced
26465:5ff735dd0d52 26466:3bbb6a284bd4
    25 
    25 
    26 package java.lang.invoke;
    26 package java.lang.invoke;
    27 
    27 
    28 import java.security.AccessController;
    28 import java.security.AccessController;
    29 import java.security.PrivilegedAction;
    29 import java.security.PrivilegedAction;
       
    30 import java.util.ArrayList;
    30 import java.util.Arrays;
    31 import java.util.Arrays;
    31 import java.util.HashMap;
    32 import java.util.Collections;
       
    33 import java.util.List;
       
    34 
    32 import sun.invoke.empty.Empty;
    35 import sun.invoke.empty.Empty;
    33 import sun.invoke.util.ValueConversions;
    36 import sun.invoke.util.ValueConversions;
    34 import sun.invoke.util.VerifyType;
    37 import sun.invoke.util.VerifyType;
    35 import sun.invoke.util.Wrapper;
    38 import sun.invoke.util.Wrapper;
    36 import sun.reflect.CallerSensitive;
    39 import sun.reflect.CallerSensitive;
    42 /**
    45 /**
    43  * Trusted implementation code for MethodHandle.
    46  * Trusted implementation code for MethodHandle.
    44  * @author jrose
    47  * @author jrose
    45  */
    48  */
    46 /*non-public*/ abstract class MethodHandleImpl {
    49 /*non-public*/ abstract class MethodHandleImpl {
       
    50     // Do not adjust this except for special platforms:
       
    51     private static final int MAX_ARITY;
       
    52     static {
       
    53         final Object[] values = { 255 };
       
    54         AccessController.doPrivileged(new PrivilegedAction<Void>() {
       
    55             @Override
       
    56             public Void run() {
       
    57                 values[0] = Integer.getInteger(MethodHandleImpl.class.getName()+".MAX_ARITY", 255);
       
    58                 return null;
       
    59             }
       
    60         });
       
    61         MAX_ARITY = (Integer) values[0];
       
    62     }
       
    63 
    47     /// Factory methods to create method handles:
    64     /// Factory methods to create method handles:
    48 
    65 
    49     static void initStatics() {
    66     static void initStatics() {
    50         // Trigger selected static initializations.
    67         // Trigger selected static initializations.
    51         MemberName.Factory.INSTANCE.getClass();
    68         MemberName.Factory.INSTANCE.getClass();
   514         static final NamedFunction NF_guardWithCatch;
   531         static final NamedFunction NF_guardWithCatch;
   515         static final NamedFunction NF_selectAlternative;
   532         static final NamedFunction NF_selectAlternative;
   516         static final NamedFunction NF_throwException;
   533         static final NamedFunction NF_throwException;
   517 
   534 
   518         static final MethodHandle MH_castReference;
   535         static final MethodHandle MH_castReference;
       
   536         static final MethodHandle MH_copyAsPrimitiveArray;
       
   537         static final MethodHandle MH_copyAsReferenceArray;
       
   538         static final MethodHandle MH_fillNewTypedArray;
       
   539         static final MethodHandle MH_fillNewArray;
       
   540         static final MethodHandle MH_arrayIdentity;
   519 
   541 
   520         static {
   542         static {
   521             try {
   543             try {
   522                 NF_checkSpreadArgument = new NamedFunction(MHI.getDeclaredMethod("checkSpreadArgument", Object.class, int.class));
   544                 NF_checkSpreadArgument = new NamedFunction(MHI.getDeclaredMethod("checkSpreadArgument", Object.class, int.class));
   523                 NF_guardWithCatch      = new NamedFunction(MHI.getDeclaredMethod("guardWithCatch", MethodHandle.class, Class.class,
   545                 NF_guardWithCatch      = new NamedFunction(MHI.getDeclaredMethod("guardWithCatch", MethodHandle.class, Class.class,
   529                 NF_checkSpreadArgument.resolve();
   551                 NF_checkSpreadArgument.resolve();
   530                 NF_guardWithCatch.resolve();
   552                 NF_guardWithCatch.resolve();
   531                 NF_selectAlternative.resolve();
   553                 NF_selectAlternative.resolve();
   532                 NF_throwException.resolve();
   554                 NF_throwException.resolve();
   533 
   555 
   534                 MethodType mt = MethodType.methodType(Object.class, Class.class, Object.class);
   556                 MH_castReference        = IMPL_LOOKUP.findStatic(MHI, "castReference",
   535                 MH_castReference = IMPL_LOOKUP.findStatic(MHI, "castReference", mt);
   557                                             MethodType.methodType(Object.class, Class.class, Object.class));
       
   558                 MH_copyAsPrimitiveArray = IMPL_LOOKUP.findStatic(MHI, "copyAsPrimitiveArray",
       
   559                                             MethodType.methodType(Object.class, Wrapper.class, Object[].class));
       
   560                 MH_copyAsReferenceArray = IMPL_LOOKUP.findStatic(MHI, "copyAsReferenceArray",
       
   561                                             MethodType.methodType(Object[].class, Class.class, Object[].class));
       
   562                 MH_arrayIdentity        = IMPL_LOOKUP.findStatic(MHI, "identity",
       
   563                                             MethodType.methodType(Object[].class, Object[].class));
       
   564                 MH_fillNewArray         = IMPL_LOOKUP.findStatic(MHI, "fillNewArray",
       
   565                                             MethodType.methodType(Object[].class, Integer.class, Object[].class));
       
   566                 MH_fillNewTypedArray    = IMPL_LOOKUP.findStatic(MHI, "fillNewTypedArray",
       
   567                                             MethodType.methodType(Object[].class, Object[].class, Integer.class, Object[].class));
   536             } catch (ReflectiveOperationException ex) {
   568             } catch (ReflectiveOperationException ex) {
   537                 throw newInternalError(ex);
   569                 throw newInternalError(ex);
   538             }
   570             }
   539         }
   571         }
   540     }
   572     }
   711         LambdaForm form = makeGuardWithCatchForm(type.basicType());
   743         LambdaForm form = makeGuardWithCatchForm(type.basicType());
   712 
   744 
   713         // Prepare auxiliary method handles used during LambdaForm interpretation.
   745         // Prepare auxiliary method handles used during LambdaForm interpretation.
   714         // Box arguments and wrap them into Object[]: ValueConversions.array().
   746         // Box arguments and wrap them into Object[]: ValueConversions.array().
   715         MethodType varargsType = type.changeReturnType(Object[].class);
   747         MethodType varargsType = type.changeReturnType(Object[].class);
   716         MethodHandle collectArgs = ValueConversions.varargsArray(type.parameterCount())
   748         MethodHandle collectArgs = varargsArray(type.parameterCount()).asType(varargsType);
   717                                                    .asType(varargsType);
       
   718         // Result unboxing: ValueConversions.unbox() OR ValueConversions.identity() OR ValueConversions.ignore().
   749         // Result unboxing: ValueConversions.unbox() OR ValueConversions.identity() OR ValueConversions.ignore().
   719         MethodHandle unboxResult;
   750         MethodHandle unboxResult;
   720         if (type.returnType().isPrimitive()) {
   751         if (type.returnType().isPrimitive()) {
   721             unboxResult = ValueConversions.unbox(type.returnType());
   752             unboxResult = ValueConversions.unbox(type.returnType());
   722         } else {
   753         } else {
   997         if (member.equals(target.internalMemberName()))
  1028         if (member.equals(target.internalMemberName()))
   998             return target;
  1029             return target;
   999         return new WrappedMember(target, target.type(), member, null);
  1030         return new WrappedMember(target, target.type(), member, null);
  1000     }
  1031     }
  1001 
  1032 
       
  1033     /// Collection of multiple arguments.
       
  1034 
       
  1035     private static MethodHandle findCollector(String name, int nargs, Class<?> rtype, Class<?>... ptypes) {
       
  1036         MethodType type = MethodType.genericMethodType(nargs)
       
  1037                 .changeReturnType(rtype)
       
  1038                 .insertParameterTypes(0, ptypes);
       
  1039         try {
       
  1040             return IMPL_LOOKUP.findStatic(MethodHandleImpl.class, name, type);
       
  1041         } catch (ReflectiveOperationException ex) {
       
  1042             return null;
       
  1043         }
       
  1044     }
       
  1045 
       
  1046     private static final Object[] NO_ARGS_ARRAY = {};
       
  1047     private static Object[] makeArray(Object... args) { return args; }
       
  1048     private static Object[] array() { return NO_ARGS_ARRAY; }
       
  1049     private static Object[] array(Object a0)
       
  1050                 { return makeArray(a0); }
       
  1051     private static Object[] array(Object a0, Object a1)
       
  1052                 { return makeArray(a0, a1); }
       
  1053     private static Object[] array(Object a0, Object a1, Object a2)
       
  1054                 { return makeArray(a0, a1, a2); }
       
  1055     private static Object[] array(Object a0, Object a1, Object a2, Object a3)
       
  1056                 { return makeArray(a0, a1, a2, a3); }
       
  1057     private static Object[] array(Object a0, Object a1, Object a2, Object a3,
       
  1058                                   Object a4)
       
  1059                 { return makeArray(a0, a1, a2, a3, a4); }
       
  1060     private static Object[] array(Object a0, Object a1, Object a2, Object a3,
       
  1061                                   Object a4, Object a5)
       
  1062                 { return makeArray(a0, a1, a2, a3, a4, a5); }
       
  1063     private static Object[] array(Object a0, Object a1, Object a2, Object a3,
       
  1064                                   Object a4, Object a5, Object a6)
       
  1065                 { return makeArray(a0, a1, a2, a3, a4, a5, a6); }
       
  1066     private static Object[] array(Object a0, Object a1, Object a2, Object a3,
       
  1067                                   Object a4, Object a5, Object a6, Object a7)
       
  1068                 { return makeArray(a0, a1, a2, a3, a4, a5, a6, a7); }
       
  1069     private static Object[] array(Object a0, Object a1, Object a2, Object a3,
       
  1070                                   Object a4, Object a5, Object a6, Object a7,
       
  1071                                   Object a8)
       
  1072                 { return makeArray(a0, a1, a2, a3, a4, a5, a6, a7, a8); }
       
  1073     private static Object[] array(Object a0, Object a1, Object a2, Object a3,
       
  1074                                   Object a4, Object a5, Object a6, Object a7,
       
  1075                                   Object a8, Object a9)
       
  1076                 { return makeArray(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); }
       
  1077     private static MethodHandle[] makeArrays() {
       
  1078         ArrayList<MethodHandle> mhs = new ArrayList<>();
       
  1079         for (;;) {
       
  1080             MethodHandle mh = findCollector("array", mhs.size(), Object[].class);
       
  1081             if (mh == null)  break;
       
  1082             mhs.add(mh);
       
  1083         }
       
  1084         assert(mhs.size() == 11);  // current number of methods
       
  1085         return mhs.toArray(new MethodHandle[MAX_ARITY+1]);
       
  1086     }
       
  1087     private static final MethodHandle[] ARRAYS = makeArrays();
       
  1088 
       
  1089     // filling versions of the above:
       
  1090     // using Integer len instead of int len and no varargs to avoid bootstrapping problems
       
  1091     private static Object[] fillNewArray(Integer len, Object[] /*not ...*/ args) {
       
  1092         Object[] a = new Object[len];
       
  1093         fillWithArguments(a, 0, args);
       
  1094         return a;
       
  1095     }
       
  1096     private static Object[] fillNewTypedArray(Object[] example, Integer len, Object[] /*not ...*/ args) {
       
  1097         Object[] a = Arrays.copyOf(example, len);
       
  1098         fillWithArguments(a, 0, args);
       
  1099         return a;
       
  1100     }
       
  1101     private static void fillWithArguments(Object[] a, int pos, Object... args) {
       
  1102         System.arraycopy(args, 0, a, pos, args.length);
       
  1103     }
       
  1104     // using Integer pos instead of int pos to avoid bootstrapping problems
       
  1105     private static Object[] fillArray(Integer pos, Object[] a, Object a0)
       
  1106                 { fillWithArguments(a, pos, a0); return a; }
       
  1107     private static Object[] fillArray(Integer pos, Object[] a, Object a0, Object a1)
       
  1108                 { fillWithArguments(a, pos, a0, a1); return a; }
       
  1109     private static Object[] fillArray(Integer pos, Object[] a, Object a0, Object a1, Object a2)
       
  1110                 { fillWithArguments(a, pos, a0, a1, a2); return a; }
       
  1111     private static Object[] fillArray(Integer pos, Object[] a, Object a0, Object a1, Object a2, Object a3)
       
  1112                 { fillWithArguments(a, pos, a0, a1, a2, a3); return a; }
       
  1113     private static Object[] fillArray(Integer pos, Object[] a, Object a0, Object a1, Object a2, Object a3,
       
  1114                                   Object a4)
       
  1115                 { fillWithArguments(a, pos, a0, a1, a2, a3, a4); return a; }
       
  1116     private static Object[] fillArray(Integer pos, Object[] a, Object a0, Object a1, Object a2, Object a3,
       
  1117                                   Object a4, Object a5)
       
  1118                 { fillWithArguments(a, pos, a0, a1, a2, a3, a4, a5); return a; }
       
  1119     private static Object[] fillArray(Integer pos, Object[] a, Object a0, Object a1, Object a2, Object a3,
       
  1120                                   Object a4, Object a5, Object a6)
       
  1121                 { fillWithArguments(a, pos, a0, a1, a2, a3, a4, a5, a6); return a; }
       
  1122     private static Object[] fillArray(Integer pos, Object[] a, Object a0, Object a1, Object a2, Object a3,
       
  1123                                   Object a4, Object a5, Object a6, Object a7)
       
  1124                 { fillWithArguments(a, pos, a0, a1, a2, a3, a4, a5, a6, a7); return a; }
       
  1125     private static Object[] fillArray(Integer pos, Object[] a, Object a0, Object a1, Object a2, Object a3,
       
  1126                                   Object a4, Object a5, Object a6, Object a7,
       
  1127                                   Object a8)
       
  1128                 { fillWithArguments(a, pos, a0, a1, a2, a3, a4, a5, a6, a7, a8); return a; }
       
  1129     private static Object[] fillArray(Integer pos, Object[] a, Object a0, Object a1, Object a2, Object a3,
       
  1130                                   Object a4, Object a5, Object a6, Object a7,
       
  1131                                   Object a8, Object a9)
       
  1132                 { fillWithArguments(a, pos, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); return a; }
       
  1133     private static MethodHandle[] makeFillArrays() {
       
  1134         ArrayList<MethodHandle> mhs = new ArrayList<>();
       
  1135         mhs.add(null);  // there is no empty fill; at least a0 is required
       
  1136         for (;;) {
       
  1137             MethodHandle mh = findCollector("fillArray", mhs.size(), Object[].class, Integer.class, Object[].class);
       
  1138             if (mh == null)  break;
       
  1139             mhs.add(mh);
       
  1140         }
       
  1141         assert(mhs.size() == 11);  // current number of methods
       
  1142         return mhs.toArray(new MethodHandle[0]);
       
  1143     }
       
  1144     private static final MethodHandle[] FILL_ARRAYS = makeFillArrays();
       
  1145 
       
  1146     private static Object[] copyAsReferenceArray(Class<? extends Object[]> arrayType, Object... a) {
       
  1147         return Arrays.copyOf(a, a.length, arrayType);
       
  1148     }
       
  1149     private static Object copyAsPrimitiveArray(Wrapper w, Object... boxes) {
       
  1150         Object a = w.makeArray(boxes.length);
       
  1151         w.copyArrayUnboxing(boxes, 0, a, 0, boxes.length);
       
  1152         return a;
       
  1153     }
       
  1154 
       
  1155     /** Return a method handle that takes the indicated number of Object
       
  1156      *  arguments and returns an Object array of them, as if for varargs.
       
  1157      */
       
  1158     static MethodHandle varargsArray(int nargs) {
       
  1159         MethodHandle mh = ARRAYS[nargs];
       
  1160         if (mh != null)  return mh;
       
  1161         mh = findCollector("array", nargs, Object[].class);
       
  1162         if (mh != null)  return ARRAYS[nargs] = mh;
       
  1163         mh = buildVarargsArray(Lazy.MH_fillNewArray, Lazy.MH_arrayIdentity, nargs);
       
  1164         assert(assertCorrectArity(mh, nargs));
       
  1165         return ARRAYS[nargs] = mh;
       
  1166     }
       
  1167 
       
  1168     private static boolean assertCorrectArity(MethodHandle mh, int arity) {
       
  1169         assert(mh.type().parameterCount() == arity) : "arity != "+arity+": "+mh;
       
  1170         return true;
       
  1171     }
       
  1172 
       
  1173     // Array identity function (used as Lazy.MH_arrayIdentity).
       
  1174     static <T> T[] identity(T[] x) {
       
  1175         return x;
       
  1176     }
       
  1177 
       
  1178     private static MethodHandle buildVarargsArray(MethodHandle newArray, MethodHandle finisher, int nargs) {
       
  1179         // Build up the result mh as a sequence of fills like this:
       
  1180         //   finisher(fill(fill(newArrayWA(23,x1..x10),10,x11..x20),20,x21..x23))
       
  1181         // The various fill(_,10*I,___*[J]) are reusable.
       
  1182         int leftLen = Math.min(nargs, LEFT_ARGS);  // absorb some arguments immediately
       
  1183         int rightLen = nargs - leftLen;
       
  1184         MethodHandle leftCollector = newArray.bindTo(nargs);
       
  1185         leftCollector = leftCollector.asCollector(Object[].class, leftLen);
       
  1186         MethodHandle mh = finisher;
       
  1187         if (rightLen > 0) {
       
  1188             MethodHandle rightFiller = fillToRight(LEFT_ARGS + rightLen);
       
  1189             if (mh == Lazy.MH_arrayIdentity)
       
  1190                 mh = rightFiller;
       
  1191             else
       
  1192                 mh = MethodHandles.collectArguments(mh, 0, rightFiller);
       
  1193         }
       
  1194         if (mh == Lazy.MH_arrayIdentity)
       
  1195             mh = leftCollector;
       
  1196         else
       
  1197             mh = MethodHandles.collectArguments(mh, 0, leftCollector);
       
  1198         return mh;
       
  1199     }
       
  1200 
       
  1201     private static final int LEFT_ARGS = (FILL_ARRAYS.length - 1);
       
  1202     private static final MethodHandle[] FILL_ARRAY_TO_RIGHT = new MethodHandle[MAX_ARITY+1];
       
  1203     /** fill_array_to_right(N).invoke(a, argL..arg[N-1])
       
  1204      *  fills a[L]..a[N-1] with corresponding arguments,
       
  1205      *  and then returns a.  The value L is a global constant (LEFT_ARGS).
       
  1206      */
       
  1207     private static MethodHandle fillToRight(int nargs) {
       
  1208         MethodHandle filler = FILL_ARRAY_TO_RIGHT[nargs];
       
  1209         if (filler != null)  return filler;
       
  1210         filler = buildFiller(nargs);
       
  1211         assert(assertCorrectArity(filler, nargs - LEFT_ARGS + 1));
       
  1212         return FILL_ARRAY_TO_RIGHT[nargs] = filler;
       
  1213     }
       
  1214     private static MethodHandle buildFiller(int nargs) {
       
  1215         if (nargs <= LEFT_ARGS)
       
  1216             return Lazy.MH_arrayIdentity;  // no args to fill; return the array unchanged
       
  1217         // we need room for both mh and a in mh.invoke(a, arg*[nargs])
       
  1218         final int CHUNK = LEFT_ARGS;
       
  1219         int rightLen = nargs % CHUNK;
       
  1220         int midLen = nargs - rightLen;
       
  1221         if (rightLen == 0) {
       
  1222             midLen = nargs - (rightLen = CHUNK);
       
  1223             if (FILL_ARRAY_TO_RIGHT[midLen] == null) {
       
  1224                 // build some precursors from left to right
       
  1225                 for (int j = LEFT_ARGS % CHUNK; j < midLen; j += CHUNK)
       
  1226                     if (j > LEFT_ARGS)  fillToRight(j);
       
  1227             }
       
  1228         }
       
  1229         if (midLen < LEFT_ARGS) rightLen = nargs - (midLen = LEFT_ARGS);
       
  1230         assert(rightLen > 0);
       
  1231         MethodHandle midFill = fillToRight(midLen);  // recursive fill
       
  1232         MethodHandle rightFill = FILL_ARRAYS[rightLen].bindTo(midLen);  // [midLen..nargs-1]
       
  1233         assert(midFill.type().parameterCount()   == 1 + midLen - LEFT_ARGS);
       
  1234         assert(rightFill.type().parameterCount() == 1 + rightLen);
       
  1235 
       
  1236         // Combine the two fills:
       
  1237         //   right(mid(a, x10..x19), x20..x23)
       
  1238         // The final product will look like this:
       
  1239         //   right(mid(newArrayLeft(24, x0..x9), x10..x19), x20..x23)
       
  1240         if (midLen == LEFT_ARGS)
       
  1241             return rightFill;
       
  1242         else
       
  1243             return MethodHandles.collectArguments(rightFill, 0, midFill);
       
  1244     }
       
  1245 
       
  1246     // Type-polymorphic version of varargs maker.
       
  1247     private static final ClassValue<MethodHandle[]> TYPED_COLLECTORS
       
  1248         = new ClassValue<MethodHandle[]>() {
       
  1249             @Override
       
  1250             protected MethodHandle[] computeValue(Class<?> type) {
       
  1251                 return new MethodHandle[256];
       
  1252             }
       
  1253     };
       
  1254 
       
  1255     static final int MAX_JVM_ARITY = 255;  // limit imposed by the JVM
       
  1256 
       
  1257     /** Return a method handle that takes the indicated number of
       
  1258      *  typed arguments and returns an array of them.
       
  1259      *  The type argument is the array type.
       
  1260      */
       
  1261     static MethodHandle varargsArray(Class<?> arrayType, int nargs) {
       
  1262         Class<?> elemType = arrayType.getComponentType();
       
  1263         if (elemType == null)  throw new IllegalArgumentException("not an array: "+arrayType);
       
  1264         // FIXME: Need more special casing and caching here.
       
  1265         if (nargs >= MAX_JVM_ARITY/2 - 1) {
       
  1266             int slots = nargs;
       
  1267             final int MAX_ARRAY_SLOTS = MAX_JVM_ARITY - 1;  // 1 for receiver MH
       
  1268             if (arrayType == double[].class || arrayType == long[].class)
       
  1269                 slots *= 2;
       
  1270             if (slots > MAX_ARRAY_SLOTS)
       
  1271                 throw new IllegalArgumentException("too many arguments: "+arrayType.getSimpleName()+", length "+nargs);
       
  1272         }
       
  1273         if (elemType == Object.class)
       
  1274             return varargsArray(nargs);
       
  1275         // other cases:  primitive arrays, subtypes of Object[]
       
  1276         MethodHandle cache[] = TYPED_COLLECTORS.get(elemType);
       
  1277         MethodHandle mh = nargs < cache.length ? cache[nargs] : null;
       
  1278         if (mh != null)  return mh;
       
  1279         if (elemType.isPrimitive()) {
       
  1280             MethodHandle builder = Lazy.MH_fillNewArray;
       
  1281             MethodHandle producer = buildArrayProducer(arrayType);
       
  1282             mh = buildVarargsArray(builder, producer, nargs);
       
  1283         } else {
       
  1284             @SuppressWarnings("unchecked")
       
  1285             Class<? extends Object[]> objArrayType = (Class<? extends Object[]>) arrayType;
       
  1286             Object[] example = Arrays.copyOf(NO_ARGS_ARRAY, 0, objArrayType);
       
  1287             MethodHandle builder = Lazy.MH_fillNewTypedArray.bindTo(example);
       
  1288             MethodHandle producer = Lazy.MH_arrayIdentity;
       
  1289             mh = buildVarargsArray(builder, producer, nargs);
       
  1290         }
       
  1291         mh = mh.asType(MethodType.methodType(arrayType, Collections.<Class<?>>nCopies(nargs, elemType)));
       
  1292         assert(assertCorrectArity(mh, nargs));
       
  1293         if (nargs < cache.length)
       
  1294             cache[nargs] = mh;
       
  1295         return mh;
       
  1296     }
       
  1297 
       
  1298     private static MethodHandle buildArrayProducer(Class<?> arrayType) {
       
  1299         Class<?> elemType = arrayType.getComponentType();
       
  1300         if (elemType.isPrimitive())
       
  1301             return Lazy.MH_copyAsPrimitiveArray.bindTo(Wrapper.forPrimitiveType(elemType));
       
  1302         else
       
  1303             return Lazy.MH_copyAsReferenceArray.bindTo(arrayType);
       
  1304     }
  1002 }
  1305 }