コード例 #1
0
ファイル: AstHashLiteral.cs プロジェクト: SealedSun/prx
        protected override void DoEmitCode(CompilerTarget target, StackSemantics stackSemantics)
        {
            if (Elements.Count == 0)
            {
                target.Emit(Position,OpCode.newobj, 0, "Hash");
            }
            else
            {
                foreach (var element in Elements)
                {
                    if (element is AstConstant)
                        throw new PrexoniteException(
                            String.Concat(
                                "Hashes are built from key-value pairs, not constants like ",
                                element,
                                ". [File: ",
                                File,
                                ", Line: ",
                                Line,
                                "]"));
                    element.EmitCode(target,stackSemantics);
                }

                if(stackSemantics == StackSemantics.Effect)
                    return;

                target.EmitStaticGetCall(Position, Elements.Count, "Hash", "Create", false);
            }
        }
コード例 #2
0
        protected override void DoEmitCode(CompilerTarget target, StackSemantics stackSemantics)
        {
            if(stackSemantics == StackSemantics.Effect)
                return;

            target.Emit(Position,OpCode.ldr_type, TypeExpression);
        }
コード例 #3
0
ファイル: AstNull.cs プロジェクト: SealedSun/prx
        protected override void DoEmitCode(CompilerTarget target, StackSemantics stackSemantics)
        {
            if(stackSemantics == StackSemantics.Effect)
                return;

            target.EmitNull(Position);
        }
コード例 #4
0
ファイル: AstAsmInstruction.cs プロジェクト: SealedSun/prx
        protected override void DoEmitCode(CompilerTarget target, StackSemantics stackSemantics)
        {
            //Jumps need special treatment for label resolution

            if (Instruction.Arguments == -1)
            {
                switch (Instruction.OpCode)
                {
                    case OpCode.jump:
                        target.EmitJump(Position, Instruction.Id);
                        break;
                    case OpCode.jump_t:
                        target.EmitJumpIfTrue(Position, Instruction.Id);
                        break;
                    case OpCode.jump_f:
                        target.EmitJumpIfFalse(Position, Instruction.Id);
                        break;
                    case OpCode.leave:
                        target.EmitLeave(Position, Instruction.Id);
                        break;
                    default:
                        goto emitNormally;
                }
            }
            else
                goto emitNormally;

            return;
            emitNormally:
            target.Emit(Position, Instruction);
        }
コード例 #5
0
ファイル: AstLogicalOr.cs プロジェクト: SealedSun/prx
        protected override void DoEmitCode(CompilerTarget target, StackSemantics stackSemantics)
        {
            var labelNs = @"Or\" + Guid.NewGuid().ToString("N");
            var trueLabel = @"True\" + labelNs;
            var falseLabel = @"False\" + labelNs;
            var evalLabel = @"Eval\" + labelNs;

            EmitCode(target, trueLabel, falseLabel);

            if (stackSemantics == StackSemantics.Value)
            {
                target.EmitLabel(Position, falseLabel);
                target.EmitConstant(Position, false);
                target.EmitJump(Position, evalLabel);
                target.EmitLabel(Position, trueLabel);
                target.EmitConstant(Position, true);
                target.EmitLabel(Position, evalLabel);
            }
            else
            {
                Debug.Assert(stackSemantics == StackSemantics.Effect);
                target.EmitLabel(Position, falseLabel);
                target.EmitLabel(Position, trueLabel);
            }
        }
