Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
More streamlining of the metasub construction process
  • Loading branch information
sorear committed May 24, 2011
1 parent 69332cd commit 7acdc4a
Show file tree
Hide file tree
Showing 2 changed files with 137 additions and 118 deletions.
208 changes: 94 additions & 114 deletions lib/CLRBackend.cs
Expand Up @@ -2359,6 +2359,20 @@ class ClrUnboxAny : ClrOp {
}
}

class ClrTypeLiteral : ClrOp {
readonly Type body;
public override ClrOp Sink() { return ClrNoop.Instance; }
public ClrTypeLiteral(Type body) {
this.body = body;
Returns = typeof(Type);
Constant = true;
}
public override void CodeGen(CgContext cx) {
cx.il.Emit(OpCodes.Ldtoken, body);
cx.il.Emit(OpCodes.Call, typeof(Type).GetMethod("GetTypeFromHandle"));
}
}

class ClrDBDLiteral : ClrOp {
readonly MethodInfo body;
public override ClrOp Sink() { return ClrNoop.Instance; }
Expand Down Expand Up @@ -2776,6 +2790,10 @@ class CpsOp {
return new CpsOp(new ClrLongLiteral(Tokens.UInt64, (long)x));
}

public static CpsOp TypeLiteral(Type x) {
return new CpsOp(new ClrTypeLiteral(x));
}

public static CpsOp DBDLiteral(MethodInfo x) {
return new CpsOp(new ClrDBDLiteral(x));
}
Expand Down Expand Up @@ -3168,9 +3186,6 @@ class NamProcessor {

handlers = new Dictionary<string, Func<NamProcessor,object[],CpsOp>>();
thandlers = new Dictionary<string, Func<CpsOp[], CpsOp>>();
Dictionary<string, Func<object[], object>> mhandlers =
new Dictionary<string, Func<object[], object>>();


handlers["null"] = delegate(NamProcessor th, object[] zyg) {
return CpsOp.Null(namtype(zyg[1])); };
Expand Down Expand Up @@ -3810,10 +3825,6 @@ class NamProcessor {
in thandlers) {
handlers[kv.Key] = MakeTotalHandler(kv.Value);
}
foreach (KeyValuePair<string, Func<object[], object>> kv
in mhandlers) {
handlers[kv.Key] = MakeMacroHandler(kv.Value);
}
}

static Func<CpsOp[], CpsOp> SimpleB(string name) {
Expand Down Expand Up @@ -3864,34 +3875,73 @@ class NamProcessor {
};
}

static Func<NamProcessor, object[], CpsOp> MakeMacroHandler(
Func<object[], object> real) {
return delegate (NamProcessor th, object[] zyg) {
return th.Scan(real(zyg)); };
}

public void MakeBody() {
cpb.ReserveLex(sub.nlexn);
cpb.Build(Scan(WrapBody()));
}

public CpsOp ProcessLADArr(object l) {
int o = sub.unit.thaw_heap.Count;
sub.unit.EmitLADArr(l);
return CpsOp.MethodCall(Tokens.RU_LoadLADArr,
CpsOp.GetSField(sub.unit.rtunit), CpsOp.IntLiteral(o));
}
void EncodeSignature(StaticSub obj) {
if (obj.sig == null) {
obj.unit.EmitInt(-1);
return;
}

List<int> sig_i = new List<int>();
List<object> sig_r = new List<object>();
object[] rsig = (object[]) obj.sig;
foreach (object p in rsig) {
object[] param = (object[]) p;
string name = JScalar.S(param[0]);
int flags = JScalar.I(param[1]);
string slot = JScalar.S(param[2]);
string[] names = JScalar.SA(0, param[3]);
Xref deflt = Xref.from(param[4]);
Xref type = Xref.from(param[5]);

sig_r.Add(name);
foreach (string n in names)
sig_r.Add(n);
int ufl = 0;
if ((flags & 4) != 0) ufl |= SubInfo.SIG_F_RWTRANS;
else if ((flags & 64) != 0) ufl |= SubInfo.SIG_F_READWRITE;

public CpsOp ProcessLAD(object l) {
int o = sub.unit.thaw_heap.Count;
sub.unit.EmitLAD(l);
return CpsOp.MethodCall(Tokens.RU_LoadLAD,
CpsOp.GetSField(sub.unit.rtunit), CpsOp.IntLiteral(o));
if ((flags & 384) != 0) ufl |= SubInfo.SIG_F_BINDLIST;
if ((flags & 512) != 0) ufl |= SubInfo.SIG_F_DEFOUTER;
if ((flags & 1024) != 0) ufl |= SubInfo.SIG_F_INVOCANT;
if ((flags & 2048) != 0) ufl |= SubInfo.SIG_F_MULTI_IGNORED;
if (deflt != null) {
ufl |= SubInfo.SIG_F_HASDEFAULT;
sig_r.Add(deflt);
}
if (type != null) {
ufl |= SubInfo.SIG_F_HASTYPE;
sig_r.Add(type);
}
if ((flags & 16) != 0) ufl |= SubInfo.SIG_F_OPTIONAL;
if ((flags & 32) != 0) ufl |= SubInfo.SIG_F_POSITIONAL;
if ((flags & 1) != 0 && (flags & 256) != 0)
ufl |= SubInfo.SIG_F_SLURPY_NAM;
if ((flags & 1) != 0 && (flags & 256) == 0)
ufl |= SubInfo.SIG_F_SLURPY_POS;
if ((flags & 2) != 0) ufl |= SubInfo.SIG_F_SLURPY_CAP;
if ((flags & 8) != 0) ufl |= SubInfo.SIG_F_SLURPY_PCL;
sig_i.Add(ufl);
sig_i.Add(slot == null ? -1 : ((LexVarish)obj.l_lexicals[slot]).index);
sig_i.Add(names.Length);
}
obj.unit.EmitIntArray(sig_i.ToArray());
obj.unit.EmitInt(sig_r.Count);
foreach (object o in sig_r) {
if (o is string) {
obj.unit.EmitStr((string)o);
} else {
obj.unit.EmitStr(null);
obj.unit.EmitXref((Xref)o);
}
}
}

public void SubInfoCtor(int ix, List<CpsOp> thaw) {
CpsOp[] args = new CpsOp[3];

int b = sub.unit.thaw_heap.Count;

int spec = 0;
Expand All @@ -3905,10 +3955,6 @@ class NamProcessor {
if (sub.parametric_role_hack != null)
spec |= RuntimeUnit.SUB_IS_PARAM_ROLE;

args[0] = CpsOp.GetSField(sub.unit.rtunit);
args[1] = CpsOp.IntLiteral(b);
args[2] = CpsOp.DBDLiteral(cpb.mb);

sub.unit.EmitInt(ix);
sub.unit.EmitByte(spec);
sub.unit.EmitStr(sub.unit.name + " " +
Expand Down Expand Up @@ -3939,8 +3985,19 @@ class NamProcessor {
if (sub.parametric_role_hack != null)
sub.unit.EmitXref(sub.parametric_role_hack);

/*not used until sub3 time*/
EncodeSignature(sub);
sub.unit.EmitByte(sub.is_phaser >= 0 ? sub.is_phaser : 0xFF);

object[] os = sub.exports ?? new object[0];
sub.unit.EmitInt(os.Length);
foreach (object o in os)
sub.unit.EmitStrArray(JScalar.SA(0,o));

thaw.Add(CpsOp.SetSField(sub.subinfo,
CpsOp.MethodCall(Tokens.RU_LoadSubInfo, args)));
CpsOp.MethodCall(Tokens.RU_LoadSubInfo,
CpsOp.GetSField(sub.unit.rtunit), CpsOp.IntLiteral(b))));

if (sub.protopad != null)
thaw.Add(CpsOp.SetSField(sub.protopad,
CpsOp.GetField(Tokens.SubInfo_protopad,
Expand Down Expand Up @@ -4173,68 +4230,6 @@ public class CLRBackend {
TypeAttributes.Class | TypeAttributes.BeforeFieldInit);
}

void EncodeSignature(List<CpsOp> thaw, StaticSub obj) {
if (obj.sig == null) return;
int b = obj.unit.thaw_heap.Count;

List<int> sig_i = new List<int>();
List<object> sig_r = new List<object>();
object[] rsig = (object[]) obj.sig;
foreach (object p in rsig) {
object[] param = (object[]) p;
string name = JScalar.S(param[0]);
int flags = JScalar.I(param[1]);
string slot = JScalar.S(param[2]);
string[] names = JScalar.SA(0, param[3]);
Xref deflt = Xref.from(param[4]);
Xref type = Xref.from(param[5]);

sig_r.Add(name);
foreach (string n in names)
sig_r.Add(n);
int ufl = 0;
if ((flags & 4) != 0) ufl |= SubInfo.SIG_F_RWTRANS;
else if ((flags & 64) != 0) ufl |= SubInfo.SIG_F_READWRITE;

if ((flags & 384) != 0) ufl |= SubInfo.SIG_F_BINDLIST;
if ((flags & 512) != 0) ufl |= SubInfo.SIG_F_DEFOUTER;
if ((flags & 1024) != 0) ufl |= SubInfo.SIG_F_INVOCANT;
if ((flags & 2048) != 0) ufl |= SubInfo.SIG_F_MULTI_IGNORED;
if (deflt != null) {
ufl |= SubInfo.SIG_F_HASDEFAULT;
sig_r.Add(deflt);
}
if (type != null) {
ufl |= SubInfo.SIG_F_HASTYPE;
sig_r.Add(type);
}
if ((flags & 16) != 0) ufl |= SubInfo.SIG_F_OPTIONAL;
if ((flags & 32) != 0) ufl |= SubInfo.SIG_F_POSITIONAL;
if ((flags & 1) != 0 && (flags & 256) != 0)
ufl |= SubInfo.SIG_F_SLURPY_NAM;
if ((flags & 1) != 0 && (flags & 256) == 0)
ufl |= SubInfo.SIG_F_SLURPY_POS;
if ((flags & 2) != 0) ufl |= SubInfo.SIG_F_SLURPY_CAP;
if ((flags & 8) != 0) ufl |= SubInfo.SIG_F_SLURPY_PCL;
sig_i.Add(ufl);
sig_i.Add(slot == null ? -1 : ((LexVarish)obj.l_lexicals[slot]).index);
sig_i.Add(names.Length);
}
obj.unit.EmitIntArray(sig_i.ToArray());
obj.unit.EmitInt(sig_r.Count);
foreach (object o in sig_r) {
if (o is string) {
obj.unit.EmitStr((string)o);
} else {
obj.unit.EmitStr(null);
obj.unit.EmitXref((Xref)o);
}
}
thaw.Add(CpsOp.MethodCall(Tokens.RU_LoadSignature,
CpsOp.GetSField(obj.unit.rtunit), CpsOp.GetSField(obj.subinfo),
CpsOp.IntLiteral(b)));
}

void SetProtolex(StaticSub obj, string n, LexVarish v, CpsOp init) {
if ((obj.flags & StaticSub.RUN_ONCE) != 0 && !Lexical.IsDynamicName(n))
thaw.Add(CpsOp.SetSField(v.stg, init));
Expand Down Expand Up @@ -4264,7 +4259,7 @@ public class CLRBackend {
unit.VisitSubsPreorder(delegate(int ix, StaticSub obj) {
if (Verbose > 0) Console.WriteLine("sub1 {0}", obj.name);
CpsBuilder cpb = new CpsBuilder(this,
Unit.SharedName('C', ix, obj.name), false);
Unit.SharedName('C', ix, obj.name), true);
NamProcessor np = aux[ix] = new NamProcessor(cpb, obj);
np.MakeBody();
});
Expand Down Expand Up @@ -4381,27 +4376,11 @@ public class CLRBackend {
CpsOp.MethodCall(Tokens.Kernel.GetMethod("BoxRaw").MakeGenericMethod(Tokens.STable), CpsOp.GetSField(m.metaObject), CpsOp.GetSField( ((Class) unit.GetCorePackage("ClassHOW")).metaObject))));
});

thaw.Add(CpsOp.MethodCall(Tokens.RuntimeUnit.GetMethod("FixupSubs"),
CpsOp.GetSField(unit.rtunit)));

unit.VisitSubsPostorder(delegate(int ix, StaticSub obj) {
if (Verbose > 0) Console.WriteLine("sub3 {0}", obj.name);
EncodeSignature(thaw, obj);

if (obj.is_phaser >= 0)
thaw.Add(CpsOp.MethodCall(Tokens.Kernel_AddPhaser,
CpsOp.IntLiteral(obj.is_phaser),
CpsOp.GetField(Tokens.SubInfo_protosub,
CpsOp.GetSField(obj.subinfo))));

if (obj.exports != null) {
foreach (object o in obj.exports) {
thaw.Add(CpsOp.SetField(Tokens.BValue_v,
CpsOp.MethodCall(Tokens.Kernel_GetVar,
CpsOp.StringArray(false, JScalar.SA(0,o))),
CpsOp.MethodCall(Tokens.Kernel_NewROScalar,
CpsOp.GetField(Tokens.SubInfo_protosub,
CpsOp.GetSField(obj.subinfo)))));
}
}

foreach (KeyValuePair<string,Lexical> l in obj.lexicals) {
if (l.Value is LexCommon) {
LexCommon lx = (LexCommon)l.Value; /* XXX cname */
Expand Down Expand Up @@ -4507,7 +4486,8 @@ public class CLRBackend {
unit_load.Add(unit.EmitStringListConsts());

unit_load[0] = CpsOp.SetSField(unit.rtunit, CpsOp.ConstructorCall(
Tokens.RuntimeUnit.GetConstructor(new Type[] { typeof(byte[]), typeof(RuntimeUnit[]), typeof(int) }),
Tokens.RuntimeUnit.GetConstructor(new Type[] { typeof(Type), typeof(byte[]), typeof(RuntimeUnit[]), typeof(int) }),
CpsOp.TypeLiteral(tb),
CpsOp.NewByteArray(typeof(byte), unit.thaw_heap.ToArray()),
CpsOp.NewArray(Tokens.RuntimeUnit, tdep_rtu.ToArray()),
CpsOp.IntLiteral(unit.xref.Length)));
Expand Down
47 changes: 43 additions & 4 deletions lib/Kernel.cs
Expand Up @@ -188,14 +188,34 @@ public sealed class BValue {
}

public sealed class RuntimeUnit {
public Type type;
public byte[] heap;
public RuntimeUnit[] depends;
public DynBlockDelegate[] methods;
public object[] xref;

public RuntimeUnit(byte[] heap, RuntimeUnit[] depends, int nx) {
public RuntimeUnit(Type type, byte[] heap, RuntimeUnit[] depends,
int nx) {
this.type = type;
this.heap = heap;
this.depends = depends;
this.xref = new object[nx];
this.methods = new DynBlockDelegate[nx];

uint d = 0;
foreach (MethodInfo mi in type.GetMethods()) {
int acc = 0;
string n = mi.Name;
if (n.Length < 2 || n[0] != 'C' || n[1] == '_') continue;
int i = 1;
while (i < n.Length && (d = (uint)(n[i] - '0')) < 10) {
acc = acc * 10 + (int)d;
i++;
}
if (n[i] != '_') continue;
methods[acc] = (DynBlockDelegate)
Delegate.CreateDelegate(typeof(DynBlockDelegate), mi);
}
}

public int ReadInt(ref int from) {
Expand All @@ -214,8 +234,9 @@ public sealed class RuntimeUnit {
return ru.xref[ReadInt(ref from)];
}

public void LoadSignature(SubInfo si, int from) {
public void ReadSignature(SubInfo si, ref int from) {
si.sig_i = ReadIntArray(ref from);
if (si.sig_i == null) return;
si.sig_r = new object[ReadInt(ref from)];
//Console.WriteLine("{0} {1} {2}", si.name, si.sig_i.Length, si.sig_r.Length);
for (int i = 0; i < si.sig_r.Length; i++) {
Expand Down Expand Up @@ -363,13 +384,13 @@ public sealed class RuntimeUnit {
public const int SUB_IS_UNSAFE = 8;
public const int SUB_IS_PARAM_ROLE = 16;

public SubInfo LoadSubInfo(int from, DynBlockDelegate code) {
public SubInfo LoadSubInfo(int from) {
int ix = ReadInt(ref from);
byte spec = heap[from++];
SubInfo ns = new SubInfo(
ReadStr(ref from), /*name*/
ReadIntArray(ref from), /*lines*/
code,
methods[ix],
(SubInfo)ReadXref(ref from), /*outer*/
ReadLAD(ref from),
ReadIntArray(ref from), /*ehspan*/
Expand All @@ -393,9 +414,26 @@ public sealed class RuntimeUnit {
if ((spec & SUB_IS_PARAM_ROLE) != 0)
((STable) ReadXref(ref from)).FillParametricRole(ns.protosub);

ns.fixups_from = from;

return ns;
}

public void FixupSubs() {
for (int i = 0; i < xref.Length; i++) {
SubInfo si = xref[i] as SubInfo;
if (si == null) continue;
int from = si.fixups_from;
ReadSignature(si, ref from);
int ph = heap[from++];
if (ph != 0xFF) Kernel.AddPhaser(ph, si.protosub);
int nex = ReadInt(ref from);
for (int j = 0; j < nex; j++)
Kernel.GetVar(ReadStrArray(ref from)).v =
Kernel.NewROScalar(si.protosub);
}
}

public LAD LoadLAD(int from) {
return ReadLAD(ref from);
}
Expand Down Expand Up @@ -480,6 +518,7 @@ public class SubInfo {
public SubInfo outer;
public P6any protosub;
public Frame protopad;
public int fixups_from;
public string name;
public Dictionary<string, BValue> hints;
// maybe should be a hint
Expand Down

0 comments on commit 7acdc4a

Please sign in to comment.