1.1 --- a/rt/emul/compact/src/main/java/java/lang/invoke/BoundMethodHandle.java Sat Aug 09 11:11:13 2014 +0200
1.2 +++ b/rt/emul/compact/src/main/java/java/lang/invoke/BoundMethodHandle.java Sun Aug 10 07:02:12 2014 +0200
1.3 @@ -25,24 +25,16 @@
1.4
1.5 package java.lang.invoke;
1.6
1.7 -import static jdk.internal.org.objectweb.asm.Opcodes.*;
1.8 import static java.lang.invoke.LambdaForm.basicTypes;
1.9 -import static java.lang.invoke.MethodHandleNatives.Constants.REF_invokeStatic;
1.10 import static java.lang.invoke.MethodHandleStatics.*;
1.11
1.12 import java.lang.invoke.LambdaForm.Name;
1.13 import java.lang.invoke.LambdaForm.NamedFunction;
1.14 import java.lang.invoke.MethodHandles.Lookup;
1.15 -import java.lang.reflect.Field;
1.16 import java.util.Arrays;
1.17 import java.util.HashMap;
1.18
1.19 import sun.invoke.util.ValueConversions;
1.20 -import sun.invoke.util.Wrapper;
1.21 -
1.22 -import jdk.internal.org.objectweb.asm.ClassWriter;
1.23 -import jdk.internal.org.objectweb.asm.MethodVisitor;
1.24 -import jdk.internal.org.objectweb.asm.Type;
1.25
1.26 /**
1.27 * The flavor of method handle which emulates an invoke instruction
1.28 @@ -373,8 +365,9 @@
1.29 this.constructor = new MethodHandle[1];
1.30 this.getters = new MethodHandle[types.length()];
1.31 } else {
1.32 - this.constructor = Factory.makeCtors(clazz, types, null);
1.33 - this.getters = Factory.makeGetters(clazz, types, null);
1.34 + throw new IllegalStateException("bound method handle");
1.35 +// this.constructor = Factory.makeCtors(clazz, types, null);
1.36 +// this.getters = Factory.makeGetters(clazz, types, null);
1.37 }
1.38 this.extensions = new SpeciesData[EXTENSION_TYPES.length()];
1.39 }
1.40 @@ -382,8 +375,8 @@
1.41 private void initForBootstrap() {
1.42 assert(!INIT_DONE);
1.43 if (constructor[0] == null) {
1.44 - Factory.makeCtors(clazz, types, this.constructor);
1.45 - Factory.makeGetters(clazz, types, this.getters);
1.46 +// Factory.makeCtors(clazz, types, this.constructor);
1.47 +// Factory.makeGetters(clazz, types, this.getters);
1.48 }
1.49 }
1.50
1.51 @@ -425,7 +418,7 @@
1.52 // Use synch. on the placeholder to prevent multiple instantiation of one species.
1.53 // Creating this class forces a recursive call to getForClass.
1.54 if (lookupCache(types).isPlaceholder())
1.55 - Factory.generateConcreteBMHClass(types);
1.56 + throw new IllegalStateException("Cannot generate anything");
1.57 }
1.58 // Reacquire cache lock.
1.59 d = lookupCache(types);
1.60 @@ -459,6 +452,7 @@
1.61 SpeciesData d0 = BoundMethodHandle.SPECIES_DATA; // trigger class init
1.62 assert(d0 == null || d0 == lookupCache("")) : d0;
1.63 try {
1.64 + /*
1.65 for (Class<?> c : rootCls.getDeclaredClasses()) {
1.66 if (rootCls.isAssignableFrom(c)) {
1.67 final Class<? extends BoundMethodHandle> cbmh = c.asSubclass(BoundMethodHandle.class);
1.68 @@ -468,6 +462,7 @@
1.69 assert(d == lookupCache(d.types));
1.70 }
1.71 }
1.72 + */
1.73 } catch (Throwable e) {
1.74 throw newInternalError(e);
1.75 }
1.76 @@ -485,375 +480,7 @@
1.77 return SpeciesData.get(types);
1.78 }
1.79
1.80 - /**
1.81 - * Generation of concrete BMH classes.
1.82 - *
1.83 - * A concrete BMH species is fit for binding a number of values adhering to a
1.84 - * given type pattern. Reference types are erased.
1.85 - *
1.86 - * BMH species are cached by type pattern.
1.87 - *
1.88 - * A BMH species has a number of fields with the concrete (possibly erased) types of
1.89 - * bound values. Setters are provided as an API in BMH. Getters are exposed as MHs,
1.90 - * which can be included as names in lambda forms.
1.91 - */
1.92 - static class Factory {
1.93
1.94 - static final String JLO_SIG = "Ljava/lang/Object;";
1.95 - static final String JLS_SIG = "Ljava/lang/String;";
1.96 - static final String JLC_SIG = "Ljava/lang/Class;";
1.97 - static final String MH = "java/lang/invoke/MethodHandle";
1.98 - static final String MH_SIG = "L"+MH+";";
1.99 - static final String BMH = "java/lang/invoke/BoundMethodHandle";
1.100 - static final String BMH_SIG = "L"+BMH+";";
1.101 - static final String SPECIES_DATA = "java/lang/invoke/BoundMethodHandle$SpeciesData";
1.102 - static final String SPECIES_DATA_SIG = "L"+SPECIES_DATA+";";
1.103 -
1.104 - static final String SPECIES_PREFIX_NAME = "Species_";
1.105 - static final String SPECIES_PREFIX_PATH = BMH + "$" + SPECIES_PREFIX_NAME;
1.106 -
1.107 - static final String BMHSPECIES_DATA_EWI_SIG = "(B)" + SPECIES_DATA_SIG;
1.108 - static final String BMHSPECIES_DATA_GFC_SIG = "(" + JLS_SIG + JLC_SIG + ")" + SPECIES_DATA_SIG;
1.109 - static final String MYSPECIES_DATA_SIG = "()" + SPECIES_DATA_SIG;
1.110 - static final String VOID_SIG = "()V";
1.111 -
1.112 - static final String SIG_INCIPIT = "(Ljava/lang/invoke/MethodType;Ljava/lang/invoke/LambdaForm;";
1.113 -
1.114 - static final Class<?>[] TYPES = new Class<?>[] { Object.class, int.class, long.class, float.class, double.class };
1.115 -
1.116 - static final String[] E_THROWABLE = new String[] { "java/lang/Throwable" };
1.117 -
1.118 - /**
1.119 - * Generate a concrete subclass of BMH for a given combination of bound types.
1.120 - *
1.121 - * A concrete BMH species adheres to the following schema:
1.122 - *
1.123 - * <pre>
1.124 - * class Species_[[types]] extends BoundMethodHandle {
1.125 - * [[fields]]
1.126 - * final SpeciesData speciesData() { return SpeciesData.get("[[types]]"); }
1.127 - * }
1.128 - * </pre>
1.129 - *
1.130 - * The {@code [[types]]} signature is precisely the string that is passed to this
1.131 - * method.
1.132 - *
1.133 - * The {@code [[fields]]} section consists of one field definition per character in
1.134 - * the type signature, adhering to the naming schema described in the definition of
1.135 - * {@link #makeFieldName}.
1.136 - *
1.137 - * For example, a concrete BMH species for two reference and one integral bound values
1.138 - * would have the following shape:
1.139 - *
1.140 - * <pre>
1.141 - * class BoundMethodHandle { ... private static
1.142 - * final class Species_LLI extends BoundMethodHandle {
1.143 - * final Object argL0;
1.144 - * final Object argL1;
1.145 - * final int argI2;
1.146 - * public Species_LLI(MethodType mt, LambdaForm lf, Object argL0, Object argL1, int argI2) {
1.147 - * super(mt, lf);
1.148 - * this.argL0 = argL0;
1.149 - * this.argL1 = argL1;
1.150 - * this.argI2 = argI2;
1.151 - * }
1.152 - * public final SpeciesData speciesData() { return SPECIES_DATA; }
1.153 - * public static final SpeciesData SPECIES_DATA = SpeciesData.getForClass("LLI", Species_LLI.class);
1.154 - * public final BoundMethodHandle clone(MethodType mt, LambdaForm lf) {
1.155 - * return SPECIES_DATA.constructor[0].invokeBasic(mt, lf, argL0, argL1, argI2);
1.156 - * }
1.157 - * public final BoundMethodHandle cloneExtendL(MethodType mt, LambdaForm lf, Object narg) {
1.158 - * return SPECIES_DATA.extendWithIndex(INDEX_L).constructor[0].invokeBasic(mt, lf, argL0, argL1, argI2, narg);
1.159 - * }
1.160 - * public final BoundMethodHandle cloneExtendI(MethodType mt, LambdaForm lf, int narg) {
1.161 - * return SPECIES_DATA.extendWithIndex(INDEX_I).constructor[0].invokeBasic(mt, lf, argL0, argL1, argI2, narg);
1.162 - * }
1.163 - * public final BoundMethodHandle cloneExtendJ(MethodType mt, LambdaForm lf, long narg) {
1.164 - * return SPECIES_DATA.extendWithIndex(INDEX_J).constructor[0].invokeBasic(mt, lf, argL0, argL1, argI2, narg);
1.165 - * }
1.166 - * public final BoundMethodHandle cloneExtendF(MethodType mt, LambdaForm lf, float narg) {
1.167 - * return SPECIES_DATA.extendWithIndex(INDEX_F).constructor[0].invokeBasic(mt, lf, argL0, argL1, argI2, narg);
1.168 - * }
1.169 - * public final BoundMethodHandle cloneExtendD(MethodType mt, LambdaForm lf, double narg) {
1.170 - * return SPECIES_DATA.extendWithIndex(INDEX_D).constructor[0].invokeBasic(mt, lf, argL0, argL1, argI2, narg);
1.171 - * }
1.172 - * }
1.173 - * </pre>
1.174 - *
1.175 - * @param types the type signature, wherein reference types are erased to 'L'
1.176 - * @return the generated concrete BMH class
1.177 - */
1.178 - static Class<? extends BoundMethodHandle> generateConcreteBMHClass(String types) {
1.179 - final ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS + ClassWriter.COMPUTE_FRAMES);
1.180 -
1.181 - final String className = SPECIES_PREFIX_PATH + types;
1.182 - final String sourceFile = SPECIES_PREFIX_NAME + types;
1.183 - cw.visit(V1_6, ACC_PUBLIC + ACC_FINAL + ACC_SUPER, className, null, BMH, null);
1.184 - cw.visitSource(sourceFile, null);
1.185 -
1.186 - // emit static types and SPECIES_DATA fields
1.187 - cw.visitField(ACC_PUBLIC + ACC_STATIC, "SPECIES_DATA", SPECIES_DATA_SIG, null, null).visitEnd();
1.188 -
1.189 - // emit bound argument fields
1.190 - for (int i = 0; i < types.length(); ++i) {
1.191 - final char t = types.charAt(i);
1.192 - final String fieldName = makeFieldName(types, i);
1.193 - final String fieldDesc = t == 'L' ? JLO_SIG : String.valueOf(t);
1.194 - cw.visitField(ACC_FINAL, fieldName, fieldDesc, null, null).visitEnd();
1.195 - }
1.196 -
1.197 - MethodVisitor mv;
1.198 -
1.199 - // emit constructor
1.200 - mv = cw.visitMethod(ACC_PUBLIC, "<init>", makeSignature(types, true), null, null);
1.201 - mv.visitCode();
1.202 - mv.visitVarInsn(ALOAD, 0);
1.203 - mv.visitVarInsn(ALOAD, 1);
1.204 - mv.visitVarInsn(ALOAD, 2);
1.205 -
1.206 - mv.visitMethodInsn(INVOKESPECIAL, BMH, "<init>", makeSignature("", true));
1.207 -
1.208 - for (int i = 0, j = 0; i < types.length(); ++i, ++j) {
1.209 - // i counts the arguments, j counts corresponding argument slots
1.210 - char t = types.charAt(i);
1.211 - mv.visitVarInsn(ALOAD, 0);
1.212 - mv.visitVarInsn(typeLoadOp(t), j + 3); // parameters start at 3
1.213 - mv.visitFieldInsn(PUTFIELD, className, makeFieldName(types, i), typeSig(t));
1.214 - if (t == 'J' || t == 'D') {
1.215 - ++j; // adjust argument register access
1.216 - }
1.217 - }
1.218 -
1.219 - mv.visitInsn(RETURN);
1.220 - mv.visitMaxs(0, 0);
1.221 - mv.visitEnd();
1.222 -
1.223 - // emit implementation of reinvokerTarget()
1.224 - mv = cw.visitMethod(ACC_PUBLIC + ACC_FINAL, "reinvokerTarget", "()" + MH_SIG, null, null);
1.225 - mv.visitCode();
1.226 - mv.visitVarInsn(ALOAD, 0);
1.227 - mv.visitFieldInsn(GETFIELD, className, "argL0", JLO_SIG);
1.228 - mv.visitTypeInsn(CHECKCAST, MH);
1.229 - mv.visitInsn(ARETURN);
1.230 - mv.visitMaxs(0, 0);
1.231 - mv.visitEnd();
1.232 -
1.233 - // emit implementation of speciesData()
1.234 - mv = cw.visitMethod(ACC_PUBLIC + ACC_FINAL, "speciesData", MYSPECIES_DATA_SIG, null, null);
1.235 - mv.visitCode();
1.236 - mv.visitFieldInsn(GETSTATIC, className, "SPECIES_DATA", SPECIES_DATA_SIG);
1.237 - mv.visitInsn(ARETURN);
1.238 - mv.visitMaxs(0, 0);
1.239 - mv.visitEnd();
1.240 -
1.241 - // emit clone()
1.242 - mv = cw.visitMethod(ACC_PUBLIC + ACC_FINAL, "clone", makeSignature("", false), null, E_THROWABLE);
1.243 - mv.visitCode();
1.244 - // return speciesData().constructor[0].invokeBasic(mt, lf, argL0, ...)
1.245 - // obtain constructor
1.246 - mv.visitVarInsn(ALOAD, 0);
1.247 - mv.visitFieldInsn(GETSTATIC, className, "SPECIES_DATA", SPECIES_DATA_SIG);
1.248 - mv.visitFieldInsn(GETFIELD, SPECIES_DATA, "constructor", "[" + MH_SIG);
1.249 - mv.visitInsn(ICONST_0);
1.250 - mv.visitInsn(AALOAD);
1.251 - // load mt, lf
1.252 - mv.visitVarInsn(ALOAD, 1);
1.253 - mv.visitVarInsn(ALOAD, 2);
1.254 - // put fields on the stack
1.255 - emitPushFields(types, className, mv);
1.256 - // finally, invoke the constructor and return
1.257 - mv.visitMethodInsn(INVOKEVIRTUAL, MH, "invokeBasic", makeSignature(types, false));
1.258 - mv.visitInsn(ARETURN);
1.259 - mv.visitMaxs(0, 0);
1.260 - mv.visitEnd();
1.261 -
1.262 - // for each type, emit cloneExtendT()
1.263 - for (Class<?> c : TYPES) {
1.264 - char t = Wrapper.basicTypeChar(c);
1.265 - mv = cw.visitMethod(ACC_PUBLIC + ACC_FINAL, "cloneExtend" + t, makeSignature(String.valueOf(t), false), null, E_THROWABLE);
1.266 - mv.visitCode();
1.267 - // return SPECIES_DATA.extendWithIndex(extensionIndex(t)).constructor[0].invokeBasic(mt, lf, argL0, ..., narg)
1.268 - // obtain constructor
1.269 - mv.visitFieldInsn(GETSTATIC, className, "SPECIES_DATA", SPECIES_DATA_SIG);
1.270 - int iconstInsn = ICONST_0 + extensionIndex(t);
1.271 - assert(iconstInsn <= ICONST_5);
1.272 - mv.visitInsn(iconstInsn);
1.273 - mv.visitMethodInsn(INVOKEVIRTUAL, SPECIES_DATA, "extendWithIndex", BMHSPECIES_DATA_EWI_SIG);
1.274 - mv.visitFieldInsn(GETFIELD, SPECIES_DATA, "constructor", "[" + MH_SIG);
1.275 - mv.visitInsn(ICONST_0);
1.276 - mv.visitInsn(AALOAD);
1.277 - // load mt, lf
1.278 - mv.visitVarInsn(ALOAD, 1);
1.279 - mv.visitVarInsn(ALOAD, 2);
1.280 - // put fields on the stack
1.281 - emitPushFields(types, className, mv);
1.282 - // put narg on stack
1.283 - mv.visitVarInsn(typeLoadOp(t), 3);
1.284 - // finally, invoke the constructor and return
1.285 - mv.visitMethodInsn(INVOKEVIRTUAL, MH, "invokeBasic", makeSignature(types + t, false));
1.286 - mv.visitInsn(ARETURN);
1.287 - mv.visitMaxs(0, 0);
1.288 - mv.visitEnd();
1.289 - }
1.290 -
1.291 - // emit class initializer
1.292 - mv = cw.visitMethod(ACC_PUBLIC | ACC_STATIC, "<clinit>", VOID_SIG, null, null);
1.293 - mv.visitCode();
1.294 - mv.visitLdcInsn(types);
1.295 - mv.visitLdcInsn(Type.getObjectType(className));
1.296 - mv.visitMethodInsn(INVOKESTATIC, SPECIES_DATA, "getForClass", BMHSPECIES_DATA_GFC_SIG);
1.297 - mv.visitFieldInsn(PUTSTATIC, className, "SPECIES_DATA", SPECIES_DATA_SIG);
1.298 - mv.visitInsn(RETURN);
1.299 - mv.visitMaxs(0, 0);
1.300 - mv.visitEnd();
1.301 -
1.302 - cw.visitEnd();
1.303 -
1.304 - // load class
1.305 - final byte[] classFile = cw.toByteArray();
1.306 - InvokerBytecodeGenerator.maybeDump(className, classFile);
1.307 - Class<? extends BoundMethodHandle> bmhClass =
1.308 - //UNSAFE.defineAnonymousClass(BoundMethodHandle.class, classFile, null).asSubclass(BoundMethodHandle.class);
1.309 - UNSAFE.defineClass(className, classFile, 0, classFile.length,
1.310 - BoundMethodHandle.class.getClassLoader(), null)
1.311 - .asSubclass(BoundMethodHandle.class);
1.312 - UNSAFE.ensureClassInitialized(bmhClass);
1.313 -
1.314 - return bmhClass;
1.315 - }
1.316 -
1.317 - private static int typeLoadOp(char t) {
1.318 - switch (t) {
1.319 - case 'L': return ALOAD;
1.320 - case 'I': return ILOAD;
1.321 - case 'J': return LLOAD;
1.322 - case 'F': return FLOAD;
1.323 - case 'D': return DLOAD;
1.324 - default : throw new InternalError("unrecognized type " + t);
1.325 - }
1.326 - }
1.327 -
1.328 - private static void emitPushFields(String types, String className, MethodVisitor mv) {
1.329 - for (int i = 0; i < types.length(); ++i) {
1.330 - char tc = types.charAt(i);
1.331 - mv.visitVarInsn(ALOAD, 0);
1.332 - mv.visitFieldInsn(GETFIELD, className, makeFieldName(types, i), typeSig(tc));
1.333 - }
1.334 - }
1.335 -
1.336 - static String typeSig(char t) {
1.337 - return t == 'L' ? JLO_SIG : String.valueOf(t);
1.338 - }
1.339 -
1.340 - //
1.341 - // Getter MH generation.
1.342 - //
1.343 -
1.344 - private static MethodHandle makeGetter(Class<?> cbmhClass, String types, int index) {
1.345 - String fieldName = makeFieldName(types, index);
1.346 - Class<?> fieldType = Wrapper.forBasicType(types.charAt(index)).primitiveType();
1.347 - try {
1.348 - return LOOKUP.findGetter(cbmhClass, fieldName, fieldType);
1.349 - } catch (NoSuchFieldException | IllegalAccessException e) {
1.350 - throw newInternalError(e);
1.351 - }
1.352 - }
1.353 -
1.354 - static MethodHandle[] makeGetters(Class<?> cbmhClass, String types, MethodHandle[] mhs) {
1.355 - if (mhs == null) mhs = new MethodHandle[types.length()];
1.356 - for (int i = 0; i < mhs.length; ++i) {
1.357 - mhs[i] = makeGetter(cbmhClass, types, i);
1.358 - assert(mhs[i].internalMemberName().getDeclaringClass() == cbmhClass);
1.359 - }
1.360 - return mhs;
1.361 - }
1.362 -
1.363 - static MethodHandle[] makeCtors(Class<? extends BoundMethodHandle> cbmh, String types, MethodHandle mhs[]) {
1.364 - if (mhs == null) mhs = new MethodHandle[1];
1.365 - mhs[0] = makeCbmhCtor(cbmh, types);
1.366 - return mhs;
1.367 - }
1.368 -
1.369 - //
1.370 - // Auxiliary methods.
1.371 - //
1.372 -
1.373 - static SpeciesData speciesDataFromConcreteBMHClass(Class<? extends BoundMethodHandle> cbmh) {
1.374 - try {
1.375 - Field F_SPECIES_DATA = cbmh.getDeclaredField("SPECIES_DATA");
1.376 - return (SpeciesData) F_SPECIES_DATA.get(null);
1.377 - } catch (ReflectiveOperationException ex) {
1.378 - throw newInternalError(ex);
1.379 - }
1.380 - }
1.381 -
1.382 - /**
1.383 - * Field names in concrete BMHs adhere to this pattern:
1.384 - * arg + type + index
1.385 - * where type is a single character (L, I, J, F, D).
1.386 - */
1.387 - private static String makeFieldName(String types, int index) {
1.388 - assert index >= 0 && index < types.length();
1.389 - return "arg" + types.charAt(index) + index;
1.390 - }
1.391 -
1.392 - private static String makeSignature(String types, boolean ctor) {
1.393 - StringBuilder buf = new StringBuilder(SIG_INCIPIT);
1.394 - for (char c : types.toCharArray()) {
1.395 - buf.append(typeSig(c));
1.396 - }
1.397 - return buf.append(')').append(ctor ? "V" : BMH_SIG).toString();
1.398 - }
1.399 -
1.400 - static MethodHandle makeCbmhCtor(Class<? extends BoundMethodHandle> cbmh, String types) {
1.401 - try {
1.402 - return linkConstructor(LOOKUP.findConstructor(cbmh, MethodType.fromMethodDescriptorString(makeSignature(types, true), null)));
1.403 - } catch (NoSuchMethodException | IllegalAccessException | IllegalArgumentException | TypeNotPresentException e) {
1.404 - throw newInternalError(e);
1.405 - }
1.406 - }
1.407 -
1.408 - /**
1.409 - * Wrap a constructor call in a {@link LambdaForm}.
1.410 - *
1.411 - * If constructors ({@code <init>} methods) are called in LFs, problems might arise if the LFs
1.412 - * are turned into bytecode, because the call to the allocator is routed through an MH, and the
1.413 - * verifier cannot find a {@code NEW} instruction preceding the {@code INVOKESPECIAL} to
1.414 - * {@code <init>}. To avoid this, we add an indirection by invoking {@code <init>} through
1.415 - * {@link MethodHandle#linkToSpecial}.
1.416 - *
1.417 - * The last {@link LambdaForm.Name Name} in the argument's form is expected to be the {@code void}
1.418 - * result of the {@code <init>} invocation. This entry is replaced.
1.419 - */
1.420 - private static MethodHandle linkConstructor(MethodHandle cmh) {
1.421 - final LambdaForm lf = cmh.form;
1.422 - final int initNameIndex = lf.names.length - 1;
1.423 - final Name initName = lf.names[initNameIndex];
1.424 - final MemberName ctorMN = initName.function.member;
1.425 - final MethodType ctorMT = ctorMN.getInvocationType();
1.426 -
1.427 - // obtain function member (call target)
1.428 - // linker method type replaces initial parameter (BMH species) with BMH to avoid naming a species (anonymous class!)
1.429 - final MethodType linkerMT = ctorMT.changeParameterType(0, BoundMethodHandle.class).appendParameterTypes(MemberName.class);
1.430 - MemberName linkerMN = new MemberName(MethodHandle.class, "linkToSpecial", linkerMT, REF_invokeStatic);
1.431 - try {
1.432 - linkerMN = MemberName.getFactory().resolveOrFail(REF_invokeStatic, linkerMN, null, NoSuchMethodException.class);
1.433 - assert(linkerMN.isStatic());
1.434 - } catch (ReflectiveOperationException ex) {
1.435 - throw newInternalError(ex);
1.436 - }
1.437 - // extend arguments array
1.438 - Object[] newArgs = Arrays.copyOf(initName.arguments, initName.arguments.length + 1);
1.439 - newArgs[newArgs.length - 1] = ctorMN;
1.440 - // replace function
1.441 - final NamedFunction nf = new NamedFunction(linkerMN);
1.442 - final Name linkedCtor = new Name(nf, newArgs);
1.443 - linkedCtor.initIndex(initNameIndex);
1.444 - lf.names[initNameIndex] = linkedCtor;
1.445 - return cmh;
1.446 - }
1.447 -
1.448 - }
1.449
1.450 private static final Lookup LOOKUP = Lookup.IMPL_LOOKUP;
1.451