Пример #1
0
        public static Expression[] CreateArgumentList(Source src, Function f)
        {
            var result = new Expression[f.Parameters.Length];

            for (int i = 0; i < result.Length; i++)
            {
                result[i] = new LoadArgument(src, f, i);

                switch (f.Parameters[i].Modifier)
                {
                case ParameterModifier.Const:
                    result[i] = new AddressOf(result[i], AddressType.Const);
                    break;

                case ParameterModifier.Ref:
                    result[i] = new AddressOf(result[i], AddressType.Ref);
                    break;

                case ParameterModifier.Out:
                    result[i] = new AddressOf(result[i], AddressType.Out);
                    break;
                }
            }

            return(result);
        }
Пример #2
0
 public override void WriteLoadArgument(LoadArgument s, ExpressionUsage u)
 {
     if (s.Parameter.IsReference)
     {
         base.WriteLoadArgument(s, ExpressionUsage.Object);
         Write("()");
     }
     else
     {
         base.WriteLoadArgument(s, u);
     }
 }
Пример #3
0
            public override void Begin(ref Expression e, ExpressionUsage u)
            {
                switch (e.ExpressionType)
                {
                case ExpressionType.CapturedArgument:
                {
                    var s = e as CapturedArgument;
                    e = new LoadArgument(s.Source, s.Function, s.ParameterIndex);
                }
                break;

                case ExpressionType.CapturedLocal:
                {
                    var s = e as CapturedLocal;
                    e = new LoadLocal(s.Source, s.Variable);
                }
                break;

                case ExpressionType.AddressOf:
                {
                    var s = e as AddressOf;

                    switch (s.Operand.ExpressionType)
                    {
                    case ExpressionType.LoadField:
                    {
                        var v = s.Operand as LoadField;

                        if (TransformedVars.Contains(v.Field))
                        {
                            e = s.Operand;
                            Begin(ref e, u);
                        }
                    }
                    break;

                    case ExpressionType.LoadLocal:
                    {
                        var v = s.Operand as LoadLocal;

                        if (TransformedVars.Contains(v.Variable))
                        {
                            e = s.Operand;
                            Begin(ref e, u);
                        }
                    }
                    break;
                    }
                }
                break;
                }
            }
Пример #4
0
        Method GetBoxedMethod(DataType dt, Method decl, Method impl)
        {
            if (dt.IsMasterDefinition)
            {
                var m = new Method(impl.Source, dt, impl.DocComment, Modifiers.Public | Modifiers.Generated, impl.Name + "_boxed",
                                   decl.ReturnType, decl.Parameters, new Scope(impl.Source));

                Variable ret = null;
                if (!impl.ReturnType.IsVoid && _backend.IsConstrained(impl))
                {
                    ret = new Variable(m.Source, m, dt.GetUniqueIdentifier("ret"), impl.ReturnType);
                    m.Body.Statements.Add(new VariableDeclaration(ret));
                }

                var args = new Expression[m.Parameters.Length];
                for (int i = 0; i < args.Length; i++)
                {
                    args[i] = new LoadArgument(m.Source, m, i);
                }

                m.Body.Statements.Add(
                    new Return(m.Source,
                               new CastOp(m.Source, m.ReturnType,
                                          new CallMethod(m.Source, new This(m.Source, dt).Address, impl, args, ret))));
                m.SetPrototype(impl);
                dt.Methods.Add(m);
                dt.InterfaceMethods[decl] = m;
                return(m);
            }

            foreach (var e in dt.MasterDefinition.InterfaceMethods)
            {
                if (e.Value.Modifiers != (Modifiers.Public | Modifiers.Generated) ||
                    e.Key.MasterDefinition != decl.MasterDefinition)
                {
                    continue;
                }

                var m = new Method(impl.Source, dt,
                                   e.Value.DocComment, e.Value.Modifiers, e.Value.Name,
                                   decl.ReturnType, decl.Parameters, e.Value.Body);
                m.SetMasterDefinition(e.Value);
                m.SetPrototype(impl);
                dt.Methods.Add(m);
                dt.InterfaceMethods[decl] = m;
                return(m);
            }

            Log.Error(impl.Source, ErrorCode.I0000, "C++: Boxed method master definition was not found.");
            return(impl);
        }
