Back to index

lightning-sunbird  0.9+nobinonly
Package Functions | Properties | Private Member Functions | Static Private Member Functions | Private Attributes | Static Private Attributes
Mozilla.XPCOM.ProxyGenerator Class Reference

List of all members.

Package Functions

 ProxyGenerator (String name)
Assembly Generate ()

Properties

static AssemblyBuilder ProxyAssembly [get]

Private Member Functions

void EmitPtrAndFlagsStore (int argnum, IntPtr ptr, sbyte flags)
void EmitTypeStore (TypeInfo.TypeDescriptor t, int argnum)
void EmitComputeBufferLoc (int argnum)
void EmitPrepareArgStore (int argnum)
void EmitLoadArg (int argnum)
void EmitLoadReturnSlot_1 (int slotnum)
void EmitOutParamPrep (TypeInfo.TypeDescriptor type, int argnum)
void EmitProxyConstructor ()
Type FixupInterfaceType (TypeInfo.ParamDescriptor desc)
unsafe void GenerateProxyMethod (MethodDescriptor desc)

Static Private Member Functions

static ProxyGenerator ()

Private Attributes

const int VARIANT_SIZE = 16
const PropertyAttributes PROPERTY_ATTRS = PropertyAttributes.None
PropertyBuilder lastProperty
TypeBuilder tb
FieldInfo thisField
LocalBuilder bufLocal
ILGenerator ilg
String proxyName

Static Private Attributes

static ModuleBuilder module
static AssemblyBuilder builder
static ConstructorInfo baseProxyCtor
static ConstructorInfo guidCtor

Detailed Description

Definition at line 19 of file proxy-generator.cs.


Constructor & Destructor Documentation

static Mozilla.XPCOM.ProxyGenerator.ProxyGenerator ( ) [inline, static, private]

Definition at line 305 of file proxy-generator.cs.

    {
        AssemblyName an = new AssemblyName();
        an.Version = new Version(1, 0, 0, 0);
        an.Name = "Mozilla.XPCOM.Proxies";
        
        AppDomain curDom = AppDomain.CurrentDomain;
        builder = curDom.DefineDynamicAssembly(an, AssemblyBuilderAccess.RunAndSave);
        
        String proxyDll =
            System.Environment.GetEnvironmentVariable("XPCOM_DOTNET_SAVE_PROXIES");
        if (proxyDll != null) {
            module = builder.DefineDynamicModule(an.Name, proxyDll);
        } else {
            module = builder.DefineDynamicModule(an.Name);
        }

        baseProxyCtor = typeof(BaseProxy).
            GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance,
                           null, new Type[1] { typeof(IntPtr) }, null);
        guidCtor = typeof(System.Guid).
            GetConstructor(new Type[1] {typeof(string)});
    }

Here is the call graph for this function:

Definition at line 336 of file proxy-generator.cs.

    {
        proxyName = name;
    }

Member Function Documentation

Definition at line 47 of file proxy-generator.cs.

    {
        ilg.Emit(OpCodes.Ldloc, bufLocal);
        ilg.Emit(OpCodes.Ldc_I4, argnum * VARIANT_SIZE);
        ilg.Emit(OpCodes.Add);
    }
void Mozilla.XPCOM.ProxyGenerator.EmitLoadArg ( int  argnum) [inline, private]

Definition at line 60 of file proxy-generator.cs.

    {
        switch (argnum) {
        case 0:
            ilg.Emit(OpCodes.Ldarg_1);
            break;
        case 1:
            ilg.Emit(OpCodes.Ldarg_2);
            break;
        case 2:
            ilg.Emit(OpCodes.Ldarg_3);
            break;
        default:
            if (argnum < 254)
                ilg.Emit(OpCodes.Ldarg_S, argnum + 1);
            else
                ilg.Emit(OpCodes.Ldarg, argnum + 1);
            break;
        }
    }

Definition at line 81 of file proxy-generator.cs.

    {
        ilg.Emit(OpCodes.Ldloc, bufLocal);
        ilg.Emit(OpCodes.Ldc_I4, (slotnum - 1) * VARIANT_SIZE);
        ilg.Emit(OpCodes.Add);
        ilg.Emit(OpCodes.Ldind_I4);
    }

