Permalink
Browse files

Make constant tables aware of the setting they are scoped to

  • Loading branch information...
1 parent a216174 commit 0e6be4661744c5f7499d847d97e2410b5227d42a @sorear committed Sep 16, 2012
Showing with 48 additions and 8 deletions.
  1. +7 −0 lib/Builtins.cs
  2. +22 −1 lib/CodeGen.cs
  3. +12 −7 lib/Kernel.cs
  4. +7 −0 lib/Utils.cs
View
@@ -173,6 +173,13 @@ class SubstrLValue: Variable {
return n;
}
}
+
+ [AttributeUsage(AttributeTargets.Method)]
+ class CpsAttribute : Attribute { }
+ [AttributeUsage(AttributeTargets.Method)]
+ class ImplicitFrameAttribute : Attribute { }
+ [AttributeUsage(AttributeTargets.Method)]
+ class ImplicitConstsAttribute : Attribute { }
}
// The special feature of this class is that Q:CgOp operations which are not
View
@@ -1416,6 +1416,18 @@ class ClrCpsFrame : ClrOp {
[Immutable] public static ClrCpsFrame Instance = new ClrCpsFrame();
}
+ class ClrCpsConsts : ClrOp {
+ public override ClrOp Sink() { return ClrNoop.Instance; }
+ private ClrCpsConsts() {
+ Returns = typeof(Constants);
+ Constant = true;
+ }
+ public override void CodeGen(CgContext cx) {
+ cx.il.Emit(OpCodes.Ldarg_0);
+ }
+ [Immutable] public static ClrCpsConsts Instance = new ClrCpsConsts();
+ }
+
class ClrNullLiteral : ClrOp {
public override ClrOp Sink() { return ClrNoop.Instance; }
public ClrNullLiteral(Type ty) {
@@ -2039,6 +2051,9 @@ class CpsOp {
public static CpsOp CallFrame() {
return new CpsOp(ClrCpsFrame.Instance);
}
+ public static CpsOp Constants() {
+ return new CpsOp(ClrCpsConsts.Instance);
+ }
public static CpsOp RxFrame() {
return IsConst(GetField(Tokens.Frame_rx, CallFrame()));
@@ -3195,8 +3210,14 @@ class NamProcessor {
static Func<CpsOp[], CpsOp> Methody(Type cps, MethodInfo mi) {
if (mi == null) throw new ArgumentException();
+ bool implicit_frame = Attribute.IsDefined(mi, typeof(ImplicitFrameAttribute));
+ bool implicit_consts = Attribute.IsDefined(mi, typeof(ImplicitConstsAttribute));
+ bool force_cps = Attribute.IsDefined(mi, typeof(CpsAttribute));
return delegate(CpsOp[] cpses) {
- return CpsOp.CpsCall(cps, mi, cpses); };
+ if (implicit_consts) cpses = Utils.PrependArr(CpsOp.Constants(), cpses);
+ if (implicit_frame) cpses = Utils.PrependArr(CpsOp.CallFrame(), cpses);
+ return CpsOp.CpsCall(force_cps ? Tokens.Variable : cps, mi, cpses);
+ };
}
static Func<CpsOp[], CpsOp> RxCall(Type cps, string name) {
View
@@ -443,7 +443,8 @@ sealed class EmitUnit {
type_builder = mod_builder.DefineType(asm_name,
TypeAttributes.Public | TypeAttributes.Sealed |
- TypeAttributes.Class | TypeAttributes.BeforeFieldInit);
+ TypeAttributes.Class | TypeAttributes.BeforeFieldInit,
+ typeof(Constants));
if (is_mainish) {
var mainb = type_builder.DefineMethod("Main",
@@ -486,9 +487,9 @@ sealed class EmitUnit {
}
}
- public Type Finish(out object constTable) {
+ public Type Finish(out Constants constTable) {
var type = type_builder.CreateType();
- constTable = Activator.CreateInstance(type);
+ constTable = (Constants)Activator.CreateInstance(type);
if (dll_name != null)
asm_builder.Save(dll_name);
@@ -685,6 +686,10 @@ class IdentityComparer : IEqualityComparer<object> {
}
}
+ public class Constants {
+ internal Compartment setting = Compartment.Top;
+ }
+
// There are two kinds of units. Primary units have their own hash of
// globals, assembly (if saved), and save file; subordinate units share
// those of the master.
@@ -704,7 +709,7 @@ public sealed class RuntimeUnit : IFreeze {
// member of a saved assembly; thus type being non-null implies
// a significance to freezing and thawing the type
public Type type;
- public object constTable;
+ public Constants constTable;
public Dictionary<object, FieldInfo> constants;
public bool inited = false;
@@ -763,7 +768,7 @@ public sealed class RuntimeUnit : IFreeze {
EmitUnit eu = new EmitUnit(null, "Anon." + Interlocked.Increment(
ref anon_id), null, false);
eu.CgSub(sub, false);
- object jit_consts;
+ Constants jit_consts;
SetConstants(eu.Finish(out jit_consts), jit_consts, eu.constants);
th.code = th.info.code = sub.code;
@@ -806,7 +811,7 @@ public sealed class RuntimeUnit : IFreeze {
ref anon_id) + "." + asm_name, null, false);
SaveSubs(eu, false);
- object jit_consts;
+ Constants jit_consts;
SetConstants(eu.Finish(out jit_consts), jit_consts, eu.constants);
}
@@ -1029,7 +1034,7 @@ public sealed class RuntimeUnit : IFreeze {
} else {
Assembly assembly = Assembly.Load(n.asm_name);
n.type = tb.type = assembly.GetType(n.asm_name, true);
- n.constTable = Activator.CreateInstance(n.type);
+ n.constTable = (Constants)Activator.CreateInstance(n.type);
n.constants = new Dictionary<object,FieldInfo>();
var fields = new Dictionary<string,FieldInfo>();
foreach (FieldInfo fi in n.type.GetFields())
View
@@ -670,6 +670,13 @@ public class Utils {
Array.Reverse(tempCharArray);
return new string(tempCharArray);
}
+
+ public static T[] PrependArr<T>(T thing, T[] to) {
+ T[] nto = new T[to.Length+1];
+ Array.Copy(to, 0, nto, 1, to.Length);
+ nto[0] = thing;
+ return nto;
+ }
}
public sealed class Complex : IFreeze {

0 comments on commit 0e6be46

Please sign in to comment.