コード例 #6
0
ファイル: AstUsing.cs プロジェクト: SealedSun/prx
        protected override void DoEmitCode(CompilerTarget target, StackSemantics stackSemantics)
        {
            if(stackSemantics == StackSemantics.Value)
                throw new NotSupportedException("Using blocks do not produce values and can thus not be used as expressions.");

            if (_resourceExpression == null)
                throw new PrexoniteException("AstUsing requires Expression to be initialized.");

            var tryNode = new AstTryCatchFinally(Position, this);
            var vContainer = _block.CreateLabel("container");
            target.Function.Variables.Add(vContainer);
            //Try block => Container = {Expression}; {Block};
            var setCont = target.Factory.Call(Position, EntityRef.Variable.Local.Create(vContainer),PCall.Set);
            setCont.Arguments.Add(_resourceExpression);

            var getCont = target.Factory.Call(Position, EntityRef.Variable.Local.Create(vContainer));

            var tryBlock = tryNode.TryBlock;
            tryBlock.Add(setCont);
            tryBlock.AddRange(_block);

            //Finally block => dispose( Container );
            var dispose = target.Factory.Call(Position, EntityRef.Command.Create(Engine.DisposeAlias));
            dispose.Arguments.Add(getCont);

            tryNode.FinallyBlock.Add(dispose);

            //Emit code!
            tryNode.EmitEffectCode(target);
        }
コード例 #7
0
ファイル: AstThrow.cs プロジェクト: SealedSun/prx
        protected override void DoEmitCode(CompilerTarget target, StackSemantics stackSemantics)
        {
            if (Expression == null)
                throw new PrexoniteException("Expression must be assigned.");

            Expression.EmitValueCode(target);
            target.Emit(Position,OpCode.@throw);

            if (stackSemantics == StackSemantics.Value)
                target.Emit(Position,OpCode.ldc_null);
        }
コード例 #8
0
ファイル: AstKeyValuePair.cs プロジェクト: SealedSun/prx
        protected override void DoEmitCode(CompilerTarget target, StackSemantics stackSemantics)
        {
            if (Key == null)
                throw new PrexoniteException("AstKeyValuePair.Key must be initialized.");
            if (Value == null)
                throw new ArgumentNullException("target");

            var call = target.Factory.Call(Position, EntityRef.Command.Create(Engine.PairAlias));
            call.Arguments.Add(Key);
            call.Arguments.Add(Value);
            call.EmitCode(target, stackSemantics);
        }
コード例 #9
0
ファイル: AstCreateCoroutine.cs プロジェクト: SealedSun/prx
        protected override void DoEmitCode(CompilerTarget target, StackSemantics stackSemantics)
        {
            if(stackSemantics == StackSemantics.Effect)
                return;

            if (Expression == null)
                throw new PrexoniteException("CreateCoroutine node requires an Expression.");

            Expression.EmitValueCode(target);
            foreach (var argument in _arguments)
                argument.EmitValueCode(target);

            target.Emit(Position,OpCode.newcor, _arguments.Count);
        }
コード例 #10
0
ファイル: AstCreateClosure.cs プロジェクト: SealedSun/prx
        protected override void DoEmitCode(CompilerTarget target, StackSemantics stackSemantics)
        {
            if (stackSemantics == StackSemantics.Effect)
                return;

            PFunction targetFunction;
            MetaEntry sharedNamesEntry;
            if (target.Loader.ParentApplication.TryGetFunction(_implementation.Id, _implementation.ModuleName, out targetFunction)
                && (!targetFunction.Meta.TryGetValue(PFunction.SharedNamesKey, out sharedNamesEntry)
                    || !sharedNamesEntry.IsList
                        || sharedNamesEntry.List.Length == 0))
                target.Emit(Position,OpCode.ldr_func, _implementation.Id, target.ToInternalModule(_implementation.ModuleName));
            else
                target.Emit(Position,OpCode.newclo, _implementation.Id, target.ToInternalModule(_implementation.ModuleName));
        }
コード例 #11
0
ファイル: AstTypeCast.cs プロジェクト: SealedSun/prx
        protected override void DoEmitCode(CompilerTarget target, StackSemantics stackSemantics)
        {
            if(stackSemantics == StackSemantics.Effect)
                return;

            Subject.EmitValueCode(target);
            var constType = Type as AstConstantTypeExpression;
            if (constType != null)
                target.Emit(Position,OpCode.cast_const, constType.TypeExpression);
            else
            {
                Type.EmitValueCode(target);
                target.Emit(Position,OpCode.cast_arg);
            }
        }
