Example #1
0
        public static void Reset(bool full_flag)
        {
            CSharpParser.yacc_verbose_flag = 0;
            Location.Reset();

            if (!full_flag)
            {
                return;
            }

            RootContext.Reset(full_flag);
            TypeManager.Reset();
            ReferenceContainer.Reset();
            PointerContainer.Reset();
            Parameter.Reset();

            Unary.Reset();
            UnaryMutator.Reset();
            Binary.Reset();
            ConstantFold.Reset();
            CastFromDecimal.Reset();
            StringConcat.Reset();

            NamespaceEntry.Reset();
            Attribute.Reset();
            AnonymousTypeClass.Reset();
            AnonymousMethodBody.Reset();
            AnonymousMethodStorey.Reset();
            SymbolWriter.Reset();
            Switch.Reset();
            Linq.QueryBlock.TransparentParameter.Reset();
            Convert.Reset();
            TypeInfo.Reset();
        }
Example #2
0
        void EmitMoveNext_NoResumePoints(EmitContext ec, Block original_block)
        {
            ec.EmitThis();
            ec.Emit(OpCodes.Ldfld, storey.PC.Spec);

            ec.EmitThis();
            ec.EmitInt((int)IteratorStorey.State.After);
            ec.Emit(OpCodes.Stfld, storey.PC.Spec);

            // We only care if the PC is zero (start executing) or non-zero (don't do anything)
            ec.Emit(OpCodes.Brtrue, move_next_error);

            iterator_body_end = ec.DefineLabel();

            SymbolWriter.StartIteratorBody(ec);
            original_block.Emit(ec);
            SymbolWriter.EndIteratorBody(ec);

            ec.MarkLabel(iterator_body_end);

            EmitMoveNextEpilogue(ec);

            ec.MarkLabel(move_next_error);

            if (ReturnType.Kind != MemberKind.Void)
            {
                ec.EmitInt(0);
                ec.Emit(OpCodes.Ret);
            }
        }
Example #3
0
        public void Save()
        {
            PortableExecutableKinds pekind;
            ImageFileMachine        machine;

            switch (Compiler.Settings.Platform)
            {
            case Platform.X86:
                pekind  = PortableExecutableKinds.Required32Bit | PortableExecutableKinds.ILOnly;
                machine = ImageFileMachine.I386;
                break;

            case Platform.X64:
                pekind  = PortableExecutableKinds.ILOnly;
                machine = ImageFileMachine.AMD64;
                break;

            case Platform.IA64:
                pekind  = PortableExecutableKinds.ILOnly;
                machine = ImageFileMachine.IA64;
                break;

            case Platform.AnyCPU:
            default:
                pekind  = PortableExecutableKinds.ILOnly;
                machine = ImageFileMachine.I386;
                break;
            }

            Compiler.TimeReporter.Start(TimeReporter.TimerType.OutputSave);
            try
            {
                if (Compiler.Settings.Target == Target.Module)
                {
                    SaveModule(pekind, machine);
                }
                else
                {
                    // TODO: Fix stuff
#if NETFRAMEWORK
                    Builder.Save(module.Builder.ScopeName, pekind, machine);
#endif
                }
            }
            catch (Exception e)
            {
                Report.Error(16, "Could not write to file `" + name + "', cause: " + e.Message);
            }
            Compiler.TimeReporter.Stop(TimeReporter.TimerType.OutputSave);

            // Save debug symbols file
            if (symbol_writer != null)
            {
                // TODO: it should run in parallel
                Compiler.TimeReporter.Start(TimeReporter.TimerType.DebugSave);
                symbol_writer.WriteSymbolFile(SymbolWriter.GetGuid(module.Builder));
                Compiler.TimeReporter.Stop(TimeReporter.TimerType.DebugSave);
            }
        }
Example #4
0
        /// <summary>
        ///   This is called immediately before emitting an IL opcode to tell the symbol
        ///   writer to which source line this opcode belongs.
        /// </summary>
        public void Mark(Location loc)
        {
            if (!SymbolWriter.HasSymbolWriter || HasSet(Options.OmitDebugInfo) || loc.IsNull)
            {
                return;
            }

            SymbolWriter.MarkSequencePoint(ig, loc);
        }