Definition at line 89 of file proxy-generator.cs.

    {
        ilg.Emit(OpCodes.Nop);
        ilg.Emit(OpCodes.Ldloc, bufLocal);
        ilg.Emit(OpCodes.Ldc_I4, argnum * VARIANT_SIZE + 13);
        ilg.Emit(OpCodes.Add);
        ilg.Emit(OpCodes.Ldc_I4, 1); // PTR_IS_DATA
        ilg.Emit(OpCodes.Stind_I1);
        
        ilg.Emit(OpCodes.Ldloc, bufLocal);
        ilg.Emit(OpCodes.Ldc_I4, argnum * VARIANT_SIZE + 8); // offsetof(ptr)
        ilg.Emit(OpCodes.Add);
        ilg.Emit(OpCodes.Ldloc, bufLocal);
        ilg.Emit(OpCodes.Ldc_I4, argnum * VARIANT_SIZE + 0); // offsetof(val)
        ilg.Emit(OpCodes.Add);
        ilg.Emit(OpCodes.Stind_I4); /* XXX 64-bitness! */
    }

Definition at line 54 of file proxy-generator.cs.

    {
        EmitComputeBufferLoc(argnum);
        EmitLoadArg(argnum);
    }

Definition at line 107 of file proxy-generator.cs.

    {
        ConstructorBuilder ctor = 
            tb.DefineConstructor(MethodAttributes.Family,
                                 CallingConventions.Standard,
                                 new Type[1] { typeof(IntPtr) });
        ILGenerator ilg = ctor.GetILGenerator();
        ilg.Emit(OpCodes.Ldarg_0);
        ilg.Emit(OpCodes.Ldarg_1);
        ilg.Emit(OpCodes.Call, baseProxyCtor);
        ilg.Emit(OpCodes.Ret);
    }
void Mozilla.XPCOM.ProxyGenerator.EmitPtrAndFlagsStore ( int  argnum,
IntPtr  ptr,
sbyte  flags 
) [inline, private]

Definition at line 21 of file proxy-generator.cs.

    {
        //= bufLocal[argnum].ptr = ptr;
        ilg.Emit(OpCodes.Ldloc, bufLocal);
        ilg.Emit(OpCodes.Ldc_I4, argnum * VARIANT_SIZE + 8);
        ilg.Emit(OpCodes.Add);
        ilg.Emit(OpCodes.Ldc_I4, ptr.ToInt32());
        ilg.Emit(OpCodes.Stind_I4);

        //= bufLocal[argnum].flags = flags;
        ilg.Emit(OpCodes.Ldloc, bufLocal);
        ilg.Emit(OpCodes.Ldc_I4, argnum * VARIANT_SIZE + 13);
        ilg.Emit(OpCodes.Add);
        ilg.Emit(OpCodes.Ldc_I4, (Int32)flags);
        ilg.Emit(OpCodes.Stind_I1);
    }

Definition at line 38 of file proxy-generator.cs.

    {
        ilg.Emit(OpCodes.Ldloc, bufLocal);
        ilg.Emit(OpCodes.Ldc_I4, argnum * VARIANT_SIZE + 12);
        ilg.Emit(OpCodes.Add);
        ilg.Emit(OpCodes.Ldc_I4, (Int32)t.tag);
        ilg.Emit(OpCodes.Stind_I4);
    }

Definition at line 126 of file proxy-generator.cs.

    {
        try {
            return TypeInfo.TypeForIID(desc.GetIID());
        } catch (Exception e) {
            // Console.WriteLine(e);
            return typeof(object);
        }
    }

Here is the call graph for this function:

Assembly Mozilla.XPCOM.ProxyGenerator.Generate ( ) [inline, package]

