Example #1
0
 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);
     }
 }
Example #2
0
    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);
            }
        }
    }
Example #3
0
        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);
        }