Example #5
0
        protected void EmitCall(EmitContext ec, Expression binder, Arguments arguments, bool isStatement)
        {
            int      dyn_args_count = arguments == null ? 0 : arguments.Count;
            TypeExpr site_type      = CreateSiteType(ec, arguments, dyn_args_count, isStatement);
            var      field          = CreateSiteField(ec, site_type);

            if (field == null)
            {
                return;
            }

            FieldExpr site_field_expr = new FieldExpr(field, loc);

            SymbolWriter.OpenCompilerGeneratedBlock(ec);

            Arguments args = new Arguments(1);

            args.Add(new Argument(binder));
            StatementExpression s = new StatementExpression(new SimpleAssign(site_field_expr, new Invocation(new MemberAccess(site_type, "Create"), args)));

            BlockContext bc = new BlockContext(ec.MemberContext, null, TypeManager.void_type);

            if (s.Resolve(bc))
            {
                Statement init = new If(new Binary(Binary.Operator.Equality, site_field_expr, new NullLiteral(loc), loc), s, loc);
                init.Emit(ec);
            }

            args = new Arguments(1 + dyn_args_count);
            args.Add(new Argument(site_field_expr));
            if (arguments != null)
            {
                foreach (Argument a in arguments)
                {
                    if (a is NamedArgument)
                    {
                        // Name is not valid in this context
                        args.Add(new Argument(a.Expr, a.ArgType));
                        continue;
                    }

                    args.Add(a);
                }
            }

            Expression target = new DelegateInvocation(new MemberAccess(site_field_expr, "Target", loc).Resolve(bc), args, loc).Resolve(bc);

            if (target != null)
            {
                target.Emit(ec);
            }

            SymbolWriter.CloseCompilerGeneratedBlock(ec);
        }
Example #6
0
        public void Save()
        {
            PortableExecutableKinds pekind;
            ImageFileMachine        machine;

            switch (RootContext.Platform)
            {
            case Platform.X86:
                pekind  = PortableExecutableKinds.Required32Bit | PortableExecutableKinds.ILOnly;
                machine = ImageFileMachine.I386;
                break;

            case Platform.X64:
                pekind  = PortableExecutableKinds.ILOnly;
                machine = ImageFileMachine.AMD64;
                break;

            case Platform.IA64:
                pekind  = PortableExecutableKinds.ILOnly;
                machine = ImageFileMachine.IA64;
                break;

            case Platform.AnyCPU:
            default:
                pekind  = PortableExecutableKinds.ILOnly;
                machine = ImageFileMachine.I386;
                break;
            }

            try
            {
                if (RootContext.Target == Target.Module)
                {
                    SaveModule(pekind, machine);
                }
                else
                {
                    Builder.Save(module.Builder.ScopeName, pekind, machine);
                }
            }
            catch (Exception e)
            {
                Report.Error(16, "Could not write to file `" + name + "', cause: " + e.Message);
            }

            // Save debug symbols file
            if (symbol_writer != null)
            {
                // TODO: it should run in parallel
                symbol_writer.WriteSymbolFile(SymbolWriter.GetGuid(module.Builder));
            }
        }
Example #7
0
        public static void Reset(bool full_flag)
        {
            Location.Reset();

            if (!full_flag)
            {
                return;
            }

            SymbolWriter.Reset();
            Linq.QueryBlock.TransparentParameter.Reset();
            TypeInfo.Reset();
        }
Example #8
0
        public static void Reset(bool full_flag)
        {
            CSharpParser.yacc_verbose_flag = 0;
            Location.Reset();

            if (!full_flag)
            {
                return;
            }

            AnonymousTypeClass.Reset();
            AnonymousMethodBody.Reset();
            AnonymousMethodStorey.Reset();
            SymbolWriter.Reset();
            Switch.Reset();
            Linq.QueryBlock.TransparentParameter.Reset();
            TypeInfo.Reset();
        }