Definition at line 341 of file proxy-generator.cs.

    {
        if (module.GetType(proxyName) != null)
            return module.Assembly;

        String baseIfaceName = proxyName.Replace("Mozilla.XPCOM.Proxies.", "");
        String ifaceName = "Mozilla.XPCOM.Interfaces." + baseIfaceName;

        Type ifaceType = System.Type.GetType(ifaceName + 
                                             ",Mozilla.XPCOM.Interfaces", true);

        ushort inheritedMethodCount;
        String parentName = TypeInfo.GetParentInfo(baseIfaceName,
                                                   out inheritedMethodCount);

        Type parentType;
        if (parentName == null) {
            parentType = typeof(BaseProxy);
        } else {
            parentType = System.Type.GetType("Mozilla.XPCOM.Proxies." +
                                             parentName +
                                             ",Mozilla.XPCOM.Proxies");
        }

        Console.WriteLine("Defining {0} (inherits {1}, impls {2})",
                          proxyName, parentType, ifaceName);
        tb = module.DefineType(proxyName, TypeAttributes.Class, parentType,
                               new Type[1] { ifaceType });
        
        thisField = typeof(BaseProxy).GetField("thisptr",
                                               BindingFlags.NonPublic |
                                               BindingFlags.Instance);

        EmitProxyConstructor();
        
        MethodDescriptor[] descs = TypeInfo.GetMethodData(baseIfaceName);

        for (int i = inheritedMethodCount; i < descs.Length; i++) {
            if (descs[i] != null) 
                GenerateProxyMethod(descs[i]);
        }

        tb.CreateType();

        thisField = null;
        tb = null;

        return module.Assembly;
    }

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 136 of file proxy-generator.cs.

    {
        if (!desc.IsVisible()) {
            Console.WriteLine("HIDDEN: {0}", desc);
            return;
        }
        MethodAttributes methodAttrs = 
            MethodAttributes.Public | MethodAttributes.Virtual;

        String methodName = desc.name;
        if (desc.IsGetter()) {
            methodName = "get_" + desc.name;
            methodAttrs |= MethodAttributes.SpecialName;
        } else if (desc.IsSetter()) {
            methodName = "set_" + desc.name;
            methodAttrs |= MethodAttributes.SpecialName;
        }
            
        // Fix up interface types in parameters
        Type ret = desc.resultType;
        if (ret == typeof(object))
            ret = FixupInterfaceType(desc.args[desc.args.Length - 1]);
        Type[] argTypes = (Type[])desc.argTypes.Clone();
        for (int i = 0; i < argTypes.Length; i++) {
            if (argTypes[i] == typeof(object))
                argTypes[i] = FixupInterfaceType(desc.args[i]);
        }
        MethodBuilder meth = tb.DefineMethod(methodName, methodAttrs, ret, argTypes);

        ilg = meth.GetILGenerator();
        bufLocal = ilg.DeclareLocal(System.Type.GetType("System.Int32*"));
        LocalBuilder guidLocal = ilg.DeclareLocal(typeof(System.Guid));
        TypeInfo.ParamDescriptor[] args = desc.args;

        Type marshalType = typeof(System.Runtime.InteropServices.Marshal);

        // Marshal.AllocCoTaskMem(constify(argBufSize))
        int argCount = args.Length;
        int argBufSize = VARIANT_SIZE * args.Length;

        ilg.Emit(OpCodes.Ldc_I4, argBufSize);
        ilg.Emit(OpCodes.Call, marshalType.GetMethod("AllocCoTaskMem"));
        ilg.Emit(OpCodes.Stloc, bufLocal);

        for (int i = 0; i < argCount; i++) {
            TypeInfo.ParamDescriptor param = args[i];
            TypeInfo.TypeDescriptor type = param.type;
            IntPtr ptr = IntPtr.Zero;
            sbyte flags = 0;
            EmitTypeStore(type, i);

            if (param.IsOut()) {
                EmitOutParamPrep(type, i);
                if (!param.IsIn())
                    continue;
            }
            switch (type.tag) {
            case TypeTag.Int8:
            case TypeTag.Int16:
            case TypeTag.UInt8:
            case TypeTag.UInt16:
            case TypeTag.Char:
            case TypeTag.WChar:
            case TypeTag.UInt32:
                EmitPrepareArgStore(i);
                // XXX do I need to cast this?
                ilg.Emit(OpCodes.Castclass, typeof(Int32));
                ilg.Emit(OpCodes.Stind_I4);
                break;
            case TypeTag.Int32:
                EmitPrepareArgStore(i);
                ilg.Emit(OpCodes.Stind_I4);
                break;
            case TypeTag.NSIdPtr:
                EmitPrepareArgStore(i);
                ilg.Emit(OpCodes.Stind_I4); // XXX 64-bitness
                break;
            case TypeTag.String:
                EmitPrepareArgStore(i);
                // the string arg is now on the stack
                ilg.Emit(OpCodes.Call,
                         marshalType.GetMethod("StringToCoTaskMemAnsi"));
                ilg.Emit(OpCodes.Stind_I4);
                break;
            case TypeTag.Interface:
                EmitPrepareArgStore(i);
                // MRP is the object passed as this arg
                ilg.Emit(OpCodes.Ldloca_S, guidLocal);
                ilg.Emit(OpCodes.Ldstr, param.GetIID().ToString());
                ilg.Emit(OpCodes.Call, guidCtor);
                ilg.Emit(OpCodes.Ldloca_S, guidLocal);
                // stack is now objarg, ref guid
                ilg.Emit(OpCodes.Call, typeof(CLRWrapper).GetMethod("Wrap"));
                // now stack has the IntPtr in position to be stored.
                ilg.Emit(OpCodes.Stind_I4);
                break;
            default:
                /*
                String msg = String.Format("{0}: type {1} not supported",
                                    param.Name(), type.tag.ToString());
                throw new Exception(msg);
                */
                break;
            }
            EmitPtrAndFlagsStore(i, ptr, flags);
        }

        //= (void)XPTC_InvokeByIndex(thisptr, desc.index, length, bufLocal);
        ilg.Emit(OpCodes.Ldarg_0);
        ilg.Emit(OpCodes.Ldfld, thisField);
        ilg.Emit(OpCodes.Ldc_I4, desc.index);
        ilg.Emit(OpCodes.Ldc_I4, args.Length);
        ilg.Emit(OpCodes.Ldloc_0);
        ilg.Emit(OpCodes.Call, typeof(Mozilla.XPCOM.Invoker).
                 GetMethod("XPTC_InvokeByIndex",
                           BindingFlags.Static | BindingFlags.NonPublic));
        ilg.Emit(OpCodes.Pop);

        if (ret == typeof(string)) {
            ilg.Emit(OpCodes.Ldstr, "FAKE RETURN STRING");
        } else if (ret == typeof(object)) {
            ilg.Emit(OpCodes.Newobj,
                     typeof(object).GetConstructor(new Type[0]));
        } else if (ret == typeof(int)) {
            EmitLoadReturnSlot_1(args.Length);
        } else if (ret == typeof(void)) {
            // Nothing
        } else {
            throw new Exception(String.Format("return type {0} not " +
                                              "supported yet",
                                              desc.result.type.tag));
        }

        //= Marshal.FreeCoTaskMem(bufLocal);
        ilg.Emit(OpCodes.Ldloc, bufLocal);
        ilg.Emit(OpCodes.Call, marshalType.GetMethod("FreeCoTaskMem"));

        ilg.Emit(OpCodes.Ret);

        ilg = null;
        bufLocal = null;

        if (desc.IsSetter()) {
            if (lastProperty != null && lastProperty.Name == desc.name) {
                lastProperty.SetSetMethod(meth);
            } else {
                tb.DefineProperty(desc.name, PROPERTY_ATTRS, desc.resultType,
                                  new Type[0]).SetSetMethod(meth);
            }
            lastProperty = null;
        } else if (desc.IsGetter()) {
            lastProperty = tb.DefineProperty(desc.name, PROPERTY_ATTRS,
                                             desc.resultType, new Type[0]);
            lastProperty.SetGetMethod(meth);
        } else {
            lastProperty = null;
        }

    }

