Type FixupInterfaceType(TypeInfo.ParamDescriptor desc) { try { String ifaceName = desc.GetInterfaceName(); return(EmitOneInterface(ifaceName)); } catch (Exception e) { Console.WriteLine(e); return(typeof(object)); } }
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); }