Example #9
0
        /// <summary>
        ///   This is called immediately before emitting an IL opcode to tell the symbol
        ///   writer to which source line this opcode belongs.
        /// </summary>
        public bool Mark(Location loc)
        {
            if ((flags & Options.OmitDebugInfo) != 0)
            {
                return(false);
            }

            if (loc.IsNull)
            {
                return(false);
            }

            if (loc.SourceFile.IsHiddenLocation(loc))
            {
                return(false);
            }

            SymbolWriter.MarkSequencePoint(ig, loc);
            return(true);
        }
Example #10
0
        void EmitMoveNext_NoResumePoints(EmitContext ec, Block original_block)
        {
            ec.Emit(OpCodes.Ldarg_0);
            ec.Emit(OpCodes.Ldfld, IteratorHost.PC.Spec);

            ec.Emit(OpCodes.Ldarg_0);
            ec.EmitInt((int)State.After);
            ec.Emit(OpCodes.Stfld, IteratorHost.PC.Spec);

            // We only care if the PC is zero (start executing) or non-zero (don't do anything)
            ec.Emit(OpCodes.Brtrue, move_next_error);

            SymbolWriter.StartIteratorBody(ec);
            original_block.Emit(ec);
            SymbolWriter.EndIteratorBody(ec);

            ec.MarkLabel(move_next_error);
            ec.Emit(OpCodes.Ldc_I4_0);
            ec.Emit(OpCodes.Ret);
        }
Example #11
0
        internal void EmitMoveNext(EmitContext ec, Block original_block)
        {
            ILGenerator ig = ec.ig;

            move_next_ok    = ig.DefineLabel();
            move_next_error = ig.DefineLabel();

            if (resume_points == null)
            {
                EmitMoveNext_NoResumePoints(ec, original_block);
                return;
            }

            current_pc = ec.GetTemporaryLocal(TypeManager.uint32_type);
            ig.Emit(OpCodes.Ldarg_0);
            ig.Emit(OpCodes.Ldfld, IteratorHost.PC.FieldBuilder);
            ig.Emit(OpCodes.Stloc, current_pc);

            // We're actually in state 'running', but this is as good a PC value as any if there's an abnormal exit
            ig.Emit(OpCodes.Ldarg_0);
            IntConstant.EmitInt(ig, (int)State.After);
            ig.Emit(OpCodes.Stfld, IteratorHost.PC.FieldBuilder);

            Label [] labels = new Label [1 + resume_points.Count];
            labels [0] = ig.DefineLabel();

            bool need_skip_finally = false;

            for (int i = 0; i < resume_points.Count; ++i)
            {
                ResumableStatement s = (ResumableStatement)resume_points [i];
                need_skip_finally |= s is ExceptionStatement;
                labels [i + 1]     = s.PrepareForEmit(ec);
            }

            if (need_skip_finally)
            {
                skip_finally = ec.GetTemporaryLocal(TypeManager.bool_type);
                ig.Emit(OpCodes.Ldc_I4_0);
                ig.Emit(OpCodes.Stloc, skip_finally);
            }

            SymbolWriter.StartIteratorDispatcher(ec.ig);
            ig.Emit(OpCodes.Ldloc, current_pc);
            ig.Emit(OpCodes.Switch, labels);

            ig.Emit(OpCodes.Br, move_next_error);
            SymbolWriter.EndIteratorDispatcher(ec.ig);

            ig.MarkLabel(labels [0]);

            SymbolWriter.StartIteratorBody(ec.ig);
            original_block.Emit(ec);
            SymbolWriter.EndIteratorBody(ec.ig);

            SymbolWriter.StartIteratorDispatcher(ec.ig);

            ig.Emit(OpCodes.Ldarg_0);
            IntConstant.EmitInt(ig, (int)State.After);
            ig.Emit(OpCodes.Stfld, IteratorHost.PC.FieldBuilder);

            ig.MarkLabel(move_next_error);
            ig.Emit(OpCodes.Ldc_I4_0);
            ig.Emit(OpCodes.Ret);

            ig.MarkLabel(move_next_ok);
            ig.Emit(OpCodes.Ldc_I4_1);
            ig.Emit(OpCodes.Ret);

            SymbolWriter.EndIteratorDispatcher(ec.ig);
        }
