Skip to content

Commit

Permalink
eval code runs with eval caller as root of protopads, not just runtime
Browse files Browse the repository at this point in the history
  • Loading branch information
sorear committed Jul 14, 2011
1 parent 355a78a commit 02fae77
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 30 deletions.
60 changes: 40 additions & 20 deletions lib/CLRBackend.cs
Original file line number Diff line number Diff line change
Expand Up @@ -979,16 +979,29 @@ public static bool IsDynamicName(string name) {
abstract class LexVarish : Lexical {
public int index;
public FieldInfo stg;
public StaticSub owner;

ClrOp GetProtoFrame() {
if (owner.protopad != null)
return new ClrGetSField(owner.protopad);
StaticSub rs = CLRBackend.Current.unit.mainline_ref.Resolve<StaticSub>();
ClrOp r = new ClrGetSField(rs.protopad);
while (rs != owner) {
rs = rs.outer.Resolve<StaticSub>();
r = new ClrGetField(Tokens.Frame_outer, r);
}
return r;
}

public override ClrOp GetCode(int up, bool proto) {
return (index < 0) ? (ClrOp) new ClrGetSField(stg) :
proto ? (ClrOp) new ClrProtoGet(index, new ClrGetSField(stg)) :
proto ? (ClrOp) new ClrProtoGet(index, GetProtoFrame()) :
new ClrPadGet(up, index);
}

public override ClrOp SetCode(int up, bool proto, ClrOp to) {
return (index < 0) ? (ClrOp)new ClrSetSField(stg, to) :
proto ? new ClrProtoSet(index, new ClrGetSField(stg), to) :
proto ? new ClrProtoSet(index, GetProtoFrame(), to) :
(ClrOp)new ClrPadSet(up, index, to);
}

Expand All @@ -1002,9 +1015,9 @@ public override void EmitInfo(Unit to) {

public override void BindFields(int six, int lix, StaticSub sub,
string name, Func<string,Type,FieldInfo> binder) {
owner = sub;
if (IsDynamicName(name) || (sub.flags & StaticSub.RUN_ONCE) == 0) {
index = sub.nlexn++;
stg = sub.protopad;
} else {
index = -1;
stg = binder(Unit.SharedName('L', six, name), Tokens.Variable);
Expand Down Expand Up @@ -4097,6 +4110,8 @@ public void SubInfoCtor(int ix, List<int> thaw) {

if ((sub.flags & StaticSub.UNSAFE) != 0)
spec |= RuntimeUnit.SUB_IS_UNSAFE;
if (sub == sub.unit.mainline_ref.Resolve<StaticSub>())
spec |= RuntimeUnit.SUB_MAINLINE;
if ((sub.flags & StaticSub.RUN_ONCE) != 0)
spec |= RuntimeUnit.SUB_RUN_ONCE;
spec |= RuntimeUnit.SUB_HAS_TYPE;
Expand Down Expand Up @@ -4517,6 +4532,26 @@ void Process(Unit unit, bool asmain) {
thaw.Add(CpsOp.SetSField(km, CpsOp.GetSField(pkg.metaObject)));
});

if (unit.is_eval) {
// XXX this caller's caller thing is a fudge
StaticSub m = unit.mainline_ref.Resolve<StaticSub>();
FieldInfo rtf = m.outer.Resolve<StaticSub>().unit.clrType.GetField("RTFRAME");
CpsOp fb;
if (rtf == null) {
fb = CpsOp.GetField(Tokens.SubInfo_protopad,
CpsOp.GetSField(m.outer.Resolve<StaticSub>().subinfo));
} else {
fb = CpsOp.GetSField(rtf);
}
CpsOp norm = CpsOp.GetField(Tokens.Frame_caller,
CpsOp.GetField(Tokens.Frame_caller,
CpsOp.CallFrame()));
CpsOp of = CpsOp.Ternary(
CpsOp.Operator(typeof(bool), OpCodes.Ceq, norm, CpsOp.Null(Tokens.Frame)),
fb, norm);
thaw.Add(CpsOp.SetField(Tokens.RuntimeUnit.GetField("context_pad"), CpsOp.GetSField(unit.rtunit), of));
}

int sub2_slot = thaw.Count;
thaw.Add(null);
List<int> sub2_pointers = new List<int>();
Expand Down Expand Up @@ -4613,25 +4648,10 @@ void Process(Unit unit, bool asmain) {
// settings are incomplete modules and have no mainline to run
if (unit.is_eval) {
if (Verbose > 0) Console.WriteLine("mainline_runner(eval)");
// XXX this caller's caller thing is a fudge
StaticSub m = unit.mainline_ref.Resolve<StaticSub>();
FieldInfo rtf = m.outer.Resolve<StaticSub>().unit.clrType.GetField("RTFRAME");
CpsOp fb;
if (rtf == null) {
fb = CpsOp.GetField(Tokens.SubInfo_protopad,
CpsOp.GetSField(m.outer.Resolve<StaticSub>().subinfo));
} else {
fb = CpsOp.GetSField(rtf);
}
CpsOp norm = CpsOp.GetField(Tokens.Frame_caller,
CpsOp.GetField(Tokens.Frame_caller,
CpsOp.CallFrame()));
CpsOp of = CpsOp.Ternary(
CpsOp.Operator(typeof(bool), OpCodes.Ceq, norm, CpsOp.Null(Tokens.Frame)),
fb, norm);
thaw.Add(CpsOp.CpsReturn(CpsOp.SubyCall(false,"",
CpsOp.MethodCall(Tokens.Kernel_MakeSub,
CpsOp.GetSField(m.subinfo), of))));
CpsOp.GetField(Tokens.SubInfo_protosub,
CpsOp.GetSField(m.subinfo)))));
} else if (unit.bottom_ref == null) {
if (Verbose > 0) Console.WriteLine("mainline_runner(norm)");
Type dty = typeof(Dictionary<string,Object>);
Expand Down
20 changes: 14 additions & 6 deletions lib/Kernel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,7 @@ public sealed class RuntimeUnit {
public DynBlockDelegate[] methods; /*C*/
public FieldInfo[] meta_fields;
public object[] xref;
public Frame context_pad;
public static bool TraceLoad = Environment.GetEnvironmentVariable("NIECZA_TRACE_LOAD") != null;

public static void HexDump(byte[] heap) {
Expand Down Expand Up @@ -441,6 +442,7 @@ public string ReadStr(ref int from) {
public const int SUB_HAS_TYPE = 4;
public const int SUB_IS_UNSAFE = 8;
public const int SUB_IS_PARAM_ROLE = 16;
public const int SUB_MAINLINE = 32;

public void LoadStashes(int from) {
int ct = ReadInt(ref from);
Expand Down Expand Up @@ -496,16 +498,22 @@ public void LoadSubInfo(int from) {
ns.run_once = true;
if ((spec & SUB_HAS_TYPE) != 0)
ns.mo = (STable) ReadXref(ref from);
if (ns.outer == null || ns.outer.protopad != null)
ns.protosub = Kernel.MakeSub(ns,
ns.outer == null ? null : ns.outer.protopad);

Frame out_pad = ns.outer == null ? null : ns.outer.protopad;

if ((spec & SUB_MAINLINE) != 0)
out_pad = context_pad ?? out_pad;

if (out_pad != null || ns.outer == null)
ns.protosub = Kernel.MakeSub(ns, out_pad);
if ((spec & MAKE_PROTOPAD) != 0)
ns.protopad = new Frame(null,
ns.outer == null ? null : ns.outer.protopad, ns,
ns.protosub);
ns.protopad = new Frame(null, out_pad, ns, ns.protosub);
if ((spec & SUB_IS_PARAM_ROLE) != 0)
((STable) ReadXref(ref from)).FillParametricRole(ns.protosub);

if (TraceLoad && ns.protopad != null) Console.WriteLine("created protopad");
if (TraceLoad && out_pad != null) Console.WriteLine("has out_pad");

ns.fixups_from = from;

meta_fields[ix*2].SetValue(null, ns);
Expand Down
6 changes: 3 additions & 3 deletions src/Metamodel.pm6
Original file line number Diff line number Diff line change
Expand Up @@ -550,9 +550,9 @@ class StaticSub is RefTarget {
}

method create_static_pad() {
return Nil if $.spad_exists;
$.spad_exists = True;
$.outer.create_static_pad if $.outer;
return Nil if $!spad_exists;
$!spad_exists = True;
$.outer.create_static_pad if $.outer && $.outer.unit === $!unit;
}

method noninlinable() {
Expand Down
2 changes: 1 addition & 1 deletion src/NieczaGrammar.pm6
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ grammar P6 is STD::P6 {
class => 'Routine',
cur_pkg => $*unit.abs_pkg('GLOBAL').xref,
name => "mainline",
run_once => !$rtop || $rtop.run_once);
run_once => (?$*niecza_outer_ref) || !$rtop || $rtop.run_once);
$*CURLEX{'!sub'}.add_my_name('$_') if !$top;
$*CURLEX{'!sub'}.add_hint('$?FILE');
$*CURLEX{'!sub'}.signature = ::GLOBAL::Sig.simple();
Expand Down

0 comments on commit 02fae77

Please sign in to comment.