// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
+#if !FULL_AOT_RUNTIME
using System;
using System.IO;
using System.Collections;
internal class CodeGenerator
{
// Code generation
+
+ static object monitor = new object ();
static ModuleBuilder _module;
- static public Type GenerateMetadataType (Type type, StreamingContext context)
+ static CodeGenerator ()
{
- if (_module == null)
- {
- lock (typeof (ObjectWriter))
- {
- if (_module == null) {
- AppDomain myDomain = System.Threading.Thread.GetDomain();
- AssemblyName myAsmName = new AssemblyName();
- myAsmName.Name = "__MetadataTypes";
-
- AssemblyBuilder myAsmBuilder = myDomain.DefineDynamicAssembly (myAsmName, AssemblyBuilderAccess.Run);
- myAsmBuilder.CorlibInternal = true;
- _module = myAsmBuilder.DefineDynamicModule("__MetadataTypesModule", true);
- }
- }
+ AppDomain myDomain = System.Threading.Thread.GetDomain();
+ AssemblyName myAsmName = new AssemblyName();
+ myAsmName.Name = "__MetadataTypes";
+
+ AssemblyBuilder myAsmBuilder = myDomain.DefineInternalDynamicAssembly (myAsmName, AssemblyBuilderAccess.Run);
+ _module = myAsmBuilder.DefineDynamicModule("__MetadataTypesModule", false);
+ }
+
+ static public Type GenerateMetadataType (Type type, StreamingContext context) {
+ /* SRE is not thread safe */
+ lock (monitor) {
+ return GenerateMetadataTypeInternal (type, context);
}
-
+ }
+
+ static public Type GenerateMetadataTypeInternal (Type type, StreamingContext context)
+ {
string name = type.Name + "__TypeMetadata";
string sufix = "";
int n = 0;
MemberInfo[] members = FormatterServices.GetSerializableMembers (type, context);
- TypeBuilder typeBuilder = _module.DefineType (name, TypeAttributes.Public, typeof(TypeMetadata));
+ TypeBuilder typeBuilder = _module.DefineType (name, TypeAttributes.Public, typeof(ClrTypeMetadata));
Type[] parameters;
MethodBuilder method;
// *********************
// METHOD public constructor (Type t): base (t);
- parameters = new Type[0];
+ parameters = Type.EmptyTypes;
- ConstructorBuilder ctor = typeBuilder.DefineConstructor (MethodAttributes.Public, CallingConventions.Standard, parameters);
- ConstructorInfo baseCtor = typeof(TypeMetadata).GetConstructor (new Type[] { typeof(Type) });
+ ConstructorBuilder ctor = typeBuilder.DefineConstructor (MethodAttributes.Public, CallingConventions.Standard, parameters);
+ ConstructorInfo baseCtor = typeof(ClrTypeMetadata).GetConstructor (new Type[] { typeof(Type) });
gen = ctor.GetILGenerator();
gen.Emit (OpCodes.Ldarg_0);
// EMIT ow.WriteAssembly (writer, memberType.Assembly);
gen.Emit (OpCodes.Ldarg_1);
gen.Emit (OpCodes.Ldarg_2);
+#if NET_4_0
+ EmitLoadType (gen, memberType);
+ gen.EmitCall (OpCodes.Callvirt, typeof(ObjectWriter).GetMethod("WriteTypeAssembly"), null);
+#else
EmitLoadTypeAssembly (gen, memberType, field.Name);
gen.EmitCall (OpCodes.Callvirt, typeof(ObjectWriter).GetMethod("WriteAssembly"), null);
+#endif
gen.Emit (OpCodes.Pop);
}
}
typeBuilder.DefineMethodOverride (method, typeof(TypeMetadata).GetMethod ("WriteAssemblies"));
// *********************
- // METHOD public override void WriteTypeData (ObjectWriter ow, BinaryWriter writer);
+ // METHOD public override void WriteTypeData (ObjectWriter ow, BinaryWriter writer, bool writeTypes);
- parameters = new Type[] { typeof(ObjectWriter), typeof(BinaryWriter) };
+ parameters = new Type[] { typeof(ObjectWriter), typeof(BinaryWriter), typeof(bool) };
method = typeBuilder.DefineMethod ("WriteTypeData", MethodAttributes.Public | MethodAttributes.Virtual, typeof(void), parameters);
gen = method.GetILGenerator();
{
// EMIT writer.Write (name);
gen.Emit (OpCodes.Ldarg_2);
-
- if (field.DeclaringType == type)
- gen.Emit (OpCodes.Ldstr, field.Name);
- else
- gen.Emit (OpCodes.Ldstr, field.DeclaringType.Name + "+" + field.Name);
+ gen.Emit (OpCodes.Ldstr, field.Name);
EmitWrite (gen, typeof(string));
}
+ Label falseLabel = gen.DefineLabel ();
+ gen.Emit (OpCodes.Ldarg_3);
+ gen.Emit (OpCodes.Brfalse, falseLabel);
+
// Types of fields
foreach (FieldInfo field in members)
{
// EMIT ow.WriteTypeSpec (writer, field.FieldType);
EmitWriteTypeSpec (gen, field.FieldType, field.Name);
}
+ gen.MarkLabel(falseLabel);
gen.Emit(OpCodes.Ret);
typeBuilder.DefineMethodOverride (method, typeof(TypeMetadata).GetMethod ("WriteTypeData"));
ig.Emit (OpCodes.Ldind_Ref);
}
- public static void EmitWriteTypeSpec (ILGenerator gen, Type type, string member)
+ static void EmitWriteTypeSpec (ILGenerator gen, Type type, string member)
{
// WARNING Keep in sync with WriteTypeSpec
// EMIT writer.Write ((int)ow.GetAssemblyId (type.Assembly));
gen.Emit (OpCodes.Ldarg_2);
gen.Emit (OpCodes.Ldarg_1);
+#if NET_4_0
+ EmitLoadType (gen, type);
+ gen.EmitCall (OpCodes.Callvirt, typeof(GetForwardedAttribute).GetMethod("GetAssemblyName"), null);
+ gen.EmitCall (OpCodes.Callvirt, typeof(ObjectWriter).GetMethod("GetAssemblyNameId"), null);
+#else
EmitLoadTypeAssembly (gen, type, member);
gen.EmitCall (OpCodes.Callvirt, typeof(ObjectWriter).GetMethod("GetAssemblyId"), null);
+#endif
gen.Emit (OpCodes.Conv_I4);
EmitWrite (gen, typeof(int));
break;
gen.EmitCall (OpCodes.Callvirt, typeof(Type).GetProperty("Assembly").GetGetMethod(), null);
}
+ static void EmitLoadType (ILGenerator gen, Type type)
+ {
+ gen.Emit (OpCodes.Ldtoken, type);
+ gen.EmitCall (OpCodes.Call, typeof(Type).GetMethod("GetTypeFromHandle"), null);
+ }
+
static void EmitWrite (ILGenerator gen, Type type)
{
gen.EmitCall (OpCodes.Callvirt, typeof(BinaryWriter).GetMethod("Write", new Type[] { type }), null);
break;
case TypeCode.DateTime:
- gen.EmitCall (OpCodes.Call, typeof(DateTime).GetProperty("Ticks").GetGetMethod(), null);
+ gen.EmitCall (OpCodes.Call, typeof(DateTime).GetMethod("ToBinary", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance), null);
EmitWrite (gen, typeof(long));
break;
}
}
+#endif