Example #12
0
        protected void EmitCall(EmitContext ec, Expression binder, Arguments arguments, bool isStatement)
        {
            //
            // This method generates all internal infrastructure for a dynamic call. The
            // reason why it's quite complicated is the mixture of dynamic and anonymous
            // methods. Dynamic itself requires a temporary class (ContainerX) and anonymous
            // methods can generate temporary storey as well (AnonStorey). Handling MVAR
            // type parameters rewrite is non-trivial in such case as there are various
            // combinations possible therefore the mutator is not straightforward. Secondly
            // we need to keep both MVAR(possibly VAR for anon storey) and type VAR to emit
            // correct Site field type and its access from EmitContext.
            //

            int dyn_args_count = arguments == null ? 0 : arguments.Count;
            int default_args   = isStatement ? 1 : 2;
            var module         = ec.Module;

            bool has_ref_out_argument = false;
            var  targs = new TypeExpression[dyn_args_count + default_args];

            targs[0] = new TypeExpression(module.PredefinedTypes.CallSite.TypeSpec, loc);

            TypeExpression[]     targs_for_instance = null;
            TypeParameterMutator mutator;

            var site_container = ec.CreateDynamicSite();

            if (context_mvars != null)
            {
                TypeParameter[] tparam;
                TypeContainer   sc = site_container;
                do
                {
                    tparam = sc.CurrentTypeParameters;
                    sc     = sc.Parent;
                } while (tparam == null);

                mutator = new TypeParameterMutator(context_mvars, tparam);

                if (!ec.IsAnonymousStoreyMutateRequired)
                {
                    targs_for_instance    = new TypeExpression[targs.Length];
                    targs_for_instance[0] = targs[0];
                }
            }
            else
            {
                mutator = null;
            }

            for (int i = 0; i < dyn_args_count; ++i)
            {
                Argument a = arguments[i];
                if (a.ArgType == Argument.AType.Out || a.ArgType == Argument.AType.Ref)
                {
                    has_ref_out_argument = true;
                }

                var t = a.Type;

                // Convert any internal type like dynamic or null to object
                if (t.Kind == MemberKind.InternalCompilerType)
                {
                    t = ec.BuiltinTypes.Object;
                }

                if (targs_for_instance != null)
                {
                    targs_for_instance[i + 1] = new TypeExpression(t, loc);
                }

                if (mutator != null)
                {
                    t = t.Mutate(mutator);
                }

                targs[i + 1] = new TypeExpression(t, loc);
            }

            TypeExpr del_type = null;
            TypeExpr del_type_instance_access = null;

            if (!has_ref_out_argument)
            {
                string d_name = isStatement ? "Action" : "Func";

                TypeExpr  te      = null;
                Namespace type_ns = module.GlobalRootNamespace.GetNamespace("System", true);
                if (type_ns != null)
                {
                    te = type_ns.LookupType(module, d_name, dyn_args_count + default_args, Location.Null);
                }

                if (te != null)
                {
                    if (!isStatement)
                    {
                        var t = type;
                        if (t.Kind == MemberKind.InternalCompilerType)
                        {
                            t = ec.BuiltinTypes.Object;
                        }

                        if (targs_for_instance != null)
                        {
                            targs_for_instance[targs_for_instance.Length - 1] = new TypeExpression(t, loc);
                        }

                        if (mutator != null)
                        {
                            t = t.Mutate(mutator);
                        }

                        targs[targs.Length - 1] = new TypeExpression(t, loc);
                    }

                    del_type = new GenericTypeExpr(te.Type, new TypeArguments(targs), loc);
                    if (targs_for_instance != null)
                    {
                        del_type_instance_access = new GenericTypeExpr(te.Type, new TypeArguments(targs_for_instance), loc);
                    }
                    else
                    {
                        del_type_instance_access = del_type;
                    }
                }
            }

            //
            // Create custom delegate when no appropriate predefined delegate has been found
            //
            Delegate d;

            if (del_type == null)
            {
                TypeSpec    rt = isStatement ? ec.BuiltinTypes.Void : type;
                Parameter[] p  = new Parameter[dyn_args_count + 1];
                p[0] = new Parameter(targs[0], "p0", Parameter.Modifier.NONE, null, loc);

                var site  = ec.CreateDynamicSite();
                int index = site.Types == null ? 0 : site.Types.Count;

                if (mutator != null)
                {
                    rt = mutator.Mutate(rt);
                }

                for (int i = 1; i < dyn_args_count + 1; ++i)
                {
                    p[i] = new Parameter(targs[i], "p" + i.ToString("X"), arguments[i - 1].Modifier, null, loc);
                }

                d = new Delegate(site.NamespaceEntry, site, new TypeExpression(rt, loc),
                                 Modifiers.INTERNAL | Modifiers.COMPILER_GENERATED,
                                 new MemberName("Container" + index.ToString("X")),
                                 new ParametersCompiled(p), null);

                d.CreateType();
                d.DefineType();
                d.Define();
                d.Emit();

                site.AddDelegate(d);
                del_type = new TypeExpression(d.CurrentType, loc);
                if (targs_for_instance != null)
                {
                    del_type_instance_access = null;
                }
                else
                {
                    del_type_instance_access = del_type;
                }
            }
            else
            {
                d = null;
            }

            var site_type_decl = new GenericTypeExpr(module.PredefinedTypes.CallSiteGeneric.TypeSpec, new TypeArguments(del_type), loc);
            var field          = site_container.CreateCallSiteField(site_type_decl, loc);

            if (field == null)
            {
                return;
            }

            if (del_type_instance_access == null)
            {
                var dt = d.CurrentType.DeclaringType.MakeGenericType(module, context_mvars.Select(l => l.Type).ToArray());
                del_type_instance_access = new TypeExpression(MemberCache.GetMember(dt, d.CurrentType), loc);
            }

            FullNamedExpression instanceAccessExprType = new GenericTypeExpr(module.PredefinedTypes.CallSiteGeneric.TypeSpec,
                                                                             new TypeArguments(del_type_instance_access), loc);

            BlockContext bc = new BlockContext(ec.MemberContext, null, ec.BuiltinTypes.Void);

            instanceAccessExprType = instanceAccessExprType.ResolveAsType(bc);
            if (instanceAccessExprType == null)
            {
                return;
            }

            bool inflate_using_mvar = context_mvars != null && ec.IsAnonymousStoreyMutateRequired;

            TypeSpec gt;

            if (inflate_using_mvar || context_mvars == null)
            {
                gt = site_container.CurrentType;
            }
            else
            {
                gt = site_container.CurrentType.MakeGenericType(module, context_mvars.Select(l => l.Type).ToArray());
            }

            // When site container already exists the inflated version has to be
            // updated manually to contain newly created field
            if (gt is InflatedTypeSpec && site_container.Fields.Count > 1)
            {
                var tparams  = gt.MemberDefinition.TypeParametersCount > 0 ? gt.MemberDefinition.TypeParameters : TypeParameterSpec.EmptyTypes;
                var inflator = new TypeParameterInflator(module, gt, tparams, gt.TypeArguments);
                gt.MemberCache.AddMember(field.InflateMember(inflator));
            }

            FieldExpr site_field_expr = new FieldExpr(MemberCache.GetMember(gt, field), loc);

            SymbolWriter.OpenCompilerGeneratedBlock(ec);

            Arguments args = new Arguments(1);

            args.Add(new Argument(binder));
            StatementExpression s = new StatementExpression(new SimpleAssign(site_field_expr, new Invocation(new MemberAccess(instanceAccessExprType, "Create"), args)));

            if (s.Resolve(bc))
            {
                Statement init = new If(new Binary(Binary.Operator.Equality, site_field_expr, new NullLiteral(loc), loc), s, loc);
                init.Emit(ec);
            }

            args = new Arguments(1 + dyn_args_count);
            args.Add(new Argument(site_field_expr));
            if (arguments != null)
            {
                int arg_pos = 1;
                foreach (Argument a in arguments)
                {
                    if (a is NamedArgument)
                    {
                        // Name is not valid in this context
                        args.Add(new Argument(a.Expr, a.ArgType));
                    }
                    else
                    {
                        args.Add(a);
                    }

                    if (inflate_using_mvar && a.Type != targs[arg_pos].Type)
                    {
                        a.Expr.Type = targs[arg_pos].Type;
                    }

                    ++arg_pos;
                }
            }

            Expression target = new DelegateInvocation(new MemberAccess(site_field_expr, "Target", loc).Resolve(bc), args, loc).Resolve(bc);

            if (target != null)
            {
                target.Emit(ec);
            }

            SymbolWriter.CloseCompilerGeneratedBlock(ec);
        }