コード例 #12
0
ファイル: AstGetSetStatic.cs プロジェクト: SealedSun/prx
        protected override void EmitGetCode(CompilerTarget target, StackSemantics stackSemantics)
        {
            var constType = TypeExpr as AstConstantTypeExpression;

            var justEffect = stackSemantics == StackSemantics.Effect;
            if (constType != null)
            {
                EmitArguments(target);
                target.EmitStaticGetCall(Position, Arguments.Count, constType.TypeExpression, _memberId, justEffect);
            }
            else
            {
                TypeExpr.EmitValueCode(target);
                target.EmitConstant(Position, _memberId);
                EmitArguments(target);
                target.EmitGetCall(Position, Arguments.Count + 1, PType.StaticCallFromStackId, justEffect);
            }
        }
コード例 #13
0
ファイル: AstReturn.cs プロジェクト: SealedSun/prx
        protected override void DoEmitCode(CompilerTarget target, StackSemantics stackSemantics)
        {
            if(stackSemantics == StackSemantics.Value)
                throw new NotSupportedException("Return nodes cannot be used with value stack semantics. (They don't produce any values)");

            var warned = false;
            if (target.Function.Meta[Coroutine.IsCoroutineKey].Switch)
                _warnInCoroutines(target, ref warned);

            if (Expression != null)
            {
                _OptimizeNode(target, ref Expression);
                if (ReturnVariant == ReturnVariant.Exit)
                {
                    _emitTailCallExit(target);
                    return;
                }
            }
            switch (ReturnVariant)
            {
                case ReturnVariant.Exit:
                    target.Emit(Position,OpCode.ret_exit);
                    break;
                case ReturnVariant.Set:
                    if (Expression == null)
                        throw new PrexoniteException("Return assignment requires an expression.");
                    Expression.EmitValueCode(target);
                    target.Emit(Position,OpCode.ret_set);
                    break;
                case ReturnVariant.Continue:
                    if (Expression != null)
                    {
                        Expression.EmitValueCode(target);
                        target.Emit(Position,OpCode.ret_set);
                        _warnInCoroutines(target, ref warned);
                    }
                    target.Emit(Position,OpCode.ret_continue);
                    break;
                case ReturnVariant.Break:
                    target.Emit(Position,OpCode.ret_break);
                    break;
            }
        }
コード例 #14
0
ファイル: AstConstant.cs プロジェクト: SealedSun/prx
        protected override void DoEmitCode(CompilerTarget target, StackSemantics stackSemantics)
        {
            if(stackSemantics == StackSemantics.Effect)
                return;

            if (Constant == null)
                target.EmitNull(Position);
            else
                switch (Type.GetTypeCode(Constant.GetType()))
                {
                    case TypeCode.Boolean:
                        target.EmitConstant(Position, (bool) Constant);
                        break;
                    case TypeCode.Int16:
                    case TypeCode.Byte:
                    case TypeCode.Int32:
                    case TypeCode.UInt16:
                    case TypeCode.UInt32:
                        target.EmitConstant(Position, (int) Constant);
                        break;
                    case TypeCode.Single:
                    case TypeCode.Double:
                        target.EmitConstant(Position, (double) Constant);
                        break;
                    case TypeCode.String:
                        target.EmitConstant(Position, (string) Constant);
                        break;
                    default:
                        var moduleName = Constant as ModuleName;

                        if (moduleName != null)
                        {
                            target.EmitConstant(Position, moduleName);
                        }
                        else
                        {
                            throw new PrexoniteException(
                                "Prexonite does not support constants of type " +
                                    Constant.GetType().Name + ".");
                        }
                        break;
                }
        }
