Beispiel #1
0
        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);
        }
Beispiel #3
0
        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);
        }
Beispiel #4
0
        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);
            }
        }
Beispiel #5
0
        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);
            }
        }