Example #13
0
 public void EndScope()
 {
     SymbolWriter.CloseScope(ig);
 }
Example #14
0
 public void BeginScope()
 {
     SymbolWriter.OpenScope(ig);
 }
Example #15
0
 public void DefineLocalVariable(string name, LocalBuilder builder)
 {
     SymbolWriter.DefineLocalVariable(name, builder);
 }
Example #16
0
        static public void Save(string name, bool saveDebugInfo, Report Report)
        {
#if GMCS_SOURCE
            PortableExecutableKinds pekind;
            ImageFileMachine        machine;

            switch (RootContext.Platform)
            {
            case Platform.X86:
                pekind  = PortableExecutableKinds.Required32Bit;
                machine = ImageFileMachine.I386;
                break;

            case Platform.X64:
                pekind  = PortableExecutableKinds.PE32Plus;
                machine = ImageFileMachine.AMD64;
                break;

            case Platform.IA64:
                pekind  = PortableExecutableKinds.PE32Plus;
                machine = ImageFileMachine.IA64;
                break;

            case Platform.AnyCPU:
            default:
                pekind  = PortableExecutableKinds.ILOnly;
                machine = ImageFileMachine.I386;
                break;
            }
#endif
            try {
#if GMCS_SOURCE
                Assembly.Builder.Save(Basename(name), pekind, machine);
#else
                Assembly.Builder.Save(Basename(name));
#endif
            }
            catch (COMException) {
                if ((RootContext.StrongNameKeyFile == null) || (!RootContext.StrongNameDelaySign))
                {
                    throw;
                }

                // FIXME: it seems Microsoft AssemblyBuilder doesn't like to delay sign assemblies
                Report.Error(1548, "Couldn't delay-sign the assembly with the '" +
                             RootContext.StrongNameKeyFile +
                             "', Use MCS with the Mono runtime or CSC to compile this assembly.");
            }
            catch (System.IO.IOException io) {
                Report.Error(16, "Could not write to file `" + name + "', cause: " + io.Message);
                return;
            }
            catch (System.UnauthorizedAccessException ua) {
                Report.Error(16, "Could not write to file `" + name + "', cause: " + ua.Message);
                return;
            }
            catch (System.NotImplementedException nie) {
                Report.RuntimeMissingSupport(Location.Null, nie.Message);
                return;
            }

            //
            // Write debuger symbol file
            //
            if (saveDebugInfo)
            {
                SymbolWriter.WriteSymbolFile();
            }
        }
