Пример #1
0
        /// <summary>
        /// Stores value from top of the evaluation stack to a temporary variable which will be returned from the exit block.
        /// </summary>
        internal void EmitTmpRet(CodeGenerator cg, Symbols.TypeSymbol stack)
        {
            // lazy initialize
            if (_retlbl == null)
            {
                _retlbl = new NamedLabel("<return>");
            }

            if (_rettmp == null)
            {
                var rtype = cg.Routine.ReturnType;
                if (rtype.SpecialType != SpecialType.System_Void)
                {
                    _rettmp = cg.GetTemporaryLocal(rtype);
                }
            }

            // <rettmp> = <stack>;
            if (_rettmp != null)
            {
                cg.EmitConvert(stack, 0, (Symbols.TypeSymbol)_rettmp.Type);
                cg.Builder.EmitLocalStore(_rettmp);
                cg.Builder.EmitBranch(ILOpCode.Br, _retlbl);
            }
            else
            {
                cg.EmitPop(stack);
            }
        }
Пример #2
0
        /// <summary>
        /// Stores value from top of the evaluation stack to a temporary variable which will be returned from the exit block.
        /// </summary>
        internal void EmitTmpRet(CodeGenerator cg, TypeSymbol stack)
        {
            if (_rettmp == null)
            {
                var rtype = cg.Routine.ReturnType;
                if (rtype.SpecialType != SpecialType.System_Void)
                {
                    _rettmp = cg.GetTemporaryLocal(rtype);
                }
            }

            // <rettmp> = <stack>;
            if (_rettmp != null)
            {
                cg.EmitConvert(stack, 0, (TypeSymbol)_rettmp.Type);
                cg.Builder.EmitLocalStore(_rettmp);
            }
            else
            {
                cg.EmitPop(stack);
            }

            //
            cg.Builder.EmitBranch(ILOpCode.Br, GetReturnLabel());
        }
Пример #3
0
        /// <summary>
        /// Stores value from top of the evaluation stack to a temporary variable which will be returned from the exit block.
        /// </summary>
        internal void EmitTmpRet(CodeGenerator cg, TypeSymbol stack, bool yielding)
        {
            if (_rettmp == null && !cg.Routine.IsGeneratorMethod())
            {
                var rtype = cg.Routine.ReturnType;
                if (rtype.SpecialType != SpecialType.System_Void)
                {
                    _rettmp = cg.GetTemporaryLocal(rtype);
                }
            }

            // <rettmp> = <stack>;
            if (_rettmp != null)
            {
                cg.EmitConvert(stack, 0, (TypeSymbol)_rettmp.Type);
                cg.Builder.EmitLocalStore(_rettmp);
            }
            else
            {
                cg.EmitPop(stack);
            }

            //
            if (cg.ExtraFinallyBlock != null && !yielding)
            {
                // state = 1;
                // goto _finally;
                cg.Builder.EmitIntConstant((int)CodeGenerator.ExtraFinallyState.Return); // 1: return
                cg.ExtraFinallyStateVariable.EmitStore();
                cg.Builder.EmitBranch(ILOpCode.Br, cg.ExtraFinallyBlock);
                return;
            }

            //
            cg.Builder.EmitBranch(ILOpCode.Br, GetReturnLabel());
        }
Пример #4
0
 private void InitializeParametersForGeneratorMethod(CodeGenerator cg, Microsoft.CodeAnalysis.CodeGen.ILBuilder il, Microsoft.CodeAnalysis.CodeGen.LocalDefinition generatorsLocals)
 {
     // Emit init of unoptimized BoundParameters using separate CodeGenerator that has locals place pointing to our generator's locals array
     using (var localsArrayCg = new CodeGenerator(
                il, cg.Module, cg.Diagnostics,
                cg.DeclaringCompilation.Options.OptimizationLevel,
                cg.EmitPdbSequencePoints,
                this.ContainingType,
                contextPlace: null,
                thisPlace: null,
                routine: this, // needed to support static variables (they need enclosing routine while binding)
                locals: new LocalPlace(generatorsLocals),
                localsInitialized: false
                ))
     {
         // EmitInit (for UnoptimizedLocals) copies arguments to locals array, does nothing for normal variables, handles local statics, global variables ...
         LocalsTable.Variables.ForEach(v => v.EmitInit(localsArrayCg));
     }
 }
Пример #5
0
        /// <summary>
        /// Stores value from top of the evaluation stack to a temporary variable which will be returned from the exit block.
        /// </summary>
        internal void EmitTmpRet(CodeGenerator cg, Symbols.TypeSymbol stack)
        {
            // lazy initialize
            if (_retlbl == null)
            {
                _retlbl = new object();
            }

            if (_rettmp == null)
            {
                var rtype = cg.Routine.ReturnType;
                if (rtype.SpecialType != SpecialType.System_Void)
                {
                    _rettmp = cg.GetTemporaryLocal(rtype);
                }
            }

            // <rettmp> = <stack>;
            if (_rettmp != null)
            {
                cg.EmitConvert(stack, 0, (Symbols.TypeSymbol)_rettmp.Type);
                cg.Builder.EmitLocalStore(_rettmp);
                cg.Builder.EmitBranch(ILOpCode.Br, _retlbl);
            }
            else
            {
                cg.EmitPop(stack);
            }
        }