diff --git a/Makefile b/Makefile index 0d83babc..8031ec3e 100644 --- a/Makefile +++ b/Makefile @@ -49,12 +49,12 @@ boot/obj/CompilerBlob.dll: .fetch-stamp src/CompilerBlob.cs $(CSC) /target:library /out:boot/obj/CompilerBlob.dll /r:Kernel \ /lib:boot/obj src/CompilerBlob.cs obj/Kernel.dll: $(patsubst %,lib/%,$(cskernel)) - $(CSC) /target:library /out:obj/Kernel.dll /lib:obj /unsafe+ \ + $(CSC) /target:exe /out:obj/Kernel.dll /lib:obj /unsafe+ \ $(patsubst %,lib/%,$(cskernel)) perl5: obj/Perl5Interpreter.dll obj/p5embed.so obj/Perl5Interpreter.dll: obj/Kernel.dll lib/Perl5Interpreter.cs - gmcs /target:library /lib:obj /out:obj/Perl5Interpreter.dll /r:Kernel.dll lib/Perl5Interpreter.cs + $(CSC) /target:library /lib:obj /out:obj/Perl5Interpreter.dll /r:Kernel.dll lib/Perl5Interpreter.cs obj/p5embed.so: lib/p5embed.c cc -shared -Wl,-soname,p5embed.so -o obj/p5embed.so lib/p5embed.c `perl -MExtUtils::Embed -e ccopts -e ldopts` diff --git a/lib/Kernel.cs b/lib/Kernel.cs index 5eb37d71..e01fe68f 100644 --- a/lib/Kernel.cs +++ b/lib/Kernel.cs @@ -316,9 +316,9 @@ public sealed class RuntimeUnit : IFreeze { public SubInfo mainline, bottom; public bool is_mainish; public Type type; + public List our_subs; // used during construction only - public List our_subs; public AssemblyBuilder asm_builder; public ModuleBuilder mod_builder; public TypeBuilder type_builder; @@ -336,6 +336,8 @@ class IdentityComparer : IEqualityComparer { } } + private RuntimeUnit() { } + public RuntimeUnit(string name, string filename, string modtime, string obj_dir, bool main, bool runnow) { this.name = name; @@ -349,10 +351,15 @@ class IdentityComparer : IEqualityComparer { this.asm_name = name.Replace("::", "."); this.dll_name = asm_name + (main ? ".exe" : ".dll"); + our_subs = new List(); + } + + void GenerateCode(bool runnow) { this.asm_builder = AppDomain.CurrentDomain.DefineDynamicAssembly( new AssemblyName(asm_name), (runnow ? AssemblyBuilderAccess.Run : - AssemblyBuilderAccess.Save), obj_dir); + AssemblyBuilderAccess.Save), + AppDomain.CurrentDomain.BaseDirectory); mod_builder = runnow ? asm_builder.DefineDynamicModule(asm_name) : asm_builder.DefineDynamicModule(asm_name, dll_name); //mod_builder = asm_builder.DefineDynamicModule(asm_name, dll_name); @@ -364,10 +371,6 @@ class IdentityComparer : IEqualityComparer { constants = new Dictionary(new IdentityComparer()); val_constants = new Dictionary(); - our_subs = new List(); - } - - void GenerateCode() { NamProcessor[] ths = new NamProcessor[our_subs.Count]; for (int i = 0; i < ths.Length; i++) { SubInfo z = our_subs[i]; @@ -385,16 +388,16 @@ class IdentityComparer : IEqualityComparer { } } - static ObjectRegistry reg = new ObjectRegistry(); + internal static ObjectRegistry reg = new ObjectRegistry(); public void Save() { - GenerateCode(); + GenerateCode(false); asm_builder.Save(dll_name); reg.SaveUnit(asm_name, this); } public void PrepareEval() { - GenerateCode(); + GenerateCode(true); foreach (SubInfo z in our_subs) if ((z.special & SubInfo.UNSAFE) != 0) @@ -634,8 +637,32 @@ class IdentityComparer : IEqualityComparer { fb.ObjRef(mainline); fb.ObjRef(bottom); + fb.Refs(our_subs); fb.Byte((byte)(is_mainish ? 1 : 0)); } + + internal static RuntimeUnit Thaw(ThawBuffer tb) { + RuntimeUnit n = new RuntimeUnit(); + tb.Register(n); + + n.name = tb.String(); + n.filename = tb.String(); + n.modtime = tb.String(); + n.asm_name = tb.String(); + n.dll_name = tb.String(); + + int ct = tb.Int(); + n.globals = new Dictionary(); + for (int i = 0; i < ct; i++) { + n.globals[tb.String()] = (StashEnt)tb.ObjRef(); + } + + n.mainline = (SubInfo)tb.ObjRef(); + n.bottom = (SubInfo)tb.ObjRef(); + n.our_subs = tb.RefsL(); + n.is_mainish = tb.Byte() != 0; + return n; + } } public sealed class LeaveHook { @@ -5113,6 +5140,20 @@ class LastFrameNode { return tf; } } + + public static void Main(string[] args) { + string cmd = args.Length > 0 ? args[0] : "-help"; + + if (cmd == "-run" && args.Length == 2) { + RuntimeUnit ru = (RuntimeUnit) + RuntimeUnit.reg.LoadUnit(args[1]).root; + + ru.PrepareEval(); + RunMain(ru); + } else { + Console.WriteLine("usage: Kernel.dll -run Unit.Name"); + } + } } public class Config { diff --git a/lib/Serialize.cs b/lib/Serialize.cs index 5b9b0713..ed494951 100644 --- a/lib/Serialize.cs +++ b/lib/Serialize.cs @@ -86,6 +86,18 @@ struct ObjRef { return false; } + public void RegisterThawed(SerUnit into, object o) { + ObjRef or; + if (into.nobj == into.bynum.Length) + Array.Resize(ref into.bynum, into.nobj * 2); + + or.unit = into; + or.id = into.nobj++; + into.bynum[or.id] = o; + + byref[o] = or; + } + // Routines for use by compilation manager // Loads a single unit from the compiled-data directory. @@ -204,11 +216,15 @@ enum SerializationCode : byte { Frame, Cursor, - // miscellany - Variant, // allow 5, see FallbackFreeze + // miscellany - keep these in same order as FallbackFreeze + String, + ArrP6any, + ArrVariable, + Int, + Double, // variables - SimpleVariable = Variant + 5, // allow 4 for flags + SimpleVariable, // allow 4 for flags SubstrLValue = SimpleVariable + 4, TiedVariable, @@ -386,7 +402,6 @@ public class FreezeBuffer { } } - // Call this to freeze a variant-typed value. (Avoid) static Type[] anyTypes = new Type[] { typeof(string), typeof(P6any[]), typeof(Variable[]), typeof(int), typeof(double), @@ -396,7 +411,7 @@ public class FreezeBuffer { int ix = 0; Type t = o.GetType(); while (ix != 11 && anyTypes[ix] != t) ix++; - Byte((byte)(((int)SerializationCode.Variant) + ix)); + Byte((byte)(((int)SerializationCode.String) + ix)); switch(ix) { case 0: @@ -479,6 +494,24 @@ class ThawBuffer { return buf; } + public List RefsL() where T : class { + int ct = Int(); + if (ct < 0) return null; + List ret = new List(); + for (int i = 0; i < ct; i++) + ret.Add((T) ObjRef()); + return ret; + } + + public T[] RefsA() where T : class { + int ct = Int(); + if (ct < 0) return null; + T[] ret = new T[ct]; + for (int i = 0; i < ct; i++) + ret[i] = (T) ObjRef(); + return ret; + } + public object ObjRef() { var tag = (SerializationCode)Byte(); int i, j; @@ -494,11 +527,18 @@ class ThawBuffer { return unit_map[i].bynum[j]; case SerializationCode.NewUnitRef: return LoadNewUnit(); + case SerializationCode.RuntimeUnit: + return RuntimeUnit.Thaw(this); default: - throw new ThawException("unexpected object tag" + (byte)tag); + throw new ThawException("unexpected object tag " + tag); } } + // call this when thawing any new object + internal void Register(object o) { + reg.RegisterThawed(unit, o); + } + object LoadNewUnit() { string name = String(); if (refed_units == unit_map.Length)