internal static STable Thaw(ThawBuffer tb) { STable n = new STable(); tb.Register(n); n.mo = (P6how)tb.ObjRef(); n.how = (P6any)tb.ObjRef(); n.who = (P6any)tb.ObjRef(); n.typeObject = (P6any)tb.ObjRef(); n.initObject = (P6any)tb.ObjRef(); n.typeVar = (Variable)tb.ObjRef(); n.initVar = (Variable)tb.ObjRef(); n.name = tb.String(); n.isSubset = tb.Byte() != 0; string box_type = tb.String(); n.box_type = box_type == null ? null : Type.GetType(box_type, true); n.all_slot = tb.Strings(); if (n.all_slot != null) { foreach (string s in n.all_slot) { n.slotMap[s] = n.nslots++; } } tb.PushRevalidate(n); return(n); }
public void FillSubset(STable super) { isSubset = stable.isSubset = true; STable[] mro = new STable[super.mo.mro.Length + 1]; Array.Copy(super.mo.mro, 0, mro, 1, mro.Length - 1); mro[0] = stable; FillClass(super.all_slot, new STable[] { super }, mro); }
static Frame default_handler(Frame th) { // XXX there HAS to be a better way to do this. STable mo = ((Variable)th.lex0).Fetch().mo; object obj = Array.CreateInstance(mo.box_type, 1).GetValue(0); th.caller.resultSlot = obj == null ? mo.typeVar : Kernel.BoxAnyMO <object>(obj, mo); return(th.caller); }
static Frame marshal_handler(Frame th) { STable mo = ((Variable)th.lex0).Fetch().mo; object clr; if (!CoerceArgument(out clr, mo.box_type, (Variable)th.lex1)) { return(Kernel.Die(th, "Cannot coerce value of type " + ((Variable)th.lex1).Fetch().mo.name + " to " + mo.box_type.FullName)); } th.caller.resultSlot = clr == null ? mo.typeVar : Kernel.BoxAnyMO <object>(clr, mo); return(th.caller); }
public void AddAttributePos(string name, int flags, P6any init, STable type, string file, int line) { AttrInfo ai; ai.name = name; ai.flags = flags; ai.init = init; ai.type = type; ai.file = file; ai.line = line; local_attr.Add(ai); }
public STable PunRole() { STable n = new STable(stable.name); n.how = Kernel.BoxAnyMO <STable>(n, Kernel.ClassHOWMO).Fetch(); n.typeObject = n.initObject = new P6opaque(n); n.typeVar = n.initVar = Kernel.NewROScalar(n.typeObject); ((P6opaque)n.typeObject).slots = null; n.mo.local_roles.Add(stable); n.mo.Compose(); return(n); }
public void FillProtoClass(STable parent, string[] slots) { if (parent == null) { FillClass(slots, new STable[] {}, new STable[] { stable }); } else { STable[] mro = new STable[parent.mo.mro.Length + 1]; Array.Copy(parent.mo.mro, 0, mro, 1, mro.Length - 1); mro[0] = stable; FillClass(slots, new STable[] { parent }, mro); } Invalidate(); }
// XXX Need jnthn to come up with a good type cache thing. public bool HasMRO(STable m) { int k = mo.mro.Length; if (k >= 20) { return(mo.isa.Contains(m)); } else { while (k != 0) { if (mo.mro[--k] == m) { return(true); } } return(false); } }
// Only call these if m.isSubset is false public bool HasType(STable m) { int k = mo.type_list.Length; if (k >= 20) { return(mo.type_set.Contains(m)); } else { while (k != 0) { if (mo.type_list[--k] == m) { return(true); } } return(false); } }
public P6opaque(STable klass) { this.mo = klass; this.slots = (klass.nslots != 0) ? new object[klass.nslots] : null; }
public bool Does(STable mo) { return(mo.isSubset ? mo.mo.CheckSubset(this) : this.mo.HasType(mo)); }
public string Compose() { if (isComposed || type == PACKAGE || type == MODULE) { isComposed = true; return(null); } if (isComposing) { return("Circularity detected while composing " + stable.name); } isComposing = true; string err; foreach (STable su in superclasses) { err = su.mo.Compose(); if (err != null) { return(err); } } isComposed = true; if (type == ROLE || type == PARAMETRIZED_ROLE || type == CURRIED_ROLE) { role_typecheck_list.Add(stable); SetMRO(Kernel.AnyMO.mo.mro); Revalidate(); stable.SetupVTables(); return(null); } if (local_roles.Count > 0) { Kernel.ApplyRoleToClass(stable, local_roles.ToArray()); } if (superclasses.Count == 0 && stable != Kernel.MuMO) { superclasses.Add(type == GRAMMAR ? Kernel.GrammarMO : Kernel.AnyMO); } STable[][] lists = new STable[superclasses.Count + 2][]; lists[0] = new STable[] { stable }; lists[superclasses.Count + 1] = superclasses.ToArray(); for (int i = 0; i < superclasses.Count; i++) { lists[i + 1] = superclasses[i].mo.mro; } List <STable> nmro = new List <STable>(); err = C3Merge(nmro, lists); if (err != null) { return("C3 MRO generation failed for " + stable.name + ": " + err); } SetMRO(nmro.ToArray()); List <string> all_slot_l = new List <string>(); foreach (STable m in mro) { foreach (AttrInfo ai in m.mo.local_attr) { all_slot_l.Add(ai.name); } } stable.all_slot = all_slot_l.ToArray(); stable.nslots = 0; foreach (string an in stable.all_slot) { stable.slotMap[an] = stable.nslots++; } Revalidate(); stable.SetupVTables(); return(null); }
string C3Merge(List <STable> into, STable[][] from) { int[] pointers = new int[from.Length]; // all 0s Dictionary <STable, int> blocked = new Dictionary <STable, int>(); foreach (STable[] list in from) { for (int i = 0; i < list.Length; i++) { int k; // set 1 block for each non-initial value used blocked.TryGetValue(list[i], out k); blocked[list[i]] = k + (i == 0 ? 0 : 1); } } while (true) { if (Config.C3Trace) { Console.WriteLine("C3 state: " + C3State(pointers, into, from)); } STable to_shift = null; STable k = null; for (int i = 0; i < from.Length; i++) { if (pointers[i] < from[i].Length && blocked[k = from[i][pointers[i]]] == 0) { to_shift = k; break; } } if (to_shift != null) { for (int i = 0; i < from.Length; i++) { if (pointers[i] < from[i].Length && from[i][pointers[i]] == to_shift) { pointers[i]++; if (pointers[i] < from[i].Length) { blocked[from[i][pointers[i]]]--; } } } into.Add(to_shift); } else { bool bad = false; for (int i = 0; i < from.Length; i++) { if (pointers[i] < from[i].Length) { bad = true; } } if (bad) { return(C3State(pointers, into, from)); } else { return(null); } } } }
static STable NewWrapper(Type t) { if (CLROpts.Debug) { Console.WriteLine("Setting up wrapper for {0}", t.FullName); } STable m = new STable("CLR::" + t.FullName.Replace(".", "::")); m.who = StashCursor.MakeCLR_WHO("." + t.FullName); STable pm = t.BaseType == null ? Kernel.AnyMO : GetWrapper(t.BaseType); STable[] mro = new STable[pm.mo.mro.Length + 1]; Array.Copy(pm.mo.mro, 0, mro, 1, pm.mo.mro.Length); mro[0] = m; m.FillClass(new string[] { }, new STable[] { pm }, mro); HashSet <string> needNewWrapper = new HashSet <string>(); needNewWrapper.Add("new"); // don't inherit constructors Dictionary <string, List <MultiCandidate> > allMembers = new Dictionary <string, List <MultiCandidate> >(); allMembers["new"] = new List <MultiCandidate>(); foreach (MethodInfo mi in t.GetMethods(BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance)) { if (CLROpts.Debug) { Console.WriteLine("Checking method : {0}", mi); } if (mi.IsSpecialName && (Utils.StartsWithInvariant(mi.Name, "set_") || Utils.StartsWithInvariant(mi.Name, "get_"))) { continue; // ignore property accessors } if (mi.GetBaseDefinition().DeclaringType == t) { needNewWrapper.Add(mi.Name); } MultiAdd(allMembers, mi.Name, mi, mi.GetParameters()); } foreach (ConstructorInfo mi in t.GetConstructors(BindingFlags.Public | BindingFlags.Instance)) { if (CLROpts.Debug) { Console.WriteLine("Checking constructor : {0}", mi); } needNewWrapper.Add("new"); MultiAdd(allMembers, "new", mi, mi.GetParameters()); } foreach (PropertyInfo pi in t.GetProperties(BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance)) { if (CLROpts.Debug) { Console.WriteLine("Checking property : {0}", pi); } if (pi.DeclaringType == t) { needNewWrapper.Add(pi.Name); } MultiAdd(allMembers, pi.Name, pi, pi.GetIndexParameters()); } foreach (FieldInfo fi in t.GetFields(BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance)) { if (CLROpts.Debug) { Console.WriteLine("Checking fields : {0}", fi); } if (fi.DeclaringType == t) { needNewWrapper.Add(fi.Name); } MultiAdd(allMembers, fi.Name, fi, new ParameterInfo[0]); } if (typeof(IDisposable).IsAssignableFrom(t)) { SubInfo si; si = new SubInfo("KERNEL dispose-hack", dispose_handler); si.sig = new Signature(Parameter.TPos("self", 0)); m.AddMethod(0, "dispose-hack", Kernel.MakeSub(si, null)); } if (t == typeof(object)) { SubInfo si; si = new SubInfo("KERNEL default", default_handler); si.sig = new Signature(Parameter.TPos("self", 0)); m.AddMethod(0, "default", Kernel.MakeSub(si, null)); si = new SubInfo("KERNEL marshal", marshal_handler); si.sig = new Signature(Parameter.TPos("self", 0), Parameter.TPos("$obj", 1)); m.AddMethod(0, "marshal", Kernel.MakeSub(si, null)); si = new SubInfo("KERNEL unmarshal", unmarshal_handler); si.sig = new Signature(Parameter.TPos("self", 0)); m.AddMethod(0, "unmarshal", Kernel.MakeSub(si, null)); si = new SubInfo("KERNEL Str", Str_handler); si.sig = new Signature(Parameter.TPos("self", 0)); m.AddMethod(0, "Str", Kernel.MakeSub(si, null)); m.AddMethod(0, "gist", Kernel.MakeSub(si, null)); } foreach (string n in needNewWrapper) { string siname = string.Format("{0}.{1}", m.name, n); SubInfo si = new SubInfo(siname, Binder); si.param = new object[] { new CandidateSet(siname, allMembers[n].ToArray()) }; if (CLROpts.Debug) { Console.WriteLine("Installing {0}", siname); } P6any sub = Kernel.MakeSub(si, null); m.AddMethod(0, n, sub); if (n == "Invoke" && typeof(Delegate).IsAssignableFrom(t)) { m.AddMethod(0, "postcircumfix:<( )>", sub); } } m.Invalidate(); m.box_type = t; m.typeObject = m.initObject = new BoxObject <object>(null, m); m.typeVar = m.initVar = Kernel.NewROScalar(m.typeObject); return(m); }
public void AddAttribute(string name, int flags, P6any init, STable type) { AddAttributePos(name, flags, init, type, "???", 0); }
public BoxObject(T x, STable klass, int na) : base(klass, na) { value = x; }
public BoxObject(T x, STable klass) : base(klass) { value = x; }
// for thawing, if klass is uninitialized public P6opaque(STable klass, int na) { this.mo = klass; this.slots = (na != 0) ? new object[na] : null; }
public bool Isa(STable mo) { return(mo.isSubset ? mo.mo.CheckSubset(this) : this.mo.HasMRO(mo)); }
public void FillProtoClass(STable parent, params string[] slots) { mo.FillProtoClass(parent, slots); }
public void AddAttribute(string name, int flags, P6any init, STable type) { mo.AddAttribute(name, flags, init, type); }
public string Compose() { if (isComposed || rtype == "package" || rtype == "module") { isComposed = true; return(null); } if (isComposing) { return("Circularity detected while composing " + stable.name); } isComposing = true; string err; foreach (STable su in superclasses) { err = su.mo.Compose(); if (err != null) { return(err); } } isComposed = true; if (rtype == "role" || rtype == "prole") { isRole = true; SetMRO(Kernel.AnyMO.mo.mro); Revalidate(); stable.SetupVTables(); return(null); } if (superclasses.Count == 0 && stable != Kernel.MuMO) { superclasses.Add(rtype == "grammar" ? Kernel.GrammarMO : Kernel.AnyMO); } STable[][] lists = new STable[superclasses.Count + 2][]; lists[0] = new STable[] { stable }; lists[superclasses.Count + 1] = superclasses.ToArray(); for (int i = 0; i < superclasses.Count; i++) { lists[i + 1] = superclasses[i].mo.mro; } List <STable> nmro = new List <STable>(); err = C3Merge(nmro, lists); if (err != null) { return("C3 MRO generation failed for " + stable.name + ": " + err); } SetMRO(nmro.ToArray()); List <string> all_slot_l = new List <string>(); foreach (STable m in mro) { foreach (AttrInfo ai in m.mo.local_attr) { all_slot_l.Add(ai.name); } } stable.all_slot = all_slot_l.ToArray(); local_does = new STable[0]; stable.nslots = 0; foreach (string an in stable.all_slot) { stable.slotMap[an] = stable.nslots++; } Revalidate(); stable.SetupVTables(); return(null); }