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(); }
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); } }
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); } }
/// <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); }
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); }
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)); } }
public static void Reset(bool full_flag) { Location.Reset(); if (!full_flag) { return; } SymbolWriter.Reset(); Linq.QueryBlock.TransparentParameter.Reset(); TypeInfo.Reset(); }
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(); }
/// <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); }
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); }
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); }
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); }
public void EndScope() { SymbolWriter.CloseScope(ig); }
public void BeginScope() { SymbolWriter.OpenScope(ig); }
public void DefineLocalVariable(string name, LocalBuilder builder) { SymbolWriter.DefineLocalVariable(name, builder); }
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(); } }
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); }
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); }
// // 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); }