The Labs \ Source Viewer \ SSCLI \ Microsoft.JScript \ FieldAccessor

  1. // ==++==
  2. //
  3. //
  4. // Copyright (c) 2006 Microsoft Corporation. All rights reserved.
  5. //
  6. // The use and distribution terms for this software are contained in the file
  7. // named license.txt, which can be found in the root of this distribution.
  8. // By using this software in any fashion, you are agreeing to be bound by the
  9. // terms of this license.
  10. //
  11. // You must not remove this notice, or any other, from this software.
  12. //
  13. //
  14. // ==--==
  15. namespace Microsoft.JScript
  16. {
  17.     using System;
  18.     using System.Collections;
  19.     using System.Reflection;
  20.     using System.Reflection.Emit;
  21.     using System.Security.Permissions;
  22.     using System.Threading;
  23.     using System.Diagnostics;
  24.    
  25.     public abstract class FieldAccessor
  26.     {
  27.        
  28.         #if !DEBUG
  29.         [DebuggerStepThroughAttribute()]
  30.         [DebuggerHiddenAttribute()]
  31.         #endif
  32.         public abstract object GetValue(object thisob);
  33.        
  34.         #if !DEBUG
  35.         [DebuggerStepThroughAttribute()]
  36.         [DebuggerHiddenAttribute()]
  37.         #endif
  38.         public abstract void SetValue(object thisob, object value);
  39.        
  40.        
  41.         private static SimpleHashtable accessorFor = new SimpleHashtable(32);
  42.         private static int count = 0;
  43.        
  44.         static internal FieldAccessor GetAccessorFor(FieldInfo field)
  45.         {
  46.             FieldAccessor accessor = FieldAccessor.accessorFor[field] as FieldAccessor;
  47.             if (accessor != null)
  48.                 return accessor;
  49.             lock (FieldAccessor.accessorFor) {
  50.                 accessor = FieldAccessor.accessorFor[field] as FieldAccessor;
  51.                 if (accessor != null)
  52.                     return accessor;
  53.                 accessor = FieldAccessor.SpitAndInstantiateClassFor(field);
  54.                 FieldAccessor.accessorFor[field] = accessor;
  55.             }
  56.             return accessor;
  57.         }
  58.        
  59.         [ReflectionPermission(SecurityAction.Assert, Unrestricted = true)]
  60.         private static FieldAccessor SpitAndInstantiateClassFor(FieldInfo field)
  61.         {
  62.             Type ft = field.FieldType;
  63.             TypeBuilder tb = Runtime.ThunkModuleBuilder.DefineType("accessor" + FieldAccessor.count++, TypeAttributes.Public, typeof(FieldAccessor));
  64.            
  65.             MethodBuilder mb = tb.DefineMethod("GetValue", MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.ReuseSlot, typeof(object), new Type[] {typeof(object)});
  66.             #if !DEBUG
  67.             mb.SetCustomAttribute(new CustomAttributeBuilder(Runtime.TypeRefs.debuggerStepThroughAttributeCtor, new object[] {}));
  68.             mb.SetCustomAttribute(new CustomAttributeBuilder(Runtime.TypeRefs.debuggerHiddenAttributeCtor, new object[] {}));
  69.             #endif
  70.             ILGenerator il = mb.GetILGenerator();
  71.             if (field.IsLiteral)
  72.                 (new ConstantWrapper(TypeReferences.GetConstantValue(field), null)).TranslateToIL(il, ft);
  73.             else if (field.IsStatic)
  74.                 il.Emit(OpCodes.Ldsfld, field);
  75.             else {
  76.                 il.Emit(OpCodes.Ldarg_1);
  77.                 il.Emit(OpCodes.Ldfld, field);
  78.             }
  79.             if (ft.IsValueType)
  80.                 il.Emit(OpCodes.Box, ft);
  81.             il.Emit(OpCodes.Ret);
  82.            
  83.            
  84.             mb = tb.DefineMethod("SetValue", MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.ReuseSlot, typeof(void), new Type[] {typeof(object), typeof(object)});
  85.             #if !DEBUG
  86.             mb.SetCustomAttribute(new CustomAttributeBuilder(Runtime.TypeRefs.debuggerStepThroughAttributeCtor, new object[] {}));
  87.             mb.SetCustomAttribute(new CustomAttributeBuilder(Runtime.TypeRefs.debuggerHiddenAttributeCtor, new object[] {}));
  88.             #endif
  89.             il = mb.GetILGenerator();
  90.             if (!field.IsLiteral) {
  91.                 if (!field.IsStatic)
  92.                     il.Emit(OpCodes.Ldarg_1);
  93.                 il.Emit(OpCodes.Ldarg_2);
  94.                 if (ft.IsValueType)
  95.                     Convert.EmitUnbox(il, ft, Type.GetTypeCode(ft));
  96.                 if (field.IsStatic)
  97.                     il.Emit(OpCodes.Stsfld, field);
  98.                 else
  99.                     il.Emit(OpCodes.Stfld, field);
  100.             }
  101.             il.Emit(OpCodes.Ret);
  102.            
  103.             Type t = tb.CreateType();
  104.             return (FieldAccessor)Activator.CreateInstance(t);
  105.         }
  106.        
  107.     }
  108. }

Developer Fusion