Skip to content

Commit

Permalink
2007-09-10 William Holmes <billholmes54@gmail.com>
Browse files Browse the repository at this point in the history
	Backport for r84147
	* marshal.c (emit_marshal_com_interface): Patch from
	  Bill Holmes to handle COM Interfaces as return values
	  for native->managed calls.

svn path=/branches/mono-1-2-5/mono/; revision=85599
  • Loading branch information
Bill Holmes committed Sep 10, 2007
1 parent 9de72f4 commit e762c8f
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 11 deletions.
11 changes: 9 additions & 2 deletions mono/metadata/ChangeLog
@@ -1,12 +1,19 @@
2007-09-10 William Holmes <billholmes54@gmail.com>

Backprot for r84130
Backport for r84147
* marshal.c (emit_marshal_com_interface): Patch from
Bill Holmes to handle COM Interfaces as return values
for native->managed calls.

2007-09-10 William Holmes <billholmes54@gmail.com>

Backport for r84130
* marshal.c (cominterop_get_idispatch_for_object): Implement
for runtime callable wrappers.

2007-09-10 William Holmes <billholmes54@gmail.com>

Backprot for r83601
Backport for r83601
* marshal.c: Use correct image when emitting
native wrapper for COM calls.

Expand Down
54 changes: 45 additions & 9 deletions mono/metadata/marshal.c
Expand Up @@ -7057,6 +7057,7 @@ emit_marshal_com_interface (EmitMarshalContext *m, int argnum, MonoType *t,
static MonoMethod* get_com_interface_for_object_internal = NULL;
static MonoMethod* get_idispatch_for_object_internal = NULL;
static MonoMethod* marshal_release = NULL;
static MonoMethod* AddRef = NULL;
if (!get_object_for_iunknown)
get_object_for_iunknown = mono_class_get_method_from_name (mono_defaults.marshal_class, "GetObjectForIUnknown", 1);
if (!get_iunknown_for_object_internal)
Expand Down Expand Up @@ -7172,24 +7173,25 @@ emit_marshal_com_interface (EmitMarshalContext *m, int argnum, MonoType *t,
break;

case MARSHAL_ACTION_CONV_RESULT: {
int ccw_obj;
int ccw_obj, ret_ptr;
guint32 pos_null = 0, pos_ccw = 0, pos_end = 0;
ccw_obj = mono_mb_add_local (mb, &mono_defaults.object_class->byval_arg);
ret_ptr = mono_mb_add_local (mb, &mono_defaults.int_class->byval_arg);

/* store return value */
mono_mb_emit_stloc (mb, 0);
mono_mb_emit_stloc (mb, ret_ptr);

mono_mb_emit_ldloc (mb, 0);
mono_mb_emit_ldloc (mb, ret_ptr);
pos_null = mono_mb_emit_short_branch (mb, CEE_BRFALSE_S);

mono_mb_emit_ldloc (mb, 0);
mono_mb_emit_ldloc (mb, ret_ptr);
mono_mb_emit_icon (mb, TRUE);
mono_mb_emit_icall (mb, cominterop_get_ccw_object);
mono_mb_emit_stloc (mb, ccw_obj);
mono_mb_emit_ldloc (mb, ccw_obj);
pos_ccw = mono_mb_emit_short_branch (mb, CEE_BRTRUE_S);

mono_mb_emit_ldloc (mb, 0);
mono_mb_emit_ldloc (mb, ret_ptr);
mono_mb_emit_managed_call (mb, get_object_for_iunknown, NULL);

if (klass && klass != mono_defaults.object_class)
Expand All @@ -7209,7 +7211,7 @@ emit_marshal_com_interface (EmitMarshalContext *m, int argnum, MonoType *t,
mono_mb_patch_short_branch (mb, pos_end);

/* need to call Release to follow COM rules of ownership */
mono_mb_emit_ldloc (mb, 0);
mono_mb_emit_ldloc (mb, ret_ptr);
mono_mb_emit_managed_call (mb, marshal_release, NULL);
mono_mb_emit_byte (mb, CEE_POP);

Expand Down Expand Up @@ -7272,7 +7274,6 @@ emit_marshal_com_interface (EmitMarshalContext *m, int argnum, MonoType *t,

case MARSHAL_ACTION_MANAGED_CONV_OUT: {
if (t->byref && t->attrs & PARAM_ATTRIBUTE_OUT) {
static MonoMethod* AddRef = NULL;
guint32 pos_null = 0;

if (!AddRef)
Expand Down Expand Up @@ -7311,8 +7312,43 @@ emit_marshal_com_interface (EmitMarshalContext *m, int argnum, MonoType *t,
}

case MARSHAL_ACTION_MANAGED_CONV_RESULT: {
char *msg = g_strdup ("Marshalling of COM Objects is not yet implemented.");
mono_mb_emit_exception_marshal_directive (mb, msg);
guint32 pos_null = 0;
int ccw_obj;
ccw_obj = mono_mb_add_local (mb, &mono_defaults.object_class->byval_arg);

if (!AddRef)
AddRef = mono_class_get_method_from_name (mono_defaults.marshal_class, "AddRef", 1);

/* store return value */
mono_mb_emit_stloc (mb, ccw_obj);

mono_mb_emit_ldloc (mb, ccw_obj);

/* if null just break, conv arg was already inited to 0 */
pos_null = mono_mb_emit_short_branch (mb, CEE_BRFALSE_S);

/* to store later */
mono_mb_emit_ldloc (mb, ccw_obj);
if (klass && klass != mono_defaults.object_class) {
mono_mb_emit_ptr (mb, t);
mono_mb_emit_icall (mb, type_from_handle);
mono_mb_emit_managed_call (mb, get_com_interface_for_object_internal, NULL);
}
else if (spec->native == MONO_NATIVE_IUNKNOWN)
mono_mb_emit_managed_call (mb, get_iunknown_for_object_internal, NULL);
else if (spec->native == MONO_NATIVE_IDISPATCH)
mono_mb_emit_managed_call (mb, get_idispatch_for_object_internal, NULL);
else if (!klass && spec->native == MONO_NATIVE_INTERFACE)
mono_mb_emit_managed_call (mb, get_iunknown_for_object_internal, NULL);
else
g_assert_not_reached ();
mono_mb_emit_stloc (mb, 3);
mono_mb_emit_ldloc (mb, 3);

mono_mb_emit_managed_call (mb, AddRef, NULL);
mono_mb_emit_byte (mb, CEE_POP);

mono_mb_patch_short_branch (mb, pos_null);
break;
}

Expand Down

0 comments on commit e762c8f

Please sign in to comment.