/** * Generate customized bytecode for a given LambdaForm. */ public static MemberName generateCustomizedCode(LambdaForm form, MethodType invokerType) { try { MemberName memberName = new MemberName(); memberName._clazz(AnonymousClass.Instance); memberName._name(form.debugName); memberName._type(invokerType); memberName._flags(MethodHandleNatives.Constants.MN_IS_METHOD | MethodHandleNatives.Constants.ACC_STATIC | (MethodHandleNatives.Constants.REF_invokeStatic << MethodHandleNatives.Constants.MN_REFERENCE_KIND_SHIFT)); memberName.vmtarget = new NativeInvokerBytecodeGenerator(form, invokerType).generateCustomizedCodeBytes(); return(memberName); } #if DEBUG catch (BailoutException x) { Console.WriteLine(x.Message); Console.WriteLine("generateCustomizedCode: " + form + ", " + invokerType); } #else catch (BailoutException) { } #endif return(InvokerBytecodeGenerator.generateCustomizedCode(form, invokerType)); }
static Lazy() { try { NamedFunction[] nfs = new NamedFunction[] { NF_internalMemberName = new NamedFunction(typeof(DirectMethodHandle).getDeclaredMethod("internalMemberName", typeof(Object))), NF_internalMemberNameEnsureInit = new NamedFunction(typeof(DirectMethodHandle).getDeclaredMethod("internalMemberNameEnsureInit", typeof(Object))), NF_ensureInitialized = new NamedFunction(typeof(DirectMethodHandle).getDeclaredMethod("ensureInitialized", typeof(Object))), NF_fieldOffset = new NamedFunction(typeof(DirectMethodHandle).getDeclaredMethod("fieldOffset", typeof(Object))), NF_checkBase = new NamedFunction(typeof(DirectMethodHandle).getDeclaredMethod("checkBase", typeof(Object))), NF_staticBase = new NamedFunction(typeof(DirectMethodHandle).getDeclaredMethod("staticBase", typeof(Object))), NF_staticOffset = new NamedFunction(typeof(DirectMethodHandle).getDeclaredMethod("staticOffset", typeof(Object))), NF_checkCast = new NamedFunction(typeof(DirectMethodHandle).getDeclaredMethod("checkCast", typeof(Object), typeof(Object))), NF_allocateInstance = new NamedFunction(typeof(DirectMethodHandle).getDeclaredMethod("allocateInstance", typeof(Object))), NF_constructorMethod = new NamedFunction(typeof(DirectMethodHandle).getDeclaredMethod("constructorMethod", typeof(Object))) }; foreach (NamedFunction nf in nfs) { // Each nf must be statically invocable or we get tied up in our bootstraps. assert(InvokerBytecodeGenerator.IsStaticallyInvocable(nf.member)) : nf; nf.resolve(); } } catch (ReflectiveOperationException ex) { throw newInternalError(ex); } }
/** * Generate an invoker method for the passed {@link LambdaForm}. */ private Delegate generateCustomizedCodeBytes() { // iterate over the form's names, generating bytecode instructions for each // start iterating at the first name following the arguments Name onStack = null; for (int i = lambdaForm._arity(); i < lambdaForm.names.Length; i++) { Name name = lambdaForm.names[i]; emitStoreResult(onStack); onStack = name; // unless otherwise modified below MethodHandleImpl.Intrinsic intr = name.function.intrinsicName(); switch (intr.name()) { case "SELECT_ALTERNATIVE": //assert isSelectAlternative(i); onStack = emitSelectAlternative(name, lambdaForm.names[i + 1]); i++; // skip MH.invokeBasic of the selectAlternative result continue; case "GUARD_WITH_CATCH": //assert isGuardWithCatch(i); onStack = emitGuardWithCatch(i); i = i + 2; // Jump to the end of GWC idiom continue; case "NEW_ARRAY": Class rtype = name.function.methodType().returnType(); if (InvokerBytecodeGenerator.isStaticallyNameable(rtype)) { emitNewArray(name); continue; } break; case "ARRAY_LOAD": emitArrayLoad(name); continue; case "IDENTITY": //assert(name.arguments.length == 1); emitPushArguments(name); continue; case "NONE": // no intrinsic associated break; // [IKVM] ARRAY_STORE and ZERO appear to be unused default: throw new BailoutException(Bailout.UnsupportedIntrinsic, "Unknown intrinsic: " + intr); } MemberName member = name.function._member(); if (isStaticallyInvocable(member)) { emitStaticInvoke(member, name); } else { emitInvoke(name); } } // return statement emitReturn(onStack); ilgen.DoEmit(); return(dm.CreateDelegate(delegateType, constants.ToArray())); }