public static void SaveToAssembly(string assemblyName, IDictionary <string, object> assemblyAttributes, params SavableScriptCode[] codes) { ContractUtils.RequiresNotNull(assemblyName, nameof(assemblyName)); ContractUtils.RequiresNotNullItems(codes, nameof(codes)); #if FEATURE_FILESYSTEM // break the assemblyName into it's dir/name/extension string dir = Path.GetDirectoryName(assemblyName); if (String.IsNullOrEmpty(dir)) { dir = Environment.CurrentDirectory; } #else string dir = null; #endif string name = Path.GetFileNameWithoutExtension(assemblyName); string ext = Path.GetExtension(assemblyName); // build the assembly & type gen that all the script codes will live in... AssemblyGen ag = new AssemblyGen(new AssemblyName(name), dir, ext, /*emitSymbols*/ false, assemblyAttributes); TypeBuilder tb = ag.DefinePublicType("DLRCachedCode", typeof(object), true); TypeGen tg = new TypeGen(ag, tb); // then compile all of the code Dictionary <Type, List <CodeInfo> > langCtxBuilders = new Dictionary <Type, List <CodeInfo> >(); foreach (SavableScriptCode sc in codes) { if (!langCtxBuilders.TryGetValue(sc.LanguageContext.GetType(), out List <CodeInfo> builders)) { langCtxBuilders[sc.LanguageContext.GetType()] = builders = new List <CodeInfo>(); } KeyValuePair <MethodBuilder, Type> compInfo = sc.CompileForSave(tg); builders.Add(new CodeInfo(compInfo.Key, sc, compInfo.Value)); } MethodBuilder mb = tb.DefineMethod( "GetScriptCodeInfo", MethodAttributes.SpecialName | MethodAttributes.Public | MethodAttributes.Static, typeof(MutableTuple <Type[], Delegate[][], string[][], string[][]>), ReflectionUtils.EmptyTypes); ILGen ilgen = new ILGen(mb.GetILGenerator()); var langsWithBuilders = langCtxBuilders.ToArray(); // lang ctx array ilgen.EmitArray(typeof(Type), langsWithBuilders.Length, (index) => { ilgen.Emit(OpCodes.Ldtoken, langsWithBuilders[index].Key); ilgen.EmitCall(typeof(Type).GetMethod(nameof(Type.GetTypeFromHandle), new[] { typeof(RuntimeTypeHandle) })); }); // builders array of array ilgen.EmitArray(typeof(Delegate[]), langsWithBuilders.Length, (index) => { List <CodeInfo> builders = langsWithBuilders[index].Value; ilgen.EmitArray(typeof(Delegate), builders.Count, (innerIndex) => { ilgen.EmitNull(); ilgen.Emit(OpCodes.Ldftn, builders[innerIndex].Builder); ilgen.EmitNew( builders[innerIndex].DelegateType, new[] { typeof(object), typeof(IntPtr) } ); }); }); // paths array of array ilgen.EmitArray(typeof(string[]), langsWithBuilders.Length, (index) => { List <CodeInfo> builders = langsWithBuilders[index].Value; ilgen.EmitArray(typeof(string), builders.Count, (innerIndex) => { ilgen.EmitString(builders[innerIndex].Code.SourceUnit.Path); }); }); // 4th element in tuple - custom per-language data ilgen.EmitArray(typeof(string[]), langsWithBuilders.Length, (index) => { List <CodeInfo> builders = langsWithBuilders[index].Value; ilgen.EmitArray(typeof(string), builders.Count, (innerIndex) => { ICustomScriptCodeData data = builders[innerIndex].Code as ICustomScriptCodeData; if (data != null) { ilgen.EmitString(data.GetCustomScriptCodeData()); } else { ilgen.Emit(OpCodes.Ldnull); } }); }); ilgen.EmitNew( typeof(MutableTuple <Type[], Delegate[][], string[][], string[][]>), new[] { typeof(Type[]), typeof(Delegate[][]), typeof(string[][]), typeof(string[][]) } ); ilgen.Emit(OpCodes.Ret); mb.SetCustomAttribute(new CustomAttributeBuilder( typeof(DlrCachedCodeAttribute).GetConstructor(ReflectionUtils.EmptyTypes), ArrayUtils.EmptyObjects )); tg.FinishType(); ag.SaveAssembly(); }
public void GetObjectData(SerializationInfo info, StreamingContext context) { ContractUtils.RequiresNotNull(info, "info"); info.AddValue("symbolName", SymbolTable.IdToString(this)); }
public ErrorCounter(ErrorSink /*!*/ sink) { ContractUtils.RequiresNotNull(sink, "sink"); _sink = sink; }
// When leaving a context we serialize out our ID as a name // rather than a raw ID. When we enter a new context we // consult it's FieldTable to get the ID of the symbol name in // the new context. private SymbolId(SerializationInfo info, StreamingContext context) { ContractUtils.RequiresNotNull(info, "info"); _id = SymbolTable.StringToId(info.GetString("symbolName"))._id; }
protected ScriptCode(SourceUnit sourceUnit) { ContractUtils.RequiresNotNull(sourceUnit, nameof(sourceUnit)); _sourceUnit = sourceUnit; }