Пример #5
0
        public override void End(ref Expression e, ExpressionUsage u)
        {
            switch (e.ExpressionType)
            {
            case ExpressionType.Lambda:
            {
                if (e == _lambda)
                {
                    var lambda = (Lambda)e;
                    e = new NewDelegate(
                        e.Source,
                        (DelegateType)lambda.ReturnType,
                        _closureStack.Peek().Expression,
                        _lambdaMethod);

                    _lambda       = null;
                    _lambdaMethod = null;
                }
                break;
            }

            case ExpressionType.LoadLocal:
            {
                var load = (LoadLocal)e;

                if (_closureVars.Contains(load.Variable))
                {
                    e = _lambda == null
                            ? _closureStack.Peek().Load(load.Variable)
                            : _closureStack.Peek().LoadInside(load.Variable);
                }
                break;
            }

            case ExpressionType.LoadArgument:
            {
                var load = (LoadArgument)e;
                if (_closureVars.Contains(load.Parameter))
                {
                    e = _lambda == null
                            ? _closureStack.Peek().Load(load.Parameter)
                            : _closureStack.Peek().LoadInside(load.Parameter);
                }
                else if (load.Function.Match(_ => false, lam => lam == _lambda))
                {
                    e = new LoadArgument(load.Source, _lambdaMethod, load.Index);
                }
                break;
            }

            case ExpressionType.This:
            {
                if (_closureVars.This && _lambda != null)
                {
                    e = _closureStack.Peek().ThisInside();
                }
                break;
            }

            case ExpressionType.StoreLocal:
            {
                var store = (StoreLocal)e;
                if (_closureVars.Contains(store.Variable))
                {
                    e = _lambda == null
                            ? _closureStack.Peek().Store(store.Variable, store.Value)
                            : _closureStack.Peek().StoreInside(store.Variable, store.Value);
                }
                break;
            }

            case ExpressionType.StoreArgument:
            {
                var store = (StoreArgument)e;
                if (_closureVars.Contains(store.Parameter))
                {
                    e = _lambda == null
                            ? _closureStack.Peek().Store(store.Parameter, store.Value)
                            : _closureStack.Peek().StoreInside(store.Parameter, store.Value);
                }
                else if (store.Function.Match(_ => false, lam => lam == _lambda))
                {
                    e = new StoreArgument(store.Source, _lambdaMethod, store.Index, store.Value);
                }
                break;
            }

            case ExpressionType.StoreThis:
            {
                var store = (StoreThis)e;
                if (_closureVars.This)
                {
                    e = _lambda == null
                            ? _closureStack.Peek().StoreThis(store.Value)
                            : _closureStack.Peek().StoreThisInside(store.Value);
                }
                break;
            }
            }
        }
Пример #6
0
 public virtual void WriteLoadArgument(LoadArgument s, ExpressionUsage u)
 {
     Write(s.Parameter.Name);
 }
