Skip to content

Commit

Permalink
Run MAIN units without a temporary file, using a collectable assembly
Browse files Browse the repository at this point in the history
  • Loading branch information
sorear committed Feb 28, 2011
1 parent b94a627 commit 6905b60
Show file tree
Hide file tree
Showing 6 changed files with 67 additions and 22 deletions.
2 changes: 1 addition & 1 deletion Makefile
Expand Up @@ -2,7 +2,7 @@


# How to run CLR programs; can be blank for Win32 # How to run CLR programs; can be blank for Win32
RUN_CLR=mono RUN_CLR=mono
CSC=gmcs CSC=dmcs
RM=rm -f RM=rm -f
CP=cp CP=cp


Expand Down
14 changes: 3 additions & 11 deletions README.pod
Expand Up @@ -15,17 +15,9 @@ C<test.pl>.


=item * =item *


To run on Mono: 2.6.4 and later are well-tested, though success has been To run on Mono: You will need 2.8.x or higher. 2.8.2 or later is
reported with 2.4.x as well. ggoebel on #perl6 reports that 2.6.7 fails recommended for best performance; you should use C<RUN_CLR=mono-sgen>
with a bus error on OS X 10.4 x86, but 2.6.4 works; 2.6.7 is fine on other in this case. 2.10 (latest stable) is also tested.
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 Windows/Mono (2.8.2 and 2.10) and other systems, download the To run on Windows/Mono (2.8.2 and 2.10) and other systems, download the
mono installers from C<http://go-mono.org/> mono installers from C<http://go-mono.org/>
Expand Down
2 changes: 0 additions & 2 deletions TODO
Expand Up @@ -61,8 +61,6 @@ MEDIUM
Audit accelerated context routines for correct undefined value and odd Audit accelerated context routines for correct undefined value and odd
representation handling. +Num shouldn't crash, etc. representation handling. +Num shouldn't crash, etc.


+ Run MAIN without a temporary file (needed for eval knockoff).

HARD HARD


Design and implement some sort of NFG thing that allows use codes, graphs, Design and implement some sort of NFG thing that allows use codes, graphs,
Expand Down
57 changes: 51 additions & 6 deletions lib/CLRBackend.cs
Expand Up @@ -3557,8 +3557,10 @@ public class CLRBackend {
AssemblyName an = new AssemblyName(mobname); AssemblyName an = new AssemblyName(mobname);
this.dir = dir; this.dir = dir;
ab = AppDomain.CurrentDomain.DefineDynamicAssembly(an, ab = AppDomain.CurrentDomain.DefineDynamicAssembly(an,
AssemblyBuilderAccess.Save, dir); (filename == null ? AssemblyBuilderAccess.RunAndCollect :
mob = ab.DefineDynamicModule(mobname, filename); AssemblyBuilderAccess.Save), dir);
mob = filename == null ? ab.DefineDynamicModule(mobname) :
ab.DefineDynamicModule(mobname, filename);


tb = mob.DefineType(mobname, TypeAttributes.Public | tb = mob.DefineType(mobname, TypeAttributes.Public |
TypeAttributes.Sealed | TypeAttributes.Abstract | TypeAttributes.Sealed | TypeAttributes.Abstract |
Expand Down Expand Up @@ -3919,6 +3921,19 @@ public class CLRBackend {
il.Emit(OpCodes.Ret); il.Emit(OpCodes.Ret);


ab.SetEntryPoint(mb); 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; [ThreadStatic] static Dictionary<string, Unit> used_units;
Expand All @@ -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) { public static void Main(string[] args) {
if (args.Length != 4) { if (args.Length != 4) {
Console.Error.WriteLine("usage : CLRBackend DIR UNITFILE OUTFILE ISMAIN"); Console.Error.WriteLine("usage : CLRBackend DIR UNITFILE OUTFILE ISMAIN");
Expand Down Expand Up @@ -3984,10 +4028,11 @@ public class DownCallAcceptor: CrossDomainReceiver {
if (args[0] == "post_save") { if (args[0] == "post_save") {
CLRBackend.Main(new string[] { args[1], args[2], args[3], args[4] }); CLRBackend.Main(new string[] { args[1], args[2], args[3], args[4] });
return new string[0]; return new string[0];
} else if (args[0] == "runnam") { } else if (args[0] == "runnam" || args[0] == "evalnam") {
Console.WriteLine("directory : {0}", args[1]); string[] argv = new string[args.Length - 3];
Console.WriteLine("unit name : {0}", args[2]); Array.Copy(args, 3, argv, 0, argv.Length);
Console.WriteLine("contents : {0}", args[3]); CLRBackend.RunMain(args[1], args[2],
args[0] == "evalnam" ? null : argv);
return new string[0]; return new string[0];
} else if (args[0] == "hello") { } else if (args[0] == "hello") {
return new string[] { Assembly.GetExecutingAssembly().Location }; return new string[] { Assembly.GetExecutingAssembly().Location };
Expand Down
3 changes: 3 additions & 0 deletions lib/Kernel.cs
Expand Up @@ -2159,6 +2159,9 @@ public class Kernel {


public static Variable RunLoop(string main_unit, public static Variable RunLoop(string main_unit,
string[] args, DynBlockDelegate boot) { string[] args, DynBlockDelegate boot) {
if (args == null) {
return BootModule(main_unit, boot);
}
commandArgs = args; commandArgs = args;
string trace = Environment.GetEnvironmentVariable("NIECZA_TRACE"); string trace = Environment.GetEnvironmentVariable("NIECZA_TRACE");
if (trace != null) { if (trace != null) {
Expand Down
11 changes: 9 additions & 2 deletions src/NieczaBackendDotnet.pm6
@@ -1,6 +1,8 @@
use NieczaBackendNAM; use NieczaBackendNAM;
class NieczaBackendDotnet is NieczaBackendNAM; class NieczaBackendDotnet is NieczaBackendNAM;


use NAMOutput;

sub upcalled(@strings) { sub upcalled(@strings) {
say "upcall: @strings.join('|')"; say "upcall: @strings.join('|')";
"ERROR"; "ERROR";
Expand All @@ -15,6 +17,13 @@ sub run_subtask($file, *@args) {
} }


method accept($unitname, $ast is rw, :$main, :$run) { 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); self.save_unit($unitname, $ast);
$ast.clear_optrees; $ast.clear_optrees;
$ast = Any; $ast = Any;
Expand All @@ -33,5 +42,3 @@ method run($name) {
my $fname = $name.split('::').join('.'); my $fname = $name.split('::').join('.');
run_subtask($.obj_dir.IO.append($fname ~ ".exe"), @$.run_args); run_subtask($.obj_dir.IO.append($fname ~ ".exe"), @$.run_args);
} }


0 comments on commit 6905b60

Please sign in to comment.