コード例 #15
0
ファイル: AstExpand.cs プロジェクト: SealedSun/prx
        protected override void DoEmitCode(CompilerTarget target, StackSemantics stackSemantics)
        {
            //instantiate macro for the current target
            MacroSession session = null;

            try
            {
                //Acquire current macro session
                session = target.AcquireMacroSession();

                //Expand macro
                var justEffect = stackSemantics == StackSemantics.Effect;
                var node = session.ExpandMacro(this, justEffect);

                //Emit generated code
                node.EmitCode(target, stackSemantics);
            }
            finally
            {
                if (session != null)
                    target.ReleaseMacroSession(session);
            }
        }
コード例 #16
0
ファイル: AstGetSet.cs プロジェクト: SealedSun/prx
 protected abstract void EmitGetCode(CompilerTarget target, StackSemantics stackSemantics);
コード例 #17
0
ファイル: AstPostExpression.cs プロジェクト: SealedSun/prx
 protected override void DoEmitCode(CompilerTarget target, StackSemantics semantics)
 {
     Expression.EmitCode(target, semantics);
     Action.EmitCode(target,StackSemantics.Effect);
     // At this point, the value of the expression remains on the stack.
 }
コード例 #18
0
ファイル: AstWhileLoop.cs プロジェクト: SealedSun/prx
        protected override void DoEmitCode(CompilerTarget target, StackSemantics stackSemantics)
        {
            if(stackSemantics == StackSemantics.Value)
                throw new NotSupportedException("While loops do not produce values and can thus not be used as expressions.");
            if (!IsInitialized)
                throw new PrexoniteException("AstWhileLoop requires Condition to be set.");

            //Optimize unary not condition
            _OptimizeNode(target, ref Condition);
            // Invert condition when unary logical not
            AstIndirectCall unaryCond;
            while (Condition.IsCommandCall(Commands.Core.Operators.LogicalNot.DefaultAlias, out unaryCond))
            {
                Condition = unaryCond.Arguments[0];
                IsPositive = !IsPositive;
            }

            //Constant conditions
            var conditionIsConstant = false;
            if (Condition is AstConstant)
            {
                var constCond = (AstConstant) Condition;
                PValue condValue;
                if (
                    !constCond.ToPValue(target).TryConvertTo(
                        target.Loader, PType.Bool, out condValue))
                    goto continueFull;
                else if ((bool) condValue.Value == IsPositive)
                    conditionIsConstant = true;
                else
                {
                    //Condition is always false
                    if (!IsPrecondition) //If do-while, emit the body without loop code
                    {
                        target.BeginBlock(Block);
                        Block.EmitEffectCode(target);
                        target.EndBlock();
                    }
                    return;
                }
            }
            continueFull:

            target.BeginBlock(Block);
            if (!Block.IsEmpty) //Body exists -> complete loop code?
            {
                if (conditionIsConstant) //Infinite, hopefully user managed, loop ->
                {
                    target.EmitLabel(Position, Block.ContinueLabel);
                    target.EmitLabel(Position, Block.BeginLabel);
                    Block.EmitEffectCode(target);
                    target.EmitJump(Position, Block.ContinueLabel);
                }
                else
                {
                    if (IsPrecondition)
                        target.EmitJump(Position, Block.ContinueLabel);

                    target.EmitLabel(Position, Block.BeginLabel);
                    Block.EmitEffectCode(target);

                    _emitCondition(target);
                }
            }
            else //Body does not exist -> Condition loop
            {
                target.EmitLabel(Position, Block.BeginLabel);
                _emitCondition(target);
            }

            target.EmitLabel(Position, Block.BreakLabel);
            target.EndBlock();
        }
コード例 #19
0
ファイル: AstObjectCreation.cs プロジェクト: SealedSun/prx
        protected override void DoEmitCode(CompilerTarget target, StackSemantics stackSemantics)
        {
            var constType = _typeExpr as AstConstantTypeExpression;

            if (constType != null)
            {
                foreach (var arg in _arguments)
                    arg.EmitValueCode(target);
                target.Emit(Position,OpCode.newobj, _arguments.Count, constType.TypeExpression);
                if(stackSemantics == StackSemantics.Effect)
                    target.Emit(Position,Instruction.CreatePop());
            }
            else
            {
                //Load type and call construct on it
                _typeExpr.EmitValueCode(target);
                foreach (var arg in _arguments)
                    arg.EmitValueCode(target);
                var justEffect = stackSemantics == StackSemantics.Effect;
                target.EmitGetCall(Position, _arguments.Count, PType.ConstructFromStackId, justEffect);
            }
        }