Here is the call graph for this function:


Member Data Documentation

ConstructorInfo Mozilla.XPCOM.ProxyGenerator.baseProxyCtor [static, private]

Definition at line 298 of file proxy-generator.cs.

LocalBuilder Mozilla.XPCOM.ProxyGenerator.bufLocal [private]

Definition at line 331 of file proxy-generator.cs.

AssemblyBuilder Mozilla.XPCOM.ProxyGenerator.builder [static, private]

Definition at line 297 of file proxy-generator.cs.

ConstructorInfo Mozilla.XPCOM.ProxyGenerator.guidCtor [static, private]

Definition at line 299 of file proxy-generator.cs.

ILGenerator Mozilla.XPCOM.ProxyGenerator.ilg [private]

Definition at line 332 of file proxy-generator.cs.

PropertyBuilder Mozilla.XPCOM.ProxyGenerator.lastProperty [private]

Definition at line 124 of file proxy-generator.cs.

ModuleBuilder Mozilla.XPCOM.ProxyGenerator.module [static, private]

Definition at line 296 of file proxy-generator.cs.

const PropertyAttributes Mozilla.XPCOM.ProxyGenerator.PROPERTY_ATTRS = PropertyAttributes.None [private]

Definition at line 122 of file proxy-generator.cs.

Definition at line 334 of file proxy-generator.cs.

TypeBuilder Mozilla.XPCOM.ProxyGenerator.tb [private]

Definition at line 329 of file proxy-generator.cs.

Definition at line 330 of file proxy-generator.cs.

Definition at line 120 of file proxy-generator.cs.


Property Documentation

AssemblyBuilder Mozilla.XPCOM.ProxyGenerator.ProxyAssembly [static, get, package]

Definition at line 301 of file proxy-generator.cs.


The documentation for this class was generated from the following file: