internal override void Generate(CodeGenContext context, CodeEmitter ilgen) { FieldWrapper fw = ClassLoaderWrapper.LoadClassCritical(Class).GetFieldWrapper(Name, Sig); fw.Link(); ilgen.Emit(OpCodes.Ldflda, fw.GetField()); }
internal override void Generate(CodeGenContext context, CodeEmitter ilgen) { FieldWrapper fw = StaticCompiler.GetClassForMapXml(context.ClassLoader, Class).GetFieldWrapper(Name, Sig); fw.Link(); ilgen.Emit(OpCodes.Ldflda, fw.GetField()); }
private static FieldInfo GetFieldInfo(long offset) { FieldWrapper fw = FieldWrapper.FromField(sun.misc.Unsafe.getField(offset)); fw.Link(); fw.ResolveField(); return(fw.GetField()); }
internal override void Generate(CodeGenContext context, CodeEmitter ilgen) { FieldWrapper fw = ClassLoaderWrapper.LoadClassCritical(Class).GetFieldWrapper(Name, Sig); fw.Link(); // we don't use fw.EmitSet because we don't want automatic unboxing and whatever ilgen.Emit(OpCodes.Stsfld, fw.GetField()); }
internal override void Generate(CodeGenContext context, CodeEmitter ilgen) { FieldWrapper fw = StaticCompiler.GetClassForMapXml(context.ClassLoader, Class).GetFieldWrapper(Name, Sig); fw.Link(); // we don't use fw.EmitSet because we don't want automatic unboxing and whatever ilgen.Emit(OpCodes.Stsfld, fw.GetField()); }
public static bool isFieldDeprecated(object field) { FieldWrapper fieldWrapper = FieldWrapper.FromField(field); FieldInfo fi = fieldWrapper.GetField(); if (fi != null) { return(fi.IsDefined(typeof(ObsoleteAttribute), false)); } return(false); }
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 override void Generate(CodeGenContext context, CodeEmitter ilgen) { if (Type != null) { ilgen.Emit(OpCodes.Ldsfld, StaticCompiler.GetType(context.ClassLoader, Type).GetField(Name, BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)); } else { FieldWrapper fw = ClassLoaderWrapper.LoadClassCritical(Class).GetFieldWrapper(Name, Sig); fw.Link(); // we don't use fw.EmitGet because we don't want automatic unboxing and whatever ilgen.Emit(OpCodes.Ldsfld, fw.GetField()); } }
private MemberInfo Resolve(CodeGenContext context) { if (type != null) { if (Class != null || Method != null || Field != null || Sig != null) { throw new NotImplementedException(); } return(StaticCompiler.GetTypeForMapXml(context.ClassLoader, type)); } else if (Class != null) { TypeWrapper tw = context.ClassLoader.LoadClassByDottedNameFast(Class); if (tw == null) { return(null); } else if (Method != null) { MethodWrapper mw = tw.GetMethodWrapper(Method, Sig, false); if (mw == null) { return(null); } return(mw.GetMethod()); } else if (Field != null) { FieldWrapper fw = tw.GetFieldWrapper(Field, Sig); if (fw == null) { return(null); } return(fw.GetField()); } else { return(tw.TypeAsBaseType); } } else { return(null); } }
private static Delegate CreateCompareExchange(long fieldOffset) { #if !WINRT FieldWrapper fw = FieldWrapper.FromField(sun.misc.Unsafe.getField(fieldOffset)); fw.Link(); fw.ResolveField(); FieldInfo field = fw.GetField(); DynamicMethod dm = new DynamicMethod("CompareExchange", field.FieldType, new Type[] { typeof(object), field.FieldType, field.FieldType }, field.DeclaringType); ILGenerator ilgen = dm.GetILGenerator(); ilgen.Emit(OpCodes.Ldarg_0); ilgen.Emit(OpCodes.Castclass, field.DeclaringType); ilgen.Emit(OpCodes.Ldflda, field); ilgen.Emit(OpCodes.Ldarg_1); ilgen.Emit(OpCodes.Ldarg_2); ilgen.Emit(OpCodes.Call, typeof(Interlocked).GetMethod("CompareExchange", new Type[] { field.FieldType.MakeByRefType(), field.FieldType, field.FieldType })); ilgen.Emit(OpCodes.Ret); return(dm.CreateDelegate(field.FieldType == typeof(int) ? typeof(CompareExchangeInt32) : typeof(CompareExchangeInt64))); #else throw new NotImplementedException(); #endif }
private static bool Unsafe_compareAndSwapObject(EmitIntrinsicContext eic) { TypeWrapper tw = eic.GetStackTypeWrapper(0, 3); if (IsSupportedArrayTypeForUnsafeOperation(tw) && eic.GetStackTypeWrapper(0, 0).IsAssignableTo(tw.ElementTypeWrapper) && eic.GetStackTypeWrapper(0, 1).IsAssignableTo(tw.ElementTypeWrapper)) { Type type = tw.TypeAsLocalOrStackType.GetElementType(); CodeEmitterLocal update = eic.Emitter.AllocTempLocal(type); CodeEmitterLocal expect = eic.Emitter.AllocTempLocal(type); CodeEmitterLocal index = eic.Emitter.AllocTempLocal(Types.Int32); CodeEmitterLocal obj = eic.Emitter.AllocTempLocal(tw.TypeAsLocalOrStackType); eic.Emitter.Emit(OpCodes.Stloc, update); eic.Emitter.Emit(OpCodes.Stloc, expect); eic.Emitter.Emit(OpCodes.Conv_Ovf_I4); eic.Emitter.Emit(OpCodes.Stloc, index); eic.Emitter.Emit(OpCodes.Stloc, obj); EmitConsumeUnsafe(eic); eic.Emitter.Emit(OpCodes.Ldloc, obj); eic.Emitter.Emit(OpCodes.Ldloc, index); eic.Emitter.Emit(OpCodes.Ldelema, type); eic.Emitter.Emit(OpCodes.Ldloc, update); eic.Emitter.Emit(OpCodes.Ldloc, expect); eic.Emitter.Emit(OpCodes.Call, AtomicReferenceFieldUpdaterEmitter.MakeCompareExchange(type)); eic.Emitter.Emit(OpCodes.Ldloc, expect); eic.Emitter.Emit(OpCodes.Ceq); eic.Emitter.ReleaseTempLocal(obj); eic.Emitter.ReleaseTempLocal(index); eic.Emitter.ReleaseTempLocal(expect); eic.Emitter.ReleaseTempLocal(update); eic.NonLeaf = false; return(true); } if ((eic.Flags[eic.OpcodeIndex] & InstructionFlags.BranchTarget) != 0 || (eic.Flags[eic.OpcodeIndex - 1] & InstructionFlags.BranchTarget) != 0 || (eic.Flags[eic.OpcodeIndex - 2] & InstructionFlags.BranchTarget) != 0) { return(false); } if ((eic.Match(-1, NormalizedByteCode.__aload) || eic.Match(-1, NormalizedByteCode.__aconst_null)) && (eic.Match(-2, NormalizedByteCode.__aload) || eic.Match(-2, NormalizedByteCode.__aconst_null)) && eic.Match(-3, NormalizedByteCode.__getstatic)) { FieldWrapper fw = GetUnsafeField(eic, eic.GetFieldref(-3)); if (fw != null && fw.IsAccessibleFrom(fw.DeclaringType, eic.Caller.DeclaringType, fw.DeclaringType) && eic.GetStackTypeWrapper(0, 0).IsAssignableTo(fw.FieldTypeWrapper) && eic.GetStackTypeWrapper(0, 1).IsAssignableTo(fw.FieldTypeWrapper) && (fw.IsStatic || fw.DeclaringType == eic.GetStackTypeWrapper(0, 3))) { Type type = fw.FieldTypeWrapper.TypeAsLocalOrStackType; CodeEmitterLocal update = eic.Emitter.AllocTempLocal(type); CodeEmitterLocal expect = eic.Emitter.AllocTempLocal(type); eic.Emitter.Emit(OpCodes.Stloc, update); eic.Emitter.Emit(OpCodes.Stloc, expect); eic.Emitter.Emit(OpCodes.Pop); // discard index if (fw.IsStatic) { eic.Emitter.Emit(OpCodes.Pop); // discard obj EmitConsumeUnsafe(eic); eic.Emitter.Emit(OpCodes.Ldsflda, fw.GetField()); } else { CodeEmitterLocal obj = eic.Emitter.AllocTempLocal(eic.Caller.DeclaringType.TypeAsLocalOrStackType); eic.Emitter.Emit(OpCodes.Stloc, obj); EmitConsumeUnsafe(eic); eic.Emitter.Emit(OpCodes.Ldloc, obj); eic.Emitter.ReleaseTempLocal(obj); eic.Emitter.Emit(OpCodes.Ldflda, fw.GetField()); } eic.Emitter.Emit(OpCodes.Ldloc, update); eic.Emitter.Emit(OpCodes.Ldloc, expect); eic.Emitter.Emit(OpCodes.Call, AtomicReferenceFieldUpdaterEmitter.MakeCompareExchange(type)); eic.Emitter.Emit(OpCodes.Ldloc, expect); eic.Emitter.Emit(OpCodes.Ceq); eic.Emitter.ReleaseTempLocal(expect); eic.Emitter.ReleaseTempLocal(update); eic.NonLeaf = false; return(true); } } return(false); }
private static bool Unsafe_putObjectImpl(EmitIntrinsicContext eic, bool membarrier) { TypeWrapper tw = eic.GetStackTypeWrapper(0, 2); if (IsSupportedArrayTypeForUnsafeOperation(tw) && eic.GetStackTypeWrapper(0, 0).IsAssignableTo(tw.ElementTypeWrapper)) { CodeEmitterLocal value = eic.Emitter.AllocTempLocal(tw.ElementTypeWrapper.TypeAsLocalOrStackType); CodeEmitterLocal index = eic.Emitter.AllocTempLocal(Types.Int32); CodeEmitterLocal array = eic.Emitter.AllocTempLocal(tw.TypeAsLocalOrStackType); eic.Emitter.Emit(OpCodes.Stloc, value); eic.Emitter.Emit(OpCodes.Conv_Ovf_I4); eic.Emitter.Emit(OpCodes.Stloc, index); eic.Emitter.Emit(OpCodes.Stloc, array); EmitConsumeUnsafe(eic); eic.Emitter.Emit(OpCodes.Ldloc, array); eic.Emitter.Emit(OpCodes.Ldloc, index); eic.Emitter.Emit(OpCodes.Ldloc, value); eic.Emitter.ReleaseTempLocal(array); eic.Emitter.ReleaseTempLocal(index); eic.Emitter.ReleaseTempLocal(value); eic.Emitter.Emit(OpCodes.Stelem_Ref); if (membarrier) { eic.Emitter.EmitMemoryBarrier(); } eic.NonLeaf = false; return(true); } if ((eic.Flags[eic.OpcodeIndex] & InstructionFlags.BranchTarget) != 0 || (eic.Flags[eic.OpcodeIndex - 1] & InstructionFlags.BranchTarget) != 0) { return(false); } if ((eic.Match(-1, NormalizedByteCode.__aload) || eic.Match(-1, NormalizedByteCode.__aconst_null)) && eic.Match(-2, NormalizedByteCode.__getstatic)) { FieldWrapper fw = GetUnsafeField(eic, eic.GetFieldref(-2)); if (fw != null && (!fw.IsFinal || (!fw.IsStatic && eic.Caller.Name == "<init>") || (fw.IsStatic && eic.Caller.Name == "<clinit>")) && fw.IsAccessibleFrom(fw.DeclaringType, eic.Caller.DeclaringType, fw.DeclaringType) && eic.GetStackTypeWrapper(0, 0).IsAssignableTo(fw.FieldTypeWrapper) && (fw.IsStatic || fw.DeclaringType == eic.GetStackTypeWrapper(0, 2))) { CodeEmitterLocal value = eic.Emitter.AllocTempLocal(fw.FieldTypeWrapper.TypeAsLocalOrStackType); eic.Emitter.Emit(OpCodes.Stloc, value); eic.Emitter.Emit(OpCodes.Pop); // discard offset field if (fw.IsStatic) { eic.Emitter.Emit(OpCodes.Pop); // discard object EmitConsumeUnsafe(eic); } else { CodeEmitterLocal obj = eic.Emitter.AllocTempLocal(fw.DeclaringType.TypeAsLocalOrStackType); eic.Emitter.Emit(OpCodes.Stloc, obj); EmitConsumeUnsafe(eic); eic.Emitter.Emit(OpCodes.Ldloc, obj); eic.Emitter.ReleaseTempLocal(obj); } eic.Emitter.Emit(OpCodes.Ldloc, value); eic.Emitter.ReleaseTempLocal(value); // note that we assume the CLR memory model where all writes are ordered, // so we don't need a volatile store or a memory barrier and putOrderedObject // is typically used with a volatile field, so to avoid the memory barrier, // we don't use FieldWrapper.EmitSet(), but emit the store directly eic.Emitter.Emit(fw.IsStatic ? OpCodes.Stsfld : OpCodes.Stfld, fw.GetField()); if (membarrier) { eic.Emitter.EmitMemoryBarrier(); } eic.NonLeaf = false; return(true); } } return(false); }