Example #17
0
        void EmitMoveNext(EmitContext ec)
        {
            move_next_ok    = ec.DefineLabel();
            move_next_error = ec.DefineLabel();

            if (resume_points == null)
            {
                EmitMoveNext_NoResumePoints(ec, block);
                return;
            }

            current_pc = ec.GetTemporaryLocal(ec.BuiltinTypes.UInt);
            ec.Emit(OpCodes.Ldarg_0);
            ec.Emit(OpCodes.Ldfld, IteratorHost.PC.Spec);
            ec.Emit(OpCodes.Stloc, current_pc);

            // We're actually in state 'running', but this is as good a PC value as any if there's an abnormal exit
            ec.Emit(OpCodes.Ldarg_0);
            ec.EmitInt((int)State.After);
            ec.Emit(OpCodes.Stfld, IteratorHost.PC.Spec);

            Label [] labels = new Label [1 + resume_points.Count];
            labels [0] = ec.DefineLabel();

            bool need_skip_finally = false;

            for (int i = 0; i < resume_points.Count; ++i)
            {
                ResumableStatement s = resume_points [i];
                need_skip_finally |= s is ExceptionStatement;
                labels [i + 1]     = s.PrepareForEmit(ec);
            }

            if (need_skip_finally)
            {
                skip_finally = ec.GetTemporaryLocal(ec.BuiltinTypes.Bool);
                ec.Emit(OpCodes.Ldc_I4_0);
                ec.Emit(OpCodes.Stloc, skip_finally);
            }

            SymbolWriter.StartIteratorDispatcher(ec);
            ec.Emit(OpCodes.Ldloc, current_pc);
            ec.Emit(OpCodes.Switch, labels);

            ec.Emit(OpCodes.Br, move_next_error);
            SymbolWriter.EndIteratorDispatcher(ec);

            ec.MarkLabel(labels [0]);

            SymbolWriter.StartIteratorBody(ec);
            block.Emit(ec);
            SymbolWriter.EndIteratorBody(ec);

            SymbolWriter.StartIteratorDispatcher(ec);

            ec.Emit(OpCodes.Ldarg_0);
            ec.EmitInt((int)State.After);
            ec.Emit(OpCodes.Stfld, IteratorHost.PC.Spec);

            ec.MarkLabel(move_next_error);
            ec.EmitInt(0);
            ec.Emit(OpCodes.Ret);

            ec.MarkLabel(move_next_ok);
            ec.Emit(OpCodes.Ldc_I4_1);
            ec.Emit(OpCodes.Ret);

            SymbolWriter.EndIteratorDispatcher(ec);
        }
