Пример #1
0
        internal override void Generate(CodeGenContext context, CodeEmitter ilgen)
        {
            FieldWrapper fw = ClassLoaderWrapper.LoadClassCritical(Class).GetFieldWrapper(Name, Sig);

            fw.Link();
            ilgen.Emit(OpCodes.Ldflda, fw.GetField());
        }
Пример #2
0
        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());
        }
Пример #3
0
    private static FieldInfo GetFieldInfo(long offset)
    {
        FieldWrapper fw = FieldWrapper.FromField(sun.misc.Unsafe.getField(offset));

        fw.Link();
        fw.ResolveField();
        return(fw.GetField());
    }
Пример #4
0
        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());
        }
Пример #5
0
        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());
        }
Пример #6
0
            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);
            }
Пример #7
0
    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);
    }
Пример #8
0
 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());
     }
 }
Пример #9
0
 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);
     }
 }
Пример #10
0
    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
    }
Пример #11
0
        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);
        }
Пример #12
0
        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);
        }