コード例 #20
0
ファイル: AstNamespaceUsage.cs プロジェクト: SealedSun/prx
 protected override void EmitGetCode(CompilerTarget target, StackSemantics stackSemantics)
 {
     target.Loader.ReportMessage(Message.Error(Resources.Parser_ExpectedEntityFoundNamespace, Position, MessageClasses.ExpectedEntityFoundNamespace));
     if(stackSemantics == StackSemantics.Value)
         target.EmitNull(Position);
 }
コード例 #21
0
ファイル: AstExplicitLabel.cs プロジェクト: SealedSun/prx
 protected override void DoEmitCode(CompilerTarget target, StackSemantics stackSemantics)
 {
     target.EmitLabel(Position, Label);
 }
コード例 #22
0
 protected override void DoEmitCode(CompilerTarget target, StackSemantics stackSemantics)
 {
     Subject.EmitValueCode(target);
     base.DoEmitCode(target, stackSemantics);
 }
コード例 #23
0
ファイル: AstTryCatchFinally.cs プロジェクト: SealedSun/prx
        protected override void DoEmitCode(CompilerTarget target, StackSemantics stackSemantics)
        {
            if(stackSemantics == StackSemantics.Value)
                throw new NotSupportedException("Try-catch-finally blocks cannot be used with value stack semantics (They don't produce values)");

            var prefix = "try\\" + Guid.NewGuid().ToString("N") + "\\";
            var beginTryLabel = prefix + "beginTry";
            var beginFinallyLabel = prefix + "beginFinally";
            var beginCatchLabel = prefix + "beginCatch";
            var endTry = prefix + "endTry";

            if (TryBlock.IsEmpty)
                if (FinallyBlock.IsEmpty)
                    return;
                else
                {
                    //The finally block is not protected
                    //  A trycatchfinally with just a finally block is equivalent to the contents of the finally block
                    //  " try {} finally { $code } " => " $code "
                    FinallyBlock.EmitEffectCode(target);
                    return;
                }

            //Emit try block
            target.EmitLabel(Position, beginTryLabel);
            target.Emit(Position,OpCode.@try);
            TryBlock.EmitEffectCode(target);

            //Emit finally block
            target.EmitLabel(FinallyBlock.Position, beginFinallyLabel);
            var beforeEmit = target.Code.Count;
            FinallyBlock.EmitEffectCode(target);
            if (FinallyBlock.Count > 0 && target.Code.Count == beforeEmit)
                target.Emit(FinallyBlock.Position, OpCode.nop);
            target.EmitLeave(FinallyBlock.Position, endTry);

            //Emit catch block
            target.EmitLabel(CatchBlock.Position, beginCatchLabel);
            var usesException = ExceptionVar != null;
            var justRethrow = CatchBlock.IsEmpty && !usesException;

            if (usesException)
            {
                //Assign exception
                ExceptionVar = _GetOptimizedNode(target, ExceptionVar) as AstGetSet ?? ExceptionVar;
                ExceptionVar.Arguments.Add(new AstGetException(File, Line, Column));
                ExceptionVar.Call = PCall.Set;
                ExceptionVar.EmitEffectCode(target);
            }

            if (!justRethrow)
            {
                //Exception handled
                CatchBlock.EmitEffectCode(target);
            }
            else
            {
                //Exception not handled => rethrow.
                // * Rethrow is implemented in the runtime *
                //AstThrow th = new AstThrow(File, Line, Column);
                //th.Expression = new AstGetException(File, Line, Column);
                //th.EmitCode(target);
            }

            target.EmitLabel(Position, endTry);
            target.Emit(Position,OpCode.nop);

            var block =
                new TryCatchFinallyBlock(
                    _getAddress(target, beginTryLabel), _getAddress(target, endTry))
                    {
                        BeginFinally =
                            (!FinallyBlock.IsEmpty ? _getAddress(target, beginFinallyLabel) : -1),
                        BeginCatch = (!justRethrow ? _getAddress(target, beginCatchLabel) : -1),
                        UsesException = usesException
                    };

            //Register try-catch-finally block
            target.Function.Meta.AddTo(TryCatchFinallyBlock.MetaKey, block);
            target.Function.InvalidateTryCatchFinallyBlocks();
        }