Example #18
0
        void EmitMoveNext(EmitContext ec)
        {
            move_next_ok    = ec.DefineLabel();
            move_next_error = ec.DefineLabel();

            if (resume_points == null)
            {
                EmitMoveNext_NoResumePoints(ec, block);
                return;
            }

            current_pc = ec.GetTemporaryLocal(ec.BuiltinTypes.UInt);
            ec.EmitThis();
            ec.Emit(OpCodes.Ldfld, storey.PC.Spec);
            ec.Emit(OpCodes.Stloc, current_pc);

            // We're actually in state 'running', but this is as good a PC value as any if there's an abnormal exit
            ec.EmitThis();
            ec.EmitInt((int)IteratorStorey.State.After);
            ec.Emit(OpCodes.Stfld, storey.PC.Spec);

            Label[] labels = new Label[1 + resume_points.Count];
            labels[0] = ec.DefineLabel();

            bool need_skip_finally = false;

            for (int i = 0; i < resume_points.Count; ++i)
            {
                ResumableStatement s = resume_points[i];
                need_skip_finally |= s is ExceptionStatement;
                labels[i + 1]      = s.PrepareForEmit(ec);
            }

            if (need_skip_finally)
            {
                skip_finally = ec.GetTemporaryLocal(ec.BuiltinTypes.Bool);
                ec.EmitInt(0);
                ec.Emit(OpCodes.Stloc, skip_finally);
            }

            var async_init = this as AsyncInitializer;

            if (async_init != null)
            {
                ec.BeginExceptionBlock();
            }

            SymbolWriter.StartIteratorDispatcher(ec);
            ec.Emit(OpCodes.Ldloc, current_pc);
            ec.Emit(OpCodes.Switch, labels);

            ec.Emit(async_init != null ? OpCodes.Leave : OpCodes.Br, move_next_error);
            SymbolWriter.EndIteratorDispatcher(ec);

            ec.MarkLabel(labels[0]);

            iterator_body_end = ec.DefineLabel();

            SymbolWriter.StartIteratorBody(ec);
            block.Emit(ec);
            SymbolWriter.EndIteratorBody(ec);

            SymbolWriter.StartIteratorDispatcher(ec);

            ec.MarkLabel(iterator_body_end);

            if (async_init != null)
            {
                var catch_value = LocalVariable.CreateCompilerGenerated(ec.Module.Compiler.BuiltinTypes.Exception, block, Location);

                ec.BeginCatchBlock(catch_value.Type);
                catch_value.EmitAssign(ec);

                ec.EmitThis();
                ec.EmitInt((int)IteratorStorey.State.After);
                ec.Emit(OpCodes.Stfld, storey.PC.Spec);

                ((AsyncTaskStorey)async_init.Storey).EmitSetException(ec, new LocalVariableReference(catch_value, Location));

                ec.Emit(OpCodes.Leave, move_next_ok);
                ec.EndExceptionBlock();
            }

            ec.EmitThis();
            ec.EmitInt((int)IteratorStorey.State.After);
            ec.Emit(OpCodes.Stfld, storey.PC.Spec);

            EmitMoveNextEpilogue(ec);

            ec.MarkLabel(move_next_error);

            if (ReturnType.Kind != MemberKind.Void)
            {
                ec.EmitInt(0);
                ec.Emit(OpCodes.Ret);
            }

            ec.MarkLabel(move_next_ok);

            if (ReturnType.Kind != MemberKind.Void)
            {
                ec.EmitInt(1);
                ec.Emit(OpCodes.Ret);
            }

            SymbolWriter.EndIteratorDispatcher(ec);
        }
