public static STable GetNamedWrapper(string nm) { lock (wrapper_cache_lock) { if (wrapper_cache == null) { wrapper_cache = new Dictionary <Type, STable>(); } if (named_wrapper_cache == null) { named_wrapper_cache = new Dictionary <string, STable>(); } STable r; if (named_wrapper_cache.TryGetValue(nm, out r)) { return(r); } Type ty = Type.GetType(nm.Substring(1)); if (CLROpts.Debug) { Console.WriteLine("Loading type {0} ... {1}", nm.Substring(1), ty == null ? "failed" : "succeeded"); } if (ty != null) { wrapper_cache[ty] = r = NewWrapper(ty); named_wrapper_cache[nm] = r; } else { named_wrapper_cache[nm] = r = StashCursor.MakePackage( "CLR" + nm.Replace(".", "::"), StashCursor.MakeCLR_WHO(nm)).Fetch().mo; } return(r); } }
public static Frame ind_method_call(Frame th, StashCursor root, string nm, P6any cap) { int cut = nm.LastIndexOf("::"); var setting = th.info.setting; var pos = (Variable[]) cap.GetSlot(setting.CaptureMO, "$!positionals"); var nam = (VarHash) cap.GetSlot(setting.CaptureMO, "$!named"); if (cut < 0) { return pos[0].Fetch().InvokeMethod(th, nm, pos, nam); } else { var from = root.Indirect(nm.Substring(0, cut), false, null) .Fetch().mo; var name = nm.Substring(cut+2); // some code copied from dispatch_fromtype if (!pos[0].Fetch().Does(from)) { return Kernel.Die(th, "Cannot dispatch to a method on " + from.name + " because it is not inherited or done by " + pos[0].Fetch().mo.name); } var de = from.FindMethod(name); if (de != null) { return de.info.SetupCall(th, de.outer, de.ip6, pos, nam, false, de); } else { return Kernel.Die(th, "Unable to resolve method " + name + " via " + from.name); } } }
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); }