Esempio n. 1
0
 Type FixupInterfaceType(TypeInfo.ParamDescriptor desc)
 {
     try {
         String ifaceName = desc.GetInterfaceName();
         return(EmitOneInterface(ifaceName));
     } catch (Exception e) {
         Console.WriteLine(e);
         return(typeof(object));
     }
 }
Esempio n. 2
0
    const int VARIANT_SIZE = 16; /* sizeof(XPTCVariant) */

    unsafe static void GenerateProxyMethod(TypeBuilder tb,
                                           MethodDescriptor desc,
                                           FieldInfo thisField)
    {
        if (!desc.IsVisible())
        {
            Console.WriteLine("HIDDEN: {0}", desc);
            return;
        }
        const MethodAttributes attrs =
            MethodAttributes.Public | MethodAttributes.Virtual;
        Type          ret  = desc.resultType;
        MethodBuilder meth =
            tb.DefineMethod(desc.name, attrs, ret, desc.argTypes);
        ILGenerator ilg = meth.GetILGenerator();

        TypeInfo.ParamDescriptor[] args = desc.args;

        LocalBuilder bufLocal =
            ilg.DeclareLocal(System.Type.GetType("System.Int32*"));

        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(ilg, bufLocal, type, i);

            if ((param.flags & ParamFlags.Out) != 0)
            {
                EmitOutParamPrep(ilg, bufLocal, type, i);
                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(ilg, bufLocal, i);
                // XXX do I need to cast this?
                ilg.Emit(OpCodes.Castclass, typeof(Int32));
                ilg.Emit(OpCodes.Stind_I4);
                break;

            case TypeTag.Int32:
                EmitPrepareArgStore(ilg, bufLocal, i);
                ilg.Emit(OpCodes.Stind_I4);
                break;

            case TypeTag.String:
                EmitPrepareArgStore(ilg, bufLocal, i);
                // the string arg is now on the stack
                ilg.Emit(OpCodes.Call,
                         marshalType.GetMethod("StringToCoTaskMemAnsi"));
                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(ilg, bufLocal, 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(ilg, bufLocal, 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);
        Console.WriteLine("$\t{0}", desc);
    }