Пример #7
0
        void FlattenMembers(DataType dt)
        {
            if (dt.HasAttribute(Essentials.DontExportAttribute))
            {
                return;
            }

            if (Backend.Has(TypeOptions.FlattenConstructors))
            {
                foreach (var f in dt.Constructors)
                {
                    var    src  = f.Source;
                    Method init = null
                    , factory   = null;

                    if (f.DeclaringType.BuiltinType != BuiltinType.Object)
                    {
                        init = new Method(src, dt, f.DocComment,
                                          (f.Modifiers & ~Modifiers.ProtectionModifiers) | Modifiers.Protected,
                                          ".ctor", DataType.Void, f.Parameters, f.Body);
                        if (!f.IsMasterDefinition)
                        {
                            init.SetMasterDefinition(((ConstructorPair)f.MasterDefinition.Tag).Initializer);
                        }
                        init.SetPrototype(f);
                        dt.Methods.Add(init);
                    }

                    if (!dt.IsAbstract)
                    {
                        var pt = TypeBuilder.Parameterize(dt.MasterDefinition);

                        if (f.IsMasterDefinition)
                        {
                            factory = new Method(src, dt, f.DocComment,
                                                 (f.Modifiers & Modifiers.ProtectionModifiers) | Modifiers.Static | Modifiers.Generated,
                                                 "New", pt, f.Parameters, new Scope(src));
                        }
                        else
                        {
                            var master = ((ConstructorPair)f.MasterDefinition.Tag).Factory;
                            factory = new Method(src, dt, f.DocComment,
                                                 (f.Modifiers & Modifiers.ProtectionModifiers) | Modifiers.Static | Modifiers.Generated,
                                                 master.UnoName, dt, f.Parameters, master.Body);
                            factory.SetMasterDefinition(master);
                        }

                        factory.SetPrototype(f);
                        dt.Methods.Add(factory);

                        if (pt == dt)
                        {
                            var var = new Variable(src, factory, dt.MasterDefinition.GetUniqueIdentifier("obj"), dt);

                            if (dt.IsClass)
                            {
                                var.OptionalValue = new AllocObject(src, dt);
                            }
                            else if (Backend.Has(TypeOptions.CopyStructs))
                            {
                                var.OptionalValue = new Default(src, dt);
                            }

                            factory.Body.Statements.Add(new VariableDeclaration(var));

                            if (init != null)
                            {
                                var args = new Expression[f.Parameters.Length];

                                for (int i = 0; i < args.Length; i++)
                                {
                                    args[i] = new LoadArgument(src, factory, i);

                                    switch (f.Parameters[i].Modifier)
                                    {
                                    case ParameterModifier.Out:
                                        args[i] = new AddressOf(args[i], AddressType.Out);
                                        break;

                                    case ParameterModifier.Ref:
                                        args[i] = new AddressOf(args[i], AddressType.Ref);
                                        break;

                                    case ParameterModifier.Const:
                                        args[i] = new AddressOf(args[i], AddressType.Const);
                                        break;
                                    }
                                }

                                factory.Body.Statements.Add(new CallMethod(src, new LoadLocal(src, var).Address, init, args));
                            }

                            factory.Body.Statements.Add(new Return(src, new LoadLocal(src, var)));
                        }
                    }

                    f.Tag = new ConstructorPair
                    {
                        Initializer = init,
                        Factory     = factory
                    };
                }

                dt.Constructors.Clear();
            }
            if (Backend.Has(TypeOptions.FlattenProperties))
            {
                foreach (var f in dt.Properties)
                {
                    if (f.GetMethod != null)
                    {
                        dt.Methods.Add(f.GetMethod);
                    }
                    if (f.SetMethod != null)
                    {
                        dt.Methods.Add(f.SetMethod);
                    }
                    if (f.ImplicitField != null)
                    {
                        dt.Fields.Add(f.ImplicitField);
                    }
                }

                dt.Properties.Clear();
            }
            if (Backend.Has(TypeOptions.FlattenEvents))
            {
                foreach (var f in dt.Events)
                {
                    if (f.AddMethod != null)
                    {
                        dt.Methods.Add(f.AddMethod);
                    }
                    if (f.RemoveMethod != null)
                    {
                        dt.Methods.Add(f.RemoveMethod);
                    }
                    if (f.ImplicitField != null)
                    {
                        dt.Fields.Add(f.ImplicitField);
                    }
                }

                dt.Events.Clear();
            }
            if (Backend.Has(TypeOptions.FlattenOperators))
            {
                foreach (var f in dt.Operators)
                {
                    if (f.IsIntrinsic)
                    {
                        continue;
                    }

                    var m = new Method(f.Source, dt, f.DocComment, f.Modifiers, f.UnoName, f.ReturnType, f.Parameters, f.Body);
                    m.SetMasterDefinition(f.MasterDefinition.Tag as Method);
                    m.SetPrototype(f);
                    dt.Methods.Add(m);
                    f.Tag = m;
                }

                dt.Operators.Clear();
            }
            if (Backend.Has(TypeOptions.FlattenCasts))
            {
                foreach (var f in dt.Casts)
                {
                    if (f.IsIntrinsic)
                    {
                        continue;
                    }

                    var m = new Method(f.Source, dt, f.DocComment, f.Modifiers & ~Modifiers.CastModifiers, f.UnoName, f.ReturnType, f.Parameters, f.Body);
                    m.SetMasterDefinition(f.MasterDefinition.Tag as Method);
                    m.SetPrototype(f);
                    dt.Methods.Add(m);
                    f.Tag = m;
                }

                dt.Casts.Clear();
            }
        }