public static Delegate DynamicCreateDelegate(object obj, Type delegateType, string name, string sig) { TypeWrapper tw = TypeWrapper.FromClass(ikvm.runtime.Util.getClassFromObject(obj)); MethodWrapper mw = tw.GetMethodWrapper(name, sig, true); if (mw == null || mw.IsStatic || !mw.IsPublic) { MethodInfo invoke = delegateType.GetMethod("Invoke"); ParameterInfo[] parameters = invoke.GetParameters(); Type[] parameterTypes = new Type[parameters.Length + 1]; parameterTypes[0] = typeof(object); for (int i = 0; i < parameters.Length; i++) { parameterTypes[i + 1] = parameters[i].ParameterType; } System.Reflection.Emit.DynamicMethod dm = new System.Reflection.Emit.DynamicMethod("Invoke", invoke.ReturnType, parameterTypes); CodeEmitter ilgen = CodeEmitter.Create(dm); ilgen.Emit(System.Reflection.Emit.OpCodes.Ldstr, tw.Name + ".Invoke" + sig); ClassLoaderWrapper.GetBootstrapClassLoader() .LoadClassByDottedName(mw == null || mw.IsStatic ? "java.lang.AbstractMethodError" : "java.lang.IllegalAccessError") .GetMethodWrapper("<init>", "(Ljava.lang.String;)V", false) .EmitNewobj(ilgen); ilgen.Emit(System.Reflection.Emit.OpCodes.Throw); ilgen.DoEmit(); return(dm.CreateDelegate(delegateType, obj)); } else { mw.ResolveMethod(); return(Delegate.CreateDelegate(delegateType, obj, (MethodInfo)mw.GetMethod())); } }
internal Delegate CreateDelegate() { ilgen.DoEmit(); return(ValidateDelegate(firstArg == 0 ? dm.CreateDelegate(delegateType) : dm.CreateDelegate(delegateType, container == null ? target : Activator.CreateInstance(container, target, value)))); }
internal Delegate CreateDelegate() { ilgen.DoEmit(); return(ValidateDelegate(firstArg == 0 ? dm.CreateDelegate(delegateType) : dm.CreateDelegate(delegateType, container == null ? firstBoundValue : Activator.CreateInstance(container, firstBoundValue, secondBoundValue)))); }
internal Delegate CreateDelegate() { //Console.WriteLine(delegateType); //ilgen.DumpMethod(); ilgen.DoEmit(); return(ValidateDelegate(firstArg == 0 ? dm.CreateDelegate(delegateType) : dm.CreateDelegate(delegateType, container == null ? firstBoundValue : Activator.CreateInstance(container, firstBoundValue, secondBoundValue)))); }
public static Delegate DynamicCreateDelegate(object obj, Type delegateType, string name, string sig) { #if !WINRT #if FIRST_PASS return(null); #else TypeWrapper tw = TypeWrapper.FromClass(ikvm.runtime.Util.getClassFromObject(obj)); MethodWrapper mw = tw.GetMethodWrapper(name, sig, true); if (mw == null || mw.IsStatic || !mw.IsPublic) { #if NO_REF_EMIT java.lang.invoke.MethodType methodType = MethodHandleUtil.GetDelegateMethodType(delegateType); if (methodType.parameterCount() > MethodHandleUtil.MaxArity) { throw new NotImplementedException(); } java.lang.invoke.MethodHandle exception = java.lang.invoke.MethodHandles.publicLookup() .findConstructor(mw == null || mw.IsStatic ? typeof(java.lang.AbstractMethodError) : typeof(java.lang.IllegalAccessError), java.lang.invoke.MethodType.methodType(typeof(void), typeof(string))) .bindTo(tw.Name + ".Invoke" + sig); return(Delegate.CreateDelegate(delegateType, java.lang.invoke.MethodHandles.dropArguments( java.lang.invoke.MethodHandles.foldArguments(java.lang.invoke.MethodHandles.throwException(methodType.returnType(), exception.type().returnType()), exception), 0, methodType.parameterArray()).vmtarget, "Invoke")); #else MethodInfo invoke = delegateType.GetMethod("Invoke"); ParameterInfo[] parameters = invoke.GetParameters(); Type[] parameterTypes = new Type[parameters.Length + 1]; parameterTypes[0] = typeof(object); for (int i = 0; i < parameters.Length; i++) { parameterTypes[i + 1] = parameters[i].ParameterType; } System.Reflection.Emit.DynamicMethod dm = new System.Reflection.Emit.DynamicMethod("Invoke", invoke.ReturnType, parameterTypes); CodeEmitter ilgen = CodeEmitter.Create(dm); ilgen.Emit(System.Reflection.Emit.OpCodes.Ldstr, tw.Name + ".Invoke" + sig); ClassLoaderWrapper.GetBootstrapClassLoader() .LoadClassByDottedName(mw == null || mw.IsStatic ? "java.lang.AbstractMethodError" : "java.lang.IllegalAccessError") .GetMethodWrapper("<init>", "(Ljava.lang.String;)V", false) .EmitNewobj(ilgen); ilgen.Emit(System.Reflection.Emit.OpCodes.Throw); ilgen.DoEmit(); return(dm.CreateDelegate(delegateType, obj)); #endif } else { mw.ResolveMethod(); return(Delegate.CreateDelegate(delegateType, obj, (MethodInfo)mw.GetMethod())); } #endif #else throw new NotImplementedException(); #endif }
private static void EmitSet(string name, TypeBuilder tb, FieldInfo field) { MethodBuilder set = tb.DefineMethod(name, MethodAttributes.Public | MethodAttributes.Virtual, Types.Void, new Type[] { Types.Object, Types.Object }); CodeEmitter ilgen = CodeEmitter.Create(set); ilgen.Emit(OpCodes.Ldarg_1); ilgen.Emit(OpCodes.Castclass, field.DeclaringType); ilgen.Emit(OpCodes.Ldarg_2); ilgen.Emit(OpCodes.Castclass, field.FieldType); ilgen.Emit(OpCodes.Volatile); ilgen.Emit(OpCodes.Stfld, field); ilgen.EmitMemoryBarrier(); ilgen.Emit(OpCodes.Ret); ilgen.DoEmit(); }
private static void DoEmit(DynamicTypeWrapper.FinishContext context, TypeWrapper wrapper, CodeEmitter ilgen, FieldWrapper field) { ConstructorBuilder cb; bool exists; lock (map) { exists = map.TryGetValue(field, out cb); } if (!exists) { // note that we don't need to lock here, because we're running as part of FinishCore, which is already protected by a lock TypeWrapper arfuTypeWrapper = ClassLoaderWrapper.LoadClassCritical("ikvm.internal.IntrinsicAtomicReferenceFieldUpdater"); TypeBuilder tb = wrapper.TypeAsBuilder.DefineNestedType("__<ARFU>_" + field.Name + field.Signature.Replace('.', '/'), TypeAttributes.NestedPrivate | TypeAttributes.Sealed, arfuTypeWrapper.TypeAsBaseType); EmitCompareAndSet("compareAndSet", tb, field.GetField()); EmitGet(tb, field.GetField()); EmitSet("set", tb, field.GetField()); cb = tb.DefineConstructor(MethodAttributes.Assembly, CallingConventions.Standard, Type.EmptyTypes); lock (map) { map.Add(field, cb); } CodeEmitter ctorilgen = CodeEmitter.Create(cb); ctorilgen.Emit(OpCodes.Ldarg_0); MethodWrapper basector = arfuTypeWrapper.GetMethodWrapper("<init>", "()V", false); basector.Link(); basector.EmitCall(ctorilgen); ctorilgen.Emit(OpCodes.Ret); ctorilgen.DoEmit(); context.RegisterPostFinishProc(delegate { arfuTypeWrapper.Finish(); tb.CreateType(); }); } ilgen.Emit(OpCodes.Pop); ilgen.Emit(OpCodes.Pop); ilgen.Emit(OpCodes.Pop); ilgen.Emit(OpCodes.Newobj, cb); }
internal FastFieldReflector(java.io.ObjectStreamField[] fields) { this.fields = fields; TypeWrapper tw = null; foreach (java.io.ObjectStreamField field in fields) { FieldWrapper fw = GetFieldWrapper(field); if (fw != null) { if (tw == null) { tw = fw.DeclaringType; } else if (tw != fw.DeclaringType) { // pre-condition is that all fields are from the same Type! throw new java.lang.InternalError(); } } } if (tw == null) { objFieldGetter = objFieldSetter = objDummy; primFieldGetter = primFieldSetter = primDummy; } else { try { tw.Finish(); } catch (RetargetableJavaException x) { throw x.ToJava(); } DynamicMethod dmObjGetter = DynamicMethodUtils.Create("__<ObjFieldGetter>", tw.TypeAsBaseType, true, null, new Type[] { typeof(object), typeof(object[]) }); DynamicMethod dmPrimGetter = DynamicMethodUtils.Create("__<PrimFieldGetter>", tw.TypeAsBaseType, true, null, new Type[] { typeof(object), typeof(byte[]) }); DynamicMethod dmObjSetter = DynamicMethodUtils.Create("__<ObjFieldSetter>", tw.TypeAsBaseType, true, null, new Type[] { typeof(object), typeof(object[]) }); DynamicMethod dmPrimSetter = DynamicMethodUtils.Create("__<PrimFieldSetter>", tw.TypeAsBaseType, true, null, new Type[] { typeof(object), typeof(byte[]) }); CodeEmitter ilgenObjGetter = CodeEmitter.Create(dmObjGetter); CodeEmitter ilgenPrimGetter = CodeEmitter.Create(dmPrimGetter); CodeEmitter ilgenObjSetter = CodeEmitter.Create(dmObjSetter); CodeEmitter ilgenPrimSetter = CodeEmitter.Create(dmPrimSetter); // we want the getters to be verifiable (because writeObject can be used from partial trust), // so we create a local to hold the properly typed object reference CodeEmitterLocal objGetterThis = ilgenObjGetter.DeclareLocal(tw.TypeAsBaseType); CodeEmitterLocal primGetterThis = ilgenPrimGetter.DeclareLocal(tw.TypeAsBaseType); ilgenObjGetter.Emit(OpCodes.Ldarg_0); ilgenObjGetter.Emit(OpCodes.Castclass, tw.TypeAsBaseType); ilgenObjGetter.Emit(OpCodes.Stloc, objGetterThis); ilgenPrimGetter.Emit(OpCodes.Ldarg_0); ilgenPrimGetter.Emit(OpCodes.Castclass, tw.TypeAsBaseType); ilgenPrimGetter.Emit(OpCodes.Stloc, primGetterThis); foreach (java.io.ObjectStreamField field in fields) { FieldWrapper fw = GetFieldWrapper(field); if (fw == null) { continue; } fw.ResolveField(); TypeWrapper fieldType = fw.FieldTypeWrapper; try { fieldType = fieldType.EnsureLoadable(tw.GetClassLoader()); fieldType.Finish(); } catch (RetargetableJavaException x) { throw x.ToJava(); } if (fieldType.IsPrimitive) { // Getter ilgenPrimGetter.Emit(OpCodes.Ldarg_1); ilgenPrimGetter.EmitLdc_I4(field.getOffset()); ilgenPrimGetter.Emit(OpCodes.Ldloc, primGetterThis); fw.EmitGet(ilgenPrimGetter); if (fieldType == PrimitiveTypeWrapper.BYTE) { ilgenPrimGetter.Emit(OpCodes.Call, WriteByteMethod); } else if (fieldType == PrimitiveTypeWrapper.BOOLEAN) { ilgenPrimGetter.Emit(OpCodes.Call, WriteBooleanMethod); } else if (fieldType == PrimitiveTypeWrapper.CHAR) { ilgenPrimGetter.Emit(OpCodes.Call, WriteCharMethod); } else if (fieldType == PrimitiveTypeWrapper.SHORT) { ilgenPrimGetter.Emit(OpCodes.Call, WriteShortMethod); } else if (fieldType == PrimitiveTypeWrapper.INT) { ilgenPrimGetter.Emit(OpCodes.Call, WriteIntMethod); } else if (fieldType == PrimitiveTypeWrapper.FLOAT) { ilgenPrimGetter.Emit(OpCodes.Call, WriteFloatMethod); } else if (fieldType == PrimitiveTypeWrapper.LONG) { ilgenPrimGetter.Emit(OpCodes.Call, WriteLongMethod); } else if (fieldType == PrimitiveTypeWrapper.DOUBLE) { ilgenPrimGetter.Emit(OpCodes.Call, WriteDoubleMethod); } else { throw new java.lang.InternalError(); } // Setter ilgenPrimSetter.Emit(OpCodes.Ldarg_0); ilgenPrimSetter.Emit(OpCodes.Castclass, tw.TypeAsBaseType); ilgenPrimSetter.Emit(OpCodes.Ldarg_1); ilgenPrimSetter.EmitLdc_I4(field.getOffset()); if (fieldType == PrimitiveTypeWrapper.BYTE) { ilgenPrimSetter.Emit(OpCodes.Call, ReadByteMethod); } else if (fieldType == PrimitiveTypeWrapper.BOOLEAN) { ilgenPrimSetter.Emit(OpCodes.Call, ReadBooleanMethod); } else if (fieldType == PrimitiveTypeWrapper.CHAR) { ilgenPrimSetter.Emit(OpCodes.Call, ReadCharMethod); } else if (fieldType == PrimitiveTypeWrapper.SHORT) { ilgenPrimSetter.Emit(OpCodes.Call, ReadShortMethod); } else if (fieldType == PrimitiveTypeWrapper.INT) { ilgenPrimSetter.Emit(OpCodes.Call, ReadIntMethod); } else if (fieldType == PrimitiveTypeWrapper.FLOAT) { ilgenPrimSetter.Emit(OpCodes.Call, ReadFloatMethod); } else if (fieldType == PrimitiveTypeWrapper.LONG) { ilgenPrimSetter.Emit(OpCodes.Call, ReadLongMethod); } else if (fieldType == PrimitiveTypeWrapper.DOUBLE) { ilgenPrimSetter.Emit(OpCodes.Call, ReadDoubleMethod); } else { throw new java.lang.InternalError(); } fw.EmitSet(ilgenPrimSetter); } else { // Getter ilgenObjGetter.Emit(OpCodes.Ldarg_1); ilgenObjGetter.EmitLdc_I4(field.getOffset()); ilgenObjGetter.Emit(OpCodes.Ldloc, objGetterThis); fw.EmitGet(ilgenObjGetter); fieldType.EmitConvSignatureTypeToStackType(ilgenObjGetter); ilgenObjGetter.Emit(OpCodes.Stelem_Ref); // Setter ilgenObjSetter.Emit(OpCodes.Ldarg_0); ilgenObjSetter.Emit(OpCodes.Ldarg_1); ilgenObjSetter.EmitLdc_I4(field.getOffset()); ilgenObjSetter.Emit(OpCodes.Ldelem_Ref); fieldType.EmitCheckcast(ilgenObjSetter); fieldType.EmitConvStackTypeToSignatureType(ilgenObjSetter, null); fw.EmitSet(ilgenObjSetter); } } ilgenObjGetter.Emit(OpCodes.Ret); ilgenPrimGetter.Emit(OpCodes.Ret); ilgenObjSetter.Emit(OpCodes.Ret); ilgenPrimSetter.Emit(OpCodes.Ret); ilgenObjGetter.DoEmit(); ilgenPrimGetter.DoEmit(); ilgenObjSetter.DoEmit(); ilgenPrimSetter.DoEmit(); objFieldGetter = (ObjFieldGetterSetter)dmObjGetter.CreateDelegate(typeof(ObjFieldGetterSetter)); primFieldGetter = (PrimFieldGetterSetter)dmPrimGetter.CreateDelegate(typeof(PrimFieldGetterSetter)); objFieldSetter = (ObjFieldGetterSetter)dmObjSetter.CreateDelegate(typeof(ObjFieldGetterSetter)); primFieldSetter = (PrimFieldGetterSetter)dmPrimSetter.CreateDelegate(typeof(PrimFieldGetterSetter)); } }
/** * 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())); }