Skip to content

Commit

Permalink
Bring compartment stack management under compiler control
Browse files Browse the repository at this point in the history
  • Loading branch information
sorear committed Nov 12, 2012
1 parent c80570d commit 532462b
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 20 deletions.
9 changes: 6 additions & 3 deletions lib/CodeGen.cs
Expand Up @@ -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) {
Expand Down
33 changes: 19 additions & 14 deletions lib/Kernel.cs
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion src/NieczaBackendDotnet.pm6
Expand Up @@ -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) {
Expand Down
4 changes: 2 additions & 2 deletions src/NieczaFrontendSTD.pm6
Expand Up @@ -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);
Expand Down

0 comments on commit 532462b

Please sign in to comment.