コード例 #24
0
        protected override void DoEmitCode(CompilerTarget target, StackSemantics stackSemantics)
        {
            foreach (var expr in Arguments)
                expr.EmitCode(target,stackSemantics);

            if(stackSemantics == StackSemantics.Value)
                target.Emit(Position,OpCode.newtype, Arguments.Count, TypeId);
        }
コード例 #25
0
ファイル: AstUnresolved.cs プロジェクト: SealedSun/prx
 protected override void EmitGetCode(CompilerTarget target, StackSemantics stackSemantics)
 {
     _reportUnresolved(target);
     target.EmitNull(Position);
 }
コード例 #26
0
 protected override void EmitGetCode(CompilerTarget target, StackSemantics stackSemantics)
 {
     target.EmitGetCall(Position, Arguments.Count, Id, stackSemantics == StackSemantics.Effect);
 }
コード例 #27
0
ファイル: AstPlaceholder.cs プロジェクト: SealedSun/prx
 protected override void EmitGetCode(CompilerTarget target, StackSemantics stackSemantics)
 {
     _throwSyntaxNotSupported();
 }
コード例 #28
0
ファイル: AstExpand.cs プロジェクト: SealedSun/prx
 protected override void EmitGetCode(CompilerTarget target, StackSemantics stackSemantics)
 {
     throw new NotSupportedException("Macro expansion requires a different mechanism. Use AstGetSet.EmitCode instead.");
 }