Example #19
0
        //
        // Initializes the code generator variables
        //
        static public bool Init(string name, string output, bool want_debugging_support, CompilerContext ctx)
        {
            FileName = output;
            AssemblyName an = Assembly.GetAssemblyName(name, output);

            if (an == null)
            {
                return(false);
            }

            if (an.KeyPair != null)
            {
                // If we are going to strong name our assembly make
                // sure all its refs are strong named
                foreach (Assembly a in GlobalRootNamespace.Instance.Assemblies)
                {
                    AssemblyName ref_name = a.GetName();
                    byte []      b        = ref_name.GetPublicKeyToken();
                    if (b == null || b.Length == 0)
                    {
                        ctx.Report.Error(1577, "Assembly generation failed " +
                                         "-- Referenced assembly '" +
                                         ref_name.Name +
                                         "' does not have a strong name.");
                        //Environment.Exit (1);
                    }
                }
            }

            current_domain = AppDomain.CurrentDomain;

            try {
                Assembly.Builder = current_domain.DefineDynamicAssembly(an,
                                                                        AssemblyBuilderAccess.RunAndSave | COMPILER_ACCESS, Dirname(name));
            }
            catch (ArgumentException) {
                // specified key may not be exportable outside it's container
                if (RootContext.StrongNameKeyContainer != null)
                {
                    ctx.Report.Error(1548, "Could not access the key inside the container `" +
                                     RootContext.StrongNameKeyContainer + "'.");
                    Environment.Exit(1);
                }
                throw;
            }
            catch (CryptographicException) {
                if ((RootContext.StrongNameKeyContainer != null) || (RootContext.StrongNameKeyFile != null))
                {
                    ctx.Report.Error(1548, "Could not use the specified key to strongname the assembly.");
                    Environment.Exit(1);
                }
                return(false);
            }

            // Get the complete AssemblyName from the builder
            // (We need to get the public key and token)
            Assembly.Name = Assembly.Builder.GetName();

            //
            // Pass a path-less name to DefineDynamicModule.  Wonder how
            // this copes with output in different directories then.
            // FIXME: figure out how this copes with --output /tmp/blah
            //
            // If the third argument is true, the ModuleBuilder will dynamically
            // load the default symbol writer.
            //
            try {
                RootContext.ToplevelTypes.Builder = Assembly.Builder.DefineDynamicModule(
                    Basename(name), Basename(output), want_debugging_support);

#if !MS_COMPATIBLE
                // TODO: We should use SymbolWriter from DefineDynamicModule
                if (want_debugging_support && !SymbolWriter.Initialize(RootContext.ToplevelTypes.Builder, output))
                {
                    ctx.Report.Error(40, "Unexpected debug information initialization error `{0}'",
                                     "Could not find the symbol writer assembly (Mono.CompilerServices.SymbolWriter.dll)");
                    return(false);
                }
#endif
            } catch (ExecutionEngineException e) {
                ctx.Report.Error(40, "Unexpected debug information initialization error `{0}'",
                                 e.Message);
                return(false);
            }

            return(true);
        }