void PopulateEnum(CilType data) { data.Builder.DefineField("value__", _linker.GetType(data.Definition.Base), FieldAttributes.Public | FieldAttributes.SpecialName | FieldAttributes.RTSpecialName); for (int i = 0, l = data.Definition.Literals.Count; i < l; i++) { var v = data.Definition.Literals[i]; var f = data.Builder.DefineField(v.UnoName, data.Builder, FieldAttributes.Public | FieldAttributes.Static | FieldAttributes.Literal); f.SetConstant(v.Value); } }
TypeBuilder CreateTypeBuilder(DataType dt, TypeBuilder parent, TypeAttributes typeAttrs, Type typeBase) { var result = parent?.DefineNestedType(dt.CilTypeName(), dt.CilTypeAttributes(true) | typeAttrs, typeBase) ?? _module.DefineType(dt.CilTypeName(), dt.CilTypeAttributes(false) | typeAttrs, typeBase); var data = new CilType(_linker, result, dt); if (!dt.IsEnum && dt.IsFlattenedDefinition) { var flatParams = dt.FlattenedParameters; var flatParamNames = new string[flatParams.Length]; for (int i = 0, l = flatParamNames.Length; i < l; i++) { flatParamNames[i] = flatParams[i].Name; } var resultParams = result.DefineGenericParameters(flatParamNames); for (int i = 0; i < resultParams.Length; i++) { data.GenericParameters.Add(new CilMember <GenericTypeParameterBuilder, GenericParameterType>(resultParams[i], flatParams[i])); } if (dt.IsGenericDefinition) { var dtParams = dt.GenericParameters; for (int i = 0, l = dtParams.Length; i < l; i++) { _linker.AddType(dtParams[i], resultParams[resultParams.Length - dtParams.Length + i]); } } } _linker.AddType(dt, result); _types.Add(data); return(result); }
void PopulateDelegate(CilType data) { var dt = (DelegateType)data.Definition; var cb = data.Builder.DefineConstructor( MethodAttributes.RTSpecialName | MethodAttributes.HideBySig | MethodAttributes.Public, CallingConventions.Standard, new[] { _linker.System_Object, _linker.System_IntPtr }); cb.SetImplementationFlags(MethodImplAttributes.Runtime | MethodImplAttributes.Managed); var mb = data.Builder.DefineMethod("Invoke", MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.NewSlot | MethodAttributes.Virtual, _linker.GetType(dt.ReturnType), _linker.GetParameterTypes(dt.Parameters)); mb.SetImplementationFlags(MethodImplAttributes.Runtime | MethodImplAttributes.Managed); if (_backend.IsPInvokable(_essentials, dt)) { for (int i = 0; i < dt.Parameters.Length; i++) { var p = dt.Parameters[i]; var pb = PInvokeBackend.DefineCilDelegateParameter(_linker.Universe, _essentials, mb, p, i); PopulateParameter(p, pb); } } else { for (int i = 0; i < dt.Parameters.Length; i++) { var p = dt.Parameters[i]; PopulateParameter(p, mb.DefineParameter(i + 1, p.CilParameterAttributes(), p.Name)); } } _linker.AddConstructor(data.Definition, cb); _linker.AddMethod(data.Definition, mb); }
void PopulateClassStructOrInterface(CilType data) { if (data.Definition is ClassType && data.Definition.Base != null) { data.Builder.SetParent(_linker.GetType(data.Definition.Base)); } foreach (var it in data.Definition.Interfaces) { data.Builder.AddInterfaceImplementation(_linker.GetType(it)); } foreach (var m in data.Definition.Fields) { _linker.AddField(m, data.DefineField(m, _linker.GetType(m.ReturnType))); } foreach (var m in data.Definition.Events) { var eb = data.DefineEvent(m, _linker.GetType(m.ReturnType)); if (m.ImplicitField != null) { _linker.AddField(m.ImplicitField, data.DefineField(m.ImplicitField, _linker.GetType(m.ImplicitField.ReturnType))); } if (m.AddMethod != null) { var mb = data.DefineMethod(m.AddMethod, MethodAttributes.SpecialName, _linker.GetType(m.AddMethod.ReturnType), _linker.GetParameterTypes(m.AddMethod.Parameters)); _linker.AddMethod(m.AddMethod, mb); eb.SetAddOnMethod(mb); } if (m.RemoveMethod != null) { var mb = data.DefineMethod(m.RemoveMethod, MethodAttributes.SpecialName, _linker.GetType(m.RemoveMethod.ReturnType), _linker.GetParameterTypes(m.RemoveMethod.Parameters)); _linker.AddMethod(m.RemoveMethod, mb); eb.SetRemoveOnMethod(mb); } } foreach (var m in data.Definition.Properties) { var pb = data.DefineProperty(m, m.Parameters.Length > 0 ? PropertyAttributes.SpecialName : 0, _linker.GetType(m.ReturnType), _linker.GetParameterTypes(m.Parameters)); if (m.ImplicitField != null) { _linker.AddField(m.ImplicitField, data.DefineField(m.ImplicitField, _linker.GetType(m.ImplicitField.ReturnType))); } if (m.GetMethod != null) { var mb = data.DefineMethod(m.GetMethod, MethodAttributes.SpecialName, _linker.GetType(m.GetMethod.ReturnType), _linker.GetParameterTypes(m.GetMethod.Parameters)); _linker.AddMethod(m.GetMethod, mb); pb.SetGetMethod(mb); } if (m.SetMethod != null) { var mb = data.DefineMethod(m.SetMethod, MethodAttributes.SpecialName, _linker.GetType(m.SetMethod.ReturnType), _linker.GetParameterTypes(m.SetMethod.Parameters)); _linker.AddMethod(m.SetMethod, mb); pb.SetSetMethod(mb); } } foreach (var m in data.Definition.Methods) { if (_backend.IsPInvokable(_essentials, m)) { var mb = PInvokeBackend.CreateCilPInvokeMethod( _linker.Universe, _essentials, data.Builder, m, m.CilMethodAttributes(), _linker.GetType(m.ReturnType), _linker.GetParameterTypes(m.Parameters)); m.SetBody(null); data.Methods.Add(new CilMember <MethodBuilder, Function>(mb, m)); _linker.AddMethod(m, mb); } else { var mb = data.DefineMethod(m); if (m.IsGenericDefinition) { var paramNames = new string[m.GenericParameters.Length]; for (int i = 0; i < paramNames.Length; i++) { paramNames[i] = m.GenericParameters[i].UnoName; } var paramTypes = mb.DefineGenericParameters(paramNames); for (int i = 0; i < paramTypes.Length; i++) { _linker.AddType(m.GenericParameters[i], paramTypes[i]); } for (int i = 0; i < paramTypes.Length; i++) { SetConstraints(paramTypes[i], m.GenericParameters[i]); } } mb.SetReturnType(_linker.GetType(m.ReturnType)); mb.SetParameters(_linker.GetParameterTypes(m.Parameters)); _linker.AddMethod(m, mb); if (m.Prototype != null && m.Prototype != m && m.Prototype.HasAttribute(_essentials.DotNetOverrideAttribute)) { _linker.AddMethod(m.Prototype, mb); } } } foreach (var m in data.Definition.Constructors) { var cb = data.DefineConstructor(m, _linker.GetParameterTypes(m.Parameters)); _linker.AddConstructor(m, cb); } foreach (var m in data.Definition.Casts) { var mb = data.DefineMethod(m, MethodAttributes.SpecialName, _linker.GetType(m.ReturnType), _linker.GetParameterTypes(m.Parameters)); _linker.AddMethod(m, mb); } foreach (var m in data.Definition.Operators) { var mb = data.DefineMethod(m, MethodAttributes.SpecialName, _linker.GetType(m.ReturnType), _linker.GetParameterTypes(m.Parameters)); _linker.AddMethod(m, mb); } if (data.Definition.Initializer != null) { data.DefineTypeInitializer(data.Definition.Initializer); } if (data.Definition.Finalizer != null) { data.DefineTypeFinalizer(data.Definition.Finalizer); } // Add dummy field if [TargetSpecificType] if (data.Definition.HasAttribute(_essentials.TargetSpecificTypeAttribute)) { data.Builder.DefineField("__ptr", _linker.System_IntPtr, FieldAttributes.Private); } }
void CompileType(CilType data) { try { if (data.Definition.Attributes != null) { foreach (var a in data.Definition.Attributes) { data.Builder.SetCustomAttribute(CreateAttributeBuilder(a)); } } foreach (var m in data.Fields) { if (m.Definition.Attributes != null) { foreach (var a in m.Definition.Attributes) { m.Builder.SetCustomAttribute(CreateAttributeBuilder(a)); } } } foreach (var m in data.Properties) { if (m.Definition.Attributes != null) { foreach (var a in m.Definition.Attributes) { m.Builder.SetCustomAttribute(CreateAttributeBuilder(a)); } } } foreach (var m in data.Events) { if (m.Definition.Attributes != null) { foreach (var a in m.Definition.Attributes) { m.Builder.SetCustomAttribute(CreateAttributeBuilder(a)); } } } foreach (var m in data.Constructors) { if (m.Definition.Attributes != null) { foreach (var a in m.Definition.Attributes) { m.Builder.SetCustomAttribute(CreateAttributeBuilder(a)); } } for (int i = 0; i < m.Definition.Parameters.Length; i++) { var p = m.Definition.Parameters[i]; data.PopulateParameter(p, m.Builder.DefineParameter(i + 1, p.CilParameterAttributes(), p.Name)); } EmitFunction(m.Builder.GetILGenerator(), m.Definition); } foreach (var m in data.Methods) { if (m.Definition.Attributes != null) { foreach (var a in m.Definition.Attributes) { m.Builder.SetCustomAttribute(CreateAttributeBuilder(a)); } } if (_backend.IsPInvokable(_essentials, m.Definition)) { continue; } for (int i = 0; i < m.Definition.Parameters.Length; i++) { var p = m.Definition.Parameters[i]; data.PopulateParameter(p, m.Builder.DefineParameter(i + 1, p.CilParameterAttributes(), p.Name)); } if (m.Definition.Parameters.Length > 0 && m.Definition.Parameters[0].Modifier == ParameterModifier.This) { m.Builder.SetCustomAttribute(new CustomAttributeBuilder(_linker.System_Runtime_CompilerServices_ExtensionAttribute_ctor, new object[0])); } var method = m.Definition as Method; if (method?.ImplementedMethod != null) { var im = method.ImplementedMethod; if (im.IsGenericParameterization) { im = im.GenericDefinition; } data.Builder.DefineMethodOverride(m.Builder, _linker.GetMethod(im)); } if (!m.Definition.IsAbstract) { EmitFunction(m.Builder.GetILGenerator(), m.Definition); } } var inheritedProperties = new Dictionary <string, PropertyBuilder>(); var inheritedEvents = new Dictionary <string, EventBuilder>(); foreach (var mi in FindInheritedInterfaceMethods(data)) { var name = mi.Name; var prefix = mi.ReflectedType.Namespace + "." + mi.ReflectedType.Name + "."; var rt = ParameterizeReturnType(mi); var pl = ParameterizeParameterList(mi); var mb = data.Builder.DefineMethod(prefix + name, MethodAttributes.Virtual | MethodAttributes.SpecialName | MethodAttributes.Final | MethodAttributes.HideBySig | MethodAttributes.NewSlot | MethodAttributes.Private, rt, pl); var cil = mb.GetILGenerator(); cil.BeginScope(); cil.Emit(OpCodes.Ldstr, mb.Name); cil.Emit(OpCodes.Newobj, _linker.System_NotSupportedException_ctor); cil.Emit(OpCodes.Throw); cil.EndScope(); data.Builder.DefineMethodOverride(mb, mi); var type = 0; if (name.StartsWith("get_", StringComparison.InvariantCulture)) { type = 1; } else if (name.StartsWith("set_", StringComparison.InvariantCulture)) { type = 2; } else if (name.StartsWith("add_", StringComparison.InvariantCulture)) { type = 3; } else if (name.StartsWith("remove_", StringComparison.InvariantCulture)) { type = 4; } if (type != 0) { var pname = prefix + name.Substring(name.IndexOf('_') + 1); switch (type) { case 1: case 2: { PropertyBuilder pb; if (!inheritedProperties.TryGetValue(pname, out pb)) { pb = data.Builder.DefineProperty(pname, PropertyAttributes.None, type == 2 ? pl[0] : rt, Type.EmptyTypes); inheritedProperties.Add(pname, pb); } switch (type) { case 1: pb.SetGetMethod(mb); break; case 2: pb.SetSetMethod(mb); break; } break; } default: { EventBuilder pb; if (!inheritedEvents.TryGetValue(pname, out pb)) { pb = data.Builder.DefineEvent(pname, EventAttributes.None, pl[0]); inheritedEvents.Add(pname, pb); } switch (type) { case 3: pb.SetAddOnMethod(mb); break; case 4: pb.SetRemoveOnMethod(mb); break; } break; } } } } data.Builder.CreateType(); } catch (Exception e) { Log.Error("Failed to compile .NET type " + data.Definition.Quote() + ": " + e.Message); } }