Permalink
Browse files

Run MAIN units without a temporary file, using a collectable assembly

  • Loading branch information...
sorear committed Feb 28, 2011
1 parent b94a627 commit 6905b6000332db5a89d324c1bf7d2458b5960419
Showing with 67 additions and 22 deletions.
  1. +1 −1 Makefile
  2. +3 −11 README.pod
  3. +0 −2 TODO
  4. +51 −6 lib/CLRBackend.cs
  5. +3 −0 lib/Kernel.cs
  6. +9 −2 src/NieczaBackendDotnet.pm6
View
@@ -2,7 +2,7 @@
# How to run CLR programs; can be blank for Win32
RUN_CLR=mono
-CSC=gmcs
+CSC=dmcs
RM=rm -f
CP=cp
View
@@ -15,17 +15,9 @@ C<test.pl>.
=item *
-To run on Mono: 2.6.4 and later are well-tested, though success has been
-reported with 2.4.x as well. ggoebel on #perl6 reports that 2.6.7 fails
-with a bus error on OS X 10.4 x86, but 2.6.4 works; 2.6.7 is fine on other
-platforms.
-
-2.8.2 or later is recommended for best performance; you should use
-C<RUN_CLR=mono-sgen> in this case. 2.10 (latest stable) is also tested.
-
-Debian and derivatives have a modular mono packaging; you should install
-'mono-complete'. (The other packages exist for the sake of Debian-packaged
-programs.)
+To run on Mono: You will need 2.8.x or higher. 2.8.2 or later is
+recommended for best performance; you should use C<RUN_CLR=mono-sgen>
+in this case. 2.10 (latest stable) is also tested.
To run on Windows/Mono (2.8.2 and 2.10) and other systems, download the
mono installers from C<http://go-mono.org/>
View
2 TODO
@@ -61,8 +61,6 @@ MEDIUM
Audit accelerated context routines for correct undefined value and odd
representation handling. +Num shouldn't crash, etc.
- + Run MAIN without a temporary file (needed for eval knockoff).
-
HARD
Design and implement some sort of NFG thing that allows use codes, graphs,
View
@@ -3557,8 +3557,10 @@ public class CLRBackend {
AssemblyName an = new AssemblyName(mobname);
this.dir = dir;
ab = AppDomain.CurrentDomain.DefineDynamicAssembly(an,
- AssemblyBuilderAccess.Save, dir);
- mob = ab.DefineDynamicModule(mobname, filename);
+ (filename == null ? AssemblyBuilderAccess.RunAndCollect :
+ AssemblyBuilderAccess.Save), dir);
+ mob = filename == null ? ab.DefineDynamicModule(mobname) :
+ ab.DefineDynamicModule(mobname, filename);
tb = mob.DefineType(mobname, TypeAttributes.Public |
TypeAttributes.Sealed | TypeAttributes.Abstract |
@@ -3919,6 +3921,19 @@ public class CLRBackend {
il.Emit(OpCodes.Ret);
ab.SetEntryPoint(mb);
+
+ mb = tb.DefineMethod("EVAL", MethodAttributes.Static |
+ MethodAttributes.Public, Tokens.Variable,
+ new Type[] { typeof(string[]) });
+ il = mb.GetILGenerator();
+
+ il.Emit(OpCodes.Ldstr, name);
+ il.Emit(OpCodes.Ldarg_0);
+ il.Emit(OpCodes.Ldnull);
+ il.Emit(OpCodes.Ldftn, boot);
+ il.Emit(OpCodes.Newobj, Tokens.DynBlockDelegate_ctor);
+ il.Emit(OpCodes.Call, Tokens.Kernel_RunLoop);
+ il.Emit(OpCodes.Ret);
}
[ThreadStatic] static Dictionary<string, Unit> used_units;
@@ -3945,6 +3960,35 @@ public class CLRBackend {
}
}
+ internal static void RunMain(string dir, string contents,
+ string[] argv) {
+ Unit root = new Unit((object[])Reader.Read(contents));
+ CLRBackend old_Current = Current;
+ Dictionary<string,Unit> old_used_units = used_units;
+ CLRBackend c = new CLRBackend(dir, root.name, null);
+ Current = c;
+
+ used_units = new Dictionary<string, Unit>();
+ used_units[root.name] = root;
+
+ foreach (object x in root.tdeps) {
+ object[] dn = (object[]) x;
+ string name = JScalar.S(dn[0]);
+ if (name == root.name) continue;
+ used_units[name] = LoadDepUnit(name);
+ }
+ root.BindDepends(true);
+
+ c.Process(root, true);
+
+ Type t = c.tb.CreateType();
+ used_units = old_used_units; Current = old_Current;
+
+ Builtins.eval_result = (Variable) t.InvokeMember("EVAL",
+ BindingFlags.Public | BindingFlags.Static |
+ BindingFlags.InvokeMethod, null, null, new object[] { argv });
+ }
+
public static void Main(string[] args) {
if (args.Length != 4) {
Console.Error.WriteLine("usage : CLRBackend DIR UNITFILE OUTFILE ISMAIN");
@@ -3984,10 +4028,11 @@ public class DownCallAcceptor: CrossDomainReceiver {
if (args[0] == "post_save") {
CLRBackend.Main(new string[] { args[1], args[2], args[3], args[4] });
return new string[0];
- } else if (args[0] == "runnam") {
- Console.WriteLine("directory : {0}", args[1]);
- Console.WriteLine("unit name : {0}", args[2]);
- Console.WriteLine("contents : {0}", args[3]);
+ } else if (args[0] == "runnam" || args[0] == "evalnam") {
+ string[] argv = new string[args.Length - 3];
+ Array.Copy(args, 3, argv, 0, argv.Length);
+ CLRBackend.RunMain(args[1], args[2],
+ args[0] == "evalnam" ? null : argv);
return new string[0];
} else if (args[0] == "hello") {
return new string[] { Assembly.GetExecutingAssembly().Location };
View
@@ -2159,6 +2159,9 @@ public class Kernel {
public static Variable RunLoop(string main_unit,
string[] args, DynBlockDelegate boot) {
+ if (args == null) {
+ return BootModule(main_unit, boot);
+ }
commandArgs = args;
string trace = Environment.GetEnvironmentVariable("NIECZA_TRACE");
if (trace != null) {
@@ -1,6 +1,8 @@
use NieczaBackendNAM;
class NieczaBackendDotnet is NieczaBackendNAM;
+use NAMOutput;
+
sub upcalled(@strings) {
say "upcall: @strings.join('|')";
"ERROR";
@@ -15,6 +17,13 @@ sub run_subtask($file, *@args) {
}
method accept($unitname, $ast is rw, :$main, :$run) {
+ if $run {
+ my $nam = NAMOutput.run($ast);
+ $ast.clear_optrees;
+ $ast = Any;
+ downcall("runnam", $.obj_dir, $nam);
+ return;
+ }
self.save_unit($unitname, $ast);
$ast.clear_optrees;
$ast = Any;
@@ -33,5 +42,3 @@ method run($name) {
my $fname = $name.split('::').join('.');
run_subtask($.obj_dir.IO.append($fname ~ ".exe"), @$.run_args);
}
-
-

0 comments on commit 6905b60

Please sign in to comment.