Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Add a JSYNC dumper
  • Loading branch information
sorear committed Nov 13, 2010
1 parent a1bb48f commit 2484b4a
Show file tree
Hide file tree
Showing 8 changed files with 223 additions and 40 deletions.
4 changes: 2 additions & 2 deletions Niecza.proj
Expand Up @@ -36,9 +36,9 @@
</Target>

<!-- Libraries -->
<Target Name="Kernel.dll" Inputs="lib\Kernel.cs;lib\Cursor.cs"
<Target Name="Kernel.dll" Inputs="lib\Kernel.cs;lib\Cursor.cs;lib/JSYNC.cs"
Outputs="obj\Kernel.dll">
<Csc Sources="lib\Kernel.cs;lib\Cursor.cs" TargetType="library"
<Csc Sources="lib\Kernel.cs;lib\Cursor.cs;lib\JSYNC.cs" TargetType="library"
OutputAssembly="obj\Kernel.dll"/>
</Target>

Expand Down
20 changes: 8 additions & 12 deletions lib/Cursor.cs
Expand Up @@ -111,10 +111,10 @@ public sealed class RxFrame {
bt = bt.prev;
if (bt == rootf) {
if (return_one) {
return Kernel.Take(th, Kernel.NewROScalar(EMPTYP));
return Kernel.Take(th, Kernel.NewROScalar(Kernel.EMPTYP));
} else {
if (EmptyList == null) {
DynObject lst = new DynObject(ListMO);
DynObject lst = new DynObject(Kernel.ListMO);
lst.slots[0 /*items*/] = new VarDeque();
lst.slots[1 /*rest*/ ] = new VarDeque();
EmptyList = Kernel.NewRWListVar(lst);
Expand Down Expand Up @@ -309,10 +309,6 @@ public sealed class RxFrame {
return new Cursor(global, st.ns.klass, from, st.pos, st.captures);
}

public static DynMetaObject MatchMO;
public static DynMetaObject ListMO;
public static DynMetaObject GatherIteratorMO;
public static IP6 EMPTYP;
public static Variable EmptyList;

public Frame FinalEnd(Frame th) {
Expand All @@ -331,12 +327,12 @@ public sealed class RxFrame {
return_one = true;
VarDeque ks = new VarDeque();
ks.Push(Kernel.NewROScalar(m));
DynObject it = new DynObject(GatherIteratorMO);
DynObject it = new DynObject(Kernel.GatherIteratorMO);
it.slots[0 /*frame*/] = Kernel.NewRWScalar(Kernel.AnyMO, th);
it.slots[1 /*reify*/] = Kernel.NewRWScalar(Kernel.AnyMO, Kernel.AnyP);
VarDeque iss = new VarDeque();
iss.Push(Kernel.NewROScalar(it));
DynObject lst = new DynObject(ListMO);
DynObject lst = new DynObject(Kernel.ListMO);
lst.slots[0 /*items*/] = ks;
lst.slots[1 /*rest*/ ] = iss;
th.caller.resultSlot = Kernel.NewRWListVar(lst);
Expand Down Expand Up @@ -375,7 +371,7 @@ public Cursor(IP6 proto, string text)
this.captures = captures;
this.pos = pos;
this.from = from;
this.mo = RxFrame.MatchMO;
this.mo = Kernel.MatchMO;
this.save_klass = klass;
}

Expand Down Expand Up @@ -414,7 +410,7 @@ public Cursor(Cursor parent, string method, int from, int to)
private Variable FixupList(VarDeque caps) {
if (caps.Count() != 0 && caps[0] == null) {
caps.Shift();
DynObject l = new DynObject(RxFrame.ListMO);
DynObject l = new DynObject(Kernel.ListMO);
l.slots[0 /*items*/] = caps;
l.slots[1 /*rest*/ ] = new VarDeque();
return Kernel.NewRWListVar(l);
Expand Down Expand Up @@ -481,7 +477,7 @@ public Cursor(Cursor parent, string method, int from, int to)
nw.captures = new CapInfo(nw.captures, new string[] { kv.Key }, kv.Value);
VarDeque ks = new VarDeque();

DynObject lst = new DynObject(RxFrame.ListMO);
DynObject lst = new DynObject(Kernel.ListMO);
lst.slots[0 /*items*/] = ks;
lst.slots[1 /*rest*/ ] = new VarDeque();

Expand All @@ -497,7 +493,7 @@ public Cursor(Cursor parent, string method, int from, int to)

VarDeque ks = new VarDeque();

DynObject lst = new DynObject(RxFrame.ListMO);
DynObject lst = new DynObject(Kernel.ListMO);
lst.slots[0 /*items*/] = ks;
lst.slots[1 /*rest*/ ] = new VarDeque();

Expand Down
161 changes: 161 additions & 0 deletions lib/JSYNC.cs
@@ -0,0 +1,161 @@
using Niecza;
using System;
using System.Collections.Generic;
using System.Text;

public class JsyncWriter {
StringBuilder o = new StringBuilder();
Dictionary<object,int> anchors = new Dictionary<object,int>();
int nextanchor = 0;

void WriteObj(IP6 obj) {
int anchor;
if (anchors.TryGetValue(obj, out anchor)) {
WriteAnchor(anchor);
} else if (!obj.IsDefined()) {
WriteNull();
} else if (obj.Isa(Kernel.ListMO)) {
WriteArray(obj);
} else if (obj.Isa(Kernel.HashMO)) {
WriteHash(obj);
} else if (obj.Isa(Kernel.BoolMO)) {
WriteBool((bool) Kernel.UnboxAny(obj));
} else if (obj.Isa(Kernel.StrMO)) {
WriteStr(true, (string) Kernel.UnboxAny(obj));
} else if (obj.Isa(Kernel.NumMO)) {
WriteNum((double) Kernel.UnboxAny(obj));
} else {
WriteGeneral(obj);
}
}

void WriteNull() {
o.Append("null");
}

void WriteArray(IP6 obj) {
int a = nextanchor++;
anchors[obj] = a;
Frame nr = new Frame(null, null, Kernel.ExitRunloopSI);
nr = obj.InvokeMethod(nr, "eager", new Variable[] { Kernel.NewROScalar(obj) }, null);
Kernel.RunCore(nr);

o.AppendFormat("[\"&{0}\"", a);
VarDeque vd = (VarDeque) obj.GetSlot("items");
for (int i = 0; i < vd.Count(); i++) {
o.Append(',');
WriteObj(vd[i].Fetch());
}
o.Append(']');
}

void WriteHash(IP6 obj) {
int a = nextanchor++;
anchors[obj] = a;
Dictionary<string,Variable> entries = (Dictionary<string,Variable>)
Kernel.UnboxAny(obj);
o.Append('{');
o.AppendFormat("\"&\":{0}", a);
foreach (KeyValuePair<string,Variable> kv in entries) {
o.Append(',');

// no object keys in hashes yet
WriteStr(true, kv.Key);
o.Append(':');
WriteObj(kv.Value.Fetch());
}
o.Append('}');
}

void WriteGeneral(IP6 obj) {
int a = nextanchor++;
anchors[obj] = a;
DynObject dyo = (DynObject) obj;
DynMetaObject mo = dyo.mo;

o.Append('{');
o.AppendFormat("\"&\":{0},\"!\":", a);
WriteStr(false, "!perl6:" + mo.name);

for (int i = 0; i < mo.nslots; i++) {
o.Append(',');
WriteStr(true, mo.all_attr[i]);
o.Append(':');
WriteObj(((Variable)dyo.slots[i]).Fetch());
}

o.Append('}');
}

bool NeedsEscape(string s) {
foreach (char ch in s) {
if (ch == '*' || ch == '%' || ch == '&' || ch == '!')
return true;
if (ch != '.')
return false;
}
return false;
}

void WriteStr(bool esc, string s) {
o.Append('"');
if (esc && NeedsEscape(s))
o.Append('.');
foreach (char ch in s) {
switch(ch) {
case '\\':
o.Append('\\');
goto default;
case '\"':
o.Append('\\');
goto default;
default:
if ((ch & 0xFF7F) < 32) {
o.AppendFormat("\\u{0:4X}", (int)ch);
} else {
o.Append(ch);
}
break;
case '\b':
o.Append('\\');
o.Append('b');
break;
case '\f':
o.Append('\\');
o.Append('f');
break;
case '\t':
o.Append('\\');
o.Append('t');
break;
case '\r':
o.Append('\\');
o.Append('r');
break;
case '\n':
o.Append('\\');
o.Append('n');
break;
}
}
o.Append('"');
}

void WriteBool(bool x) {
o.Append(x ? "true" : "false");
}

void WriteNum(double x) {
o.Append(x);
}

void WriteAnchor(int i) {
o.AppendFormat("\"*{0}\"", i);
}

public static string ToJsync(IP6 obj) {
JsyncWriter w = new JsyncWriter();
w.WriteObj(obj);
return w.o.ToString();
}
}
40 changes: 22 additions & 18 deletions lib/Kernel.cs
Expand Up @@ -737,12 +737,26 @@ public class Kernel {
return nw;
}

public static DynMetaObject AnyMO;
public static DynMetaObject BoolMO;
public static DynMetaObject CallFrameMO;
public static DynMetaObject CaptureMO;

public static readonly DynMetaObject SubMO;
public static DynMetaObject GatherIteratorMO;
public static DynMetaObject HashMO;
public static DynMetaObject IterCursorMO;
public static DynMetaObject ListMO;
public static DynMetaObject MatchMO;
public static DynMetaObject NumMO;
public static DynMetaObject StrMO;
public static IP6 AnyP;
public static IP6 ArrayP;
public static IP6 EMPTYP;
public static IP6 HashP;
public static IP6 IteratorP;
public static IP6 StrP;
public static readonly DynMetaObject ScalarMO;
public static readonly DynMetaObject StashMO;

public static readonly DynMetaObject SubMO;
public static readonly IP6 StashP;

public static bool TraceCont;
Expand Down Expand Up @@ -958,14 +972,14 @@ public class Kernel {

public static Frame PromoteToList(Frame th, Variable v) {
if (!v.islist) {
DynObject lst = new DynObject(RxFrame.ListMO);
DynObject lst = new DynObject(Kernel.ListMO);
lst.slots[0 /*items*/] = new VarDeque(new Variable[] { v });
lst.slots[1 /*rest*/ ] = new VarDeque();
th.resultSlot = Kernel.NewRWListVar(lst);
return th;
}
IP6 o = v.Fetch();
if (o.mo.HasMRO(RxFrame.ListMO)) {
if (o.mo.HasMRO(Kernel.ListMO)) {
th.resultSlot = v;
return th;
}
Expand Down Expand Up @@ -1023,7 +1037,7 @@ public class Kernel {
if (inq0.mo.HasMRO(IterCursorMO)) {
th.MarkSharedChain();
th.ip = 2;
DynObject thunk = new DynObject(RxFrame.GatherIteratorMO);
DynObject thunk = new DynObject(Kernel.GatherIteratorMO);
thunk.slots[0] = NewRWScalar(AnyMO, th);
thunk.slots[1] = NewRWScalar(AnyMO, AnyP);
outq.Push(NewROScalar(thunk));
Expand All @@ -1045,7 +1059,7 @@ public class Kernel {
if ((Boolean) th.resultSlot) {
return Take(th, inq.Shift());
} else {
return Take(th, NewROScalar(RxFrame.EMPTYP));
return Take(th, NewROScalar(Kernel.EMPTYP));
}
default:
return Die(th, "invalid IP");
Expand Down Expand Up @@ -1108,17 +1122,14 @@ public class Kernel {
}
}

public static IP6 IteratorP;
public static DynMetaObject IterCursorMO;

public static Frame GetFirst(Frame th, Variable lst) {
if (!lst.islist) {
th.resultSlot = lst;
return th;
}
DynObject dyl = lst.Fetch() as DynObject;
if (dyl == null) goto slow;
if (dyl.mo != RxFrame.ListMO) goto slow;
if (dyl.mo != Kernel.ListMO) goto slow;
VarDeque itemsl = (VarDeque) dyl.GetSlot("items");
if (itemsl.Count() == 0) goto slow;
th.resultSlot = itemsl[0];
Expand All @@ -1129,13 +1140,6 @@ public class Kernel {
lst }, null);
}

public static DynMetaObject AnyMO;
public static IP6 AnyP;
public static IP6 ArrayP;
public static IP6 HashP;
public static IP6 StrP;
public static DynMetaObject CallFrameMO;

public static BValue PackageLookup(IP6 parent, string name) {
Dictionary<string,BValue> stash = (Dictionary<string,BValue>)
UnboxAny(parent);
Expand Down
17 changes: 10 additions & 7 deletions src/CSharpBackend.pm
Expand Up @@ -166,21 +166,24 @@ sub stash3 {
}
}

# xxx check for SAFE::
my %loopbacks = (
'MAny', 'Kernel.AnyMO',
'MBool', 'Kernel.BoolMO',
'MCallFrame', 'Kernel.CallFrameMO',
'MCapture', 'Kernel.CaptureMO',
'MGatherIterator', 'RxFrame.GatherIteratorMO',
'MList', 'RxFrame.ListMO',
'MMatch', 'RxFrame.MatchMO',
'MGatherIterator', 'Kernel.GatherIteratorMO',
'MHash', 'Kernel.HashMO',
'MIterCursor', 'Kernel.IterCursorMO',
'MList', 'Kernel.ListMO',
'MMatch', 'Kernel.MatchMO',
'MNum', 'Kernel.NumMO',
'MStr', 'Kernel.StrMO',
'PAny', 'Kernel.AnyP',
'PArray', 'Kernel.ArrayP',
'PEMPTY', 'RxFrame.EMPTYP',
'PEMPTY', 'Kernel.EMPTYP',
'PHash', 'Kernel.HashP',
'PStr', 'Kernel.StrP',
'PIterator', 'Kernel.IteratorP',
'MIterCursor', 'Kernel.IterCursorMO',
'PStr', 'Kernel.StrP',
);

sub pkg0 {
Expand Down
1 change: 1 addition & 0 deletions src/CgOp.pm
Expand Up @@ -242,6 +242,7 @@ use warnings;
sub iter_copy_elems { rawscall('Kernel.IterCopyElems:m,VarDeque', $_[0]) }

sub sig_slurp_capture { rawscall('Kernel.SigSlurpCapture:m,IP6', callframe()) }
sub to_jsync { rawscall('JsyncWriter.ToJsync:m,String', $_[0]) }

sub newboundvar {
rawscall('Kernel.NewBoundVar', bool($_[0] || $_[1]), bool($_[1]),
Expand Down
2 changes: 1 addition & 1 deletion src/CompilerDriver.pm
Expand Up @@ -239,7 +239,7 @@ sub compile {
@args = ("gmcs", "/debug",
"/out:" . $args{selfcontained},
(map { File::Spec->catfile($libdir, $_) }
"Kernel.cs", "Cursor.cs"),
"Kernel.cs", "Cursor.cs", "JSYNC.cs"),
(map { build_file($_ . ".cs") }
(sort keys %{ $ast->tdeps })),
$csfile);
Expand Down

0 comments on commit 2484b4a

Please sign in to comment.