Permalink
Browse files

Bring compartment stack management under compiler control

  • Loading branch information...
sorear committed Nov 12, 2012
1 parent c80570d commit 532462be25e09e1f812bd4f36e742562e9d3b2a7
Showing with 28 additions and 20 deletions.
  1. +6 −3 lib/CodeGen.cs
  2. +19 −14 lib/Kernel.cs
  3. +1 −1 src/NieczaBackendDotnet.pm6
  4. +2 −2 src/NieczaFrontendSTD.pm6
View
@@ -3645,11 +3645,14 @@ public class DowncallReceiver : CallReceiver {
return null;
}
public static object push_compartment(object[] args) {
- Compartment.Push();
- return null;
+ var old = Compartment.Top;
+ Compartment.Top = new Compartment();
+ Kernel.InitCompartment();
+ return Handle.Wrap(old);
}
public static object pop_compartment(object[] args) {
- Compartment.Pop();
+ Compartment.Top.RunEnd();
+ Compartment.Top = (Compartment)Handle.Unbox(args[1]);
return null;
}
public static object new_unit(object[] args) {
View
@@ -4624,34 +4624,39 @@ public class Compartment {
internal static void BeforeExit(object sender, EventArgs args) {
if (disable_end) return;
disable_end = true;
- while (Top.prev != null) { Pop(); }
- Top.end.Run();
+
+ while (true) {
+ Compartment tokill = null;
+ lock (pending) {
+ if (pending.Count > 0) tokill = ((IEnumerable<Compartment>)pending).GetEnumerator().Current;
+ }
+ if (tokill == null) break;
+ tokill.RunEnd();
+ }
+
// XXX is this really the best place?
Builtins.stdout.Flush();
Builtins.stderr.Flush();
}
- Compartment prev;
- private Compartment() { }
+ internal Compartment() { lock(pending) pending.Add(this); }
+ [TrueGlobal]
+ internal static HashSet<Compartment> pending = new HashSet<Compartment>();
[TrueGlobal]
public static Compartment Top = new Compartment();
+ internal bool end_run;
internal PhaserList check = new PhaserList(true);
internal PhaserList init = new PhaserList(false);
internal PhaserList end = new PhaserList(true);
- internal static void Push() {
- Compartment n = new Compartment();
- n.prev = Top;
-
- Top = n;
- Kernel.InitCompartment();
- }
+ internal void RunEnd() {
+ if (end_run) return;
+ end_run = true;
+ lock(pending) pending.Remove(this);
- internal static void Pop() {
- Top.end.Run();
- Top = Top.prev;
+ end.Run();
}
// and here's a bunch of smart constructors
@@ -342,7 +342,7 @@ class Unit {
}
method push_compartment() { downcall("push_compartment") }
-method pop_compartment() { downcall("pop_compartment") }
+method pop_compartment($c) { downcall("pop_compartment", $c) }
method get_codepoint($str) { downcall("get_codepoint", $str) }
method create_unit($name, $filename, $source, $main, $run) {
@@ -269,8 +269,8 @@ method parse(:$unitname, :$filename, :$source, :$outer, :$run, :$main, :$evalmod
my $*UNIT;
my $*CCSTATE; my $*BORG; my %*RX; my $*XACT; my $*VAR; my $*IN_REDUCE;
- $*backend.push_compartment unless $evalmode;
- LEAVE { $*backend.pop_compartment unless $evalmode };
+ my $oldc = $*backend.push_compartment unless $evalmode;
+ LEAVE { $*backend.pop_compartment($oldc) unless $evalmode };
my $*unit = $*backend.create_unit($unitname, $filename, $*no_incl_source ?? $Backend.gethash($source) !! $source, $main, $run);
my $*settingref = $*niecza_outer_ref ||
($lang ne 'NULL' ?? $*unit.need_unit($lang).bottom !! Any);

0 comments on commit 532462b

Please sign in to comment.