Ejemplo n.º 1
0
        void Fix(FixOp fo, Action store, bool pop)
        {
            switch (fo.Operator)
            {
            case FixOpType.IncreaseBefore:
            case FixOpType.DecreaseBefore:
            {
                LoadOne(fo.Operand.ReturnType);         // obj value 1
                Emit(fo.Operator == FixOpType.IncreaseBefore
                                ? Opcodes.Add
                                : Opcodes.Sub);
                var temp = StoreTemp(fo.Operand.ReturnType, pop); // obj (value+-1)
                store();
                LoadTemp(temp);                                   // (value+-1)
            }
            break;

            case FixOpType.IncreaseAfter:
            case FixOpType.DecreaseAfter:
            {
                var temp = StoreTemp(fo.Operand.ReturnType, pop); // obj value
                LoadOne(fo.Operand.ReturnType);                   // obj value 1
                Emit(fo.Operator == FixOpType.IncreaseAfter
                                ? Opcodes.Add
                                : Opcodes.Sub);
                store();
                LoadTemp(temp);         // value
            }
            break;
            }
        }
Ejemplo n.º 2
0
        public virtual void WriteFixOp(FixOp s, ExpressionUsage u)
        {
            Begin(u);

            switch (s.Operator)
            {
            case FixOpType.IncreaseBefore: Write("++"); break;

            case FixOpType.DecreaseBefore: Write("--"); break;
            }

            WriteExpression(s.Operand, ExpressionUsage.Object);

            switch (s.Operator)
            {
            case FixOpType.IncreaseAfter: Write("++"); break;

            case FixOpType.DecreaseAfter: Write("--"); break;
            }

            End(u);
        }
Ejemplo n.º 3
0
        void CompileFixOp(FixOp fo, bool pop, bool addressMode)
        {
            switch (fo.Operand.ExpressionType)
            {
            case ExpressionType.LoadLocal:
            {
                var ll = fo.Operand as LoadLocal;

                Emit(Opcodes.LoadLocal, ll.Variable);
                Fix(fo, () => Emit(Opcodes.StoreLocal, ll.Variable), pop);
            }
            break;

            case ExpressionType.LoadField:
            {
                var lf = fo.Operand as LoadField;

                if (lf.Object != null)
                {
                    CompileExpression(lf.Object);      // obj
                    Emit(Opcodes.Dup);                 // obj obj
                    Emit(Opcodes.LoadField, lf.Field); // obj value
                    Fix(fo, () => Emit(Opcodes.StoreField, lf.Field), pop);
                }
                else
                {
                    Emit(Opcodes.LoadStaticfield, lf.Field);         // value
                    Fix(fo, () => Emit(Opcodes.StoreStaticField, lf.Field), pop);
                }
            }
            break;

            case ExpressionType.LoadElement:
            {
                var lae     = fo.Operand as LoadElement;
                var elmType = lae.Array.ReturnType.ElementType;

                CompileExpression(lae.Array); // array
                Emit(Opcodes.Dup);            // array array

                CompileExpression(lae.Index); // array array index
                var tempIndex = StoreTemp(lae.Index.ReturnType, false);

                Emit(Opcodes.LoadArrayElement, elmType);         // array value

                Fix(fo, () =>
                    {
                        // array (value+-1)
                        var tempValue = StoreTempDontDup(elmType); // array
                        LoadTemp(tempIndex);                       // array index
                        LoadTemp(tempValue);                       // array index value
                        Emit(Opcodes.StoreArrayElement, elmType);  //
                    }, pop);
            }
            break;

            case ExpressionType.LoadArgument:
            {
                var lp = fo.Operand as LoadArgument;

                var paramRef = lp.Parameter.IsReference;

                if (!paramRef)
                {
                    Emit(Opcodes.LoadArg, lp.Index);         // value
                    Fix(fo, () => Emit(Opcodes.StoreArg, lp.Index), pop);
                }
                else
                {
                    Emit(Opcodes.LoadArg, lp.Index);          // argptr
                    Emit(Opcodes.LoadArg, lp.Index);          // argptr argptr
                    Emit(Opcodes.LoadObj, lp.Parameter.Type); // argpr value
                    Fix(fo, () => Emit(Opcodes.StoreObj, lp.Parameter.Type), pop);
                }
            }
            break;

            default:
                throw new FatalException(fo.Source, ErrorCode.I0027, "Unhandled fix-operator");
            }

            if (!pop && addressMode)
            {
                CreateIndirection(fo.Operand.ReturnType);
            }
        }