コード例 #29
0
ファイル: AstForeachLoop.cs プロジェクト: SealedSun/prx
        protected override void DoEmitCode(CompilerTarget target, StackSemantics stackSemantics)
        {
            if(stackSemantics == StackSemantics.Value)
                throw new NotSupportedException("Foreach loops don't produce values and can thus not be emitted with value semantics.");

            if (!IsInitialized)
                throw new PrexoniteException("AstForeachLoop requires List and Element to be set.");

            //Optimize expression
            _OptimizeNode(target, ref List);

            //Create the enumerator variable
            var enumVar = Block.CreateLabel("enumerator");
            target.Function.Variables.Add(enumVar);

            //Create the element assignment statement
            var element = Element.GetCopy();
            AstExpr optElem;
            if (element.TryOptimize(target, out optElem))
            {
                element = optElem as AstGetSet;
                if (element == null)
                {
                    target.Loader.ReportMessage(Message.Error(Resources.AstForeachLoop_DoEmitCode_ElementTooComplicated,Position,MessageClasses.ForeachElementTooComplicated));
                    return;
                }
            }
            var ldEnumVar = target.Factory.Call(Position, EntityRef.Variable.Local.Create(enumVar));
            var getCurrent =
                new AstGetSetMemberAccess(File, Line, Column, ldEnumVar, "Current");
            element.Arguments.Add(getCurrent);
            element.Call = PCall.Set;

            //Actual Code Generation
            var moveNextAddr = -1;
            var getCurrentAddr = -1;
            var disposeAddr = -1;

            //Get the enumerator
            target.BeginBlock(Block);

            List.EmitValueCode(target);
            target.EmitGetCall(List.Position, 0, "GetEnumerator");
            var castAddr = target.Code.Count;
            target.Emit(List.Position, OpCode.cast_const, "Object(\"System.Collections.IEnumerator\")");
            target.EmitStoreLocal(List.Position, enumVar);

            //check whether an enhanced CIL implementation is possible
            bool emitHint;
            if (element.DefaultAdditionalArguments + element.Arguments.Count > 1)
                //has additional arguments
                emitHint = false;
            else
                emitHint = true;

            var @try = new AstTryCatchFinally(Position, Block);

            @try.TryBlock = new AstActionBlock
                (
                Position, @try,
                delegate
                    {
                        target.EmitJump(Position, Block.ContinueLabel);

                        //Assignment (begin)
                        target.EmitLabel(Position, Block.BeginLabel);
                        getCurrentAddr = target.Code.Count;
                        element.EmitEffectCode(target);

                        //Code block
                        Block.EmitEffectCode(target);

                        //Condition (continue)
                        target.EmitLabel(Position, Block.ContinueLabel);
                        moveNextAddr = target.Code.Count;
                        target.EmitLoadLocal(List.Position, enumVar);
                        target.EmitGetCall(List.Position, 0, "MoveNext");
                        target.EmitJumpIfTrue(Position, Block.BeginLabel);

                        //Break
                        target.EmitLabel(Position, Block.BreakLabel);
                    });
            @try.FinallyBlock = new AstActionBlock
                (
                Position, @try,
                delegate
                    {
                        disposeAddr = target.Code.Count;
                        target.EmitLoadLocal(List.Position, enumVar);
                        target.EmitCommandCall(List.Position, 1, Engine.DisposeAlias, true);
                    });
                

            @try.EmitEffectCode(target);

            target.EndBlock();

            if (getCurrentAddr < 0 || moveNextAddr < 0 || disposeAddr < 0)
                throw new PrexoniteException(
                    "Could not capture addresses within foreach construct for CIL compiler hint.");
            else if (emitHint)
            {
                var hint = new ForeachHint(enumVar, castAddr, getCurrentAddr, moveNextAddr,
                    disposeAddr);
                Cil.Compiler.AddCilHint(target, hint);

                Action<int, int> mkHook =
                    (index, original) =>
                        {
                            AddressChangeHook hook = null;
                            hook = new AddressChangeHook(
                                original,
                                newAddr =>
                                    {
                                        foreach (
                                            var hintEntry in target.Meta[Loader.CilHintsKey].List)
                                        {
                                            var entry = hintEntry.List;
                                            if (entry[0] == ForeachHint.Key &&
                                                entry[index].Text == original.ToString(CultureInfo.InvariantCulture))
                                            {
                                                entry[index] = newAddr.ToString(CultureInfo.InvariantCulture);
                                                // AddressChangeHook.ctor can be trusted not to call the closure.
                                                // ReSharper disable PossibleNullReferenceException
                                                // ReSharper disable AccessToModifiedClosure
                                                hook.InstructionIndex = newAddr;
                                                // ReSharper restore AccessToModifiedClosure
                                                // ReSharper restore PossibleNullReferenceException
                                                original = newAddr;
                                            }
                                        }
                                    });
                            target.AddressChangeHooks.Add(hook);
                        };

                mkHook(ForeachHint.CastAddressIndex + 1, castAddr);
                mkHook(ForeachHint.GetCurrentAddressIndex + 1, getCurrentAddr);
                mkHook(ForeachHint.MoveNextAddressIndex + 1, moveNextAddr);
                mkHook(ForeachHint.DisposeAddressIndex + 1, disposeAddr);
            } // else nothing
        }
コード例 #30
0
ファイル: AstGetSet.cs プロジェクト: SealedSun/prx
 protected override void DoEmitCode(CompilerTarget target, StackSemantics stackSemantics)
 {
     if (Call == PCall.Get)
     {
         EmitArguments(target);
         EmitGetCode(target, stackSemantics);
     }
     else
     {
         EmitArguments(target, stackSemantics == StackSemantics.Value);
         EmitSetCode(target);
     }
 }