diff --git a/src/installer/pkg/sfx/Microsoft.NETCore.App/Directory.Build.props b/src/installer/pkg/sfx/Microsoft.NETCore.App/Directory.Build.props
index 61f577981d136..07d77161002bc 100644
--- a/src/installer/pkg/sfx/Microsoft.NETCore.App/Directory.Build.props
+++ b/src/installer/pkg/sfx/Microsoft.NETCore.App/Directory.Build.props
@@ -205,13 +205,6 @@
-
-
-
-
-
-
-
diff --git a/src/libraries/System.Diagnostics.Tracing/tests/System.Diagnostics.Tracing.Tests.csproj b/src/libraries/System.Diagnostics.Tracing/tests/System.Diagnostics.Tracing.Tests.csproj
index 75300d8460ba8..35b1a833abb56 100644
--- a/src/libraries/System.Diagnostics.Tracing/tests/System.Diagnostics.Tracing.Tests.csproj
+++ b/src/libraries/System.Diagnostics.Tracing/tests/System.Diagnostics.Tracing.Tests.csproj
@@ -6,7 +6,7 @@
true
- diagnostics_tracing;marshal-ilgen
+ diagnostics_tracing
diff --git a/src/mono/mono.proj b/src/mono/mono.proj
index 26ca5545d761b..38731e968660a 100644
--- a/src/mono/mono.proj
+++ b/src/mono/mono.proj
@@ -733,8 +733,7 @@
-
-
+
diff --git a/src/mono/mono/component/CMakeLists.txt b/src/mono/mono/component/CMakeLists.txt
index d83c9144af07f..7c864322f5f37 100644
--- a/src/mono/mono/component/CMakeLists.txt
+++ b/src/mono/mono/component/CMakeLists.txt
@@ -6,12 +6,9 @@ set(MONO_EVENTPIPE_GEN_INCLUDE_PATH "${CMAKE_CURRENT_BINARY_DIR}/eventpipe")
set(MONO_HOT_RELOAD_COMPONENT_NAME "hot_reload")
set(MONO_DIAGNOSTICS_TRACING_COMPONENT_NAME "diagnostics_tracing")
set(MONO_DEBUGGER_COMPONENT_NAME "debugger")
-set(MONO_MARSHAL_ILGEN_COMPONENT_NAME "marshal-ilgen")
# a list of every component.
set(components "")
-# a list of components needed by the AOT compiler
-set(components_for_aot "")
# the sources for each individiable component define a new
# component_name-sources list for each component, and a
@@ -82,53 +79,17 @@ set(${MONO_DIAGNOSTICS_TRACING_COMPONENT_NAME}-dependencies
${MONO_DIAGNOSTICS_TRACING_COMPONENT_NAME}-gen-sources
)
-# marshal-ilgen
-list(APPEND components
- ${MONO_MARSHAL_ILGEN_COMPONENT_NAME}
-)
-list(APPEND components_for_aot
- ${MONO_MARSHAL_ILGEN_COMPONENT_NAME}
-)
-
-set(${MONO_MARSHAL_ILGEN_COMPONENT_NAME}-sources
- ${MONO_COMPONENT_PATH}/marshal-ilgen.c
- ${MONO_COMPONENT_PATH}/marshal-ilgen.h
- ${MONO_COMPONENT_PATH}/marshal-ilgen-noilgen.c
- ${MONO_COMPONENT_PATH}/marshal-ilgen-noilgen.h
-)
-
-# For every component not build into the AOT compiler, build the stub instead
-set(stubs_for_aot "")
-foreach (component IN LISTS components)
- if (NOT (component IN_LIST components_for_aot))
- list(APPEND stubs_for_aot "${component}")
- endif()
-endforeach()
-
-
-set(${MONO_MARSHAL_ILGEN_COMPONENT_NAME}-stub-sources
- ${MONO_COMPONENT_PATH}/marshal-ilgen-stub.c
-)
-
-if (AOT_COMPONENTS)
- set(components_to_build ${components_for_aot})
- set(stubs_to_build ${stubs_for_aot})
-else()
- set(components_to_build ${components})
- set(stubs_to_build ${components})
-endif()
-
# from here down, all the components are treated in the same way
#define a library for each component and component stub
function(define_component_libs)
# NOTE: keep library naming pattern in sync with RuntimeComponentManifest.targets
- if (AOT_COMPONENTS OR NOT DISABLE_LIBS )
- foreach(component IN LISTS components_to_build)
+ if (NOT DISABLE_LIBS)
+ foreach(component IN LISTS components)
add_library("mono-component-${component}-static" STATIC $)
install(TARGETS "mono-component-${component}-static" LIBRARY)
endforeach()
- foreach(component IN LISTS stubs_to_build)
+ foreach(component IN LISTS components)
add_library("mono-component-${component}-stub-static" STATIC $)
install(TARGETS "mono-component-${component}-stub-static" LIBRARY)
endforeach()
@@ -142,7 +103,7 @@ target_sources(component_base INTERFACE
)
target_link_libraries(component_base INTERFACE monoapi)
-if(NOT AOT_COMPONENTS AND (DISABLE_COMPONENTS OR DISABLE_LIBS))
+if(DISABLE_COMPONENTS OR DISABLE_LIBS)
set(DISABLE_COMPONENT_OBJECTS 1)
endif()
@@ -162,7 +123,7 @@ endforeach()
if(NOT DISABLE_COMPONENTS AND NOT STATIC_COMPONENTS)
# define a shared library for each component
- foreach(component IN LISTS components_to_build)
+ foreach(component IN LISTS components)
# NOTE: keep library naming pattern in sync with RuntimeComponentManifest.targets
if(HOST_WIN32)
add_library("mono-component-${component}" SHARED "${${component}-sources}")
@@ -194,14 +155,14 @@ if(NOT DISABLE_COMPONENTS AND NOT STATIC_COMPONENTS)
#define a library for each component and component stub
define_component_libs()
-elseif(AOT_COMPONENTS OR (NOT DISABLE_COMPONENTS AND STATIC_COMPONENTS))
+elseif(NOT DISABLE_COMPONENTS AND STATIC_COMPONENTS)
#define a library for each component and component stub
define_component_libs()
# define a list of mono-components objects for mini if building a shared libmono with static-linked components
set(mono-components-objects "")
- foreach(component IN LISTS components_to_build)
+ foreach(component IN LISTS components)
list(APPEND mono-components-objects $)
endforeach()
diff --git a/src/mono/mono/component/marshal-ilgen-noilgen.c b/src/mono/mono/component/marshal-ilgen-noilgen.c
deleted file mode 100644
index 6cf9dfd5ac628..0000000000000
--- a/src/mono/mono/component/marshal-ilgen-noilgen.c
+++ /dev/null
@@ -1,186 +0,0 @@
-#include "mono/component/marshal-ilgen.h"
-#include "mono/component/marshal-ilgen-noilgen.h"
-
-#ifndef ENABLE_ILGEN
-static int
-emit_marshal_array_noilgen (EmitMarshalContext *m, int argnum, MonoType *t,
- MonoMarshalSpec *spec,
- int conv_arg, MonoType **conv_arg_type,
- MarshalAction action)
-{
- MonoType *int_type = mono_get_int_type ();
- MonoType *object_type = mono_get_object_type ();
- switch (action) {
- case MARSHAL_ACTION_CONV_IN:
- *conv_arg_type = object_type;
- break;
- case MARSHAL_ACTION_MANAGED_CONV_IN:
- *conv_arg_type = int_type;
- break;
- }
- return conv_arg;
-}
-
-static int
-emit_marshal_ptr_noilgen (EmitMarshalContext *m, int argnum, MonoType *t,
- MonoMarshalSpec *spec, int conv_arg,
- MonoType **conv_arg_type, MarshalAction action)
-{
- return conv_arg;
-}
-#endif
-
-#if !defined(ENABLE_ILGEN) || defined(DISABLE_NONBLITTABLE)
-static int
-emit_marshal_vtype_noilgen (EmitMarshalContext *m, int argnum, MonoType *t,
- MonoMarshalSpec *spec,
- int conv_arg, MonoType **conv_arg_type,
- MarshalAction action)
-{
- return conv_arg;
-}
-
-static int
-emit_marshal_string_noilgen (EmitMarshalContext *m, int argnum, MonoType *t,
- MonoMarshalSpec *spec,
- int conv_arg, MonoType **conv_arg_type,
- MarshalAction action)
-{
- MonoType *int_type = mono_get_int_type ();
- switch (action) {
- case MARSHAL_ACTION_CONV_IN:
- *conv_arg_type = int_type;
- break;
- case MARSHAL_ACTION_MANAGED_CONV_IN:
- *conv_arg_type = int_type;
- break;
- }
- return conv_arg;
-}
-
-static int
-emit_marshal_safehandle_noilgen (EmitMarshalContext *m, int argnum, MonoType *t,
- MonoMarshalSpec *spec, int conv_arg,
- MonoType **conv_arg_type, MarshalAction action)
-{
- MonoType *int_type = mono_get_int_type ();
- if (action == MARSHAL_ACTION_CONV_IN)
- *conv_arg_type = int_type;
- return conv_arg;
-}
-
-static int
-emit_marshal_handleref_noilgen (EmitMarshalContext *m, int argnum, MonoType *t,
- MonoMarshalSpec *spec, int conv_arg,
- MonoType **conv_arg_type, MarshalAction action)
-{
- MonoType *int_type = mono_get_int_type ();
- if (action == MARSHAL_ACTION_CONV_IN)
- *conv_arg_type = int_type;
- return conv_arg;
-}
-
-static int
-emit_marshal_object_noilgen (EmitMarshalContext *m, int argnum, MonoType *t,
- MonoMarshalSpec *spec,
- int conv_arg, MonoType **conv_arg_type,
- MarshalAction action)
-{
- MonoType *int_type = mono_get_int_type ();
- if (action == MARSHAL_ACTION_CONV_IN)
- *conv_arg_type = int_type;
- return conv_arg;
-}
-
-static int
-emit_marshal_variant_noilgen (EmitMarshalContext *m, int argnum, MonoType *t,
- MonoMarshalSpec *spec,
- int conv_arg, MonoType **conv_arg_type,
- MarshalAction action)
-{
- g_assert_not_reached ();
-}
-
-static int
-emit_marshal_asany_noilgen (EmitMarshalContext *m, int argnum, MonoType *t,
- MonoMarshalSpec *spec,
- int conv_arg, MonoType **conv_arg_type,
- MarshalAction action)
-{
- return conv_arg;
-}
-
-static int
-emit_marshal_boolean_noilgen (EmitMarshalContext *m, int argnum, MonoType *t,
- MonoMarshalSpec *spec,
- int conv_arg, MonoType **conv_arg_type,
- MarshalAction action)
-{
- MonoType *int_type = mono_get_int_type ();
- switch (action) {
- case MARSHAL_ACTION_CONV_IN:
- if (m_type_is_byref (t))
- *conv_arg_type = int_type;
- else
- *conv_arg_type = mono_marshal_boolean_conv_in_get_local_type (spec, NULL);
- break;
-
- case MARSHAL_ACTION_MANAGED_CONV_IN: {
- MonoClass* conv_arg_class = mono_marshal_boolean_managed_conv_in_get_conv_arg_class (spec, NULL);
- if (m_type_is_byref (t))
- *conv_arg_type = m_class_get_this_arg (conv_arg_class);
- else
- *conv_arg_type = m_class_get_byval_arg (conv_arg_class);
- break;
- }
-
- }
- return conv_arg;
-}
-
-static int
-emit_marshal_char_noilgen (EmitMarshalContext *m, int argnum, MonoType *t,
- MonoMarshalSpec *spec, int conv_arg,
- MonoType **conv_arg_type, MarshalAction action)
-{
- return conv_arg;
-}
-
-static int
-emit_marshal_custom_noilgen (EmitMarshalContext *m, int argnum, MonoType *t,
- MonoMarshalSpec *spec,
- int conv_arg, MonoType **conv_arg_type,
- MarshalAction action)
-{
- MonoType *int_type = mono_get_int_type ();
- if (action == MARSHAL_ACTION_CONV_IN && t->type == MONO_TYPE_VALUETYPE)
- *conv_arg_type = int_type;
- return conv_arg;
-}
-#endif
-
-#ifndef ENABLE_ILGEN
-
-void
-mono_marshal_noilgen_init_heavyweight (void)
-{
- MonoMarshalILgenCallbacks ilgen_cb;
-
- ilgen_cb.version = MONO_MARSHAL_CALLBACKS_VERSION;
- ilgen_cb.emit_marshal_array = emit_marshal_array_noilgen;
- ilgen_cb.emit_marshal_vtype = emit_marshal_vtype_noilgen;
- ilgen_cb.emit_marshal_string = emit_marshal_string_noilgen;
- ilgen_cb.emit_marshal_safehandle = emit_marshal_safehandle_noilgen;
- ilgen_cb.emit_marshal_handleref = emit_marshal_handleref_noilgen;
- ilgen_cb.emit_marshal_object = emit_marshal_object_noilgen;
- ilgen_cb.emit_marshal_variant = emit_marshal_variant_noilgen;
- ilgen_cb.emit_marshal_asany = emit_marshal_asany_noilgen;
- ilgen_cb.emit_marshal_boolean = emit_marshal_boolean_noilgen;
- ilgen_cb.emit_marshal_custom = emit_marshal_custom_noilgen;
- ilgen_cb.emit_marshal_ptr = emit_marshal_ptr_noilgen;
-
- ilgen_cb.emit_marshal_char = emit_marshal_char_noilgen;
- mono_install_marshal_callbacks_ilgen(&ilgen_cb);
-}
-
-#endif
\ No newline at end of file
diff --git a/src/mono/mono/component/marshal-ilgen-noilgen.h b/src/mono/mono/component/marshal-ilgen-noilgen.h
deleted file mode 100644
index 5e877c223833c..0000000000000
--- a/src/mono/mono/component/marshal-ilgen-noilgen.h
+++ /dev/null
@@ -1,11 +0,0 @@
-/**
- * \file
- * Copyright 2022 Microsoft
- * Licensed under the MIT license. See LICENSE file in the project root for full license information.
- */
-#ifndef __MARSHAL_ILGEN_NOILGEN_H__
-#define __MARSHAL_ILGEN_NOILGEN_H__
-
-void mono_marshal_noilgen_init_heavyweight (void);
-
-#endif // __MARSHAL_ILGEN_NOILGEN_H__
\ No newline at end of file
diff --git a/src/mono/mono/component/marshal-ilgen-stub.c b/src/mono/mono/component/marshal-ilgen-stub.c
deleted file mode 100644
index 8182c95b7e286..0000000000000
--- a/src/mono/mono/component/marshal-ilgen-stub.c
+++ /dev/null
@@ -1,41 +0,0 @@
-
-#include
-#include
-#include
-
-static bool
-marshal_ilgen_available (void)
-{
- return false;
-}
-
-static int
-stub_emit_marshal_ilgen (EmitMarshalContext *m, int argnum, MonoType *t,
- MonoMarshalSpec *spec, int conv_arg,
- MonoType **conv_arg_type, MarshalAction action, MonoMarshalLightweightCallbacks* lightweigth_cb)
-{
- return 0;
-}
-
-static void
-mono_component_marshal_ilgen_stub_init(void)
-{
-}
-
-static void
-stub_mono_marshal_ilgen_install_callbacks_mono (IlgenCallbacksToMono *callbacks)
-{
-}
-
-static MonoComponentMarshalILgen component_func_table = {
- { MONO_COMPONENT_ITF_VERSION, &marshal_ilgen_available },
- mono_component_marshal_ilgen_stub_init,
- stub_emit_marshal_ilgen,
- stub_mono_marshal_ilgen_install_callbacks_mono
-};
-
-MonoComponentMarshalILgen*
-mono_component_marshal_ilgen_init (void)
-{
- return &component_func_table;
-}
diff --git a/src/mono/mono/component/marshal-ilgen.c b/src/mono/mono/component/marshal-ilgen.c
deleted file mode 100644
index e6deeea556409..0000000000000
--- a/src/mono/mono/component/marshal-ilgen.c
+++ /dev/null
@@ -1,2861 +0,0 @@
-
-#include "mono/metadata/debug-helpers.h"
-#include "metadata/marshal.h"
-#include "component/marshal-ilgen.h"
-#include "mono/component/marshal-ilgen.h"
-#include "mono/component/marshal-ilgen-noilgen.h"
-#include "metadata/marshal-lightweight.h"
-#include "metadata/marshal-shared.h"
-#include "metadata/method-builder-ilgen.h"
-#include "metadata/custom-attrs-internals.h"
-#include "metadata/class-init.h"
-#include "mono/metadata/class-internals.h"
-#include "metadata/reflection-internals.h"
-#include "mono/metadata/handle.h"
-#include "mono/component/component.h"
-
-#define OPDEF(a,b,c,d,e,f,g,h,i,j) \
- a = i,
-
-enum {
-#include "mono/cil/opcode.def"
- LAST = 0xff
-};
-#undef OPDEF
-
-#define mono_mb_emit_jit_icall(mb, name) (cb_to_mono->mb_emit_icall_id ((mb), MONO_JIT_ICALL_ ## name))
-
-static GENERATE_GET_CLASS_WITH_CACHE (date_time, "System", "DateTime");
-static GENERATE_TRY_GET_CLASS_WITH_CACHE (icustom_marshaler, "System.Runtime.InteropServices", "ICustomMarshaler");
-
-static void emit_string_free_icall (MonoMethodBuilder *mb, MonoMarshalConv conv);
-
-static void mono_marshal_ilgen_legacy_init (void);
-
-static gboolean ilgen_cb_inited = FALSE;
-static MonoMarshalILgenCallbacks ilgen_marshal_cb;
-
-static IlgenCallbacksToMono *cb_to_mono;
-
-static bool
-marshal_ilgen_available (void)
-{
- return true;
-}
-
-static MonoComponentMarshalILgen component_func_table = {
- { MONO_COMPONENT_ITF_VERSION, &marshal_ilgen_available },
- &mono_marshal_ilgen_init,
- &mono_emit_marshal_ilgen,
- &mono_marshal_ilgen_install_callbacks_mono
-};
-
-
-MonoComponentMarshalILgen*
-mono_component_marshal_ilgen_init (void)
-{
- return &component_func_table;
-}
-
-void
-mono_install_marshal_callbacks_ilgen (MonoMarshalILgenCallbacks *cb)
-{
- g_assert (!ilgen_cb_inited);
- g_assert (cb->version == MONO_MARSHAL_CALLBACKS_VERSION);
- memcpy (&ilgen_marshal_cb, cb, sizeof (MonoMarshalILgenCallbacks));
- ilgen_cb_inited = TRUE;
-}
-
-void
-mono_marshal_ilgen_install_callbacks_mono (IlgenCallbacksToMono *callbacks)
-{
- cb_to_mono = callbacks;
-}
-
-static void
-emit_struct_free (MonoMethodBuilder *mb, MonoClass *klass, int struct_var)
-{
- /* Call DestroyStructure */
- /* FIXME: Only do this if needed */
- cb_to_mono->mb_emit_byte (mb, MONO_CUSTOM_PREFIX);
- cb_to_mono->mb_emit_op (mb, CEE_MONO_CLASSCONST, klass);
- cb_to_mono->mb_emit_ldloc (mb, struct_var);
- mono_mb_emit_jit_icall (mb, mono_struct_delete_old);
-}
-
-static int
-emit_marshal_array_ilgen (EmitMarshalContext *m, int argnum, MonoType *t,
- MonoMarshalSpec *spec,
- int conv_arg, MonoType **conv_arg_type,
- MarshalAction action)
-{
- MonoMethodBuilder *mb = m->mb;
- MonoClass *klass = mono_class_from_mono_type_internal (t);
- MonoMarshalNative encoding;
-
- encoding = cb_to_mono->get_string_encoding (m->piinfo, spec);
- MonoType *int_type = cb_to_mono->get_int_type ();
- MonoType *object_type = cb_to_mono->get_object_type ();
-
- MonoClass *eklass = m_class_get_element_class (klass);
-
- switch (action) {
- case MARSHAL_ACTION_CONV_IN:
- *conv_arg_type = object_type;
- conv_arg = cb_to_mono->mb_add_local (mb, object_type);
-
- if (m_class_is_blittable (eklass)) {
- cb_to_mono->mb_emit_ldarg (mb, argnum);
- if (m_type_is_byref (t))
- cb_to_mono->mb_emit_byte (mb, CEE_LDIND_I);
- cb_to_mono->mb_emit_icall_id (mb, cb_to_mono->conv_to_icall (MONO_MARSHAL_CONV_ARRAY_LPARRAY, NULL));
- cb_to_mono->mb_emit_stloc (mb, conv_arg);
- } else {
-#ifdef DISABLE_NONBLITTABLE
- char *msg = g_strdup ("Non-blittable marshalling conversion is disabled");
- cb_to_mono->mb_emit_exception_marshal_directive (mb, msg);
-#else
- guint32 label1, label2, label3;
- int index_var, src_var, dest_ptr, esize;
- MonoMarshalConv conv;
- gboolean is_string = FALSE;
-
- dest_ptr = cb_to_mono->mb_add_local (mb, int_type);
-
- if (eklass == cb_to_mono->mono_defaults->string_class) {
- is_string = TRUE;
- conv = cb_to_mono->get_string_to_ptr_conv (m->piinfo, spec);
- }
- else if (eklass == cb_to_mono->try_get_stringbuilder_class ()) {
- is_string = TRUE;
- conv = cb_to_mono->get_stringbuilder_to_ptr_conv (m->piinfo, spec);
- }
- else
- conv = MONO_MARSHAL_CONV_INVALID;
-
- if (is_string && conv == MONO_MARSHAL_CONV_INVALID) {
- char *msg = g_strdup_printf ("string/stringbuilder marshalling conversion %d not implemented", encoding);
- cb_to_mono->mb_emit_exception_marshal_directive (mb, msg);
- break;
- }
-
- src_var = cb_to_mono->mb_add_local (mb, object_type);
- cb_to_mono->mb_emit_ldarg (mb, argnum);
- if (m_type_is_byref (t))
- cb_to_mono->mb_emit_byte (mb, CEE_LDIND_I);
- cb_to_mono->mb_emit_stloc (mb, src_var);
-
- /* Check null */
- cb_to_mono->mb_emit_ldloc (mb, src_var);
- cb_to_mono->mb_emit_stloc (mb, conv_arg);
- cb_to_mono->mb_emit_ldloc (mb, src_var);
- label1 = cb_to_mono->mb_emit_branch (mb, CEE_BRFALSE);
-
- if (is_string)
- esize = TARGET_SIZEOF_VOID_P;
- else if (eklass == cb_to_mono->mono_defaults->char_class) /*can't call mono_marshal_type_size since it causes all sorts of asserts*/
- esize = cb_to_mono->pinvoke_is_unicode (m->piinfo) ? 2 : 1;
- else
- esize = cb_to_mono->class_native_size (eklass, NULL);
-
- /* allocate space for the native struct and store the address */
- cb_to_mono->mb_emit_icon (mb, esize);
- cb_to_mono->mb_emit_ldloc (mb, src_var);
- cb_to_mono->mb_emit_byte (mb, CEE_LDLEN);
-
- if (eklass == cb_to_mono->mono_defaults->string_class) {
- /* Make the array bigger for the terminating null */
- cb_to_mono->mb_emit_byte (mb, CEE_LDC_I4_1);
- cb_to_mono->mb_emit_byte (mb, CEE_ADD);
- }
- cb_to_mono->mb_emit_byte (mb, CEE_MUL);
- cb_to_mono->mb_emit_byte (mb, CEE_PREFIX1);
- cb_to_mono->mb_emit_byte (mb, CEE_LOCALLOC);
- cb_to_mono->mb_emit_stloc (mb, conv_arg);
-
- cb_to_mono->mb_emit_ldloc (mb, conv_arg);
- cb_to_mono->mb_emit_stloc (mb, dest_ptr);
-
- /* Emit marshalling loop */
- index_var = cb_to_mono->mb_add_local (mb, int_type);
- cb_to_mono->mb_emit_byte (mb, CEE_LDC_I4_0);
- cb_to_mono->mb_emit_stloc (mb, index_var);
- label2 = cb_to_mono->mb_get_label (mb);
- cb_to_mono->mb_emit_ldloc (mb, index_var);
- cb_to_mono->mb_emit_ldloc (mb, src_var);
- cb_to_mono->mb_emit_byte (mb, CEE_LDLEN);
- label3 = cb_to_mono->mb_emit_branch (mb, CEE_BGE);
-
- /* Emit marshalling code */
-
- if (is_string) {
- int stind_op;
- cb_to_mono->mb_emit_ldloc (mb, dest_ptr);
- cb_to_mono->mb_emit_ldloc (mb, src_var);
- cb_to_mono->mb_emit_ldloc (mb, index_var);
- cb_to_mono->mb_emit_byte (mb, CEE_LDELEM_REF);
- cb_to_mono->mb_emit_icall_id (mb, cb_to_mono->conv_to_icall (conv, &stind_op));
- cb_to_mono->mb_emit_byte (mb, GINT_TO_UINT8 (stind_op));
- } else {
- /* set the src_ptr */
- cb_to_mono->mb_emit_ldloc (mb, src_var);
- cb_to_mono->mb_emit_ldloc (mb, index_var);
- cb_to_mono->mb_emit_op (mb, CEE_LDELEMA, eklass);
- cb_to_mono->mb_emit_stloc (mb, 0);
-
- /* set dst_ptr */
- cb_to_mono->mb_emit_ldloc (mb, dest_ptr);
- cb_to_mono->mb_emit_stloc (mb, 1);
-
- /* emit valuetype conversion code */
- cb_to_mono->emit_struct_conv_full (mb, eklass, FALSE, 0, eklass == cb_to_mono->mono_defaults->char_class ? encoding : (MonoMarshalNative)-1);
- }
-
- cb_to_mono->mb_emit_add_to_local (mb, GINT_TO_UINT16 (index_var), 1);
- cb_to_mono->mb_emit_add_to_local (mb, GINT_TO_UINT16 (dest_ptr), esize);
-
- cb_to_mono->mb_emit_branch_label (mb, CEE_BR, label2);
-
- cb_to_mono->mb_patch_branch (mb, label3);
-
- if (eklass == cb_to_mono->mono_defaults->string_class) {
- /* Null terminate */
- cb_to_mono->mb_emit_ldloc (mb, dest_ptr);
- cb_to_mono->mb_emit_byte (mb, CEE_LDC_I4_0);
- cb_to_mono->mb_emit_byte (mb, CEE_STIND_I);
- }
-
- cb_to_mono->mb_patch_branch (mb, label1);
-#endif
- }
-
- break;
-
- case MARSHAL_ACTION_CONV_OUT: {
-#ifndef DISABLE_NONBLITTABLE
- gboolean need_convert, need_free;
- /* Unicode character arrays are implicitly marshalled as [Out] under MS.NET */
- need_convert = ((eklass == cb_to_mono->mono_defaults->char_class) && (encoding == MONO_NATIVE_LPWSTR)) || (eklass == cb_to_mono->try_get_stringbuilder_class ()) || (t->attrs & PARAM_ATTRIBUTE_OUT);
- need_free = cb_to_mono->need_free (m_class_get_byval_arg (eklass), m->piinfo, spec);
-
- if ((t->attrs & PARAM_ATTRIBUTE_OUT) && spec && spec->native == MONO_NATIVE_LPARRAY && spec->data.array_data.param_num != -1) {
- int param_num = spec->data.array_data.param_num;
- MonoType *param_type;
-
- param_type = m->sig->params [param_num];
-
- if (m_type_is_byref (param_type) && param_type->type != MONO_TYPE_I4) {
- char *msg = g_strdup ("Not implemented.");
- cb_to_mono->mb_emit_exception_marshal_directive (mb, msg);
- break;
- }
-
- if (m_type_is_byref (t) ) {
- cb_to_mono->mb_emit_ldarg (mb, argnum);
-
- /* Create the managed array */
- cb_to_mono->mb_emit_ldarg (mb, param_num);
- if (m_type_is_byref (m->sig->params [param_num]))
- // FIXME: Support other types
- cb_to_mono->mb_emit_byte (mb, CEE_LDIND_I4);
- cb_to_mono->mb_emit_byte (mb, CEE_CONV_OVF_I);
- cb_to_mono->mb_emit_op (mb, CEE_NEWARR, eklass);
- /* Store into argument */
- cb_to_mono->mb_emit_byte (mb, CEE_STIND_REF);
- }
- }
-
- if (need_convert || need_free) {
- /* FIXME: Optimize blittable case */
- guint32 label1, label2, label3;
- int index_var, src_ptr, loc, esize;
-
- if ((eklass == cb_to_mono->try_get_stringbuilder_class ()) || (eklass == cb_to_mono->mono_defaults->string_class))
- esize = TARGET_SIZEOF_VOID_P;
- else if (eklass == cb_to_mono->mono_defaults->char_class)
- esize = cb_to_mono->pinvoke_is_unicode (m->piinfo) ? 2 : 1;
- else
- esize = cb_to_mono->class_native_size (eklass, NULL);
- src_ptr = cb_to_mono->mb_add_local (mb, int_type);
- loc = cb_to_mono->mb_add_local (mb, int_type);
-
- /* Check null */
- cb_to_mono->mb_emit_ldarg (mb, argnum);
- if (m_type_is_byref (t))
- cb_to_mono->mb_emit_byte (mb, CEE_LDIND_I);
- label1 = cb_to_mono->mb_emit_branch (mb, CEE_BRFALSE);
-
- cb_to_mono->mb_emit_ldloc (mb, conv_arg);
- cb_to_mono->mb_emit_stloc (mb, src_ptr);
-
- /* Emit marshalling loop */
- index_var = cb_to_mono->mb_add_local (mb, int_type);
- cb_to_mono->mb_emit_byte (mb, CEE_LDC_I4_0);
- cb_to_mono->mb_emit_stloc (mb, index_var);
- label2 = cb_to_mono->mb_get_label (mb);
- cb_to_mono->mb_emit_ldloc (mb, index_var);
- cb_to_mono->mb_emit_ldarg (mb, argnum);
- if (m_type_is_byref (t))
- cb_to_mono->mb_emit_byte (mb, CEE_LDIND_REF);
- cb_to_mono->mb_emit_byte (mb, CEE_LDLEN);
- label3 = cb_to_mono->mb_emit_branch (mb, CEE_BGE);
-
- /* Emit marshalling code */
-
- if (eklass == cb_to_mono->try_get_stringbuilder_class ()) {
- gboolean need_free2;
- MonoMarshalConv conv = cb_to_mono->get_ptr_to_stringbuilder_conv (m->piinfo, spec, &need_free2);
-
- g_assert (conv != MONO_MARSHAL_CONV_INVALID);
-
- /* dest */
- cb_to_mono->mb_emit_ldarg (mb, argnum);
- if (m_type_is_byref (t))
- cb_to_mono->mb_emit_byte (mb, CEE_LDIND_I);
- cb_to_mono->mb_emit_ldloc (mb, index_var);
- cb_to_mono->mb_emit_byte (mb, CEE_LDELEM_REF);
-
- /* src */
- cb_to_mono->mb_emit_ldloc (mb, src_ptr);
- cb_to_mono->mb_emit_byte (mb, CEE_LDIND_I);
-
- cb_to_mono->mb_emit_icall_id (mb, cb_to_mono->conv_to_icall (conv, NULL));
-
- if (need_free) {
- /* src */
- cb_to_mono->mb_emit_ldloc (mb, src_ptr);
- cb_to_mono->mb_emit_byte (mb, CEE_LDIND_I);
-
- mono_mb_emit_jit_icall (mb, mono_marshal_free);
- }
- }
- else if (eklass == cb_to_mono->mono_defaults->string_class) {
- if (need_free) {
- /* src */
- cb_to_mono->mb_emit_ldloc (mb, src_ptr);
- cb_to_mono->mb_emit_byte (mb, CEE_LDIND_I);
-
- mono_mb_emit_jit_icall (mb, mono_marshal_free);
- }
- }
- else {
- if (need_convert) {
- /* set the src_ptr */
- cb_to_mono->mb_emit_ldloc (mb, src_ptr);
- cb_to_mono->mb_emit_stloc (mb, 0);
-
- /* set dst_ptr */
- cb_to_mono->mb_emit_ldarg (mb, argnum);
- if (m_type_is_byref (t))
- cb_to_mono->mb_emit_byte (mb, CEE_LDIND_REF);
- cb_to_mono->mb_emit_ldloc (mb, index_var);
- cb_to_mono->mb_emit_op (mb, CEE_LDELEMA, eklass);
- cb_to_mono->mb_emit_stloc (mb, 1);
-
- /* emit valuetype conversion code */
- cb_to_mono->emit_struct_conv_full (mb, eklass, TRUE, 0, eklass == cb_to_mono->mono_defaults->char_class ? encoding : (MonoMarshalNative)-1);
- }
-
- if (need_free) {
- cb_to_mono->mb_emit_ldloc (mb, src_ptr);
- cb_to_mono->mb_emit_stloc (mb, loc);
-
- emit_struct_free (mb, eklass, loc);
- }
- }
-
- cb_to_mono->mb_emit_add_to_local (mb, GINT_TO_UINT16 (index_var), 1);
- cb_to_mono->mb_emit_add_to_local (mb, GINT_TO_UINT16 (src_ptr), esize);
-
- cb_to_mono->mb_emit_branch_label (mb, CEE_BR, label2);
-
- cb_to_mono->mb_patch_branch (mb, label1);
- cb_to_mono->mb_patch_branch (mb, label3);
- }
-#endif
-
- if (m_class_is_blittable (eklass)) {
- /* free memory allocated (if any) by MONO_MARSHAL_CONV_ARRAY_LPARRAY */
-
- cb_to_mono->mb_emit_ldarg (mb, argnum);
- if (m_type_is_byref (t))
- cb_to_mono->mb_emit_byte (mb, CEE_LDIND_REF);
- cb_to_mono->mb_emit_ldloc (mb, conv_arg);
- cb_to_mono->mb_emit_icall_id (mb, cb_to_mono->conv_to_icall (MONO_MARSHAL_FREE_LPARRAY, NULL));
- }
-
- break;
- }
-
- case MARSHAL_ACTION_PUSH:
- if (m_type_is_byref (t))
- cb_to_mono->mb_emit_ldloc_addr (mb, conv_arg);
- else
- cb_to_mono->mb_emit_ldloc (mb, conv_arg);
- break;
-
- case MARSHAL_ACTION_CONV_RESULT: {
- cb_to_mono->mb_emit_byte (mb, CEE_POP);
- char *msg = g_strdup_printf ("Cannot marshal 'return value': Invalid managed/unmanaged type combination.");
- cb_to_mono->mb_emit_exception_marshal_directive (mb, msg);
- break;
- }
-
- case MARSHAL_ACTION_MANAGED_CONV_IN: {
- guint32 label1, label2, label3;
- int index_var, src_ptr, esize, param_num, num_elem;
- MonoMarshalConv conv;
- gboolean is_string = FALSE;
-
- conv_arg = cb_to_mono->mb_add_local (mb, object_type);
- *conv_arg_type = int_type;
-
- if (m_type_is_byref (t)) {
- char *msg = g_strdup ("Byref array marshalling to managed code is not implemented.");
- cb_to_mono->mb_emit_exception_marshal_directive (mb, msg);
- return conv_arg;
- }
- if (!spec) {
- char *msg = g_strdup ("[MarshalAs] attribute required to marshal arrays to managed code.");
- cb_to_mono->mb_emit_exception_marshal_directive (mb, msg);
- return conv_arg;
- }
-
- switch (spec->native) {
- case MONO_NATIVE_LPARRAY:
- break;
- case MONO_NATIVE_SAFEARRAY:
-#ifndef DISABLE_COM
- if (spec->data.safearray_data.elem_type != MONO_VARIANT_VARIANT) {
- char *msg = g_strdup ("Only SAFEARRAY(VARIANT) marshalling to managed code is implemented.");
- cb_to_mono->mb_emit_exception_marshal_directive (mb, msg);
- return conv_arg;
- }
- return mono_cominterop_emit_marshal_safearray (m, argnum, t, spec, conv_arg, conv_arg_type, action);
-#endif
- default: {
- char *msg = g_strdup ("Unsupported array type marshalling to managed code.");
- cb_to_mono->mb_emit_exception_marshal_directive (mb, msg);
- return conv_arg;
- }
- }
-
- /* FIXME: t is from the method which is wrapped, not the delegate type */
- /* g_assert (t->attrs & PARAM_ATTRIBUTE_IN); */
-
- param_num = spec->data.array_data.param_num;
- num_elem = spec->data.array_data.num_elem;
- if (spec->data.array_data.elem_mult == 0)
- /* param_num is not specified */
- param_num = -1;
-
- if (param_num == -1) {
- if (num_elem <= 0) {
- char *msg = g_strdup ("Either SizeConst or SizeParamIndex should be specified when marshalling arrays to managed code.");
- cb_to_mono->mb_emit_exception_marshal_directive (mb, msg);
- return conv_arg;
- }
- }
-
- /* FIXME: Optimize blittable case */
-
-#ifndef DISABLE_NONBLITTABLE
- if (eklass == cb_to_mono->mono_defaults->string_class) {
- is_string = TRUE;
- gboolean need_free;
- conv = cb_to_mono->get_ptr_to_string_conv (m->piinfo, spec, &need_free);
- }
- else if (eklass == cb_to_mono->try_get_stringbuilder_class ()) {
- is_string = TRUE;
- gboolean need_free;
- conv = cb_to_mono->get_ptr_to_stringbuilder_conv (m->piinfo, spec, &need_free);
- }
- else
- conv = MONO_MARSHAL_CONV_INVALID;
-#endif
-
- cb_to_mono->load_type_info (eklass);
-
- if (is_string)
- esize = TARGET_SIZEOF_VOID_P;
- else
- esize = cb_to_mono->class_native_size (eklass, NULL);
- src_ptr = cb_to_mono->mb_add_local (mb, int_type);
-
- cb_to_mono->mb_emit_byte (mb, CEE_LDNULL);
- cb_to_mono->mb_emit_stloc (mb, conv_arg);
-
- /* Check param index */
- if (param_num != -1) {
- if (param_num >= m->sig->param_count) {
- char *msg = g_strdup ("Array size control parameter index is out of range.");
- cb_to_mono->mb_emit_exception_marshal_directive (mb, msg);
- return conv_arg;
- }
- switch (m->sig->params [param_num]->type) {
- case MONO_TYPE_I1:
- case MONO_TYPE_U1:
- case MONO_TYPE_I2:
- case MONO_TYPE_U2:
- case MONO_TYPE_I4:
- case MONO_TYPE_U4:
- case MONO_TYPE_I:
- case MONO_TYPE_U:
- case MONO_TYPE_I8:
- case MONO_TYPE_U8:
- break;
- default: {
- char *msg = g_strdup ("Array size control parameter must be an integral type.");
- cb_to_mono->mb_emit_exception_marshal_directive (mb, msg);
- return conv_arg;
- }
- }
- }
-
- /* Check null */
- cb_to_mono->mb_emit_ldarg (mb, argnum);
- label1 = cb_to_mono->mb_emit_branch (mb, CEE_BRFALSE);
-
- cb_to_mono->mb_emit_ldarg (mb, argnum);
- cb_to_mono->mb_emit_stloc (mb, src_ptr);
-
- /* Create managed array */
- /*
- * The LPArray marshalling spec says that sometimes param_num starts
- * from 1, sometimes it starts from 0. But MS seems to allways start
- * from 0.
- */
-
- if (param_num == -1) {
- cb_to_mono->mb_emit_icon (mb, num_elem);
- } else {
- cb_to_mono->mb_emit_ldarg (mb, param_num);
- if (num_elem > 0) {
- cb_to_mono->mb_emit_icon (mb, num_elem);
- cb_to_mono->mb_emit_byte (mb, CEE_ADD);
- }
- cb_to_mono->mb_emit_byte (mb, CEE_CONV_OVF_I);
- }
-
- cb_to_mono->mb_emit_op (mb, CEE_NEWARR, eklass);
- cb_to_mono->mb_emit_stloc (mb, conv_arg);
-
- if (m_class_is_blittable (eklass)) {
- cb_to_mono->mb_emit_ldloc (mb, conv_arg);
- cb_to_mono->mb_emit_byte (mb, CEE_CONV_I);
- cb_to_mono->mb_emit_icon (mb, MONO_STRUCT_OFFSET (MonoArray, vector));
- cb_to_mono->mb_emit_byte (mb, CEE_ADD);
- cb_to_mono->mb_emit_ldarg (mb, argnum);
- cb_to_mono->mb_emit_ldloc (mb, conv_arg);
- cb_to_mono->mb_emit_byte (mb, CEE_LDLEN);
- cb_to_mono->mb_emit_icon (mb, esize);
- cb_to_mono->mb_emit_byte (mb, CEE_MUL);
- cb_to_mono->mb_emit_byte (mb, CEE_PREFIX1);
- cb_to_mono->mb_emit_byte (mb, CEE_CPBLK);
- cb_to_mono->mb_patch_branch (mb, label1);
- break;
- }
-#ifdef DISABLE_NONBLITTABLE
- else {
- char *msg = g_strdup ("Non-blittable marshalling conversion is disabled");
- cb_to_mono->mb_emit_exception_marshal_directive (mb, msg);
- }
-#else
- /* Emit marshalling loop */
- index_var = cb_to_mono->mb_add_local (mb, int_type);
- cb_to_mono->mb_emit_byte (mb, CEE_LDC_I4_0);
- cb_to_mono->mb_emit_stloc (mb, index_var);
- label2 = cb_to_mono->mb_get_label (mb);
- cb_to_mono->mb_emit_ldloc (mb, index_var);
- cb_to_mono->mb_emit_ldloc (mb, conv_arg);
- cb_to_mono->mb_emit_byte (mb, CEE_LDLEN);
- label3 = cb_to_mono->mb_emit_branch (mb, CEE_BGE);
-
- /* Emit marshalling code */
- if (is_string) {
- g_assert (conv != MONO_MARSHAL_CONV_INVALID);
-
- cb_to_mono->mb_emit_ldloc (mb, conv_arg);
- cb_to_mono->mb_emit_ldloc (mb, index_var);
-
- cb_to_mono->mb_emit_ldloc (mb, src_ptr);
- cb_to_mono->mb_emit_byte (mb, CEE_LDIND_I);
-
- cb_to_mono->mb_emit_icall_id (mb, cb_to_mono->conv_to_icall (conv, NULL));
- cb_to_mono->mb_emit_byte (mb, CEE_STELEM_REF);
- }
- else {
- char *msg = g_strdup ("Marshalling of non-string and non-blittable arrays to managed code is not implemented.");
- cb_to_mono->mb_emit_exception_marshal_directive (mb, msg);
- return conv_arg;
- }
-
- cb_to_mono->mb_emit_add_to_local (mb, GINT_TO_UINT16 (index_var), 1);
- cb_to_mono->mb_emit_add_to_local (mb, GINT_TO_UINT16 (src_ptr), esize);
-
- cb_to_mono->mb_emit_branch_label (mb, CEE_BR, label2);
-
- cb_to_mono->mb_patch_branch (mb, label1);
- cb_to_mono->mb_patch_branch (mb, label3);
-#endif
-
- break;
- }
- case MARSHAL_ACTION_MANAGED_CONV_OUT: {
- guint32 label1, label2, label3;
- int index_var, dest_ptr, esize, param_num, num_elem;
- MonoMarshalConv conv;
- gboolean is_string = FALSE;
-
- if (!spec)
- /* Already handled in CONV_IN */
- break;
-
- /* These are already checked in CONV_IN */
- g_assert (!m_type_is_byref (t));
- g_assert (spec->native == MONO_NATIVE_LPARRAY);
- g_assert (t->attrs & PARAM_ATTRIBUTE_OUT);
-
- param_num = spec->data.array_data.param_num;
- num_elem = spec->data.array_data.num_elem;
-
- if (spec->data.array_data.elem_mult == 0)
- /* param_num is not specified */
- param_num = -1;
-
- if (param_num == -1) {
- if (num_elem <= 0) {
- g_assert_not_reached ();
- }
- }
-
- /* FIXME: Optimize blittable case */
-
-#ifndef DISABLE_NONBLITTABLE
- if (eklass == cb_to_mono->mono_defaults->string_class) {
- is_string = TRUE;
- conv = cb_to_mono->get_string_to_ptr_conv (m->piinfo, spec);
- }
- else if (eklass == cb_to_mono->try_get_stringbuilder_class ()) {
- is_string = TRUE;
- conv = cb_to_mono->get_stringbuilder_to_ptr_conv (m->piinfo, spec);
- }
- else
- conv = MONO_MARSHAL_CONV_INVALID;
-#endif
-
- cb_to_mono->load_type_info (eklass);
-
- if (is_string)
- esize = TARGET_SIZEOF_VOID_P;
- else
- esize = cb_to_mono->class_native_size (eklass, NULL);
-
- dest_ptr = cb_to_mono->mb_add_local (mb, int_type);
-
- /* Check null */
- cb_to_mono->mb_emit_ldloc (mb, conv_arg);
- label1 = cb_to_mono->mb_emit_branch (mb, CEE_BRFALSE);
-
- cb_to_mono->mb_emit_ldarg (mb, argnum);
- cb_to_mono->mb_emit_stloc (mb, dest_ptr);
-
- if (m_class_is_blittable (eklass)) {
- /* dest */
- cb_to_mono->mb_emit_ldarg (mb, argnum);
- /* src */
- cb_to_mono->mb_emit_ldloc (mb, conv_arg);
- cb_to_mono->mb_emit_byte (mb, CEE_CONV_I);
- cb_to_mono->mb_emit_icon (mb, MONO_STRUCT_OFFSET (MonoArray, vector));
- cb_to_mono->mb_emit_byte (mb, CEE_ADD);
- /* length */
- cb_to_mono->mb_emit_ldloc (mb, conv_arg);
- cb_to_mono->mb_emit_byte (mb, CEE_LDLEN);
- cb_to_mono->mb_emit_icon (mb, esize);
- cb_to_mono->mb_emit_byte (mb, CEE_MUL);
- cb_to_mono->mb_emit_byte (mb, CEE_PREFIX1);
- cb_to_mono->mb_emit_byte (mb, CEE_CPBLK);
- cb_to_mono->mb_patch_branch (mb, label1);
- break;
- }
-
-#ifndef DISABLE_NONBLITTABLE
- /* Emit marshalling loop */
- index_var = cb_to_mono->mb_add_local (mb, int_type);
- cb_to_mono->mb_emit_byte (mb, CEE_LDC_I4_0);
- cb_to_mono->mb_emit_stloc (mb, index_var);
- label2 = cb_to_mono->mb_get_label (mb);
- cb_to_mono->mb_emit_ldloc (mb, index_var);
- cb_to_mono->mb_emit_ldloc (mb, conv_arg);
- cb_to_mono->mb_emit_byte (mb, CEE_LDLEN);
- label3 = cb_to_mono->mb_emit_branch (mb, CEE_BGE);
-
- /* Emit marshalling code */
- if (is_string) {
- int stind_op;
- g_assert (conv != MONO_MARSHAL_CONV_INVALID);
-
- /* dest */
- cb_to_mono->mb_emit_ldloc (mb, dest_ptr);
-
- /* src */
- cb_to_mono->mb_emit_ldloc (mb, conv_arg);
- cb_to_mono->mb_emit_ldloc (mb, index_var);
-
- cb_to_mono->mb_emit_byte (mb, CEE_LDELEM_REF);
-
- cb_to_mono->mb_emit_icall_id (mb, cb_to_mono->conv_to_icall (conv, &stind_op));
- cb_to_mono->mb_emit_byte (mb, GINT_TO_UINT8 (stind_op));
- }
- else {
- char *msg = g_strdup ("Marshalling of non-string and non-blittable arrays to managed code is not implemented.");
- cb_to_mono->mb_emit_exception_marshal_directive (mb, msg);
- return conv_arg;
- }
-
- cb_to_mono->mb_emit_add_to_local (mb, GINT_TO_UINT16 (index_var), 1);
- cb_to_mono->mb_emit_add_to_local (mb, GINT_TO_UINT16 (dest_ptr), esize);
-
- cb_to_mono->mb_emit_branch_label (mb, CEE_BR, label2);
-
- cb_to_mono->mb_patch_branch (mb, label1);
- cb_to_mono->mb_patch_branch (mb, label3);
-#endif
-
- break;
- }
- case MARSHAL_ACTION_MANAGED_CONV_RESULT: {
-#ifndef DISABLE_NONBLITTABLE
- guint32 label1, label2, label3;
- int index_var, src, dest, esize;
- MonoMarshalConv conv = MONO_MARSHAL_CONV_INVALID;
- gboolean is_string = FALSE;
-
- g_assert (!m_type_is_byref (t));
-
- cb_to_mono->load_type_info (eklass);
-
- if (eklass == cb_to_mono->mono_defaults->string_class) {
- is_string = TRUE;
- conv = cb_to_mono->get_string_to_ptr_conv (m->piinfo, spec);
- }
- else {
- g_assert_not_reached ();
- }
-
- if (is_string)
- esize = TARGET_SIZEOF_VOID_P;
- else if (eklass == cb_to_mono->mono_defaults->char_class)
- esize = cb_to_mono->pinvoke_is_unicode (m->piinfo) ? 2 : 1;
- else
- esize = cb_to_mono->class_native_size (eklass, NULL);
-
- src = cb_to_mono->mb_add_local (mb, object_type);
- dest = cb_to_mono->mb_add_local (mb, int_type);
-
- cb_to_mono->mb_emit_stloc (mb, src);
- cb_to_mono->mb_emit_ldloc (mb, src);
- cb_to_mono->mb_emit_stloc (mb, 3);
-
- /* Check for null */
- cb_to_mono->mb_emit_ldloc (mb, src);
- label1 = cb_to_mono->mb_emit_branch (mb, CEE_BRFALSE);
-
- /* Allocate native array */
- cb_to_mono->mb_emit_icon (mb, esize);
- cb_to_mono->mb_emit_ldloc (mb, src);
- cb_to_mono->mb_emit_byte (mb, CEE_LDLEN);
-
- if (eklass == cb_to_mono->mono_defaults->string_class) {
- /* Make the array bigger for the terminating null */
- cb_to_mono->mb_emit_byte (mb, CEE_LDC_I4_1);
- cb_to_mono->mb_emit_byte (mb, CEE_ADD);
- }
- cb_to_mono->mb_emit_byte (mb, CEE_MUL);
- mono_mb_emit_jit_icall (mb, ves_icall_marshal_alloc);
- cb_to_mono->mb_emit_stloc (mb, dest);
- cb_to_mono->mb_emit_ldloc (mb, dest);
- cb_to_mono->mb_emit_stloc (mb, 3);
-
- /* Emit marshalling loop */
- index_var = cb_to_mono->mb_add_local (mb, int_type);
- cb_to_mono->mb_emit_byte (mb, CEE_LDC_I4_0);
- cb_to_mono->mb_emit_stloc (mb, index_var);
- label2 = cb_to_mono->mb_get_label (mb);
- cb_to_mono->mb_emit_ldloc (mb, index_var);
- cb_to_mono->mb_emit_ldloc (mb, src);
- cb_to_mono->mb_emit_byte (mb, CEE_LDLEN);
- label3 = cb_to_mono->mb_emit_branch (mb, CEE_BGE);
-
- /* Emit marshalling code */
- if (is_string) {
- int stind_op;
- g_assert (conv != MONO_MARSHAL_CONV_INVALID);
-
- /* dest */
- cb_to_mono->mb_emit_ldloc (mb, dest);
-
- /* src */
- cb_to_mono->mb_emit_ldloc (mb, src);
- cb_to_mono->mb_emit_ldloc (mb, index_var);
-
- cb_to_mono->mb_emit_byte (mb, CEE_LDELEM_REF);
-
- cb_to_mono->mb_emit_icall_id (mb, cb_to_mono->conv_to_icall (conv, &stind_op));
- cb_to_mono->mb_emit_byte (mb, GINT_TO_UINT8 (stind_op));
- }
- else {
- char *msg = g_strdup ("Marshalling of non-string arrays to managed code is not implemented.");
- cb_to_mono->mb_emit_exception_marshal_directive (mb, msg);
- return conv_arg;
- }
-
- cb_to_mono->mb_emit_add_to_local (mb, GINT_TO_UINT16 (index_var), 1);
- cb_to_mono->mb_emit_add_to_local (mb, GINT_TO_UINT16 (dest), esize);
-
- cb_to_mono->mb_emit_branch_label (mb, CEE_BR, label2);
-
- cb_to_mono->mb_patch_branch (mb, label3);
- cb_to_mono->mb_patch_branch (mb, label1);
-#endif
- break;
- }
- default:
- g_assert_not_reached ();
- }
- return conv_arg;
-}
-
-static gboolean
-emit_native_wrapper_validate_signature (MonoMethodBuilder *mb, MonoMethodSignature* sig, MonoMarshalSpec** mspecs)
-{
- if (mspecs) {
- for (int i = 0; i < sig->param_count; i ++) {
- if (mspecs [i + 1] && mspecs [i + 1]->native == MONO_NATIVE_CUSTOM) {
- if (!mspecs [i + 1]->data.custom_data.custom_name || *mspecs [i + 1]->data.custom_data.custom_name == '\0') {
- cb_to_mono->mb_emit_exception_full (mb, "System", "TypeLoadException", g_strdup ("Missing ICustomMarshaler type"));
- return FALSE;
- }
-
- switch (sig->params[i]->type) {
- case MONO_TYPE_CLASS:
- case MONO_TYPE_OBJECT:
- case MONO_TYPE_STRING:
- case MONO_TYPE_ARRAY:
- case MONO_TYPE_SZARRAY:
- case MONO_TYPE_VALUETYPE:
- break;
-
- default:
- cb_to_mono->mb_emit_exception_full (mb, "System.Runtime.InteropServices", "MarshalDirectiveException", g_strdup_printf ("custom marshalling of type %x is currently not supported", sig->params[i]->type));
- return FALSE;
- }
- }
- else if (sig->params[i]->type == MONO_TYPE_VALUETYPE) {
- MonoMarshalType *marshal_type = mono_marshal_load_type_info (mono_class_from_mono_type_internal (sig->params [i]));
- for (guint32 field_idx = 0; field_idx < marshal_type->num_fields; ++field_idx) {
- if (marshal_type->fields [field_idx].mspec && marshal_type->fields [field_idx].mspec->native == MONO_NATIVE_CUSTOM) {
- cb_to_mono->mb_emit_exception_full (mb, "System", "TypeLoadException", g_strdup ("Value type includes custom marshaled fields"));
- return FALSE;
- }
- }
- }
- }
- }
-
- return TRUE;
-}
-
-static int
-emit_marshal_ptr_ilgen (EmitMarshalContext *m, int argnum, MonoType *t,
- MonoMarshalSpec *spec, int conv_arg,
- MonoType **conv_arg_type, MarshalAction action)
-{
- MonoMethodBuilder *mb = m->mb;
- switch (action) {
- case MARSHAL_ACTION_CONV_IN:
- /* MS seems to allow this in some cases, ie. bxc #158 */
- /*
- if (MONO_TYPE_ISSTRUCT (t->data.type) && !mono_class_from_mono_type_internal (t->data.type)->blittable) {
- char *msg = g_strdup_printf ("Can not marshal 'parameter #%d': Pointers can not reference marshaled structures. Use byref instead.", argnum + 1);
- cb_to_mono->mb_emit_exception_marshal_directive (m->mb, msg);
- }
- */
- break;
-
- case MARSHAL_ACTION_PUSH:
- cb_to_mono->mb_emit_ldarg (mb, argnum);
- break;
-
- case MARSHAL_ACTION_CONV_RESULT:
- /* no conversions necessary */
- cb_to_mono->mb_emit_stloc (mb, 3);
- break;
-
- default:
- break;
- }
- return conv_arg;
-}
-
-static int
-emit_marshal_boolean_ilgen (EmitMarshalContext *m, int argnum, MonoType *t,
- MonoMarshalSpec *spec,
- int conv_arg, MonoType **conv_arg_type,
- MarshalAction action)
-{
- MonoMethodBuilder *mb = m->mb;
- MonoType *int_type = cb_to_mono->get_int_type ();
- MonoType *boolean_type = m_class_get_byval_arg (cb_to_mono->mono_defaults->boolean_class);
-
- switch (action) {
- case MARSHAL_ACTION_CONV_IN: {
- MonoType *local_type;
- int label_false;
- guint8 ldc_op = CEE_LDC_I4_1;
-
- local_type = cb_to_mono->boolean_conv_in_get_local_type (spec, &ldc_op);
- if (m_type_is_byref (t))
- *conv_arg_type = int_type;
- else
- *conv_arg_type = local_type;
- conv_arg = cb_to_mono->mb_add_local (mb, local_type);
-
- cb_to_mono->mb_emit_ldarg (mb, argnum);
- if (m_type_is_byref (t))
- cb_to_mono->mb_emit_byte (mb, CEE_LDIND_I1);
- label_false = cb_to_mono->mb_emit_branch (mb, CEE_BRFALSE);
- cb_to_mono->mb_emit_byte (mb, ldc_op);
- cb_to_mono->mb_emit_stloc (mb, conv_arg);
- cb_to_mono->mb_patch_branch (mb, label_false);
-
- break;
- }
-
- case MARSHAL_ACTION_CONV_OUT:
- {
- int label_false, label_end;
- if (!m_type_is_byref (t))
- break;
-
- cb_to_mono->mb_emit_ldarg (mb, argnum);
- cb_to_mono->mb_emit_ldloc (mb, conv_arg);
-
- label_false = cb_to_mono->mb_emit_branch (mb, CEE_BRFALSE);
- cb_to_mono->mb_emit_byte (mb, CEE_LDC_I4_1);
-
- label_end = cb_to_mono->mb_emit_branch (mb, CEE_BR);
- cb_to_mono->mb_patch_branch (mb, label_false);
- cb_to_mono->mb_emit_byte (mb, CEE_LDC_I4_0);
- cb_to_mono->mb_patch_branch (mb, label_end);
-
- cb_to_mono->mb_emit_byte (mb, CEE_STIND_I1);
- break;
- }
-
- case MARSHAL_ACTION_PUSH:
- if (m_type_is_byref (t))
- cb_to_mono->mb_emit_ldloc_addr (mb, conv_arg);
- else if (conv_arg)
- cb_to_mono->mb_emit_ldloc (mb, conv_arg);
- else
- cb_to_mono->mb_emit_ldarg (mb, argnum);
- break;
-
- case MARSHAL_ACTION_CONV_RESULT:
- /* maybe we need to make sure that it fits within 8 bits */
- cb_to_mono->mb_emit_stloc (mb, 3);
- break;
-
- case MARSHAL_ACTION_MANAGED_CONV_IN: {
- MonoClass* conv_arg_class = cb_to_mono->mono_defaults->int32_class;
- guint8 ldop = CEE_LDIND_I4;
- int label_null, label_false;
-
- conv_arg_class = cb_to_mono->boolean_managed_conv_in_get_conv_arg_class (spec, &ldop);
- conv_arg = cb_to_mono->mb_add_local (mb, boolean_type);
-
- if (m_type_is_byref (t))
- *conv_arg_type = m_class_get_this_arg (conv_arg_class);
- else
- *conv_arg_type = m_class_get_byval_arg (conv_arg_class);
-
-
- cb_to_mono->mb_emit_ldarg (mb, argnum);
-
- /* Check null */
- if (m_type_is_byref (t)) {
- label_null = cb_to_mono->mb_emit_branch (mb, CEE_BRFALSE);
- cb_to_mono->mb_emit_ldarg (mb, argnum);
- cb_to_mono->mb_emit_byte (mb, ldop);
- } else
- label_null = 0;
-
- label_false = cb_to_mono->mb_emit_branch (mb, CEE_BRFALSE);
- cb_to_mono->mb_emit_byte (mb, CEE_LDC_I4_1);
- cb_to_mono->mb_emit_stloc (mb, conv_arg);
- cb_to_mono->mb_patch_branch (mb, label_false);
-
- if (m_type_is_byref (t))
- cb_to_mono->mb_patch_branch (mb, label_null);
- break;
- }
-
- case MARSHAL_ACTION_MANAGED_CONV_OUT: {
- guint8 stop = CEE_STIND_I4;
- guint8 ldc_op = CEE_LDC_I4_1;
- int label_null,label_false, label_end;
-
- if (!m_type_is_byref (t))
- break;
- if (spec) {
- switch (spec->native) {
- case MONO_NATIVE_I1:
- case MONO_NATIVE_U1:
- stop = CEE_STIND_I1;
- break;
- case MONO_NATIVE_VARIANTBOOL:
- stop = CEE_STIND_I2;
- ldc_op = CEE_LDC_I4_M1;
- break;
- default:
- break;
- }
- }
-
- /* Check null */
- cb_to_mono->mb_emit_ldarg (mb, argnum);
- label_null = cb_to_mono->mb_emit_branch (mb, CEE_BRFALSE);
-
- cb_to_mono->mb_emit_ldarg (mb, argnum);
- cb_to_mono->mb_emit_ldloc (mb, conv_arg);
-
- label_false = cb_to_mono->mb_emit_branch (mb, CEE_BRFALSE);
- cb_to_mono->mb_emit_byte (mb, ldc_op);
- label_end = cb_to_mono->mb_emit_branch (mb, CEE_BR);
-
- cb_to_mono->mb_patch_branch (mb, label_false);
- cb_to_mono->mb_emit_byte (mb, CEE_LDC_I4_0);
- cb_to_mono->mb_patch_branch (mb, label_end);
-
- cb_to_mono->mb_emit_byte (mb, stop);
- cb_to_mono->mb_patch_branch (mb, label_null);
- break;
- }
-
- default:
- g_assert_not_reached ();
- }
- return conv_arg;
-}
-
-static int
-emit_marshal_char_ilgen (EmitMarshalContext *m, int argnum, MonoType *t,
- MonoMarshalSpec *spec, int conv_arg,
- MonoType **conv_arg_type, MarshalAction action)
-{
- MonoMethodBuilder *mb = m->mb;
-
- switch (action) {
- case MARSHAL_ACTION_PUSH:
- /* fixme: dont know how to marshal that. We cant simply
- * convert it to a one byte UTF8 character, because an
- * unicode character may need more that one byte in UTF8 */
- cb_to_mono->mb_emit_ldarg (mb, argnum);
- break;
-
- case MARSHAL_ACTION_CONV_RESULT:
- /* fixme: we need conversions here */
- cb_to_mono->mb_emit_stloc (mb, 3);
- break;
-
- default:
- break;
- }
- return conv_arg;
-}
-
-static int
-emit_marshal_custom_ilgen_throw_exception (MonoMethodBuilder *mb, const char *exc_nspace, const char *exc_name, const char *msg, MarshalAction action)
-{
- /* Throw exception and emit compensation code, if neccesary */
- switch (action) {
- case MARSHAL_ACTION_CONV_IN:
- case MARSHAL_ACTION_MANAGED_CONV_IN:
- case MARSHAL_ACTION_CONV_RESULT:
- case MARSHAL_ACTION_MANAGED_CONV_RESULT:
- if ((action == MARSHAL_ACTION_CONV_RESULT) || (action == MARSHAL_ACTION_MANAGED_CONV_RESULT))
- cb_to_mono->mb_emit_byte (mb, CEE_POP);
-
- cb_to_mono->mb_emit_exception_full (mb, exc_nspace, exc_name, msg);
-
- break;
- case MARSHAL_ACTION_PUSH:
- cb_to_mono->mb_emit_byte (mb, CEE_LDNULL);
- break;
- default:
- break;
- }
-
- return 0;
-}
-
-static int
-emit_marshal_custom_ilgen (EmitMarshalContext *m, int argnum, MonoType *t,
- MonoMarshalSpec *spec,
- int conv_arg, MonoType **conv_arg_type,
- MarshalAction action)
-{
- ERROR_DECL (error);
- MonoType *mtype;
- MonoClass *mklass;
- static MonoClass *ICustomMarshaler = NULL;
- static MonoMethod *cleanup_native, *cleanup_managed;
- static MonoMethod *marshal_managed_to_native, *marshal_native_to_managed;
- MonoMethodBuilder *mb = m->mb;
- MonoAssemblyLoadContext *alc = mono_alc_get_ambient ();
- guint32 loc1;
- int pos2;
-
- MonoType *int_type = cb_to_mono->get_int_type ();
- MonoType *object_type = cb_to_mono->get_object_type ();
-
- if (!ICustomMarshaler) {
- MonoClass *klass = mono_class_try_get_icustom_marshaler_class ();
- if (!klass)
- return emit_marshal_custom_ilgen_throw_exception (mb, "System", "ApplicationException", g_strdup ("Current profile doesn't support ICustomMarshaler"), action);
-
- cleanup_native = cb_to_mono->get_method_nofail (klass, "CleanUpNativeData", 1, 0);
- g_assert (cleanup_native);
-
- cleanup_managed = cb_to_mono->get_method_nofail (klass, "CleanUpManagedData", 1, 0);
- g_assert (cleanup_managed);
-
- marshal_managed_to_native = cb_to_mono->get_method_nofail (klass, "MarshalManagedToNative", 1, 0);
- g_assert (marshal_managed_to_native);
-
- marshal_native_to_managed = cb_to_mono->get_method_nofail (klass, "MarshalNativeToManaged", 1, 0);
- g_assert (marshal_native_to_managed);
-
- cb_to_mono->memory_barrier ();
- ICustomMarshaler = klass;
- }
-
- if (spec->data.custom_data.image)
- mtype = cb_to_mono->reflection_type_from_name_checked (spec->data.custom_data.custom_name, alc, spec->data.custom_data.image, error);
- else
- mtype = cb_to_mono->reflection_type_from_name_checked (spec->data.custom_data.custom_name, alc, m->image, error);
-
- if (!mtype)
- return emit_marshal_custom_ilgen_throw_exception (mb, "System", "TypeLoadException", g_strdup ("Failed to load ICustomMarshaler type"), action);
-
- mklass = mono_class_from_mono_type_internal (mtype);
- g_assert (mklass != NULL);
-
- switch (action) {
- case MARSHAL_ACTION_CONV_IN:
- switch (t->type) {
- case MONO_TYPE_CLASS:
- case MONO_TYPE_OBJECT:
- case MONO_TYPE_STRING:
- case MONO_TYPE_ARRAY:
- case MONO_TYPE_SZARRAY:
- case MONO_TYPE_VALUETYPE:
- break;
-
- default:
- g_warning ("custom marshalling of type %x is currently not supported", t->type);
- g_assert_not_reached ();
- break;
- }
-
- conv_arg = cb_to_mono->mb_add_local (mb, int_type);
-
- cb_to_mono->mb_emit_byte (mb, CEE_LDNULL);
- cb_to_mono->mb_emit_stloc (mb, conv_arg);
-
- if (m_type_is_byref (t) && (t->attrs & PARAM_ATTRIBUTE_OUT))
- break;
-
- /* Minic MS.NET behavior */
- if (!m_type_is_byref (t) && (t->attrs & PARAM_ATTRIBUTE_OUT) && !(t->attrs & PARAM_ATTRIBUTE_IN))
- break;
-
- /* Check for null */
- cb_to_mono->mb_emit_ldarg (mb, argnum);
- if (m_type_is_byref (t))
- cb_to_mono->mb_emit_byte (mb, CEE_LDIND_I);
- pos2 = cb_to_mono->mb_emit_branch (mb, CEE_BRFALSE);
-
- cb_to_mono->emit_marshal_custom_get_instance (mb, mklass, spec);
-
- cb_to_mono->mb_emit_ldarg (mb, argnum);
- if (m_type_is_byref (t))
- cb_to_mono->mb_emit_byte (mb, CEE_LDIND_REF);
-
- if (t->type == MONO_TYPE_VALUETYPE) {
- /*
- * Since we can't determine the type of the argument, we
- * will assume the unmanaged function takes a pointer.
- */
- *conv_arg_type = int_type;
-
- cb_to_mono->mb_emit_op (mb, CEE_BOX, mono_class_from_mono_type_internal (t));
- }
-
- cb_to_mono->mb_emit_op (mb, CEE_CALLVIRT, marshal_managed_to_native);
- cb_to_mono->mb_emit_stloc (mb, conv_arg);
-
- cb_to_mono->mb_patch_branch (mb, pos2);
- break;
-
- case MARSHAL_ACTION_CONV_OUT:
- /* Check for null */
- cb_to_mono->mb_emit_ldloc (mb, conv_arg);
- pos2 = cb_to_mono->mb_emit_branch (mb, CEE_BRFALSE);
-
- if (m_type_is_byref (t) && !(t->attrs & PARAM_ATTRIBUTE_OUT)) {
- cb_to_mono->mb_emit_ldarg (mb, argnum);
-
- cb_to_mono->emit_marshal_custom_get_instance (mb, mklass, spec);
- cb_to_mono->mb_emit_byte (mb, CEE_DUP);
-
- cb_to_mono->mb_emit_ldarg (mb, argnum);
- cb_to_mono->mb_emit_byte (mb, CEE_LDIND_REF);
- cb_to_mono->mb_emit_op (mb, CEE_CALLVIRT, cleanup_managed);
-
- cb_to_mono->mb_emit_ldloc (mb, conv_arg);
- cb_to_mono->mb_emit_op (mb, CEE_CALLVIRT, marshal_native_to_managed);
- cb_to_mono->mb_emit_byte (mb, CEE_STIND_REF);
- } else if (m_type_is_byref (t) && (t->attrs & PARAM_ATTRIBUTE_OUT)) {
- cb_to_mono->mb_emit_ldarg (mb, argnum);
-
- cb_to_mono->emit_marshal_custom_get_instance (mb, mklass, spec);
-
- cb_to_mono->mb_emit_ldloc (mb, conv_arg);
- cb_to_mono->mb_emit_op (mb, CEE_CALLVIRT, marshal_native_to_managed);
- cb_to_mono->mb_emit_byte (mb, CEE_STIND_REF);
- } else if (t->attrs & PARAM_ATTRIBUTE_OUT) {
- cb_to_mono->emit_marshal_custom_get_instance (mb, mklass, spec);
-
- cb_to_mono->mb_emit_ldloc (mb, conv_arg);
- cb_to_mono->mb_emit_op (mb, CEE_CALLVIRT, marshal_native_to_managed);
- /* We have nowhere to store the result */
- cb_to_mono->mb_emit_byte (mb, CEE_POP);
- }
-
- // Only call cleanup_native if MARSHAL_ACTION_CONV_IN called marshal_managed_to_native.
- if (!(m_type_is_byref (t) && (t->attrs & PARAM_ATTRIBUTE_OUT)) &&
- !(!m_type_is_byref (t) && (t->attrs & PARAM_ATTRIBUTE_OUT) && !(t->attrs & PARAM_ATTRIBUTE_IN))) {
- cb_to_mono->emit_marshal_custom_get_instance (mb, mklass, spec);
-
- cb_to_mono->mb_emit_ldloc (mb, conv_arg);
-
- cb_to_mono->mb_emit_op (mb, CEE_CALLVIRT, cleanup_native);
- }
-
- cb_to_mono->mb_patch_branch (mb, pos2);
- break;
-
- case MARSHAL_ACTION_PUSH:
- if (m_type_is_byref (t))
- cb_to_mono->mb_emit_ldloc_addr (mb, conv_arg);
- else
- cb_to_mono->mb_emit_ldloc (mb, conv_arg);
- break;
-
- case MARSHAL_ACTION_CONV_RESULT:
- cb_to_mono->mb_emit_stloc (mb, 3);
-
- /* Check for null */
- cb_to_mono->mb_emit_ldloc (mb, 3);
- pos2 = cb_to_mono->mb_emit_branch (mb, CEE_BRFALSE);
-
- cb_to_mono->emit_marshal_custom_get_instance (mb, mklass, spec);
-
- cb_to_mono->mb_emit_ldloc (mb, 3);
- cb_to_mono->mb_emit_op (mb, CEE_CALLVIRT, marshal_native_to_managed);
- cb_to_mono->mb_emit_stloc (mb, 3);
-
- cb_to_mono->mb_patch_branch (mb, pos2);
- break;
-
- case MARSHAL_ACTION_MANAGED_CONV_IN:
- switch (t->type) {
- case MONO_TYPE_CLASS:
- case MONO_TYPE_OBJECT:
- case MONO_TYPE_STRING:
- case MONO_TYPE_ARRAY:
- case MONO_TYPE_SZARRAY:
- case MONO_TYPE_VALUETYPE:
- case MONO_TYPE_BOOLEAN:
- break;
-
- default:
- g_warning ("custom marshalling of type %x is currently not supported", t->type);
- g_assert_not_reached ();
- break;
- }
-
- conv_arg = cb_to_mono->mb_add_local (mb, object_type);
-
- cb_to_mono->mb_emit_byte (mb, CEE_LDNULL);
- cb_to_mono->mb_emit_stloc (mb, conv_arg);
-
- if (m_type_is_byref (t) && t->attrs & PARAM_ATTRIBUTE_OUT)
- break;
-
- /* Check for null */
- cb_to_mono->mb_emit_ldarg (mb, argnum);
- if (m_type_is_byref (t))
- cb_to_mono->mb_emit_byte (mb, CEE_LDIND_I);
- pos2 = cb_to_mono->mb_emit_branch (mb, CEE_BRFALSE);
-
- cb_to_mono->emit_marshal_custom_get_instance (mb, mklass, spec);
-
- cb_to_mono->mb_emit_ldarg (mb, argnum);
- if (m_type_is_byref (t))
- cb_to_mono->mb_emit_byte (mb, CEE_LDIND_I);
-
- cb_to_mono->mb_emit_op (mb, CEE_CALLVIRT, marshal_native_to_managed);
- cb_to_mono->mb_emit_stloc (mb, conv_arg);
-
- cb_to_mono->mb_patch_branch (mb, pos2);
- break;
-
- case MARSHAL_ACTION_MANAGED_CONV_RESULT:
- g_assert (!m_type_is_byref (t));
-
- loc1 = cb_to_mono->mb_add_local (mb, object_type);
-
- cb_to_mono->mb_emit_stloc (mb, 3);
-
- cb_to_mono->mb_emit_ldloc (mb, 3);
- cb_to_mono->mb_emit_stloc (mb, loc1);
-
- /* Check for null */
- cb_to_mono->mb_emit_ldloc (mb, 3);
- pos2 = cb_to_mono->mb_emit_branch (mb, CEE_BRFALSE);
-
- cb_to_mono->emit_marshal_custom_get_instance (mb, mklass, spec);
- cb_to_mono->mb_emit_byte (mb, CEE_DUP);
-
- cb_to_mono->mb_emit_ldloc (mb, 3);
- cb_to_mono->mb_emit_op (mb, CEE_CALLVIRT, marshal_managed_to_native);
- cb_to_mono->mb_emit_stloc (mb, 3);
-
- cb_to_mono->mb_emit_ldloc (mb, loc1);
- cb_to_mono->mb_emit_op (mb, CEE_CALLVIRT, cleanup_managed);
-
- cb_to_mono->mb_patch_branch (mb, pos2);
- break;
-
- case MARSHAL_ACTION_MANAGED_CONV_OUT:
-
- /* Check for null */
- cb_to_mono->mb_emit_ldloc (mb, conv_arg);
- pos2 = cb_to_mono->mb_emit_branch (mb, CEE_BRFALSE);
-
- if (m_type_is_byref (t)) {
- cb_to_mono->mb_emit_ldarg (mb, argnum);
-
- cb_to_mono->emit_marshal_custom_get_instance (mb, mklass, spec);
-
- cb_to_mono->mb_emit_ldloc (mb, conv_arg);
- cb_to_mono->mb_emit_op (mb, CEE_CALLVIRT, marshal_managed_to_native);
- cb_to_mono->mb_emit_byte (mb, CEE_STIND_I);
- }
-
- // Only call cleanup_managed if MARSHAL_ACTION_MANAGED_CONV_IN called marshal_native_to_managed.
- if (!(m_type_is_byref (t) && (t->attrs & PARAM_ATTRIBUTE_OUT))) {
- cb_to_mono->emit_marshal_custom_get_instance (mb, mklass, spec);
- cb_to_mono->mb_emit_ldloc (mb, conv_arg);
- cb_to_mono->mb_emit_op (mb, CEE_CALLVIRT, cleanup_managed);
- }
-
- cb_to_mono->mb_patch_branch (mb, pos2);
- break;
-
- default:
- g_assert_not_reached ();
- }
- return conv_arg;
-}
-
-static int
-emit_marshal_asany_ilgen (EmitMarshalContext *m, int argnum, MonoType *t,
- MonoMarshalSpec *spec,
- int conv_arg, MonoType **conv_arg_type,
- MarshalAction action)
-{
- MonoMethodBuilder *mb = m->mb;
-
- MonoType *int_type = cb_to_mono->get_int_type ();
- switch (action) {
- case MARSHAL_ACTION_CONV_IN: {
- MonoMarshalNative encoding = cb_to_mono->get_string_encoding (m->piinfo, NULL);
-
- g_assert (t->type == MONO_TYPE_OBJECT);
- g_assert (!m_type_is_byref (t));
-
- conv_arg = cb_to_mono->mb_add_local (mb, int_type);
- cb_to_mono->mb_emit_ldarg (mb, argnum);
- cb_to_mono->mb_emit_icon (mb, encoding);
- cb_to_mono->mb_emit_icon (mb, t->attrs);
- mono_mb_emit_jit_icall (mb, mono_marshal_asany);
- cb_to_mono->mb_emit_stloc (mb, conv_arg);
- break;
- }
-
- case MARSHAL_ACTION_PUSH:
- cb_to_mono->mb_emit_ldloc (mb, conv_arg);
- break;
-
- case MARSHAL_ACTION_CONV_OUT: {
- MonoMarshalNative encoding = cb_to_mono->get_string_encoding (m->piinfo, NULL);
-
- cb_to_mono->mb_emit_ldarg (mb, argnum);
- cb_to_mono->mb_emit_ldloc (mb, conv_arg);
- cb_to_mono->mb_emit_icon (mb, encoding);
- cb_to_mono->mb_emit_icon (mb, t->attrs);
- mono_mb_emit_jit_icall (mb, mono_marshal_free_asany);
- break;
- }
-
- default:
- g_assert_not_reached ();
- }
- return conv_arg;
-}
-
-static int
-emit_marshal_vtype_ilgen (EmitMarshalContext *m, int argnum, MonoType *t,
- MonoMarshalSpec *spec,
- int conv_arg, MonoType **conv_arg_type,
- MarshalAction action)
-{
- MonoMethodBuilder *mb = m->mb;
- MonoClass *klass, *date_time_class;
- int pos = 0, pos2;
-
- klass = mono_class_from_mono_type_internal (t);
-
- date_time_class = mono_class_get_date_time_class ();
-
- MonoType *int_type = cb_to_mono->get_int_type ();
- MonoType *double_type = m_class_get_byval_arg (cb_to_mono->mono_defaults->double_class);
-
- switch (action) {
- case MARSHAL_ACTION_CONV_IN:
- if (klass == date_time_class) {
- /* Convert it to an OLE DATE type */
-
- conv_arg = cb_to_mono->mb_add_local (mb, double_type);
-
- if (m_type_is_byref (t)) {
- cb_to_mono->mb_emit_ldarg (mb, argnum);
- pos = cb_to_mono->mb_emit_branch (mb, CEE_BRFALSE);
- }
-
- if (!(m_type_is_byref (t) && !(t->attrs & PARAM_ATTRIBUTE_IN) && (t->attrs & PARAM_ATTRIBUTE_OUT))) {
- if (!m_type_is_byref (t))
- m->csig->params [argnum - m->csig->hasthis] = double_type;
-
- MONO_STATIC_POINTER_INIT (MonoMethod, to_oadate)
- to_oadate = cb_to_mono->get_method_nofail (date_time_class, "ToOADate", 0, 0);
- g_assert (to_oadate);
- MONO_STATIC_POINTER_INIT_END (MonoMethod, to_oadate)
-
- cb_to_mono->mb_emit_ldarg_addr (mb, argnum);
- cb_to_mono->mb_emit_managed_call (mb, to_oadate, NULL);
- cb_to_mono->mb_emit_stloc (mb, conv_arg);
- }
-
- if (m_type_is_byref (t))
- cb_to_mono->mb_patch_branch (mb, pos);
- break;
- }
-
- if (mono_class_is_explicit_layout (klass) || m_class_is_blittable (klass) || m_class_is_enumtype (klass))
- break;
-
- conv_arg = cb_to_mono->mb_add_local (mb, int_type);
-
- /* store the address of the source into local variable 0 */
- if (m_type_is_byref (t))
- cb_to_mono->mb_emit_ldarg (mb, argnum);
- else
- cb_to_mono->mb_emit_ldarg_addr (mb, argnum);
-
- cb_to_mono->mb_emit_stloc (mb, 0);
-
- /* allocate space for the native struct and
- * store the address into local variable 1 (dest) */
- cb_to_mono->mb_emit_icon (mb, cb_to_mono->class_native_size (klass, NULL));
- cb_to_mono->mb_emit_byte (mb, CEE_PREFIX1);
- cb_to_mono->mb_emit_byte (mb, CEE_LOCALLOC);
- cb_to_mono->mb_emit_stloc (mb, conv_arg);
-
- if (m_type_is_byref (t)) {
- cb_to_mono->mb_emit_ldloc (mb, 0);
- pos = cb_to_mono->mb_emit_branch (mb, CEE_BRFALSE);
- }
-
- if (!(m_type_is_byref (t) && !(t->attrs & PARAM_ATTRIBUTE_IN) && (t->attrs & PARAM_ATTRIBUTE_OUT))) {
- /* set dst_ptr */
- cb_to_mono->mb_emit_ldloc (mb, conv_arg);
- cb_to_mono->mb_emit_stloc (mb, 1);
-
- /* emit valuetype conversion code */
- cb_to_mono->emit_struct_conv (mb, klass, FALSE);
- }
-
- if (m_type_is_byref (t))
- cb_to_mono->mb_patch_branch (mb, pos);
- break;
-
- case MARSHAL_ACTION_PUSH:
- if (spec && spec->native == MONO_NATIVE_LPSTRUCT) {
- /* FIXME: */
- g_assert (!m_type_is_byref (t));
-
- /* Have to change the signature since the vtype is passed byref */
- m->csig->params [argnum - m->csig->hasthis] = int_type;
-
- if (mono_class_is_explicit_layout (klass) || m_class_is_blittable (klass) || m_class_is_enumtype (klass))
- cb_to_mono->mb_emit_ldarg_addr (mb, argnum);
- else
- cb_to_mono->mb_emit_ldloc (mb, conv_arg);
- break;
- }
-
- if (klass == date_time_class) {
- if (m_type_is_byref (t))
- cb_to_mono->mb_emit_ldloc_addr (mb, conv_arg);
- else
- cb_to_mono->mb_emit_ldloc (mb, conv_arg);
- break;
- }
-
- if (mono_class_is_explicit_layout (klass) || m_class_is_blittable (klass) || m_class_is_enumtype (klass)) {
- cb_to_mono->mb_emit_ldarg (mb, argnum);
- break;
- }
- cb_to_mono->mb_emit_ldloc (mb, conv_arg);
- if (!m_type_is_byref (t)) {
- cb_to_mono->mb_emit_byte (mb, MONO_CUSTOM_PREFIX);
- cb_to_mono->mb_emit_op (mb, CEE_MONO_LDNATIVEOBJ, klass);
- }
- break;
-
- case MARSHAL_ACTION_CONV_OUT:
- if (klass == date_time_class) {
- /* Convert from an OLE DATE type */
-
- if (!m_type_is_byref (t))
- break;
-
- if (!((t->attrs & PARAM_ATTRIBUTE_IN) && !(t->attrs & PARAM_ATTRIBUTE_OUT))) {
-
- MONO_STATIC_POINTER_INIT (MonoMethod, from_oadate)
- from_oadate = cb_to_mono->get_method_nofail (date_time_class, "FromOADate", 1, 0);
- MONO_STATIC_POINTER_INIT_END (MonoMethod, from_oadate)
-
- g_assert (from_oadate);
-
- cb_to_mono->mb_emit_ldarg (mb, argnum);
- cb_to_mono->mb_emit_ldloc (mb, conv_arg);
- cb_to_mono->mb_emit_managed_call (mb, from_oadate, NULL);
- cb_to_mono->mb_emit_op (mb, CEE_STOBJ, date_time_class);
- }
- break;
- }
-
- if (mono_class_is_explicit_layout (klass) || m_class_is_blittable (klass) || m_class_is_enumtype (klass))
- break;
-
- if (m_type_is_byref (t)) {
- /* dst = argument */
- cb_to_mono->mb_emit_ldarg (mb, argnum);
- cb_to_mono->mb_emit_stloc (mb, 1);
-
- cb_to_mono->mb_emit_ldloc (mb, 1);
- pos = cb_to_mono->mb_emit_branch (mb, CEE_BRFALSE);
-
- if (!((t->attrs & PARAM_ATTRIBUTE_IN) && !(t->attrs & PARAM_ATTRIBUTE_OUT))) {
- /* src = tmp_locals [i] */
- cb_to_mono->mb_emit_ldloc (mb, conv_arg);
- cb_to_mono->mb_emit_stloc (mb, 0);
-
- /* emit valuetype conversion code */
- cb_to_mono->emit_struct_conv (mb, klass, TRUE);
- }
- }
-
- emit_struct_free (mb, klass, conv_arg);
-
- if (m_type_is_byref (t))
- cb_to_mono->mb_patch_branch (mb, pos);
- break;
-
- case MARSHAL_ACTION_CONV_RESULT:
- if (mono_class_is_explicit_layout (klass) || m_class_is_blittable (klass)) {
- cb_to_mono->mb_emit_stloc (mb, 3);
- break;
- }
-
- /* load pointer to returned value type */
- g_assert (m->vtaddr_var);
- cb_to_mono->mb_emit_ldloc (mb, m->vtaddr_var);
- /* store the address of the source into local variable 0 */
- cb_to_mono->mb_emit_stloc (mb, 0);
- /* set dst_ptr */
- cb_to_mono->mb_emit_ldloc_addr (mb, 3);
- cb_to_mono->mb_emit_stloc (mb, 1);
-
- /* emit valuetype conversion code */
- cb_to_mono->emit_struct_conv (mb, klass, TRUE);
- break;
-
- case MARSHAL_ACTION_MANAGED_CONV_IN:
- if (mono_class_is_explicit_layout (klass) || m_class_is_blittable (klass) || m_class_is_enumtype (klass)) {
- conv_arg = 0;
- break;
- }
-
- conv_arg = cb_to_mono->mb_add_local (mb, m_class_get_byval_arg (klass));
-
- if (t->attrs & PARAM_ATTRIBUTE_OUT)
- break;
-
- if (m_type_is_byref (t))
- cb_to_mono->mb_emit_ldarg (mb, argnum);
- else
- cb_to_mono->mb_emit_ldarg_addr (mb, argnum);
- cb_to_mono->mb_emit_stloc (mb, 0);
-
- if (m_type_is_byref (t)) {
- cb_to_mono->mb_emit_ldloc (mb, 0);
- pos = cb_to_mono->mb_emit_branch (mb, CEE_BRFALSE);
- }
-
- cb_to_mono->mb_emit_ldloc_addr (mb, conv_arg);
- cb_to_mono->mb_emit_stloc (mb, 1);
-
- /* emit valuetype conversion code */
- cb_to_mono->emit_struct_conv (mb, klass, TRUE);
-
- if (m_type_is_byref (t))
- cb_to_mono->mb_patch_branch (mb, pos);
- break;
-
- case MARSHAL_ACTION_MANAGED_CONV_OUT:
- if (mono_class_is_explicit_layout (klass) || m_class_is_blittable (klass) || m_class_is_enumtype (klass))
- break;
- if (m_type_is_byref (t) && (t->attrs & PARAM_ATTRIBUTE_IN) && !(t->attrs & PARAM_ATTRIBUTE_OUT))
- break;
-
- /* Check for null */
- cb_to_mono->mb_emit_ldarg (mb, argnum);
- pos2 = cb_to_mono->mb_emit_branch (mb, CEE_BRFALSE);
-
- /* Set src */
- cb_to_mono->mb_emit_ldloc_addr (mb, conv_arg);
- cb_to_mono->mb_emit_stloc (mb, 0);
-
- /* Set dest */
- cb_to_mono->mb_emit_ldarg (mb, argnum);
- cb_to_mono->mb_emit_stloc (mb, 1);
-
- /* emit valuetype conversion code */
- cb_to_mono->emit_struct_conv (mb, klass, FALSE);
-
- cb_to_mono->mb_patch_branch (mb, pos2);
- break;
-
- case MARSHAL_ACTION_MANAGED_CONV_RESULT:
- if (mono_class_is_explicit_layout (klass) || m_class_is_blittable (klass) || m_class_is_enumtype (klass)) {
- cb_to_mono->mb_emit_stloc (mb, 3);
- m->retobj_var = 0;
- break;
- }
-
- /* load pointer to returned value type */
- g_assert (m->vtaddr_var);
- cb_to_mono->mb_emit_ldloc (mb, m->vtaddr_var);
-
- /* store the address of the source into local variable 0 */
- cb_to_mono->mb_emit_stloc (mb, 0);
- /* allocate space for the native struct and
- * store the address into dst_ptr */
- m->retobj_var = cb_to_mono->mb_add_local (mb, int_type);
- m->retobj_class = klass;
- g_assert (m->retobj_var);
- cb_to_mono->mb_emit_icon (mb, cb_to_mono->class_native_size (klass, NULL));
- cb_to_mono->mb_emit_byte (mb, CEE_CONV_I);
- mono_mb_emit_jit_icall (mb, ves_icall_marshal_alloc);
- cb_to_mono->mb_emit_stloc (mb, 1);
- cb_to_mono->mb_emit_ldloc (mb, 1);
- cb_to_mono->mb_emit_stloc (mb, m->retobj_var);
-
- /* emit valuetype conversion code */
- cb_to_mono->emit_struct_conv (mb, klass, FALSE);
- break;
-
- default:
- g_assert_not_reached ();
- }
- return conv_arg;
-}
-
-static void
-emit_string_free_icall (MonoMethodBuilder *mb, MonoMarshalConv conv)
-{
- if (conv == MONO_MARSHAL_CONV_BSTR_STR || conv == MONO_MARSHAL_CONV_ANSIBSTR_STR || conv == MONO_MARSHAL_CONV_TBSTR_STR)
- mono_mb_emit_jit_icall (mb, mono_free_bstr);
- else
- mono_mb_emit_jit_icall (mb, mono_marshal_free);
-}
-
-static int
-emit_marshal_string_ilgen (EmitMarshalContext *m, int argnum, MonoType *t,
- MonoMarshalSpec *spec,
- int conv_arg, MonoType **conv_arg_type,
- MarshalAction action)
-{
- MonoMethodBuilder *mb = m->mb;
- MonoMarshalNative encoding = cb_to_mono->get_string_encoding (m->piinfo, spec);
- MonoMarshalConv conv = cb_to_mono->get_string_to_ptr_conv (m->piinfo, spec);
- gboolean need_free;
-
- MonoType *int_type = cb_to_mono->get_int_type ();
- MonoType *object_type = cb_to_mono->get_object_type ();
- switch (action) {
- case MARSHAL_ACTION_CONV_IN:
- *conv_arg_type = int_type;
- conv_arg = cb_to_mono->mb_add_local (mb, int_type);
-
- if (m_type_is_byref (t)) {
- if (t->attrs & PARAM_ATTRIBUTE_OUT)
- break;
-
- cb_to_mono->mb_emit_ldarg (mb, argnum);
- cb_to_mono->mb_emit_byte (mb, CEE_LDIND_I);
- } else {
- cb_to_mono->mb_emit_ldarg (mb, argnum);
- }
-
- if (conv == MONO_MARSHAL_CONV_INVALID) {
- char *msg = g_strdup_printf ("string marshalling conversion %d not implemented", encoding);
- cb_to_mono->mb_emit_exception_marshal_directive (mb, msg);
- } else {
- cb_to_mono->mb_emit_icall_id (mb, cb_to_mono->conv_to_icall (conv, NULL));
-
- cb_to_mono->mb_emit_stloc (mb, conv_arg);
- }
- break;
-
- case MARSHAL_ACTION_CONV_OUT:
- conv = cb_to_mono->get_ptr_to_string_conv (m->piinfo, spec, &need_free);
- if (conv == MONO_MARSHAL_CONV_INVALID) {
- char *msg = g_strdup_printf ("string marshalling conversion %d not implemented", encoding);
- cb_to_mono->mb_emit_exception_marshal_directive (mb, msg);
- break;
- }
-
- if (encoding == MONO_NATIVE_VBBYREFSTR) {
-
- if (!m_type_is_byref (t)) {
- char *msg = g_strdup ("VBByRefStr marshalling requires a ref parameter.");
- cb_to_mono->mb_emit_exception_marshal_directive (mb, msg);
- break;
- }
-
- MONO_STATIC_POINTER_INIT (MonoMethod, method)
-
- method = cb_to_mono->get_method_nofail (cb_to_mono->mono_defaults->string_class, "get_Length", -1, 0);
-
- MONO_STATIC_POINTER_INIT_END (MonoMethod, method)
-
- /*
- * Have to allocate a new string with the same length as the original, and
- * copy the contents of the buffer pointed to by CONV_ARG into it.
- */
- g_assert (m_type_is_byref (t));
- cb_to_mono->mb_emit_ldarg (mb, argnum);
- cb_to_mono->mb_emit_ldloc (mb, conv_arg);
- cb_to_mono->mb_emit_ldarg (mb, argnum);
- cb_to_mono->mb_emit_byte (mb, CEE_LDIND_I);
- cb_to_mono->mb_emit_managed_call (mb, method, NULL);
- mono_mb_emit_jit_icall (mb, mono_string_new_len_wrapper);
- cb_to_mono->mb_emit_byte (mb, CEE_STIND_REF);
- } else if (m_type_is_byref (t) && (t->attrs & PARAM_ATTRIBUTE_OUT || !(t->attrs & PARAM_ATTRIBUTE_IN))) {
- int stind_op;
- cb_to_mono->mb_emit_ldarg (mb, argnum);
- cb_to_mono->mb_emit_ldloc (mb, conv_arg);
- cb_to_mono->mb_emit_icall_id (mb, cb_to_mono->conv_to_icall (conv, &stind_op));
- cb_to_mono->mb_emit_byte (mb, GINT_TO_UINT8 (stind_op));
- need_free = TRUE;
- }
-
- if (need_free) {
- cb_to_mono->mb_emit_ldloc (mb, conv_arg);
- emit_string_free_icall (mb, conv);
- }
- break;
-
- case MARSHAL_ACTION_PUSH:
- if (m_type_is_byref (t) && encoding != MONO_NATIVE_VBBYREFSTR)
- cb_to_mono->mb_emit_ldloc_addr (mb, conv_arg);
- else
- cb_to_mono->mb_emit_ldloc (mb, conv_arg);
- break;
-
- case MARSHAL_ACTION_CONV_RESULT:
- cb_to_mono->mb_emit_stloc (mb, 0);
-
- conv = cb_to_mono->get_ptr_to_string_conv (m->piinfo, spec, &need_free);
- if (conv == MONO_MARSHAL_CONV_INVALID) {
- char *msg = g_strdup_printf ("string marshalling conversion %d not implemented", encoding);
- cb_to_mono->mb_emit_exception_marshal_directive (mb, msg);
- break;
- }
-
- cb_to_mono->mb_emit_ldloc (mb, 0);
- cb_to_mono->mb_emit_icall_id (mb, cb_to_mono->conv_to_icall (conv, NULL));
- cb_to_mono->mb_emit_stloc (mb, 3);
-
- /* free the string */
- cb_to_mono->mb_emit_ldloc (mb, 0);
- emit_string_free_icall (mb, conv);
- break;
-
- case MARSHAL_ACTION_MANAGED_CONV_IN:
- conv_arg = cb_to_mono->mb_add_local (mb, object_type);
-
- *conv_arg_type = int_type;
-
- if (m_type_is_byref (t)) {
- if (t->attrs & PARAM_ATTRIBUTE_OUT)
- break;
- }
-
- conv = cb_to_mono->get_ptr_to_string_conv (m->piinfo, spec, &need_free);
- if (conv == MONO_MARSHAL_CONV_INVALID) {
- char *msg = g_strdup_printf ("string marshalling conversion %d not implemented", encoding);
- cb_to_mono->mb_emit_exception_marshal_directive (mb, msg);
- break;
- }
-
- cb_to_mono->mb_emit_ldarg (mb, argnum);
- if (m_type_is_byref (t))
- cb_to_mono->mb_emit_byte (mb, CEE_LDIND_I);
- cb_to_mono->mb_emit_icall_id (mb, cb_to_mono->conv_to_icall (conv, NULL));
- cb_to_mono->mb_emit_stloc (mb, conv_arg);
- break;
-
- case MARSHAL_ACTION_MANAGED_CONV_OUT:
- if (m_type_is_byref (t)) {
- if (conv_arg) {
- int stind_op;
- cb_to_mono->mb_emit_ldarg (mb, argnum);
- cb_to_mono->mb_emit_ldloc (mb, conv_arg);
- cb_to_mono->mb_emit_icall_id (mb, cb_to_mono->conv_to_icall (conv, &stind_op));
- cb_to_mono->mb_emit_byte (mb, GINT_TO_UINT8 (stind_op));
- }
- }
- break;
-
- case MARSHAL_ACTION_MANAGED_CONV_RESULT:
- if (cb_to_mono->conv_to_icall (conv, NULL) == MONO_JIT_ICALL_mono_marshal_string_to_utf16)
- /* We need to make a copy so the caller is able to free it */
- mono_mb_emit_jit_icall (mb, mono_marshal_string_to_utf16_copy);
- else
- cb_to_mono->mb_emit_icall_id (mb, cb_to_mono->conv_to_icall (conv, NULL));
- cb_to_mono->mb_emit_stloc (mb, 3);
- break;
-
- default:
- g_assert_not_reached ();
- }
- return conv_arg;
-}
-
-static int
-emit_marshal_safehandle_ilgen (EmitMarshalContext *m, int argnum, MonoType *t,
- MonoMarshalSpec *spec, int conv_arg,
- MonoType **conv_arg_type, MarshalAction action)
-{
- MonoMethodBuilder *mb = m->mb;
- MonoType *int_type = cb_to_mono->get_int_type ();
- MonoType *boolean_type = m_class_get_byval_arg (cb_to_mono->mono_defaults->boolean_class);
-
- switch (action){
- case MARSHAL_ACTION_CONV_IN: {
- int dar_release_slot, pos;
-
- conv_arg = cb_to_mono->mb_add_local (mb, int_type);
- *conv_arg_type = int_type;
-
- if (!*cb_to_mono->get_sh_dangerous_add_ref())
- cb_to_mono->init_safe_handle ();
-
- cb_to_mono->mb_emit_ldarg (mb, argnum);
- pos = cb_to_mono->mb_emit_branch (mb, CEE_BRTRUE);
- cb_to_mono->mb_emit_exception (mb, "ArgumentNullException", NULL);
-
- cb_to_mono->mb_patch_branch (mb, pos);
-
- /* Create local to hold the ref parameter to DangerousAddRef */
- dar_release_slot = cb_to_mono->mb_add_local (mb, boolean_type);
-
- /* set release = false; */
- cb_to_mono->mb_emit_icon (mb, 0);
- cb_to_mono->mb_emit_stloc (mb, dar_release_slot);
-
- if (m_type_is_byref (t)) {
- int old_handle_value_slot = cb_to_mono->mb_add_local (mb, int_type);
-
- if (!cb_to_mono->is_in (t)) {
- cb_to_mono->mb_emit_icon (mb, 0);
- cb_to_mono->mb_emit_stloc (mb, conv_arg);
- } else {
- /* safehandle.DangerousAddRef (ref release) */
- cb_to_mono->mb_emit_ldarg (mb, argnum);
- cb_to_mono->mb_emit_byte (mb, CEE_LDIND_REF);
- cb_to_mono->mb_emit_ldloc_addr (mb, dar_release_slot);
- cb_to_mono->mb_emit_managed_call (mb, *cb_to_mono->get_sh_dangerous_add_ref(), NULL);
-
- /* Pull the handle field from SafeHandle */
- cb_to_mono->mb_emit_ldarg (mb, argnum);
- cb_to_mono->mb_emit_byte (mb, CEE_LDIND_REF);
- cb_to_mono->mb_emit_ldflda (mb, MONO_STRUCT_OFFSET (MonoSafeHandle, handle));
- cb_to_mono->mb_emit_byte (mb, CEE_LDIND_I);
- cb_to_mono->mb_emit_byte (mb, CEE_DUP);
- cb_to_mono->mb_emit_stloc (mb, conv_arg);
- cb_to_mono->mb_emit_stloc (mb, old_handle_value_slot);
- }
- } else {
- /* safehandle.DangerousAddRef (ref release) */
- cb_to_mono->mb_emit_ldarg (mb, argnum);
- cb_to_mono->mb_emit_ldloc_addr (mb, dar_release_slot);
- cb_to_mono->mb_emit_managed_call (mb, *cb_to_mono->get_sh_dangerous_add_ref(), NULL);
-
- /* Pull the handle field from SafeHandle */
- cb_to_mono->mb_emit_ldarg (mb, argnum);
- cb_to_mono->mb_emit_ldflda (mb, MONO_STRUCT_OFFSET (MonoSafeHandle, handle));
- cb_to_mono->mb_emit_byte (mb, CEE_LDIND_I);
- cb_to_mono->mb_emit_stloc (mb, conv_arg);
- }
-
- break;
- }
-
- case MARSHAL_ACTION_PUSH:
- if (m_type_is_byref (t))
- cb_to_mono->mb_emit_ldloc_addr (mb, conv_arg);
- else
- cb_to_mono->mb_emit_ldloc (mb, conv_arg);
- break;
-
- case MARSHAL_ACTION_CONV_OUT: {
- /* The slot for the boolean is the next temporary created after conv_arg, see the CONV_IN code */
- int dar_release_slot = conv_arg + 1;
- int label_next = 0;
-
- if (!*cb_to_mono->get_sh_dangerous_release())
- cb_to_mono->init_safe_handle ();
-
- if (m_type_is_byref (t)) {
- /* If there was SafeHandle on input we have to release the reference to it */
- if (cb_to_mono->is_in (t)) {
- cb_to_mono->mb_emit_ldloc (mb, dar_release_slot);
- label_next = cb_to_mono->mb_emit_branch (mb, CEE_BRFALSE);
- cb_to_mono->mb_emit_ldarg (mb, argnum);
- cb_to_mono->mb_emit_byte (mb, CEE_LDIND_I);
- cb_to_mono->mb_emit_managed_call (mb, *cb_to_mono->get_sh_dangerous_release (), NULL);
- cb_to_mono->mb_patch_branch (mb, label_next);
- }
-
- if (cb_to_mono->is_out (t)) {
- ERROR_DECL (local_error);
- MonoMethod *ctor;
-
- /*
- * If the SafeHandle was marshalled on input we can skip the marshalling on
- * output if the handle value is identical.
- */
- if (cb_to_mono->is_in (t)) {
- int old_handle_value_slot = dar_release_slot + 1;
- cb_to_mono->mb_emit_ldloc (mb, old_handle_value_slot);
- cb_to_mono->mb_emit_ldloc (mb, conv_arg);
- label_next = cb_to_mono->mb_emit_branch (mb, CEE_BEQ);
- }
-
- /*
- * Create an empty SafeHandle (of correct derived type).
- *
- * FIXME: If an out-of-memory situation or exception happens here we will
- * leak the handle. We should move the allocation of the SafeHandle to the
- * input marshalling code to prevent that.
- */
- ctor = mono_class_get_method_from_name_checked (t->data.klass, ".ctor", 0, 0, local_error);
- if (ctor == NULL || !is_ok (local_error)){
- cb_to_mono->mb_emit_exception (mb, "MissingMethodException", "parameterless constructor required");
- mono_error_cleanup (local_error);
- break;
- }
-
- /* refval = new SafeHandleDerived ()*/
- cb_to_mono->mb_emit_ldarg (mb, argnum);
- cb_to_mono->mb_emit_op (mb, CEE_NEWOBJ, ctor);
- cb_to_mono->mb_emit_byte (mb, CEE_STIND_REF);
-
- /* refval.handle = returned_handle */
- cb_to_mono->mb_emit_ldarg (mb, argnum);
- cb_to_mono->mb_emit_byte (mb, CEE_LDIND_REF);
- cb_to_mono->mb_emit_ldflda (mb, MONO_STRUCT_OFFSET (MonoSafeHandle, handle));
- cb_to_mono->mb_emit_ldloc (mb, conv_arg);
- cb_to_mono->mb_emit_byte (mb, CEE_STIND_I);
-
- if (cb_to_mono->is_in (t) && label_next) {
- cb_to_mono->mb_patch_branch (mb, label_next);
- }
- }
- } else {
- cb_to_mono->mb_emit_ldloc (mb, dar_release_slot);
- label_next = cb_to_mono->mb_emit_branch (mb, CEE_BRFALSE);
- cb_to_mono->mb_emit_ldarg (mb, argnum);
- cb_to_mono->mb_emit_managed_call (mb, *cb_to_mono->get_sh_dangerous_release (), NULL);
- cb_to_mono->mb_patch_branch (mb, label_next);
- }
- break;
- }
-
- case MARSHAL_ACTION_CONV_RESULT: {
- ERROR_DECL (error);
- MonoMethod *ctor = NULL;
- int intptr_handle_slot;
-
- if (mono_class_is_abstract (t->data.klass)) {
- cb_to_mono->mb_emit_byte (mb, CEE_POP);
- cb_to_mono->mb_emit_exception_marshal_directive (mb, g_strdup ("Returned SafeHandles should not be abstract"));
- break;
- }
-
- ctor = mono_class_get_method_from_name_checked (t->data.klass, ".ctor", 0, 0, error);
- if (ctor == NULL || !is_ok (error)){
- mono_error_cleanup (error);
- cb_to_mono->mb_emit_byte (mb, CEE_POP);
- cb_to_mono->mb_emit_exception (mb, "MissingMethodException", "parameterless constructor required");
- break;
- }
- /* Store the IntPtr results into a local */
- intptr_handle_slot = cb_to_mono->mb_add_local (mb, int_type);
- cb_to_mono->mb_emit_stloc (mb, intptr_handle_slot);
-
- /* Create return value */
- cb_to_mono->mb_emit_op (mb, CEE_NEWOBJ, ctor);
- cb_to_mono->mb_emit_stloc (mb, 3);
-
- /* Set the return.handle to the value, am using ldflda, not sure if thats a good idea */
- cb_to_mono->mb_emit_ldloc (mb, 3);
- cb_to_mono->mb_emit_ldflda (mb, MONO_STRUCT_OFFSET (MonoSafeHandle, handle));
- cb_to_mono->mb_emit_ldloc (mb, intptr_handle_slot);
- cb_to_mono->mb_emit_byte (mb, CEE_STIND_I);
- break;
- }
-
- case MARSHAL_ACTION_MANAGED_CONV_IN:
- fprintf (stderr, "mono/marshal: SafeHandles missing MANAGED_CONV_IN\n");
- break;
-
- case MARSHAL_ACTION_MANAGED_CONV_OUT:
- fprintf (stderr, "mono/marshal: SafeHandles missing MANAGED_CONV_OUT\n");
- break;
-
- case MARSHAL_ACTION_MANAGED_CONV_RESULT:
- fprintf (stderr, "mono/marshal: SafeHandles missing MANAGED_CONV_RESULT\n");
- break;
- default:
- printf ("Unhandled case for MarshalAction: %d\n", action);
- }
- return conv_arg;
-}
-
-static int
-emit_marshal_handleref_ilgen (EmitMarshalContext *m, int argnum, MonoType *t,
- MonoMarshalSpec *spec, int conv_arg,
- MonoType **conv_arg_type, MarshalAction action)
-{
- MonoMethodBuilder *mb = m->mb;
-
- MonoType *int_type = cb_to_mono->get_int_type ();
- switch (action){
- case MARSHAL_ACTION_CONV_IN: {
- conv_arg = cb_to_mono->mb_add_local (mb, int_type);
- *conv_arg_type = int_type;
-
- if (m_type_is_byref (t)) {
- char *msg = g_strdup ("HandleRefs can not be returned from unmanaged code (or passed by ref)");
- cb_to_mono->mb_emit_exception_marshal_directive (mb, msg);
- break;
- }
- cb_to_mono->mb_emit_ldarg_addr (mb, argnum);
- cb_to_mono->mb_emit_icon (mb, MONO_STRUCT_OFFSET (MonoHandleRef, handle));
- cb_to_mono->mb_emit_byte (mb, CEE_ADD);
- cb_to_mono->mb_emit_byte (mb, CEE_LDIND_I);
- cb_to_mono->mb_emit_stloc (mb, conv_arg);
- break;
- }
-
- case MARSHAL_ACTION_PUSH:
- cb_to_mono->mb_emit_ldloc (mb, conv_arg);
- break;
-
- case MARSHAL_ACTION_CONV_OUT: {
- /* no resource release required */
- break;
- }
-
- case MARSHAL_ACTION_CONV_RESULT: {
- char *msg = g_strdup ("HandleRefs can not be returned from unmanaged code (or passed by ref)");
- cb_to_mono->mb_emit_exception_marshal_directive (mb, msg);
- break;
- }
-
- case MARSHAL_ACTION_MANAGED_CONV_IN:
- fprintf (stderr, "mono/marshal: SafeHandles missing MANAGED_CONV_IN\n");
- break;
-
- case MARSHAL_ACTION_MANAGED_CONV_OUT:
- fprintf (stderr, "mono/marshal: SafeHandles missing MANAGED_CONV_OUT\n");
- break;
-
- case MARSHAL_ACTION_MANAGED_CONV_RESULT:
- fprintf (stderr, "mono/marshal: SafeHandles missing MANAGED_CONV_RESULT\n");
- break;
- default:
- fprintf (stderr, "Unhandled case for MarshalAction: %d\n", action);
- }
- return conv_arg;
-}
-
-static int
-emit_marshal_object_ilgen (EmitMarshalContext *m, int argnum, MonoType *t,
- MonoMarshalSpec *spec,
- int conv_arg, MonoType **conv_arg_type,
- MarshalAction action)
-{
- MonoMethodBuilder *mb = m->mb;
- MonoClass *klass = mono_class_from_mono_type_internal (t);
- int pos, pos2, loc;
-
- MonoType *int_type = cb_to_mono->get_int_type ();
- switch (action) {
- case MARSHAL_ACTION_CONV_IN:
- *conv_arg_type = int_type;
- conv_arg = cb_to_mono->mb_add_local (mb, int_type);
-
- m->orig_conv_args [argnum] = 0;
-
- if (mono_class_from_mono_type_internal (t) == cb_to_mono->mono_defaults->object_class) {
- char *msg = g_strdup_printf ("Marshalling of type object is not implemented");
- cb_to_mono->mb_emit_exception_marshal_directive (mb, msg);
- break;
- }
-
- if (m_class_is_delegate (klass)) {
- if (m_type_is_byref (t)) {
- if (!(t->attrs & PARAM_ATTRIBUTE_OUT)) {
- char *msg = g_strdup_printf ("Byref marshalling of delegates is not implemented.");
- cb_to_mono->mb_emit_exception_marshal_directive (mb, msg);
- }
- cb_to_mono->mb_emit_byte (mb, CEE_LDNULL);
- cb_to_mono->mb_emit_stloc (mb, conv_arg);
- } else {
- cb_to_mono->mb_emit_ldarg (mb, argnum);
- cb_to_mono->mb_emit_icall_id (mb, cb_to_mono->conv_to_icall (MONO_MARSHAL_CONV_DEL_FTN, NULL));
- cb_to_mono->mb_emit_stloc (mb, conv_arg);
- }
- } else if (klass == cb_to_mono->try_get_stringbuilder_class ()) {
- MonoMarshalNative encoding = cb_to_mono->get_string_encoding (m->piinfo, spec);
- MonoMarshalConv conv = cb_to_mono->get_stringbuilder_to_ptr_conv (m->piinfo, spec);
-
-#if 0
- if (m_type_is_byref (t)) {
- if (!(t->attrs & PARAM_ATTRIBUTE_OUT)) {
- char *msg = g_strdup_printf ("Byref marshalling of stringbuilders is not implemented.");
- cb_to_mono->mb_emit_exception_marshal_directive (mb, msg);
- }
- break;
- }
-#endif
-
- if (m_type_is_byref (t) && !(t->attrs & PARAM_ATTRIBUTE_IN) && (t->attrs & PARAM_ATTRIBUTE_OUT))
- break;
-
- if (conv == MONO_MARSHAL_CONV_INVALID) {
- char *msg = g_strdup_printf ("stringbuilder marshalling conversion %d not implemented", encoding);
- cb_to_mono->mb_emit_exception_marshal_directive (mb, msg);
- break;
- }
-
- cb_to_mono->mb_emit_ldarg (mb, argnum);
- if (m_type_is_byref (t))
- cb_to_mono->mb_emit_byte (mb, CEE_LDIND_I);
-
- cb_to_mono->mb_emit_icall_id (mb, cb_to_mono->conv_to_icall (conv, NULL));
- cb_to_mono->mb_emit_stloc (mb, conv_arg);
- } else if (m_class_is_blittable (klass)) {
- cb_to_mono->mb_emit_byte (mb, CEE_LDNULL);
- cb_to_mono->mb_emit_stloc (mb, conv_arg);
-
- cb_to_mono->mb_emit_ldarg (mb, argnum);
- pos = cb_to_mono->mb_emit_branch (mb, CEE_BRFALSE);
-
- cb_to_mono->mb_emit_ldarg (mb, argnum);
- cb_to_mono->mb_emit_ldflda (mb, MONO_ABI_SIZEOF (MonoObject));
- cb_to_mono->mb_emit_stloc (mb, conv_arg);
-
- cb_to_mono->mb_patch_branch (mb, pos);
- break;
- } else {
- cb_to_mono->mb_emit_byte (mb, CEE_LDNULL);
- cb_to_mono->mb_emit_stloc (mb, conv_arg);
-
- if (m_type_is_byref (t)) {
- /* we dont need any conversions for out parameters */
- if (t->attrs & PARAM_ATTRIBUTE_OUT)
- break;
-
- cb_to_mono->mb_emit_ldarg (mb, argnum);
- cb_to_mono->mb_emit_byte (mb, CEE_LDIND_I);
-
- } else {
- cb_to_mono->mb_emit_ldarg (mb, argnum);
- cb_to_mono->mb_emit_byte (mb, MONO_CUSTOM_PREFIX);
- cb_to_mono->mb_emit_byte (mb, CEE_MONO_OBJADDR);
- }
-
- /* store the address of the source into local variable 0 */
- cb_to_mono->mb_emit_stloc (mb, 0);
- cb_to_mono->mb_emit_ldloc (mb, 0);
- pos = cb_to_mono->mb_emit_branch (mb, CEE_BRFALSE);
-
- /* allocate space for the native struct and store the address */
- cb_to_mono->mb_emit_icon (mb, cb_to_mono->class_native_size (klass, NULL));
- cb_to_mono->mb_emit_byte (mb, CEE_PREFIX1);
- cb_to_mono->mb_emit_byte (mb, CEE_LOCALLOC);
- cb_to_mono->mb_emit_stloc (mb, conv_arg);
-
- if (m_type_is_byref (t)) {
- /* Need to store the original buffer so we can free it later */
- m->orig_conv_args [argnum] = cb_to_mono->mb_add_local (mb, int_type);
- cb_to_mono->mb_emit_ldloc (mb, conv_arg);
- cb_to_mono->mb_emit_stloc (mb, m->orig_conv_args [argnum]);
- }
-
- /* set the src_ptr */
- cb_to_mono->mb_emit_ldloc (mb, 0);
- cb_to_mono->mb_emit_ldflda (mb, MONO_ABI_SIZEOF (MonoObject));
- cb_to_mono->mb_emit_stloc (mb, 0);
-
- /* set dst_ptr */
- cb_to_mono->mb_emit_ldloc (mb, conv_arg);
- cb_to_mono->mb_emit_stloc (mb, 1);
-
- /* emit valuetype conversion code */
- cb_to_mono->emit_struct_conv (mb, klass, FALSE);
-
- cb_to_mono->mb_patch_branch (mb, pos);
- }
- break;
-
- case MARSHAL_ACTION_CONV_OUT:
- if (klass == cb_to_mono->try_get_stringbuilder_class ()) {
- gboolean need_free;
- MonoMarshalNative encoding;
- MonoMarshalConv conv;
-
- encoding = cb_to_mono->get_string_encoding (m->piinfo, spec);
- conv = cb_to_mono->get_ptr_to_stringbuilder_conv (m->piinfo, spec, &need_free);
-
- g_assert (encoding != -1);
-
- if (m_type_is_byref (t)) {
- //g_assert (!(t->attrs & PARAM_ATTRIBUTE_OUT));
-
- need_free = TRUE;
-
- cb_to_mono->mb_emit_ldarg (mb, argnum);
- cb_to_mono->mb_emit_ldloc (mb, conv_arg);
-
- switch (encoding) {
- case MONO_NATIVE_LPWSTR:
- mono_mb_emit_jit_icall (mb, mono_string_utf16_to_builder2);
- break;
- case MONO_NATIVE_LPSTR:
- mono_mb_emit_jit_icall (mb, mono_string_utf8_to_builder2);
- break;
- case MONO_NATIVE_UTF8STR:
- mono_mb_emit_jit_icall (mb, mono_string_utf8_to_builder2);
- break;
- default:
- g_assert_not_reached ();
- }
-
- cb_to_mono->mb_emit_byte (mb, CEE_STIND_REF);
- } else if (t->attrs & PARAM_ATTRIBUTE_OUT || !(t->attrs & PARAM_ATTRIBUTE_IN)) {
- cb_to_mono->mb_emit_ldarg (mb, argnum);
- cb_to_mono->mb_emit_ldloc (mb, conv_arg);
-
- cb_to_mono->mb_emit_icall_id (mb, cb_to_mono->conv_to_icall (conv, NULL));
- }
-
- if (need_free) {
- cb_to_mono->mb_emit_ldloc (mb, conv_arg);
- mono_mb_emit_jit_icall (mb, mono_marshal_free);
- }
- break;
- }
-
- if (m_class_is_delegate (klass)) {
- if (m_type_is_byref (t)) {
- cb_to_mono->mb_emit_ldarg (mb, argnum);
- cb_to_mono->mb_emit_byte (mb, MONO_CUSTOM_PREFIX);
- cb_to_mono->mb_emit_op (mb, CEE_MONO_CLASSCONST, klass);
- cb_to_mono->mb_emit_ldloc (mb, conv_arg);
- cb_to_mono->mb_emit_icall_id (mb, cb_to_mono->conv_to_icall (MONO_MARSHAL_CONV_FTN_DEL, NULL));
- cb_to_mono->mb_emit_byte (mb, CEE_STIND_REF);
- }
- break;
- }
-
- if (m_type_is_byref (t) && (t->attrs & PARAM_ATTRIBUTE_OUT)) {
- /* allocate a new object */
- cb_to_mono->mb_emit_ldarg (mb, argnum);
- cb_to_mono->mb_emit_byte (mb, MONO_CUSTOM_PREFIX);
- cb_to_mono->mb_emit_op (mb, CEE_MONO_NEWOBJ, klass);
- cb_to_mono->mb_emit_byte (mb, CEE_STIND_REF);
- }
-
- /* dst = *argument */
- cb_to_mono->mb_emit_ldarg (mb, argnum);
-
- if (m_type_is_byref (t))
- cb_to_mono->mb_emit_byte (mb, CEE_LDIND_I);
-
- cb_to_mono->mb_emit_stloc (mb, 1);
-
- cb_to_mono->mb_emit_ldloc (mb, 1);
- pos = cb_to_mono->mb_emit_branch (mb, CEE_BRFALSE);
-
- if (m_type_is_byref (t) || (t->attrs & PARAM_ATTRIBUTE_OUT)) {
- cb_to_mono->mb_emit_ldloc (mb, 1);
- cb_to_mono->mb_emit_icon (mb, MONO_ABI_SIZEOF (MonoObject));
- cb_to_mono->mb_emit_byte (mb, CEE_ADD);
- cb_to_mono->mb_emit_stloc (mb, 1);
-
- /* src = tmp_locals [i] */
- cb_to_mono->mb_emit_ldloc (mb, conv_arg);
- cb_to_mono->mb_emit_stloc (mb, 0);
-
- /* emit valuetype conversion code */
- cb_to_mono->emit_struct_conv (mb, klass, TRUE);
-
- /* Free the structure returned by the native code */
- emit_struct_free (mb, klass, conv_arg);
-
- if (m->orig_conv_args [argnum]) {
- /*
- * If the native function changed the pointer, then free
- * the original structure plus the new pointer.
- */
- cb_to_mono->mb_emit_ldloc (mb, m->orig_conv_args [argnum]);
- cb_to_mono->mb_emit_ldloc (mb, conv_arg);
- pos2 = cb_to_mono->mb_emit_branch (mb, CEE_BEQ);
-
- if (!(t->attrs & PARAM_ATTRIBUTE_OUT)) {
- g_assert (m->orig_conv_args [argnum]);
-
- emit_struct_free (mb, klass, m->orig_conv_args [argnum]);
- }
-
- cb_to_mono->mb_emit_ldloc (mb, conv_arg);
- mono_mb_emit_jit_icall (mb, mono_marshal_free);
-
- cb_to_mono->mb_patch_branch (mb, pos2);
- }
- }
- else
- /* Free the original structure passed to native code */
- emit_struct_free (mb, klass, conv_arg);
-
- cb_to_mono->mb_patch_branch (mb, pos);
- break;
-
- case MARSHAL_ACTION_PUSH:
- if (m_type_is_byref (t))
- cb_to_mono->mb_emit_ldloc_addr (mb, conv_arg);
- else
- cb_to_mono->mb_emit_ldloc (mb, conv_arg);
- break;
-
- case MARSHAL_ACTION_CONV_RESULT:
- if (m_class_is_delegate (klass)) {
- g_assert (!m_type_is_byref (t));
- cb_to_mono->mb_emit_stloc (mb, 0);
- cb_to_mono->mb_emit_byte (mb, MONO_CUSTOM_PREFIX);
- cb_to_mono->mb_emit_op (mb, CEE_MONO_CLASSCONST, klass);
- cb_to_mono->mb_emit_ldloc (mb, 0);
- cb_to_mono->mb_emit_icall_id (mb, cb_to_mono->conv_to_icall (MONO_MARSHAL_CONV_FTN_DEL, NULL));
- cb_to_mono->mb_emit_stloc (mb, 3);
- } else if (klass == cb_to_mono->try_get_stringbuilder_class ()) {
- // FIXME:
- char *msg = g_strdup_printf ("Return marshalling of stringbuilders is not implemented.");
- cb_to_mono->mb_emit_exception_marshal_directive (mb, msg);
- } else {
- /* set src */
- cb_to_mono->mb_emit_stloc (mb, 0);
-
- /* Make a copy since emit_conv modifies local 0 */
- loc = cb_to_mono->mb_add_local (mb, int_type);
- cb_to_mono->mb_emit_ldloc (mb, 0);
- cb_to_mono->mb_emit_stloc (mb, loc);
-
- cb_to_mono->mb_emit_byte (mb, CEE_LDNULL);
- cb_to_mono->mb_emit_stloc (mb, 3);
-
- cb_to_mono->mb_emit_ldloc (mb, 0);
- pos = cb_to_mono->mb_emit_branch (mb, CEE_BRFALSE);
-
- /* allocate result object */
-
- cb_to_mono->mb_emit_byte (mb, MONO_CUSTOM_PREFIX);
- cb_to_mono->mb_emit_op (mb, CEE_MONO_NEWOBJ, klass);
- cb_to_mono->mb_emit_stloc (mb, 3);
-
- /* set dst */
-
- cb_to_mono->mb_emit_ldloc (mb, 3);
- cb_to_mono->mb_emit_ldflda (mb, MONO_ABI_SIZEOF (MonoObject));
- cb_to_mono->mb_emit_stloc (mb, 1);
-
- /* emit conversion code */
- cb_to_mono->emit_struct_conv (mb, klass, TRUE);
-
- emit_struct_free (mb, klass, loc);
-
- /* Free the pointer allocated by unmanaged code */
- cb_to_mono->mb_emit_ldloc (mb, loc);
- mono_mb_emit_jit_icall (mb, mono_marshal_free);
- cb_to_mono->mb_patch_branch (mb, pos);
- }
- break;
-
- case MARSHAL_ACTION_MANAGED_CONV_IN:
- conv_arg = cb_to_mono->mb_add_local (mb, m_class_get_byval_arg (klass));
-
- if (m_class_is_delegate (klass)) {
- cb_to_mono->mb_emit_byte (mb, MONO_CUSTOM_PREFIX);
- cb_to_mono->mb_emit_op (mb, CEE_MONO_CLASSCONST, klass);
- cb_to_mono->mb_emit_ldarg (mb, argnum);
- if (m_type_is_byref (t))
- cb_to_mono->mb_emit_byte (mb, CEE_LDIND_I);
- cb_to_mono->mb_emit_icall_id (mb, cb_to_mono->conv_to_icall (MONO_MARSHAL_CONV_FTN_DEL, NULL));
- cb_to_mono->mb_emit_stloc (mb, conv_arg);
- break;
- }
-
- if (klass == cb_to_mono->try_get_stringbuilder_class ()) {
- MonoMarshalNative encoding;
-
- encoding = cb_to_mono->get_string_encoding (m->piinfo, spec);
-
- // FIXME:
- g_assert (encoding == MONO_NATIVE_LPSTR || encoding == MONO_NATIVE_UTF8STR);
-
- g_assert (!m_type_is_byref (t));
- g_assert (encoding != -1);
-
- cb_to_mono->mb_emit_ldarg (mb, argnum);
- mono_mb_emit_jit_icall (mb, mono_string_utf8_to_builder2);
- cb_to_mono->mb_emit_stloc (mb, conv_arg);
- break;
- }
-
- /* The class can not have an automatic layout */
- if (mono_class_is_auto_layout (klass)) {
- cb_to_mono->mb_emit_auto_layout_exception (mb, klass);
- break;
- }
-
- if (t->attrs & PARAM_ATTRIBUTE_OUT) {
- cb_to_mono->mb_emit_byte (mb, CEE_LDNULL);
- cb_to_mono->mb_emit_stloc (mb, conv_arg);
- break;
- }
-
- /* Set src */
- cb_to_mono->mb_emit_ldarg (mb, argnum);
- if (m_type_is_byref (t)) {
- /* Check for NULL and raise an exception */
- pos2 = cb_to_mono->mb_emit_branch (mb, CEE_BRTRUE);
-
- cb_to_mono->mb_emit_exception (mb, "ArgumentNullException", NULL);
-
- cb_to_mono->mb_patch_branch (mb, pos2);
- cb_to_mono->mb_emit_ldarg (mb, argnum);
- cb_to_mono->mb_emit_byte (mb, CEE_LDIND_I);
- }
-
- cb_to_mono->mb_emit_stloc (mb, 0);
-
- cb_to_mono->mb_emit_byte (mb, CEE_LDC_I4_0);
- cb_to_mono->mb_emit_stloc (mb, conv_arg);
-
- cb_to_mono->mb_emit_ldloc (mb, 0);
- pos = cb_to_mono->mb_emit_branch (mb, CEE_BRFALSE);
-
- /* Create and set dst */
- cb_to_mono->mb_emit_byte (mb, MONO_CUSTOM_PREFIX);
- cb_to_mono->mb_emit_op (mb, CEE_MONO_NEWOBJ, klass);
- cb_to_mono->mb_emit_stloc (mb, conv_arg);
- cb_to_mono->mb_emit_ldloc (mb, conv_arg);
- cb_to_mono->mb_emit_ldflda (mb, MONO_ABI_SIZEOF (MonoObject));
- cb_to_mono->mb_emit_stloc (mb, 1);
-
- /* emit valuetype conversion code */
- cb_to_mono->emit_struct_conv (mb, klass, TRUE);
-
- cb_to_mono->mb_patch_branch (mb, pos);
- break;
-
- case MARSHAL_ACTION_MANAGED_CONV_OUT:
- if (m_class_is_delegate (klass)) {
- if (m_type_is_byref (t)) {
- int stind_op;
- cb_to_mono->mb_emit_ldarg (mb, argnum);
- cb_to_mono->mb_emit_ldloc (mb, conv_arg);
- cb_to_mono->mb_emit_icall_id (mb, cb_to_mono->conv_to_icall (MONO_MARSHAL_CONV_DEL_FTN, &stind_op));
- cb_to_mono->mb_emit_byte (mb, GINT_TO_UINT8 (stind_op));
- break;
- }
- }
-
- if (m_type_is_byref (t)) {
- /* Check for null */
- cb_to_mono->mb_emit_ldloc (mb, conv_arg);
- pos = cb_to_mono->mb_emit_branch (mb, CEE_BRTRUE);
- cb_to_mono->mb_emit_ldarg (mb, argnum);
- cb_to_mono->mb_emit_byte (mb, CEE_LDC_I4_0);
- cb_to_mono->mb_emit_byte (mb, CEE_STIND_I);
- pos2 = cb_to_mono->mb_emit_branch (mb, CEE_BR);
-
- cb_to_mono->mb_patch_branch (mb, pos);
-
- /* Set src */
- cb_to_mono->mb_emit_ldloc (mb, conv_arg);
- cb_to_mono->mb_emit_ldflda (mb, MONO_ABI_SIZEOF (MonoObject));
- cb_to_mono->mb_emit_stloc (mb, 0);
-
- /* Allocate and set dest */
- cb_to_mono->mb_emit_icon (mb, cb_to_mono->class_native_size (klass, NULL));
- cb_to_mono->mb_emit_byte (mb, CEE_CONV_I);
- mono_mb_emit_jit_icall (mb, ves_icall_marshal_alloc);
- cb_to_mono->mb_emit_stloc (mb, 1);
-
- /* Update argument pointer */
- cb_to_mono->mb_emit_ldarg (mb, argnum);
- cb_to_mono->mb_emit_ldloc (mb, 1);
- cb_to_mono->mb_emit_byte (mb, CEE_STIND_I);
-
- /* emit valuetype conversion code */
- cb_to_mono->emit_struct_conv (mb, klass, FALSE);
-
- cb_to_mono->mb_patch_branch (mb, pos2);
- } else if (klass == cb_to_mono->try_get_stringbuilder_class ()) {
- // FIXME: What to do here ?
- } else {
- /* byval [Out] marshalling */
-
- /* FIXME: Handle null */
-
- /* Set src */
- cb_to_mono->mb_emit_ldloc (mb, conv_arg);
- cb_to_mono->mb_emit_ldflda (mb, MONO_ABI_SIZEOF (MonoObject));
- cb_to_mono->mb_emit_stloc (mb, 0);
-
- /* Set dest */
- cb_to_mono->mb_emit_ldarg (mb, argnum);
- cb_to_mono->mb_emit_stloc (mb, 1);
-
- /* emit valuetype conversion code */
- cb_to_mono->emit_struct_conv (mb, klass, FALSE);
- }
- break;
-
- case MARSHAL_ACTION_MANAGED_CONV_RESULT:
- if (m_class_is_delegate (klass)) {
- cb_to_mono->mb_emit_icall_id (mb, cb_to_mono->conv_to_icall (MONO_MARSHAL_CONV_DEL_FTN, NULL));
- cb_to_mono->mb_emit_stloc (mb, 3);
- break;
- }
-
- /* The class can not have an automatic layout */
- if (mono_class_is_auto_layout (klass)) {
- cb_to_mono->mb_emit_auto_layout_exception (mb, klass);
- break;
- }
-
- cb_to_mono->mb_emit_stloc (mb, 0);
- /* Check for null */
- cb_to_mono->mb_emit_ldloc (mb, 0);
- pos = cb_to_mono->mb_emit_branch (mb, CEE_BRTRUE);
- cb_to_mono->mb_emit_byte (mb, CEE_LDNULL);
- cb_to_mono->mb_emit_stloc (mb, 3);
- pos2 = cb_to_mono->mb_emit_branch (mb, CEE_BR);
-
- cb_to_mono->mb_patch_branch (mb, pos);
-
- /* Set src */
- cb_to_mono->mb_emit_ldloc (mb, 0);
- cb_to_mono->mb_emit_ldflda (mb, MONO_ABI_SIZEOF (MonoObject));
- cb_to_mono->mb_emit_stloc (mb, 0);
-
- /* Allocate and set dest */
- cb_to_mono->mb_emit_icon (mb, cb_to_mono->class_native_size (klass, NULL));
- cb_to_mono->mb_emit_byte (mb, CEE_CONV_I);
- mono_mb_emit_jit_icall (mb, ves_icall_marshal_alloc);
- cb_to_mono->mb_emit_byte (mb, CEE_DUP);
- cb_to_mono->mb_emit_stloc (mb, 1);
- cb_to_mono->mb_emit_stloc (mb, 3);
-
- cb_to_mono->emit_struct_conv (mb, klass, FALSE);
-
- cb_to_mono->mb_patch_branch (mb, pos2);
- break;
-
- default:
- g_assert_not_reached ();
- }
- return conv_arg;
-}
-
-static int
-emit_marshal_variant_ilgen (EmitMarshalContext *m, int argnum, MonoType *t,
- MonoMarshalSpec *spec,
- int conv_arg, MonoType **conv_arg_type,
- MarshalAction action)
-{
-#ifndef DISABLE_COM
- MonoMethodBuilder *mb = m->mb;
- MonoType *variant_type = m_class_get_byval_arg (mono_class_get_variant_class ());
- MonoType *variant_type_byref = mono_class_get_byref_type (mono_class_get_variant_class ());
- MonoType *object_type = cb_to_mono->get_object_type ();
-
- switch (action) {
- case MARSHAL_ACTION_CONV_IN: {
- conv_arg = cb_to_mono->mb_add_local (mb, variant_type);
-
- if (m_type_is_byref (t))
- *conv_arg_type = variant_type_byref;
- else
- *conv_arg_type = variant_type;
-
- if (m_type_is_byref (t) && !(t->attrs & PARAM_ATTRIBUTE_IN) && t->attrs & PARAM_ATTRIBUTE_OUT)
- break;
-
- cb_to_mono->mb_emit_ldarg (mb, argnum);
- if (m_type_is_byref (t))
- cb_to_mono->mb_emit_byte(mb, CEE_LDIND_REF);
- cb_to_mono->mb_emit_ldloc_addr (mb, conv_arg);
- cb_to_mono->mb_emit_managed_call (mb, mono_get_Marshal_GetNativeVariantForObject (), NULL);
- break;
- }
-
- case MARSHAL_ACTION_CONV_OUT: {
- if (m_type_is_byref (t) && (t->attrs & PARAM_ATTRIBUTE_OUT || !(t->attrs & PARAM_ATTRIBUTE_IN))) {
- cb_to_mono->mb_emit_ldarg (mb, argnum);
- cb_to_mono->mb_emit_ldloc_addr (mb, conv_arg);
- cb_to_mono->mb_emit_managed_call (mb, mono_get_Marshal_GetObjectForNativeVariant (), NULL);
- cb_to_mono->mb_emit_byte (mb, CEE_STIND_REF);
- }
-
- cb_to_mono->mb_emit_ldloc_addr (mb, conv_arg);
- cb_to_mono->mb_emit_managed_call (mb, mono_get_Variant_Clear (), NULL);
- break;
- }
-
- case MARSHAL_ACTION_PUSH:
- if (m_type_is_byref (t))
- cb_to_mono->mb_emit_ldloc_addr (mb, conv_arg);
- else
- cb_to_mono->mb_emit_ldloc (mb, conv_arg);
- break;
-
- case MARSHAL_ACTION_CONV_RESULT: {
- char *msg = g_strdup ("Marshalling of VARIANT not supported as a return type.");
- cb_to_mono->mb_emit_exception_marshal_directive (mb, msg);
- break;
- }
-
- case MARSHAL_ACTION_MANAGED_CONV_IN: {
- conv_arg = cb_to_mono->mb_add_local (mb, object_type);
-
- if (m_type_is_byref (t))
- *conv_arg_type = variant_type_byref;
- else
- *conv_arg_type = variant_type;
-
- if (m_type_is_byref (t) && !(t->attrs & PARAM_ATTRIBUTE_IN) && t->attrs & PARAM_ATTRIBUTE_OUT)
- break;
-
- if (m_type_is_byref (t))
- cb_to_mono->mb_emit_ldarg (mb, argnum);
- else
- cb_to_mono->mb_emit_ldarg_addr (mb, argnum);
- cb_to_mono->mb_emit_managed_call (mb, mono_get_Marshal_GetObjectForNativeVariant (), NULL);
- cb_to_mono->mb_emit_stloc (mb, conv_arg);
- break;
- }
-
- case MARSHAL_ACTION_MANAGED_CONV_OUT: {
- if (m_type_is_byref (t) && (t->attrs & PARAM_ATTRIBUTE_OUT || !(t->attrs & PARAM_ATTRIBUTE_IN))) {
- cb_to_mono->mb_emit_ldloc (mb, conv_arg);
- cb_to_mono->mb_emit_ldarg (mb, argnum);
- cb_to_mono->mb_emit_managed_call (mb, mono_get_Marshal_GetNativeVariantForObject (), NULL);
- }
- break;
- }
-
- case MARSHAL_ACTION_MANAGED_CONV_RESULT: {
- char *msg = g_strdup ("Marshalling of VARIANT not supported as a return type.");
- cb_to_mono->mb_emit_exception_marshal_directive (mb, msg);
- break;
- }
-
- default:
- g_assert_not_reached ();
- }
-#endif /* DISABLE_COM */
-
- return conv_arg;
-}
-
-
-static MonoMarshalILgenCallbacks *
-get_marshal_cb (void)
-{
- if (G_UNLIKELY (!ilgen_cb_inited)) {
-#ifdef ENABLE_ILGEN
- mono_marshal_ilgen_init ();
-#else
- mono_marshal_noilgen_init_heavyweight ();
-#endif
- }
- return &ilgen_marshal_cb;
-}
-
-int
-mono_emit_marshal_ilgen (EmitMarshalContext *m, int argnum, MonoType *t,
- MonoMarshalSpec *spec, int conv_arg,
- MonoType **conv_arg_type, MarshalAction action, MonoMarshalLightweightCallbacks* lightweigth_cb)
-{
- if (spec && spec->native == MONO_NATIVE_CUSTOM)
- return get_marshal_cb ()->emit_marshal_custom (m, argnum, t, spec, conv_arg, conv_arg_type, action);
-
- if (spec && spec->native == MONO_NATIVE_ASANY)
- return get_marshal_cb ()->emit_marshal_asany (m, argnum, t, spec, conv_arg, conv_arg_type, action);
-
- switch (t->type) {
- case MONO_TYPE_VALUETYPE:
- if (t->data.klass == cb_to_mono->class_try_get_handleref_class ())
- return get_marshal_cb ()->emit_marshal_handleref (m, argnum, t, spec, conv_arg, conv_arg_type, action);
-
- return get_marshal_cb ()->emit_marshal_vtype (m, argnum, t, spec, conv_arg, conv_arg_type, action);
- case MONO_TYPE_STRING:
- return get_marshal_cb ()->emit_marshal_string (m, argnum, t, spec, conv_arg, conv_arg_type, action);
- case MONO_TYPE_CLASS:
- case MONO_TYPE_OBJECT:
-#if !defined(DISABLE_COM)
- if (spec && spec->native == MONO_NATIVE_STRUCT)
- return get_marshal_cb ()->emit_marshal_variant (m, argnum, t, spec, conv_arg, conv_arg_type, action);
-#endif
-
-#if !defined(DISABLE_COM)
- if ((spec && (spec->native == MONO_NATIVE_IUNKNOWN ||
- spec->native == MONO_NATIVE_IDISPATCH ||
- spec->native == MONO_NATIVE_INTERFACE)) ||
- (t->type == MONO_TYPE_CLASS && mono_cominterop_is_interface(t->data.klass)))
- return mono_cominterop_emit_marshal_com_interface (m, argnum, t, spec, conv_arg, conv_arg_type, action);
- if (spec && (spec->native == MONO_NATIVE_SAFEARRAY) &&
- (spec->data.safearray_data.elem_type == MONO_VARIANT_VARIANT) &&
- ((action == MARSHAL_ACTION_CONV_OUT) || (action == MARSHAL_ACTION_CONV_IN) || (action == MARSHAL_ACTION_PUSH)))
- return mono_cominterop_emit_marshal_safearray (m, argnum, t, spec, conv_arg, conv_arg_type, action);
-#endif
-
- if (cb_to_mono->try_get_safehandle_class () != NULL && t->data.klass &&
- cb_to_mono->is_subclass_of_internal (t->data.klass, cb_to_mono->try_get_safehandle_class (), FALSE))
- return get_marshal_cb ()->emit_marshal_safehandle (m, argnum, t, spec, conv_arg, conv_arg_type, action);
-
- return get_marshal_cb ()->emit_marshal_object (m, argnum, t, spec, conv_arg, conv_arg_type, action);
- case MONO_TYPE_ARRAY:
- case MONO_TYPE_SZARRAY:
- return get_marshal_cb ()->emit_marshal_array (m, argnum, t, spec, conv_arg, conv_arg_type, action);
- case MONO_TYPE_BOOLEAN:
- return get_marshal_cb ()->emit_marshal_boolean (m, argnum, t, spec, conv_arg, conv_arg_type, action);
- case MONO_TYPE_PTR:
- return get_marshal_cb ()->emit_marshal_ptr (m, argnum, t, spec, conv_arg, conv_arg_type, action);
- case MONO_TYPE_CHAR:
- return get_marshal_cb ()->emit_marshal_char (m, argnum, t, spec, conv_arg, conv_arg_type, action);
- case MONO_TYPE_I1:
- case MONO_TYPE_U1:
- case MONO_TYPE_I2:
- case MONO_TYPE_U2:
- case MONO_TYPE_I4:
- case MONO_TYPE_U4:
- case MONO_TYPE_I:
- case MONO_TYPE_U:
- case MONO_TYPE_R4:
- case MONO_TYPE_R8:
- case MONO_TYPE_I8:
- case MONO_TYPE_U8:
- case MONO_TYPE_FNPTR:
- return lightweigth_cb->emit_marshal_scalar (m, argnum, t, spec, conv_arg, conv_arg_type, action);
- case MONO_TYPE_GENERICINST:
- if (mono_type_generic_inst_is_valuetype (t))
- return get_marshal_cb ()->emit_marshal_vtype (m, argnum, t, spec, conv_arg, conv_arg_type, action);
- else
- return get_marshal_cb ()->emit_marshal_object (m, argnum, t, spec, conv_arg, conv_arg_type, action);
- default:
- return conv_arg;
- }
-}
-
-void
-mono_marshal_ilgen_init (void)
-{
- MonoMarshalILgenCallbacks cb;
- cb.version = MONO_MARSHAL_CALLBACKS_VERSION;
- cb.emit_marshal_array = emit_marshal_array_ilgen;
- cb.emit_marshal_ptr = emit_marshal_ptr_ilgen;
- cb.emit_marshal_char = emit_marshal_char_ilgen;
- cb.emit_marshal_vtype = emit_marshal_vtype_ilgen;
- cb.emit_marshal_string = emit_marshal_string_ilgen;
- cb.emit_marshal_variant = emit_marshal_variant_ilgen;
- cb.emit_marshal_safehandle = emit_marshal_safehandle_ilgen;
- cb.emit_marshal_object = emit_marshal_object_ilgen;
- cb.emit_marshal_boolean = emit_marshal_boolean_ilgen;
- cb.emit_marshal_custom = emit_marshal_custom_ilgen;
- cb.emit_marshal_asany = emit_marshal_asany_ilgen;
- cb.emit_marshal_handleref = emit_marshal_handleref_ilgen;
-
-#ifdef DISABLE_NONBLITTABLE
- mono_marshal_noilgen_init_blittable (&cb);
-#endif
- mono_install_marshal_callbacks_ilgen (&cb);
-}
-
-
diff --git a/src/mono/mono/metadata/CMakeLists.txt b/src/mono/mono/metadata/CMakeLists.txt
index 69394f0aba1d0..3eb15313804f3 100644
--- a/src/mono/mono/metadata/CMakeLists.txt
+++ b/src/mono/mono/metadata/CMakeLists.txt
@@ -16,6 +16,8 @@ set(ilgen_base_sources
method-builder-ilgen.c
method-builder-ilgen.h
method-builder-ilgen-internals.h
+ marshal-ilgen.c
+ marshal-ilgen.h
marshal-lightweight.c
marshal-lightweight.h
marshal-shared.c
@@ -95,7 +97,6 @@ set(metadata_common_sources
marshal.h
marshal-internals.h
marshal-noilgen.c
- marshal-noilgen.h
mempool.c
mempool.h
mempool-internals.h
diff --git a/src/mono/mono/metadata/components.c b/src/mono/mono/metadata/components.c
index 204c3d9c462f8..f6f94a0b507c9 100644
--- a/src/mono/mono/metadata/components.c
+++ b/src/mono/mono/metadata/components.c
@@ -43,9 +43,6 @@ typedef struct _MonoComponentEntry {
#define DEBUGGER_LIBRARY_NAME "debugger"
#define DEBUGGER_COMPONENT_NAME DEBUGGER_LIBRARY_NAME
-#define MARSHAL_ILGEN_LIBRARY_NAME "marshal-ilgen"
-#define MARSHAL_ILGEN_COMPONENT_NAME "marshal_ilgen"
-
MonoComponentHotReload *mono_component_hot_reload_private_ptr = NULL;
MonoComponentDebugger *mono_component_debugger_private_ptr = NULL;
@@ -53,8 +50,6 @@ MonoComponentDebugger *mono_component_debugger_private_ptr = NULL;
MonoComponentEventPipe *mono_component_event_pipe_private_ptr = NULL;
MonoComponentDiagnosticsServer *mono_component_diagnostics_server_private_ptr = NULL;
-MonoComponentMarshalILgen* mono_component_marshal_ilgen_private_ptr = NULL;
-
// DiagnosticsServer/EventPipe components currently hosted by diagnostics_tracing library.
#define DIAGNOSTICS_TRACING_LIBRARY_NAME "diagnostics_tracing"
#define EVENT_PIPE_COMPONENT_NAME "event_pipe"
@@ -66,7 +61,6 @@ MonoComponentEntry components[] = {
{ HOT_RELOAD_LIBRARY_NAME, HOT_RELOAD_COMPONENT_NAME, COMPONENT_INIT_FUNC (hot_reload), (MonoComponent**)&mono_component_hot_reload_private_ptr, NULL },
{ DIAGNOSTICS_TRACING_LIBRARY_NAME, EVENT_PIPE_COMPONENT_NAME, COMPONENT_INIT_FUNC (event_pipe), (MonoComponent**)&mono_component_event_pipe_private_ptr, NULL },
{ DIAGNOSTICS_TRACING_LIBRARY_NAME, DIAGNOSTICS_SERVER_COMPONENT_NAME, COMPONENT_INIT_FUNC (diagnostics_server), (MonoComponent**)&mono_component_diagnostics_server_private_ptr, NULL },
- { MARSHAL_ILGEN_LIBRARY_NAME, MARSHAL_ILGEN_COMPONENT_NAME, COMPONENT_INIT_FUNC (marshal_ilgen), (MonoComponent**)&mono_component_marshal_ilgen_private_ptr, NULL }
};
#ifndef STATIC_COMPONENTS
diff --git a/src/mono/mono/metadata/components.h b/src/mono/mono/metadata/components.h
index f6b8696d194f0..aba0317458943 100644
--- a/src/mono/mono/metadata/components.h
+++ b/src/mono/mono/metadata/components.h
@@ -8,7 +8,6 @@
#include
#include
#include
-#include
#include
#include
@@ -25,7 +24,6 @@ extern MonoComponentHotReload *mono_component_hot_reload_private_ptr;
extern MonoComponentEventPipe *mono_component_event_pipe_private_ptr;
extern MonoComponentDiagnosticsServer *mono_component_diagnostics_server_private_ptr;
extern MonoComponentDebugger *mono_component_debugger_private_ptr;
-extern MonoComponentMarshalILgen *mono_component_marshal_ilgen_private_ptr;
/* Declare each component's getter function here */
static inline
@@ -56,11 +54,4 @@ mono_component_debugger (void)
return mono_component_debugger_private_ptr;
}
-static inline
-MonoComponentMarshalILgen*
-mono_component_marshal_ilgen (void)
-{
- return mono_component_marshal_ilgen_private_ptr;
-}
-
-#endif/*_MONO_METADATA_COMPONENTS_H*/
\ No newline at end of file
+#endif/*_MONO_METADATA_COMPONENTS_H*/
diff --git a/src/mono/mono/metadata/marshal-ilgen.c b/src/mono/mono/metadata/marshal-ilgen.c
new file mode 100644
index 0000000000000..ceceb70149f21
--- /dev/null
+++ b/src/mono/mono/metadata/marshal-ilgen.c
@@ -0,0 +1,2830 @@
+#include "mono/metadata/debug-helpers.h"
+#include "metadata/marshal.h"
+#include "metadata/marshal-ilgen.h"
+#include "metadata/marshal-lightweight.h"
+#include "metadata/marshal-shared.h"
+#include "metadata/method-builder-ilgen.h"
+#include "metadata/custom-attrs-internals.h"
+#include "metadata/class-init.h"
+#include "mono/metadata/class-internals.h"
+#include "metadata/reflection-internals.h"
+#include "mono/metadata/handle.h"
+
+
+
+#define OPDEF(a,b,c,d,e,f,g,h,i,j) \
+ a = i,
+
+enum {
+#include "mono/cil/opcode.def"
+ LAST = 0xff
+};
+#undef OPDEF
+
+static GENERATE_GET_CLASS_WITH_CACHE (date_time, "System", "DateTime");
+static GENERATE_TRY_GET_CLASS_WITH_CACHE (icustom_marshaler, "System.Runtime.InteropServices", "ICustomMarshaler");
+
+static void emit_string_free_icall (MonoMethodBuilder *mb, MonoMarshalConv conv);
+
+// TODO: Does this need to loose the mono_ prefix?
+static void mono_marshal_ilgen_legacy_init (void);
+
+static gboolean ilgen_cb_inited = FALSE;
+static MonoMarshalIlgenCallbacks ilgen_marshal_cb;
+
+void
+mono_install_marshal_callbacks_ilgen (MonoMarshalIlgenCallbacks *cb)
+{
+ g_assert (!ilgen_cb_inited);
+ g_assert (cb->version == MONO_MARSHAL_CALLBACKS_VERSION);
+ memcpy (&ilgen_marshal_cb, cb, sizeof (MonoMarshalIlgenCallbacks));
+ ilgen_cb_inited = TRUE;
+}
+
+
+static void
+emit_struct_free (MonoMethodBuilder *mb, MonoClass *klass, int struct_var)
+{
+ /* Call DestroyStructure */
+ /* FIXME: Only do this if needed */
+ mono_mb_emit_byte (mb, MONO_CUSTOM_PREFIX);
+ mono_mb_emit_op (mb, CEE_MONO_CLASSCONST, klass);
+ mono_mb_emit_ldloc (mb, struct_var);
+ mono_mb_emit_icall (mb, mono_struct_delete_old);
+}
+
+static int
+emit_marshal_array_ilgen (EmitMarshalContext *m, int argnum, MonoType *t,
+ MonoMarshalSpec *spec,
+ int conv_arg, MonoType **conv_arg_type,
+ MarshalAction action)
+{
+ MonoMethodBuilder *mb = m->mb;
+ MonoClass *klass = mono_class_from_mono_type_internal (t);
+ MonoMarshalNative encoding;
+
+ encoding = mono_marshal_get_string_encoding (m->piinfo, spec);
+ MonoType *int_type = mono_get_int_type ();
+ MonoType *object_type = mono_get_object_type ();
+
+ MonoClass *eklass = m_class_get_element_class (klass);
+
+ switch (action) {
+ case MARSHAL_ACTION_CONV_IN:
+ *conv_arg_type = object_type;
+ conv_arg = mono_mb_add_local (mb, object_type);
+
+ if (m_class_is_blittable (eklass)) {
+ mono_mb_emit_ldarg (mb, argnum);
+ if (m_type_is_byref (t))
+ mono_mb_emit_byte (mb, CEE_LDIND_I);
+ mono_mb_emit_icall_id (mb, mono_marshal_shared_conv_to_icall (MONO_MARSHAL_CONV_ARRAY_LPARRAY, NULL));
+ mono_mb_emit_stloc (mb, conv_arg);
+ } else {
+#ifdef DISABLE_NONBLITTABLE
+ char *msg = g_strdup ("Non-blittable marshalling conversion is disabled");
+ mono_marshal_shared_mb_emit_exception_marshal_directive (mb, msg);
+#else
+ guint32 label1, label2, label3;
+ int index_var, src_var, dest_ptr, esize;
+ MonoMarshalConv conv;
+ gboolean is_string = FALSE;
+
+ dest_ptr = mono_mb_add_local (mb, int_type);
+
+ if (eklass == mono_defaults.string_class) {
+ is_string = TRUE;
+ conv = mono_marshal_get_string_to_ptr_conv (m->piinfo, spec);
+ }
+ else if (eklass == mono_class_try_get_stringbuilder_class ()) {
+ is_string = TRUE;
+ conv = mono_marshal_get_stringbuilder_to_ptr_conv (m->piinfo, spec);
+ }
+ else
+ conv = MONO_MARSHAL_CONV_INVALID;
+
+ if (is_string && conv == MONO_MARSHAL_CONV_INVALID) {
+ char *msg = g_strdup_printf ("string/stringbuilder marshalling conversion %d not implemented", encoding);
+ mono_marshal_shared_mb_emit_exception_marshal_directive (mb, msg);
+ break;
+ }
+
+ src_var = mono_mb_add_local (mb, object_type);
+ mono_mb_emit_ldarg (mb, argnum);
+ if (m_type_is_byref (t))
+ mono_mb_emit_byte (mb, CEE_LDIND_I);
+ mono_mb_emit_stloc (mb, src_var);
+
+ /* Check null */
+ mono_mb_emit_ldloc (mb, src_var);
+ mono_mb_emit_stloc (mb, conv_arg);
+ mono_mb_emit_ldloc (mb, src_var);
+ label1 = mono_mb_emit_branch (mb, CEE_BRFALSE);
+
+ if (is_string)
+ esize = TARGET_SIZEOF_VOID_P;
+ else if (eklass == mono_defaults.char_class) /*can't call mono_marshal_type_size since it causes all sorts of asserts*/
+ esize = mono_pinvoke_is_unicode (m->piinfo) ? 2 : 1;
+ else
+ esize = mono_class_native_size (eklass, NULL);
+
+ /* allocate space for the native struct and store the address */
+ mono_mb_emit_icon (mb, esize);
+ mono_mb_emit_ldloc (mb, src_var);
+ mono_mb_emit_byte (mb, CEE_LDLEN);
+
+ if (eklass == mono_defaults.string_class) {
+ /* Make the array bigger for the terminating null */
+ mono_mb_emit_byte (mb, CEE_LDC_I4_1);
+ mono_mb_emit_byte (mb, CEE_ADD);
+ }
+ mono_mb_emit_byte (mb, CEE_MUL);
+ mono_mb_emit_byte (mb, CEE_PREFIX1);
+ mono_mb_emit_byte (mb, CEE_LOCALLOC);
+ mono_mb_emit_stloc (mb, conv_arg);
+
+ mono_mb_emit_ldloc (mb, conv_arg);
+ mono_mb_emit_stloc (mb, dest_ptr);
+
+ /* Emit marshalling loop */
+ index_var = mono_mb_add_local (mb, int_type);
+ mono_mb_emit_byte (mb, CEE_LDC_I4_0);
+ mono_mb_emit_stloc (mb, index_var);
+ label2 = mono_mb_get_label (mb);
+ mono_mb_emit_ldloc (mb, index_var);
+ mono_mb_emit_ldloc (mb, src_var);
+ mono_mb_emit_byte (mb, CEE_LDLEN);
+ label3 = mono_mb_emit_branch (mb, CEE_BGE);
+
+ /* Emit marshalling code */
+
+ if (is_string) {
+ int stind_op;
+ mono_mb_emit_ldloc (mb, dest_ptr);
+ mono_mb_emit_ldloc (mb, src_var);
+ mono_mb_emit_ldloc (mb, index_var);
+ mono_mb_emit_byte (mb, CEE_LDELEM_REF);
+ mono_mb_emit_icall_id (mb, mono_marshal_shared_conv_to_icall (conv, &stind_op));
+ mono_mb_emit_byte (mb, GINT_TO_UINT8 (stind_op));
+ } else {
+ /* set the src_ptr */
+ mono_mb_emit_ldloc (mb, src_var);
+ mono_mb_emit_ldloc (mb, index_var);
+ mono_mb_emit_op (mb, CEE_LDELEMA, eklass);
+ mono_mb_emit_stloc (mb, 0);
+
+ /* set dst_ptr */
+ mono_mb_emit_ldloc (mb, dest_ptr);
+ mono_mb_emit_stloc (mb, 1);
+
+ /* emit valuetype conversion code */
+ mono_marshal_shared_emit_struct_conv_full (mb, eklass, FALSE, 0, eklass == mono_defaults.char_class ? encoding : (MonoMarshalNative)-1);
+ }
+
+ mono_mb_emit_add_to_local (mb, GINT_TO_UINT16 (index_var), 1);
+ mono_mb_emit_add_to_local (mb, GINT_TO_UINT16 (dest_ptr), esize);
+
+ mono_mb_emit_branch_label (mb, CEE_BR, label2);
+
+ mono_mb_patch_branch (mb, label3);
+
+ if (eklass == mono_defaults.string_class) {
+ /* Null terminate */
+ mono_mb_emit_ldloc (mb, dest_ptr);
+ mono_mb_emit_byte (mb, CEE_LDC_I4_0);
+ mono_mb_emit_byte (mb, CEE_STIND_I);
+ }
+
+ mono_mb_patch_branch (mb, label1);
+#endif
+ }
+
+ break;
+
+ case MARSHAL_ACTION_CONV_OUT: {
+#ifndef DISABLE_NONBLITTABLE
+ gboolean need_convert, need_free;
+ /* Unicode character arrays are implicitly marshalled as [Out] under MS.NET */
+ need_convert = ((eklass == mono_defaults.char_class) && (encoding == MONO_NATIVE_LPWSTR)) || (eklass == mono_class_try_get_stringbuilder_class ()) || (t->attrs & PARAM_ATTRIBUTE_OUT);
+ need_free = mono_marshal_need_free (m_class_get_byval_arg (eklass), m->piinfo, spec);
+
+ if ((t->attrs & PARAM_ATTRIBUTE_OUT) && spec && spec->native == MONO_NATIVE_LPARRAY && spec->data.array_data.param_num != -1) {
+ int param_num = spec->data.array_data.param_num;
+ MonoType *param_type;
+
+ param_type = m->sig->params [param_num];
+
+ if (m_type_is_byref (param_type) && param_type->type != MONO_TYPE_I4) {
+ char *msg = g_strdup ("Not implemented.");
+ mono_marshal_shared_mb_emit_exception_marshal_directive (mb, msg);
+ break;
+ }
+
+ if (m_type_is_byref (t) ) {
+ mono_mb_emit_ldarg (mb, argnum);
+
+ /* Create the managed array */
+ mono_mb_emit_ldarg (mb, param_num);
+ if (m_type_is_byref (m->sig->params [param_num]))
+ // FIXME: Support other types
+ mono_mb_emit_byte (mb, CEE_LDIND_I4);
+ mono_mb_emit_byte (mb, CEE_CONV_OVF_I);
+ mono_mb_emit_op (mb, CEE_NEWARR, eklass);
+ /* Store into argument */
+ mono_mb_emit_byte (mb, CEE_STIND_REF);
+ }
+ }
+
+ if (need_convert || need_free) {
+ /* FIXME: Optimize blittable case */
+ guint32 label1, label2, label3;
+ int index_var, src_ptr, loc, esize;
+
+ if ((eklass == mono_class_try_get_stringbuilder_class ()) || (eklass == mono_defaults.string_class))
+ esize = TARGET_SIZEOF_VOID_P;
+ else if (eklass == mono_defaults.char_class)
+ esize = mono_pinvoke_is_unicode (m->piinfo) ? 2 : 1;
+ else
+ esize = mono_class_native_size (eklass, NULL);
+ src_ptr = mono_mb_add_local (mb, int_type);
+ loc = mono_mb_add_local (mb, int_type);
+
+ /* Check null */
+ mono_mb_emit_ldarg (mb, argnum);
+ if (m_type_is_byref (t))
+ mono_mb_emit_byte (mb, CEE_LDIND_I);
+ label1 = mono_mb_emit_branch (mb, CEE_BRFALSE);
+
+ mono_mb_emit_ldloc (mb, conv_arg);
+ mono_mb_emit_stloc (mb, src_ptr);
+
+ /* Emit marshalling loop */
+ index_var = mono_mb_add_local (mb, int_type);
+ mono_mb_emit_byte (mb, CEE_LDC_I4_0);
+ mono_mb_emit_stloc (mb, index_var);
+ label2 = mono_mb_get_label (mb);
+ mono_mb_emit_ldloc (mb, index_var);
+ mono_mb_emit_ldarg (mb, argnum);
+ if (m_type_is_byref (t))
+ mono_mb_emit_byte (mb, CEE_LDIND_REF);
+ mono_mb_emit_byte (mb, CEE_LDLEN);
+ label3 = mono_mb_emit_branch (mb, CEE_BGE);
+
+ /* Emit marshalling code */
+
+ if (eklass == mono_class_try_get_stringbuilder_class ()) {
+ gboolean need_free2;
+ MonoMarshalConv conv = mono_marshal_get_ptr_to_stringbuilder_conv (m->piinfo, spec, &need_free2);
+
+ g_assert (conv != MONO_MARSHAL_CONV_INVALID);
+
+ /* dest */
+ mono_mb_emit_ldarg (mb, argnum);
+ if (m_type_is_byref (t))
+ mono_mb_emit_byte (mb, CEE_LDIND_I);
+ mono_mb_emit_ldloc (mb, index_var);
+ mono_mb_emit_byte (mb, CEE_LDELEM_REF);
+
+ /* src */
+ mono_mb_emit_ldloc (mb, src_ptr);
+ mono_mb_emit_byte (mb, CEE_LDIND_I);
+
+ mono_mb_emit_icall_id (mb, mono_marshal_shared_conv_to_icall (conv, NULL));
+
+ if (need_free) {
+ /* src */
+ mono_mb_emit_ldloc (mb, src_ptr);
+ mono_mb_emit_byte (mb, CEE_LDIND_I);
+
+ mono_mb_emit_icall (mb, mono_marshal_free);
+ }
+ }
+ else if (eklass == mono_defaults.string_class) {
+ if (need_free) {
+ /* src */
+ mono_mb_emit_ldloc (mb, src_ptr);
+ mono_mb_emit_byte (mb, CEE_LDIND_I);
+
+ mono_mb_emit_icall (mb, mono_marshal_free);
+ }
+ }
+ else {
+ if (need_convert) {
+ /* set the src_ptr */
+ mono_mb_emit_ldloc (mb, src_ptr);
+ mono_mb_emit_stloc (mb, 0);
+
+ /* set dst_ptr */
+ mono_mb_emit_ldarg (mb, argnum);
+ if (m_type_is_byref (t))
+ mono_mb_emit_byte (mb, CEE_LDIND_REF);
+ mono_mb_emit_ldloc (mb, index_var);
+ mono_mb_emit_op (mb, CEE_LDELEMA, eklass);
+ mono_mb_emit_stloc (mb, 1);
+
+ /* emit valuetype conversion code */
+ mono_marshal_shared_emit_struct_conv_full (mb, eklass, TRUE, 0, eklass == mono_defaults.char_class ? encoding : (MonoMarshalNative)-1);
+ }
+
+ if (need_free) {
+ mono_mb_emit_ldloc (mb, src_ptr);
+ mono_mb_emit_stloc (mb, loc);
+
+ emit_struct_free (mb, eklass, loc);
+ }
+ }
+
+ mono_mb_emit_add_to_local (mb, GINT_TO_UINT16 (index_var), 1);
+ mono_mb_emit_add_to_local (mb, GINT_TO_UINT16 (src_ptr), esize);
+
+ mono_mb_emit_branch_label (mb, CEE_BR, label2);
+
+ mono_mb_patch_branch (mb, label1);
+ mono_mb_patch_branch (mb, label3);
+ }
+#endif
+
+ if (m_class_is_blittable (eklass)) {
+ /* free memory allocated (if any) by MONO_MARSHAL_CONV_ARRAY_LPARRAY */
+
+ mono_mb_emit_ldarg (mb, argnum);
+ if (m_type_is_byref (t))
+ mono_mb_emit_byte (mb, CEE_LDIND_REF);
+ mono_mb_emit_ldloc (mb, conv_arg);
+ mono_mb_emit_icall_id (mb, mono_marshal_shared_conv_to_icall (MONO_MARSHAL_FREE_LPARRAY, NULL));
+ }
+
+ break;
+ }
+
+ case MARSHAL_ACTION_PUSH:
+ if (m_type_is_byref (t))
+ mono_mb_emit_ldloc_addr (mb, conv_arg);
+ else
+ mono_mb_emit_ldloc (mb, conv_arg);
+ break;
+
+ case MARSHAL_ACTION_CONV_RESULT: {
+ mono_mb_emit_byte (mb, CEE_POP);
+ char *msg = g_strdup_printf ("Cannot marshal 'return value': Invalid managed/unmanaged type combination.");
+ mono_marshal_shared_mb_emit_exception_marshal_directive (mb, msg);
+ break;
+ }
+
+ case MARSHAL_ACTION_MANAGED_CONV_IN: {
+ guint32 label1, label2, label3;
+ int index_var, src_ptr, esize, param_num, num_elem;
+ MonoMarshalConv conv;
+ gboolean is_string = FALSE;
+
+ conv_arg = mono_mb_add_local (mb, object_type);
+ *conv_arg_type = int_type;
+
+ if (m_type_is_byref (t)) {
+ char *msg = g_strdup ("Byref array marshalling to managed code is not implemented.");
+ mono_marshal_shared_mb_emit_exception_marshal_directive (mb, msg);
+ return conv_arg;
+ }
+ if (!spec) {
+ char *msg = g_strdup ("[MarshalAs] attribute required to marshal arrays to managed code.");
+ mono_marshal_shared_mb_emit_exception_marshal_directive (mb, msg);
+ return conv_arg;
+ }
+
+ switch (spec->native) {
+ case MONO_NATIVE_LPARRAY:
+ break;
+ case MONO_NATIVE_SAFEARRAY:
+#ifndef DISABLE_COM
+ if (spec->data.safearray_data.elem_type != MONO_VARIANT_VARIANT) {
+ char *msg = g_strdup ("Only SAFEARRAY(VARIANT) marshalling to managed code is implemented.");
+ mono_marshal_shared_mb_emit_exception_marshal_directive (mb, msg);
+ return conv_arg;
+ }
+ return mono_cominterop_emit_marshal_safearray (m, argnum, t, spec, conv_arg, conv_arg_type, action);
+#endif
+ default: {
+ char *msg = g_strdup ("Unsupported array type marshalling to managed code.");
+ mono_marshal_shared_mb_emit_exception_marshal_directive (mb, msg);
+ return conv_arg;
+ }
+ }
+
+ /* FIXME: t is from the method which is wrapped, not the delegate type */
+ /* g_assert (t->attrs & PARAM_ATTRIBUTE_IN); */
+
+ param_num = spec->data.array_data.param_num;
+ num_elem = spec->data.array_data.num_elem;
+ if (spec->data.array_data.elem_mult == 0)
+ /* param_num is not specified */
+ param_num = -1;
+
+ if (param_num == -1) {
+ if (num_elem <= 0) {
+ char *msg = g_strdup ("Either SizeConst or SizeParamIndex should be specified when marshalling arrays to managed code.");
+ mono_marshal_shared_mb_emit_exception_marshal_directive (mb, msg);
+ return conv_arg;
+ }
+ }
+
+ /* FIXME: Optimize blittable case */
+
+#ifndef DISABLE_NONBLITTABLE
+ if (eklass == mono_defaults.string_class) {
+ is_string = TRUE;
+ gboolean need_free;
+ conv = mono_marshal_get_ptr_to_string_conv (m->piinfo, spec, &need_free);
+ }
+ else if (eklass == mono_class_try_get_stringbuilder_class ()) {
+ is_string = TRUE;
+ gboolean need_free;
+ conv = mono_marshal_get_ptr_to_stringbuilder_conv (m->piinfo, spec, &need_free);
+ }
+ else
+ conv = MONO_MARSHAL_CONV_INVALID;
+#endif
+
+ mono_marshal_load_type_info (eklass);
+
+ if (is_string)
+ esize = TARGET_SIZEOF_VOID_P;
+ else
+ esize = mono_class_native_size (eklass, NULL);
+ src_ptr = mono_mb_add_local (mb, int_type);
+
+ mono_mb_emit_byte (mb, CEE_LDNULL);
+ mono_mb_emit_stloc (mb, conv_arg);
+
+ /* Check param index */
+ if (param_num != -1) {
+ if (param_num >= m->sig->param_count) {
+ char *msg = g_strdup ("Array size control parameter index is out of range.");
+ mono_marshal_shared_mb_emit_exception_marshal_directive (mb, msg);
+ return conv_arg;
+ }
+ switch (m->sig->params [param_num]->type) {
+ case MONO_TYPE_I1:
+ case MONO_TYPE_U1:
+ case MONO_TYPE_I2:
+ case MONO_TYPE_U2:
+ case MONO_TYPE_I4:
+ case MONO_TYPE_U4:
+ case MONO_TYPE_I:
+ case MONO_TYPE_U:
+ case MONO_TYPE_I8:
+ case MONO_TYPE_U8:
+ break;
+ default: {
+ char *msg = g_strdup ("Array size control parameter must be an integral type.");
+ mono_marshal_shared_mb_emit_exception_marshal_directive (mb, msg);
+ return conv_arg;
+ }
+ }
+ }
+
+ /* Check null */
+ mono_mb_emit_ldarg (mb, argnum);
+ label1 = mono_mb_emit_branch (mb, CEE_BRFALSE);
+
+ mono_mb_emit_ldarg (mb, argnum);
+ mono_mb_emit_stloc (mb, src_ptr);
+
+ /* Create managed array */
+ /*
+ * The LPArray marshalling spec says that sometimes param_num starts
+ * from 1, sometimes it starts from 0. But MS seems to always start
+ * from 0.
+ */
+
+ if (param_num == -1) {
+ mono_mb_emit_icon (mb, num_elem);
+ } else {
+ mono_mb_emit_ldarg (mb, param_num);
+ if (num_elem > 0) {
+ mono_mb_emit_icon (mb, num_elem);
+ mono_mb_emit_byte (mb, CEE_ADD);
+ }
+ mono_mb_emit_byte (mb, CEE_CONV_OVF_I);
+ }
+
+ mono_mb_emit_op (mb, CEE_NEWARR, eklass);
+ mono_mb_emit_stloc (mb, conv_arg);
+
+ if (m_class_is_blittable (eklass)) {
+ mono_mb_emit_ldloc (mb, conv_arg);
+ mono_mb_emit_byte (mb, CEE_CONV_I);
+ mono_mb_emit_icon (mb, MONO_STRUCT_OFFSET (MonoArray, vector));
+ mono_mb_emit_byte (mb, CEE_ADD);
+ mono_mb_emit_ldarg (mb, argnum);
+ mono_mb_emit_ldloc (mb, conv_arg);
+ mono_mb_emit_byte (mb, CEE_LDLEN);
+ mono_mb_emit_icon (mb, esize);
+ mono_mb_emit_byte (mb, CEE_MUL);
+ mono_mb_emit_byte (mb, CEE_PREFIX1);
+ mono_mb_emit_byte (mb, CEE_CPBLK);
+ mono_mb_patch_branch (mb, label1);
+ break;
+ }
+#ifdef DISABLE_NONBLITTABLE
+ else {
+ char *msg = g_strdup ("Non-blittable marshalling conversion is disabled");
+ mono_marshal_shared_mb_emit_exception_marshal_directive (mb, msg);
+ }
+#else
+ /* Emit marshalling loop */
+ index_var = mono_mb_add_local (mb, int_type);
+ mono_mb_emit_byte (mb, CEE_LDC_I4_0);
+ mono_mb_emit_stloc (mb, index_var);
+ label2 = mono_mb_get_label (mb);
+ mono_mb_emit_ldloc (mb, index_var);
+ mono_mb_emit_ldloc (mb, conv_arg);
+ mono_mb_emit_byte (mb, CEE_LDLEN);
+ label3 = mono_mb_emit_branch (mb, CEE_BGE);
+
+ /* Emit marshalling code */
+ if (is_string) {
+ g_assert (conv != MONO_MARSHAL_CONV_INVALID);
+
+ mono_mb_emit_ldloc (mb, conv_arg);
+ mono_mb_emit_ldloc (mb, index_var);
+
+ mono_mb_emit_ldloc (mb, src_ptr);
+ mono_mb_emit_byte (mb, CEE_LDIND_I);
+
+ mono_mb_emit_icall_id (mb, mono_marshal_shared_conv_to_icall (conv, NULL));
+ mono_mb_emit_byte (mb, CEE_STELEM_REF);
+ }
+ else {
+ char *msg = g_strdup ("Marshalling of non-string and non-blittable arrays to managed code is not implemented.");
+ mono_marshal_shared_mb_emit_exception_marshal_directive (mb, msg);
+ return conv_arg;
+ }
+
+ mono_mb_emit_add_to_local (mb, GINT_TO_UINT16 (index_var), 1);
+ mono_mb_emit_add_to_local (mb, GINT_TO_UINT16 (src_ptr), esize);
+
+ mono_mb_emit_branch_label (mb, CEE_BR, label2);
+
+ mono_mb_patch_branch (mb, label1);
+ mono_mb_patch_branch (mb, label3);
+#endif
+
+ break;
+ }
+ case MARSHAL_ACTION_MANAGED_CONV_OUT: {
+ guint32 label1, label2, label3;
+ int index_var, dest_ptr, esize, param_num, num_elem;
+ MonoMarshalConv conv;
+ gboolean is_string = FALSE;
+
+ if (!spec)
+ /* Already handled in CONV_IN */
+ break;
+
+ /* These are already checked in CONV_IN */
+ g_assert (!m_type_is_byref (t));
+ g_assert (spec->native == MONO_NATIVE_LPARRAY);
+ g_assert (t->attrs & PARAM_ATTRIBUTE_OUT);
+
+ param_num = spec->data.array_data.param_num;
+ num_elem = spec->data.array_data.num_elem;
+
+ if (spec->data.array_data.elem_mult == 0)
+ /* param_num is not specified */
+ param_num = -1;
+
+ if (param_num == -1) {
+ if (num_elem <= 0) {
+ g_assert_not_reached ();
+ }
+ }
+
+ /* FIXME: Optimize blittable case */
+
+#ifndef DISABLE_NONBLITTABLE
+ if (eklass == mono_defaults.string_class) {
+ is_string = TRUE;
+ conv = mono_marshal_get_string_to_ptr_conv (m->piinfo, spec);
+ }
+ else if (eklass == mono_class_try_get_stringbuilder_class ()) {
+ is_string = TRUE;
+ conv = mono_marshal_get_stringbuilder_to_ptr_conv (m->piinfo, spec);
+ }
+ else
+ conv = MONO_MARSHAL_CONV_INVALID;
+#endif
+
+ mono_marshal_load_type_info (eklass);
+
+ if (is_string)
+ esize = TARGET_SIZEOF_VOID_P;
+ else
+ esize = mono_class_native_size (eklass, NULL);
+
+ dest_ptr = mono_mb_add_local (mb, int_type);
+
+ /* Check null */
+ mono_mb_emit_ldloc (mb, conv_arg);
+ label1 = mono_mb_emit_branch (mb, CEE_BRFALSE);
+
+ mono_mb_emit_ldarg (mb, argnum);
+ mono_mb_emit_stloc (mb, dest_ptr);
+
+ if (m_class_is_blittable (eklass)) {
+ /* dest */
+ mono_mb_emit_ldarg (mb, argnum);
+ /* src */
+ mono_mb_emit_ldloc (mb, conv_arg);
+ mono_mb_emit_byte (mb, CEE_CONV_I);
+ mono_mb_emit_icon (mb, MONO_STRUCT_OFFSET (MonoArray, vector));
+ mono_mb_emit_byte (mb, CEE_ADD);
+ /* length */
+ mono_mb_emit_ldloc (mb, conv_arg);
+ mono_mb_emit_byte (mb, CEE_LDLEN);
+ mono_mb_emit_icon (mb, esize);
+ mono_mb_emit_byte (mb, CEE_MUL);
+ mono_mb_emit_byte (mb, CEE_PREFIX1);
+ mono_mb_emit_byte (mb, CEE_CPBLK);
+ mono_mb_patch_branch (mb, label1);
+ break;
+ }
+
+#ifndef DISABLE_NONBLITTABLE
+ /* Emit marshalling loop */
+ index_var = mono_mb_add_local (mb, int_type);
+ mono_mb_emit_byte (mb, CEE_LDC_I4_0);
+ mono_mb_emit_stloc (mb, index_var);
+ label2 = mono_mb_get_label (mb);
+ mono_mb_emit_ldloc (mb, index_var);
+ mono_mb_emit_ldloc (mb, conv_arg);
+ mono_mb_emit_byte (mb, CEE_LDLEN);
+ label3 = mono_mb_emit_branch (mb, CEE_BGE);
+
+ /* Emit marshalling code */
+ if (is_string) {
+ int stind_op;
+ g_assert (conv != MONO_MARSHAL_CONV_INVALID);
+
+ /* dest */
+ mono_mb_emit_ldloc (mb, dest_ptr);
+
+ /* src */
+ mono_mb_emit_ldloc (mb, conv_arg);
+ mono_mb_emit_ldloc (mb, index_var);
+
+ mono_mb_emit_byte (mb, CEE_LDELEM_REF);
+
+ mono_mb_emit_icall_id (mb, mono_marshal_shared_conv_to_icall (conv, &stind_op));
+ mono_mb_emit_byte (mb, GINT_TO_UINT8 (stind_op));
+ }
+ else {
+ char *msg = g_strdup ("Marshalling of non-string and non-blittable arrays to managed code is not implemented.");
+ mono_marshal_shared_mb_emit_exception_marshal_directive (mb, msg);
+ return conv_arg;
+ }
+
+ mono_mb_emit_add_to_local (mb, GINT_TO_UINT16 (index_var), 1);
+ mono_mb_emit_add_to_local (mb, GINT_TO_UINT16 (dest_ptr), esize);
+
+ mono_mb_emit_branch_label (mb, CEE_BR, label2);
+
+ mono_mb_patch_branch (mb, label1);
+ mono_mb_patch_branch (mb, label3);
+#endif
+
+ break;
+ }
+ case MARSHAL_ACTION_MANAGED_CONV_RESULT: {
+#ifndef DISABLE_NONBLITTABLE
+ guint32 label1, label2, label3;
+ int index_var, src, dest, esize;
+ MonoMarshalConv conv = MONO_MARSHAL_CONV_INVALID;
+ gboolean is_string = FALSE;
+
+ g_assert (!m_type_is_byref (t));
+
+ mono_marshal_load_type_info (eklass);
+
+ if (eklass == mono_defaults.string_class) {
+ is_string = TRUE;
+ conv = mono_marshal_get_string_to_ptr_conv (m->piinfo, spec);
+ }
+ else {
+ g_assert_not_reached ();
+ }
+
+ if (is_string)
+ esize = TARGET_SIZEOF_VOID_P;
+ else if (eklass == mono_defaults.char_class)
+ esize = mono_pinvoke_is_unicode (m->piinfo) ? 2 : 1;
+ else
+ esize = mono_class_native_size (eklass, NULL);
+
+ src = mono_mb_add_local (mb, object_type);
+ dest = mono_mb_add_local (mb, int_type);
+
+ mono_mb_emit_stloc (mb, src);
+ mono_mb_emit_ldloc (mb, src);
+ mono_mb_emit_stloc (mb, 3);
+
+ /* Check for null */
+ mono_mb_emit_ldloc (mb, src);
+ label1 = mono_mb_emit_branch (mb, CEE_BRFALSE);
+
+ /* Allocate native array */
+ mono_mb_emit_icon (mb, esize);
+ mono_mb_emit_ldloc (mb, src);
+ mono_mb_emit_byte (mb, CEE_LDLEN);
+
+ if (eklass == mono_defaults.string_class) {
+ /* Make the array bigger for the terminating null */
+ mono_mb_emit_byte (mb, CEE_LDC_I4_1);
+ mono_mb_emit_byte (mb, CEE_ADD);
+ }
+ mono_mb_emit_byte (mb, CEE_MUL);
+ mono_mb_emit_icall (mb, ves_icall_marshal_alloc);
+ mono_mb_emit_stloc (mb, dest);
+ mono_mb_emit_ldloc (mb, dest);
+ mono_mb_emit_stloc (mb, 3);
+
+ /* Emit marshalling loop */
+ index_var = mono_mb_add_local (mb, int_type);
+ mono_mb_emit_byte (mb, CEE_LDC_I4_0);
+ mono_mb_emit_stloc (mb, index_var);
+ label2 = mono_mb_get_label (mb);
+ mono_mb_emit_ldloc (mb, index_var);
+ mono_mb_emit_ldloc (mb, src);
+ mono_mb_emit_byte (mb, CEE_LDLEN);
+ label3 = mono_mb_emit_branch (mb, CEE_BGE);
+
+ /* Emit marshalling code */
+ if (is_string) {
+ int stind_op;
+ g_assert (conv != MONO_MARSHAL_CONV_INVALID);
+
+ /* dest */
+ mono_mb_emit_ldloc (mb, dest);
+
+ /* src */
+ mono_mb_emit_ldloc (mb, src);
+ mono_mb_emit_ldloc (mb, index_var);
+
+ mono_mb_emit_byte (mb, CEE_LDELEM_REF);
+
+ mono_mb_emit_icall_id (mb, mono_marshal_shared_conv_to_icall (conv, &stind_op));
+ mono_mb_emit_byte (mb, GINT_TO_UINT8 (stind_op));
+ }
+ else {
+ char *msg = g_strdup ("Marshalling of non-string arrays to managed code is not implemented.");
+ mono_marshal_shared_mb_emit_exception_marshal_directive (mb, msg);
+ return conv_arg;
+ }
+
+ mono_mb_emit_add_to_local (mb, GINT_TO_UINT16 (index_var), 1);
+ mono_mb_emit_add_to_local (mb, GINT_TO_UINT16 (dest), esize);
+
+ mono_mb_emit_branch_label (mb, CEE_BR, label2);
+
+ mono_mb_patch_branch (mb, label3);
+ mono_mb_patch_branch (mb, label1);
+#endif
+ break;
+ }
+ default:
+ g_assert_not_reached ();
+ }
+ return conv_arg;
+}
+
+static gboolean
+emit_native_wrapper_validate_signature (MonoMethodBuilder *mb, MonoMethodSignature* sig, MonoMarshalSpec** mspecs)
+{
+ if (mspecs) {
+ for (int i = 0; i < sig->param_count; i ++) {
+ if (mspecs [i + 1] && mspecs [i + 1]->native == MONO_NATIVE_CUSTOM) {
+ if (!mspecs [i + 1]->data.custom_data.custom_name || *mspecs [i + 1]->data.custom_data.custom_name == '\0') {
+ mono_mb_emit_exception_full (mb, "System", "TypeLoadException", g_strdup ("Missing ICustomMarshaler type"));
+ return FALSE;
+ }
+
+ switch (sig->params[i]->type) {
+ case MONO_TYPE_CLASS:
+ case MONO_TYPE_OBJECT:
+ case MONO_TYPE_STRING:
+ case MONO_TYPE_ARRAY:
+ case MONO_TYPE_SZARRAY:
+ case MONO_TYPE_VALUETYPE:
+ break;
+
+ default:
+ mono_mb_emit_exception_full (mb, "System.Runtime.InteropServices", "MarshalDirectiveException", g_strdup_printf ("custom marshalling of type %x is currently not supported", sig->params[i]->type));
+ return FALSE;
+ }
+ }
+ else if (sig->params[i]->type == MONO_TYPE_VALUETYPE) {
+ MonoMarshalType *marshal_type = mono_marshal_load_type_info (mono_class_from_mono_type_internal (sig->params [i]));
+ for (guint32 field_idx = 0; field_idx < marshal_type->num_fields; ++field_idx) {
+ if (marshal_type->fields [field_idx].mspec && marshal_type->fields [field_idx].mspec->native == MONO_NATIVE_CUSTOM) {
+ mono_mb_emit_exception_full (mb, "System", "TypeLoadException", g_strdup ("Value type includes custom marshaled fields"));
+ return FALSE;
+ }
+ }
+ }
+ }
+ }
+
+ return TRUE;
+}
+
+static int
+emit_marshal_ptr_ilgen (EmitMarshalContext *m, int argnum, MonoType *t,
+ MonoMarshalSpec *spec, int conv_arg,
+ MonoType **conv_arg_type, MarshalAction action)
+{
+ MonoMethodBuilder *mb = m->mb;
+ switch (action) {
+ case MARSHAL_ACTION_CONV_IN:
+ /* MS seems to allow this in some cases, ie. bxc #158 */
+ /*
+ if (MONO_TYPE_ISSTRUCT (t->data.type) && !mono_class_from_mono_type_internal (t->data.type)->blittable) {
+ char *msg = g_strdup_printf ("Can not marshal 'parameter #%d': Pointers can not reference marshaled structures. Use byref instead.", argnum + 1);
+ mono_marshal_shared_mb_emit_exception_marshal_directive (m->mb, msg);
+ }
+ */
+ break;
+
+ case MARSHAL_ACTION_PUSH:
+ mono_mb_emit_ldarg (mb, argnum);
+ break;
+
+ case MARSHAL_ACTION_CONV_RESULT:
+ /* no conversions necessary */
+ mono_mb_emit_stloc (mb, 3);
+ break;
+
+ default:
+ break;
+ }
+ return conv_arg;
+}
+
+static int
+emit_marshal_boolean_ilgen (EmitMarshalContext *m, int argnum, MonoType *t,
+ MonoMarshalSpec *spec,
+ int conv_arg, MonoType **conv_arg_type,
+ MarshalAction action)
+{
+ MonoMethodBuilder *mb = m->mb;
+ MonoType *int_type = mono_get_int_type ();
+ MonoType *boolean_type = m_class_get_byval_arg (mono_defaults.boolean_class);
+
+ switch (action) {
+ case MARSHAL_ACTION_CONV_IN: {
+ MonoType *local_type;
+ int label_false;
+ guint8 ldc_op = CEE_LDC_I4_1;
+
+ local_type = mono_marshal_boolean_conv_in_get_local_type (spec, &ldc_op);
+ if (m_type_is_byref (t))
+ *conv_arg_type = int_type;
+ else
+ *conv_arg_type = local_type;
+ conv_arg = mono_mb_add_local (mb, local_type);
+
+ mono_mb_emit_ldarg (mb, argnum);
+ if (m_type_is_byref (t))
+ mono_mb_emit_byte (mb, CEE_LDIND_I1);
+ label_false = mono_mb_emit_branch (mb, CEE_BRFALSE);
+ mono_mb_emit_byte (mb, ldc_op);
+ mono_mb_emit_stloc (mb, conv_arg);
+ mono_mb_patch_branch (mb, label_false);
+
+ break;
+ }
+
+ case MARSHAL_ACTION_CONV_OUT:
+ {
+ int label_false, label_end;
+ if (!m_type_is_byref (t))
+ break;
+
+ mono_mb_emit_ldarg (mb, argnum);
+ mono_mb_emit_ldloc (mb, conv_arg);
+
+ label_false = mono_mb_emit_branch (mb, CEE_BRFALSE);
+ mono_mb_emit_byte (mb, CEE_LDC_I4_1);
+
+ label_end = mono_mb_emit_branch (mb, CEE_BR);
+ mono_mb_patch_branch (mb, label_false);
+ mono_mb_emit_byte (mb, CEE_LDC_I4_0);
+ mono_mb_patch_branch (mb, label_end);
+
+ mono_mb_emit_byte (mb, CEE_STIND_I1);
+ break;
+ }
+
+ case MARSHAL_ACTION_PUSH:
+ if (m_type_is_byref (t))
+ mono_mb_emit_ldloc_addr (mb, conv_arg);
+ else if (conv_arg)
+ mono_mb_emit_ldloc (mb, conv_arg);
+ else
+ mono_mb_emit_ldarg (mb, argnum);
+ break;
+
+ case MARSHAL_ACTION_CONV_RESULT:
+ /* maybe we need to make sure that it fits within 8 bits */
+ mono_mb_emit_stloc (mb, 3);
+ break;
+
+ case MARSHAL_ACTION_MANAGED_CONV_IN: {
+ MonoClass* conv_arg_class = mono_defaults.int32_class;
+ guint8 ldop = CEE_LDIND_I4;
+ int label_null, label_false;
+
+ conv_arg_class = mono_marshal_boolean_managed_conv_in_get_conv_arg_class (spec, &ldop);
+ conv_arg = mono_mb_add_local (mb, boolean_type);
+
+ if (m_type_is_byref (t))
+ *conv_arg_type = m_class_get_this_arg (conv_arg_class);
+ else
+ *conv_arg_type = m_class_get_byval_arg (conv_arg_class);
+
+
+ mono_mb_emit_ldarg (mb, argnum);
+
+ /* Check null */
+ if (m_type_is_byref (t)) {
+ label_null = mono_mb_emit_branch (mb, CEE_BRFALSE);
+ mono_mb_emit_ldarg (mb, argnum);
+ mono_mb_emit_byte (mb, ldop);
+ } else
+ label_null = 0;
+
+ label_false = mono_mb_emit_branch (mb, CEE_BRFALSE);
+ mono_mb_emit_byte (mb, CEE_LDC_I4_1);
+ mono_mb_emit_stloc (mb, conv_arg);
+ mono_mb_patch_branch (mb, label_false);
+
+ if (m_type_is_byref (t))
+ mono_mb_patch_branch (mb, label_null);
+ break;
+ }
+
+ case MARSHAL_ACTION_MANAGED_CONV_OUT: {
+ guint8 stop = CEE_STIND_I4;
+ guint8 ldc_op = CEE_LDC_I4_1;
+ int label_null,label_false, label_end;
+
+ if (!m_type_is_byref (t))
+ break;
+ if (spec) {
+ switch (spec->native) {
+ case MONO_NATIVE_I1:
+ case MONO_NATIVE_U1:
+ stop = CEE_STIND_I1;
+ break;
+ case MONO_NATIVE_VARIANTBOOL:
+ stop = CEE_STIND_I2;
+ ldc_op = CEE_LDC_I4_M1;
+ break;
+ default:
+ break;
+ }
+ }
+
+ /* Check null */
+ mono_mb_emit_ldarg (mb, argnum);
+ label_null = mono_mb_emit_branch (mb, CEE_BRFALSE);
+
+ mono_mb_emit_ldarg (mb, argnum);
+ mono_mb_emit_ldloc (mb, conv_arg);
+
+ label_false = mono_mb_emit_branch (mb, CEE_BRFALSE);
+ mono_mb_emit_byte (mb, ldc_op);
+ label_end = mono_mb_emit_branch (mb, CEE_BR);
+
+ mono_mb_patch_branch (mb, label_false);
+ mono_mb_emit_byte (mb, CEE_LDC_I4_0);
+ mono_mb_patch_branch (mb, label_end);
+
+ mono_mb_emit_byte (mb, stop);
+ mono_mb_patch_branch (mb, label_null);
+ break;
+ }
+
+ default:
+ g_assert_not_reached ();
+ }
+ return conv_arg;
+}
+
+static int
+emit_marshal_char_ilgen (EmitMarshalContext *m, int argnum, MonoType *t,
+ MonoMarshalSpec *spec, int conv_arg,
+ MonoType **conv_arg_type, MarshalAction action)
+{
+ MonoMethodBuilder *mb = m->mb;
+
+ switch (action) {
+ case MARSHAL_ACTION_PUSH:
+ /* fixme: dont know how to marshal that. We cant simply
+ * convert it to a one byte UTF8 character, because an
+ * unicode character may need more that one byte in UTF8 */
+ mono_mb_emit_ldarg (mb, argnum);
+ break;
+
+ case MARSHAL_ACTION_CONV_RESULT:
+ /* fixme: we need conversions here */
+ mono_mb_emit_stloc (mb, 3);
+ break;
+
+ default:
+ break;
+ }
+ return conv_arg;
+}
+
+static int
+emit_marshal_custom_ilgen_throw_exception (MonoMethodBuilder *mb, const char *exc_nspace, const char *exc_name, const char *msg, MarshalAction action)
+{
+ /* Throw exception and emit compensation code, if necessary */
+ switch (action) {
+ case MARSHAL_ACTION_CONV_IN:
+ case MARSHAL_ACTION_MANAGED_CONV_IN:
+ case MARSHAL_ACTION_CONV_RESULT:
+ case MARSHAL_ACTION_MANAGED_CONV_RESULT:
+ if ((action == MARSHAL_ACTION_CONV_RESULT) || (action == MARSHAL_ACTION_MANAGED_CONV_RESULT))
+ mono_mb_emit_byte (mb, CEE_POP);
+
+ mono_mb_emit_exception_full (mb, exc_nspace, exc_name, msg);
+
+ break;
+ case MARSHAL_ACTION_PUSH:
+ mono_mb_emit_byte (mb, CEE_LDNULL);
+ break;
+ default:
+ break;
+ }
+
+ return 0;
+}
+
+static int
+emit_marshal_custom_ilgen (EmitMarshalContext *m, int argnum, MonoType *t,
+ MonoMarshalSpec *spec,
+ int conv_arg, MonoType **conv_arg_type,
+ MarshalAction action)
+{
+ ERROR_DECL (error);
+ MonoType *mtype;
+ MonoClass *mklass;
+ static MonoClass *ICustomMarshaler = NULL;
+ static MonoMethod *cleanup_native, *cleanup_managed;
+ static MonoMethod *marshal_managed_to_native, *marshal_native_to_managed;
+ MonoMethodBuilder *mb = m->mb;
+ MonoAssemblyLoadContext *alc = mono_alc_get_ambient ();
+ guint32 loc1;
+ int pos2;
+
+ MonoType *int_type = mono_get_int_type ();
+ MonoType *object_type = mono_get_object_type ();
+
+ if (!ICustomMarshaler) {
+ MonoClass *klass = mono_class_try_get_icustom_marshaler_class ();
+ if (!klass)
+ return emit_marshal_custom_ilgen_throw_exception (mb, "System", "ApplicationException", g_strdup ("Current profile doesn't support ICustomMarshaler"), action);
+
+ cleanup_native = mono_marshal_shared_get_method_nofail (klass, "CleanUpNativeData", 1, 0);
+ g_assert (cleanup_native);
+
+ cleanup_managed = mono_marshal_shared_get_method_nofail (klass, "CleanUpManagedData", 1, 0);
+ g_assert (cleanup_managed);
+
+ marshal_managed_to_native = mono_marshal_shared_get_method_nofail (klass, "MarshalManagedToNative", 1, 0);
+ g_assert (marshal_managed_to_native);
+
+ marshal_native_to_managed = mono_marshal_shared_get_method_nofail (klass, "MarshalNativeToManaged", 1, 0);
+ g_assert (marshal_native_to_managed);
+
+ mono_memory_barrier ();
+ ICustomMarshaler = klass;
+ }
+
+ if (spec->data.custom_data.image)
+ mtype = mono_reflection_type_from_name_checked (spec->data.custom_data.custom_name, alc, spec->data.custom_data.image, error);
+ else
+ mtype = mono_reflection_type_from_name_checked (spec->data.custom_data.custom_name, alc, m->image, error);
+
+ if (!mtype)
+ return emit_marshal_custom_ilgen_throw_exception (mb, "System", "TypeLoadException", g_strdup ("Failed to load ICustomMarshaler type"), action);
+
+ mklass = mono_class_from_mono_type_internal (mtype);
+ g_assert (mklass != NULL);
+
+ switch (action) {
+ case MARSHAL_ACTION_CONV_IN:
+ switch (t->type) {
+ case MONO_TYPE_CLASS:
+ case MONO_TYPE_OBJECT:
+ case MONO_TYPE_STRING:
+ case MONO_TYPE_ARRAY:
+ case MONO_TYPE_SZARRAY:
+ case MONO_TYPE_VALUETYPE:
+ break;
+
+ default:
+ g_warning ("custom marshalling of type %x is currently not supported", t->type);
+ g_assert_not_reached ();
+ break;
+ }
+
+ conv_arg = mono_mb_add_local (mb, int_type);
+
+ mono_mb_emit_byte (mb, CEE_LDNULL);
+ mono_mb_emit_stloc (mb, conv_arg);
+
+ if (m_type_is_byref (t) && (t->attrs & PARAM_ATTRIBUTE_OUT))
+ break;
+
+ /* Minic MS.NET behavior */
+ if (!m_type_is_byref (t) && (t->attrs & PARAM_ATTRIBUTE_OUT) && !(t->attrs & PARAM_ATTRIBUTE_IN))
+ break;
+
+ /* Check for null */
+ mono_mb_emit_ldarg (mb, argnum);
+ if (m_type_is_byref (t))
+ mono_mb_emit_byte (mb, CEE_LDIND_I);
+ pos2 = mono_mb_emit_branch (mb, CEE_BRFALSE);
+
+ mono_marshal_shared_emit_marshal_custom_get_instance (mb, mklass, spec);
+
+ mono_mb_emit_ldarg (mb, argnum);
+ if (m_type_is_byref (t))
+ mono_mb_emit_byte (mb, CEE_LDIND_REF);
+
+ if (t->type == MONO_TYPE_VALUETYPE) {
+ /*
+ * Since we can't determine the type of the argument, we
+ * will assume the unmanaged function takes a pointer.
+ */
+ *conv_arg_type = int_type;
+
+ mono_mb_emit_op (mb, CEE_BOX, mono_class_from_mono_type_internal (t));
+ }
+
+ mono_mb_emit_op (mb, CEE_CALLVIRT, marshal_managed_to_native);
+ mono_mb_emit_stloc (mb, conv_arg);
+
+ mono_mb_patch_branch (mb, pos2);
+ break;
+
+ case MARSHAL_ACTION_CONV_OUT:
+ /* Check for null */
+ mono_mb_emit_ldloc (mb, conv_arg);
+ pos2 = mono_mb_emit_branch (mb, CEE_BRFALSE);
+
+ if (m_type_is_byref (t) && !(t->attrs & PARAM_ATTRIBUTE_OUT)) {
+ mono_mb_emit_ldarg (mb, argnum);
+
+ mono_marshal_shared_emit_marshal_custom_get_instance (mb, mklass, spec);
+ mono_mb_emit_byte (mb, CEE_DUP);
+
+ mono_mb_emit_ldarg (mb, argnum);
+ mono_mb_emit_byte (mb, CEE_LDIND_REF);
+ mono_mb_emit_op (mb, CEE_CALLVIRT, cleanup_managed);
+
+ mono_mb_emit_ldloc (mb, conv_arg);
+ mono_mb_emit_op (mb, CEE_CALLVIRT, marshal_native_to_managed);
+ mono_mb_emit_byte (mb, CEE_STIND_REF);
+ } else if (m_type_is_byref (t) && (t->attrs & PARAM_ATTRIBUTE_OUT)) {
+ mono_mb_emit_ldarg (mb, argnum);
+
+ mono_marshal_shared_emit_marshal_custom_get_instance (mb, mklass, spec);
+
+ mono_mb_emit_ldloc (mb, conv_arg);
+ mono_mb_emit_op (mb, CEE_CALLVIRT, marshal_native_to_managed);
+ mono_mb_emit_byte (mb, CEE_STIND_REF);
+ } else if (t->attrs & PARAM_ATTRIBUTE_OUT) {
+ mono_marshal_shared_emit_marshal_custom_get_instance (mb, mklass, spec);
+
+ mono_mb_emit_ldloc (mb, conv_arg);
+ mono_mb_emit_op (mb, CEE_CALLVIRT, marshal_native_to_managed);
+ /* We have nowhere to store the result */
+ mono_mb_emit_byte (mb, CEE_POP);
+ }
+
+ // Only call cleanup_native if MARSHAL_ACTION_CONV_IN called marshal_managed_to_native.
+ if (!(m_type_is_byref (t) && (t->attrs & PARAM_ATTRIBUTE_OUT)) &&
+ !(!m_type_is_byref (t) && (t->attrs & PARAM_ATTRIBUTE_OUT) && !(t->attrs & PARAM_ATTRIBUTE_IN))) {
+ mono_marshal_shared_emit_marshal_custom_get_instance (mb, mklass, spec);
+
+ mono_mb_emit_ldloc (mb, conv_arg);
+
+ mono_mb_emit_op (mb, CEE_CALLVIRT, cleanup_native);
+ }
+
+ mono_mb_patch_branch (mb, pos2);
+ break;
+
+ case MARSHAL_ACTION_PUSH:
+ if (m_type_is_byref (t))
+ mono_mb_emit_ldloc_addr (mb, conv_arg);
+ else
+ mono_mb_emit_ldloc (mb, conv_arg);
+ break;
+
+ case MARSHAL_ACTION_CONV_RESULT:
+ mono_mb_emit_stloc (mb, 3);
+
+ /* Check for null */
+ mono_mb_emit_ldloc (mb, 3);
+ pos2 = mono_mb_emit_branch (mb, CEE_BRFALSE);
+
+ mono_marshal_shared_emit_marshal_custom_get_instance (mb, mklass, spec);
+
+ mono_mb_emit_ldloc (mb, 3);
+ mono_mb_emit_op (mb, CEE_CALLVIRT, marshal_native_to_managed);
+ mono_mb_emit_stloc (mb, 3);
+
+ mono_mb_patch_branch (mb, pos2);
+ break;
+
+ case MARSHAL_ACTION_MANAGED_CONV_IN:
+ switch (t->type) {
+ case MONO_TYPE_CLASS:
+ case MONO_TYPE_OBJECT:
+ case MONO_TYPE_STRING:
+ case MONO_TYPE_ARRAY:
+ case MONO_TYPE_SZARRAY:
+ case MONO_TYPE_VALUETYPE:
+ case MONO_TYPE_BOOLEAN:
+ break;
+
+ default:
+ g_warning ("custom marshalling of type %x is currently not supported", t->type);
+ g_assert_not_reached ();
+ break;
+ }
+
+ conv_arg = mono_mb_add_local (mb, object_type);
+
+ mono_mb_emit_byte (mb, CEE_LDNULL);
+ mono_mb_emit_stloc (mb, conv_arg);
+
+ if (m_type_is_byref (t) && t->attrs & PARAM_ATTRIBUTE_OUT)
+ break;
+
+ /* Check for null */
+ mono_mb_emit_ldarg (mb, argnum);
+ if (m_type_is_byref (t))
+ mono_mb_emit_byte (mb, CEE_LDIND_I);
+ pos2 = mono_mb_emit_branch (mb, CEE_BRFALSE);
+
+ mono_marshal_shared_emit_marshal_custom_get_instance (mb, mklass, spec);
+
+ mono_mb_emit_ldarg (mb, argnum);
+ if (m_type_is_byref (t))
+ mono_mb_emit_byte (mb, CEE_LDIND_I);
+
+ mono_mb_emit_op (mb, CEE_CALLVIRT, marshal_native_to_managed);
+ mono_mb_emit_stloc (mb, conv_arg);
+
+ mono_mb_patch_branch (mb, pos2);
+ break;
+
+ case MARSHAL_ACTION_MANAGED_CONV_RESULT:
+ g_assert (!m_type_is_byref (t));
+
+ loc1 = mono_mb_add_local (mb, object_type);
+
+ mono_mb_emit_stloc (mb, 3);
+
+ mono_mb_emit_ldloc (mb, 3);
+ mono_mb_emit_stloc (mb, loc1);
+
+ /* Check for null */
+ mono_mb_emit_ldloc (mb, 3);
+ pos2 = mono_mb_emit_branch (mb, CEE_BRFALSE);
+
+ mono_marshal_shared_emit_marshal_custom_get_instance (mb, mklass, spec);
+ mono_mb_emit_byte (mb, CEE_DUP);
+
+ mono_mb_emit_ldloc (mb, 3);
+ mono_mb_emit_op (mb, CEE_CALLVIRT, marshal_managed_to_native);
+ mono_mb_emit_stloc (mb, 3);
+
+ mono_mb_emit_ldloc (mb, loc1);
+ mono_mb_emit_op (mb, CEE_CALLVIRT, cleanup_managed);
+
+ mono_mb_patch_branch (mb, pos2);
+ break;
+
+ case MARSHAL_ACTION_MANAGED_CONV_OUT:
+
+ /* Check for null */
+ mono_mb_emit_ldloc (mb, conv_arg);
+ pos2 = mono_mb_emit_branch (mb, CEE_BRFALSE);
+
+ if (m_type_is_byref (t)) {
+ mono_mb_emit_ldarg (mb, argnum);
+
+ mono_marshal_shared_emit_marshal_custom_get_instance (mb, mklass, spec);
+
+ mono_mb_emit_ldloc (mb, conv_arg);
+ mono_mb_emit_op (mb, CEE_CALLVIRT, marshal_managed_to_native);
+ mono_mb_emit_byte (mb, CEE_STIND_I);
+ }
+
+ // Only call cleanup_managed if MARSHAL_ACTION_MANAGED_CONV_IN called marshal_native_to_managed.
+ if (!(m_type_is_byref (t) && (t->attrs & PARAM_ATTRIBUTE_OUT))) {
+ mono_marshal_shared_emit_marshal_custom_get_instance (mb, mklass, spec);
+ mono_mb_emit_ldloc (mb, conv_arg);
+ mono_mb_emit_op (mb, CEE_CALLVIRT, cleanup_managed);
+ }
+
+ mono_mb_patch_branch (mb, pos2);
+ break;
+
+ default:
+ g_assert_not_reached ();
+ }
+ return conv_arg;
+}
+
+static int
+emit_marshal_asany_ilgen (EmitMarshalContext *m, int argnum, MonoType *t,
+ MonoMarshalSpec *spec,
+ int conv_arg, MonoType **conv_arg_type,
+ MarshalAction action)
+{
+ MonoMethodBuilder *mb = m->mb;
+
+ MonoType *int_type = mono_get_int_type ();
+ switch (action) {
+ case MARSHAL_ACTION_CONV_IN: {
+ MonoMarshalNative encoding = mono_marshal_get_string_encoding (m->piinfo, NULL);
+
+ g_assert (t->type == MONO_TYPE_OBJECT);
+ g_assert (!m_type_is_byref (t));
+
+ conv_arg = mono_mb_add_local (mb, int_type);
+ mono_mb_emit_ldarg (mb, argnum);
+ mono_mb_emit_icon (mb, encoding);
+ mono_mb_emit_icon (mb, t->attrs);
+ mono_mb_emit_icall (mb, mono_marshal_asany);
+ mono_mb_emit_stloc (mb, conv_arg);
+ break;
+ }
+
+ case MARSHAL_ACTION_PUSH:
+ mono_mb_emit_ldloc (mb, conv_arg);
+ break;
+
+ case MARSHAL_ACTION_CONV_OUT: {
+ MonoMarshalNative encoding = mono_marshal_get_string_encoding (m->piinfo, NULL);
+
+ mono_mb_emit_ldarg (mb, argnum);
+ mono_mb_emit_ldloc (mb, conv_arg);
+ mono_mb_emit_icon (mb, encoding);
+ mono_mb_emit_icon (mb, t->attrs);
+ mono_mb_emit_icall (mb, mono_marshal_free_asany);
+ break;
+ }
+
+ default:
+ g_assert_not_reached ();
+ }
+ return conv_arg;
+}
+
+static int
+emit_marshal_vtype_ilgen (EmitMarshalContext *m, int argnum, MonoType *t,
+ MonoMarshalSpec *spec,
+ int conv_arg, MonoType **conv_arg_type,
+ MarshalAction action)
+{
+ MonoMethodBuilder *mb = m->mb;
+ MonoClass *klass, *date_time_class;
+ int pos = 0, pos2;
+
+ klass = mono_class_from_mono_type_internal (t);
+
+ date_time_class = mono_class_get_date_time_class ();
+
+ MonoType *int_type = mono_get_int_type ();
+ MonoType *double_type = m_class_get_byval_arg (mono_defaults.double_class);
+
+ switch (action) {
+ case MARSHAL_ACTION_CONV_IN:
+ if (klass == date_time_class) {
+ /* Convert it to an OLE DATE type */
+
+ conv_arg = mono_mb_add_local (mb, double_type);
+
+ if (m_type_is_byref (t)) {
+ mono_mb_emit_ldarg (mb, argnum);
+ pos = mono_mb_emit_branch (mb, CEE_BRFALSE);
+ }
+
+ if (!(m_type_is_byref (t) && !(t->attrs & PARAM_ATTRIBUTE_IN) && (t->attrs & PARAM_ATTRIBUTE_OUT))) {
+ if (!m_type_is_byref (t))
+ m->csig->params [argnum - m->csig->hasthis] = double_type;
+
+ MONO_STATIC_POINTER_INIT (MonoMethod, to_oadate)
+ to_oadate = mono_marshal_shared_get_method_nofail (date_time_class, "ToOADate", 0, 0);
+ g_assert (to_oadate);
+ MONO_STATIC_POINTER_INIT_END (MonoMethod, to_oadate)
+
+ mono_mb_emit_ldarg_addr (mb, argnum);
+ mono_mb_emit_managed_call (mb, to_oadate, NULL);
+ mono_mb_emit_stloc (mb, conv_arg);
+ }
+
+ if (m_type_is_byref (t))
+ mono_mb_patch_branch (mb, pos);
+ break;
+ }
+
+ if (mono_class_is_explicit_layout (klass) || m_class_is_blittable (klass) || m_class_is_enumtype (klass))
+ break;
+
+ conv_arg = mono_mb_add_local (mb, int_type);
+
+ /* store the address of the source into local variable 0 */
+ if (m_type_is_byref (t))
+ mono_mb_emit_ldarg (mb, argnum);
+ else
+ mono_mb_emit_ldarg_addr (mb, argnum);
+
+ mono_mb_emit_stloc (mb, 0);
+
+ /* allocate space for the native struct and
+ * store the address into local variable 1 (dest) */
+ mono_mb_emit_icon (mb, mono_class_native_size (klass, NULL));
+ mono_mb_emit_byte (mb, CEE_PREFIX1);
+ mono_mb_emit_byte (mb, CEE_LOCALLOC);
+ mono_mb_emit_stloc (mb, conv_arg);
+
+ if (m_type_is_byref (t)) {
+ mono_mb_emit_ldloc (mb, 0);
+ pos = mono_mb_emit_branch (mb, CEE_BRFALSE);
+ }
+
+ if (!(m_type_is_byref (t) && !(t->attrs & PARAM_ATTRIBUTE_IN) && (t->attrs & PARAM_ATTRIBUTE_OUT))) {
+ /* set dst_ptr */
+ mono_mb_emit_ldloc (mb, conv_arg);
+ mono_mb_emit_stloc (mb, 1);
+
+ /* emit valuetype conversion code */
+ mono_marshal_shared_emit_struct_conv (mb, klass, FALSE);
+ }
+
+ if (m_type_is_byref (t))
+ mono_mb_patch_branch (mb, pos);
+ break;
+
+ case MARSHAL_ACTION_PUSH:
+ if (spec && spec->native == MONO_NATIVE_LPSTRUCT) {
+ /* FIXME: */
+ g_assert (!m_type_is_byref (t));
+
+ /* Have to change the signature since the vtype is passed byref */
+ m->csig->params [argnum - m->csig->hasthis] = int_type;
+
+ if (mono_class_is_explicit_layout (klass) || m_class_is_blittable (klass) || m_class_is_enumtype (klass))
+ mono_mb_emit_ldarg_addr (mb, argnum);
+ else
+ mono_mb_emit_ldloc (mb, conv_arg);
+ break;
+ }
+
+ if (klass == date_time_class) {
+ if (m_type_is_byref (t))
+ mono_mb_emit_ldloc_addr (mb, conv_arg);
+ else
+ mono_mb_emit_ldloc (mb, conv_arg);
+ break;
+ }
+
+ if (mono_class_is_explicit_layout (klass) || m_class_is_blittable (klass) || m_class_is_enumtype (klass)) {
+ mono_mb_emit_ldarg (mb, argnum);
+ break;
+ }
+ mono_mb_emit_ldloc (mb, conv_arg);
+ if (!m_type_is_byref (t)) {
+ mono_mb_emit_byte (mb, MONO_CUSTOM_PREFIX);
+ mono_mb_emit_op (mb, CEE_MONO_LDNATIVEOBJ, klass);
+ }
+ break;
+
+ case MARSHAL_ACTION_CONV_OUT:
+ if (klass == date_time_class) {
+ /* Convert from an OLE DATE type */
+
+ if (!m_type_is_byref (t))
+ break;
+
+ if (!((t->attrs & PARAM_ATTRIBUTE_IN) && !(t->attrs & PARAM_ATTRIBUTE_OUT))) {
+
+ MONO_STATIC_POINTER_INIT (MonoMethod, from_oadate)
+ from_oadate = mono_marshal_shared_get_method_nofail (date_time_class, "FromOADate", 1, 0);
+ MONO_STATIC_POINTER_INIT_END (MonoMethod, from_oadate)
+
+ g_assert (from_oadate);
+
+ mono_mb_emit_ldarg (mb, argnum);
+ mono_mb_emit_ldloc (mb, conv_arg);
+ mono_mb_emit_managed_call (mb, from_oadate, NULL);
+ mono_mb_emit_op (mb, CEE_STOBJ, date_time_class);
+ }
+ break;
+ }
+
+ if (mono_class_is_explicit_layout (klass) || m_class_is_blittable (klass) || m_class_is_enumtype (klass))
+ break;
+
+ if (m_type_is_byref (t)) {
+ /* dst = argument */
+ mono_mb_emit_ldarg (mb, argnum);
+ mono_mb_emit_stloc (mb, 1);
+
+ mono_mb_emit_ldloc (mb, 1);
+ pos = mono_mb_emit_branch (mb, CEE_BRFALSE);
+
+ if (!((t->attrs & PARAM_ATTRIBUTE_IN) && !(t->attrs & PARAM_ATTRIBUTE_OUT))) {
+ /* src = tmp_locals [i] */
+ mono_mb_emit_ldloc (mb, conv_arg);
+ mono_mb_emit_stloc (mb, 0);
+
+ /* emit valuetype conversion code */
+ mono_marshal_shared_emit_struct_conv (mb, klass, TRUE);
+ }
+ }
+
+ emit_struct_free (mb, klass, conv_arg);
+
+ if (m_type_is_byref (t))
+ mono_mb_patch_branch (mb, pos);
+ break;
+
+ case MARSHAL_ACTION_CONV_RESULT:
+ if (mono_class_is_explicit_layout (klass) || m_class_is_blittable (klass)) {
+ mono_mb_emit_stloc (mb, 3);
+ break;
+ }
+
+ /* load pointer to returned value type */
+ g_assert (m->vtaddr_var);
+ mono_mb_emit_ldloc (mb, m->vtaddr_var);
+ /* store the address of the source into local variable 0 */
+ mono_mb_emit_stloc (mb, 0);
+ /* set dst_ptr */
+ mono_mb_emit_ldloc_addr (mb, 3);
+ mono_mb_emit_stloc (mb, 1);
+
+ /* emit valuetype conversion code */
+ mono_marshal_shared_emit_struct_conv (mb, klass, TRUE);
+ break;
+
+ case MARSHAL_ACTION_MANAGED_CONV_IN:
+ if (mono_class_is_explicit_layout (klass) || m_class_is_blittable (klass) || m_class_is_enumtype (klass)) {
+ conv_arg = 0;
+ break;
+ }
+
+ conv_arg = mono_mb_add_local (mb, m_class_get_byval_arg (klass));
+
+ if (t->attrs & PARAM_ATTRIBUTE_OUT)
+ break;
+
+ if (m_type_is_byref (t))
+ mono_mb_emit_ldarg (mb, argnum);
+ else
+ mono_mb_emit_ldarg_addr (mb, argnum);
+ mono_mb_emit_stloc (mb, 0);
+
+ if (m_type_is_byref (t)) {
+ mono_mb_emit_ldloc (mb, 0);
+ pos = mono_mb_emit_branch (mb, CEE_BRFALSE);
+ }
+
+ mono_mb_emit_ldloc_addr (mb, conv_arg);
+ mono_mb_emit_stloc (mb, 1);
+
+ /* emit valuetype conversion code */
+ mono_marshal_shared_emit_struct_conv (mb, klass, TRUE);
+
+ if (m_type_is_byref (t))
+ mono_mb_patch_branch (mb, pos);
+ break;
+
+ case MARSHAL_ACTION_MANAGED_CONV_OUT:
+ if (mono_class_is_explicit_layout (klass) || m_class_is_blittable (klass) || m_class_is_enumtype (klass))
+ break;
+ if (m_type_is_byref (t) && (t->attrs & PARAM_ATTRIBUTE_IN) && !(t->attrs & PARAM_ATTRIBUTE_OUT))
+ break;
+
+ /* Check for null */
+ mono_mb_emit_ldarg (mb, argnum);
+ pos2 = mono_mb_emit_branch (mb, CEE_BRFALSE);
+
+ /* Set src */
+ mono_mb_emit_ldloc_addr (mb, conv_arg);
+ mono_mb_emit_stloc (mb, 0);
+
+ /* Set dest */
+ mono_mb_emit_ldarg (mb, argnum);
+ mono_mb_emit_stloc (mb, 1);
+
+ /* emit valuetype conversion code */
+ mono_marshal_shared_emit_struct_conv (mb, klass, FALSE);
+
+ mono_mb_patch_branch (mb, pos2);
+ break;
+
+ case MARSHAL_ACTION_MANAGED_CONV_RESULT:
+ if (mono_class_is_explicit_layout (klass) || m_class_is_blittable (klass) || m_class_is_enumtype (klass)) {
+ mono_mb_emit_stloc (mb, 3);
+ m->retobj_var = 0;
+ break;
+ }
+
+ /* load pointer to returned value type */
+ g_assert (m->vtaddr_var);
+ mono_mb_emit_ldloc (mb, m->vtaddr_var);
+
+ /* store the address of the source into local variable 0 */
+ mono_mb_emit_stloc (mb, 0);
+ /* allocate space for the native struct and
+ * store the address into dst_ptr */
+ m->retobj_var = mono_mb_add_local (mb, int_type);
+ m->retobj_class = klass;
+ g_assert (m->retobj_var);
+ mono_mb_emit_icon (mb, mono_class_native_size (klass, NULL));
+ mono_mb_emit_byte (mb, CEE_CONV_I);
+ mono_mb_emit_icall (mb, ves_icall_marshal_alloc);
+ mono_mb_emit_stloc (mb, 1);
+ mono_mb_emit_ldloc (mb, 1);
+ mono_mb_emit_stloc (mb, m->retobj_var);
+
+ /* emit valuetype conversion code */
+ mono_marshal_shared_emit_struct_conv (mb, klass, FALSE);
+ break;
+
+ default:
+ g_assert_not_reached ();
+ }
+ return conv_arg;
+}
+
+static void
+emit_string_free_icall (MonoMethodBuilder *mb, MonoMarshalConv conv)
+{
+ if (conv == MONO_MARSHAL_CONV_BSTR_STR || conv == MONO_MARSHAL_CONV_ANSIBSTR_STR || conv == MONO_MARSHAL_CONV_TBSTR_STR)
+ mono_mb_emit_icall (mb, mono_free_bstr);
+ else
+ mono_mb_emit_icall (mb, mono_marshal_free);
+}
+
+static int
+emit_marshal_string_ilgen (EmitMarshalContext *m, int argnum, MonoType *t,
+ MonoMarshalSpec *spec,
+ int conv_arg, MonoType **conv_arg_type,
+ MarshalAction action)
+{
+ MonoMethodBuilder *mb = m->mb;
+ MonoMarshalNative encoding = mono_marshal_get_string_encoding (m->piinfo, spec);
+ MonoMarshalConv conv = mono_marshal_get_string_to_ptr_conv (m->piinfo, spec);
+ gboolean need_free;
+
+ MonoType *int_type = mono_get_int_type ();
+ MonoType *object_type = mono_get_object_type ();
+ switch (action) {
+ case MARSHAL_ACTION_CONV_IN:
+ *conv_arg_type = int_type;
+ conv_arg = mono_mb_add_local (mb, int_type);
+
+ if (m_type_is_byref (t)) {
+ if (t->attrs & PARAM_ATTRIBUTE_OUT)
+ break;
+
+ mono_mb_emit_ldarg (mb, argnum);
+ mono_mb_emit_byte (mb, CEE_LDIND_I);
+ } else {
+ mono_mb_emit_ldarg (mb, argnum);
+ }
+
+ if (conv == MONO_MARSHAL_CONV_INVALID) {
+ char *msg = g_strdup_printf ("string marshalling conversion %d not implemented", encoding);
+ mono_marshal_shared_mb_emit_exception_marshal_directive (mb, msg);
+ } else {
+ mono_mb_emit_icall_id (mb, mono_marshal_shared_conv_to_icall (conv, NULL));
+
+ mono_mb_emit_stloc (mb, conv_arg);
+ }
+ break;
+
+ case MARSHAL_ACTION_CONV_OUT:
+ conv = mono_marshal_get_ptr_to_string_conv (m->piinfo, spec, &need_free);
+ if (conv == MONO_MARSHAL_CONV_INVALID) {
+ char *msg = g_strdup_printf ("string marshalling conversion %d not implemented", encoding);
+ mono_marshal_shared_mb_emit_exception_marshal_directive (mb, msg);
+ break;
+ }
+
+ if (encoding == MONO_NATIVE_VBBYREFSTR) {
+
+ if (!m_type_is_byref (t)) {
+ char *msg = g_strdup ("VBByRefStr marshalling requires a ref parameter.");
+ mono_marshal_shared_mb_emit_exception_marshal_directive (mb, msg);
+ break;
+ }
+
+ MONO_STATIC_POINTER_INIT (MonoMethod, method)
+
+ method = mono_marshal_shared_get_method_nofail (mono_defaults.string_class, "get_Length", -1, 0);
+
+ MONO_STATIC_POINTER_INIT_END (MonoMethod, method)
+
+ /*
+ * Have to allocate a new string with the same length as the original, and
+ * copy the contents of the buffer pointed to by CONV_ARG into it.
+ */
+ g_assert (m_type_is_byref (t));
+ mono_mb_emit_ldarg (mb, argnum);
+ mono_mb_emit_ldloc (mb, conv_arg);
+ mono_mb_emit_ldarg (mb, argnum);
+ mono_mb_emit_byte (mb, CEE_LDIND_I);
+ mono_mb_emit_managed_call (mb, method, NULL);
+ mono_mb_emit_icall (mb, mono_string_new_len_wrapper);
+ mono_mb_emit_byte (mb, CEE_STIND_REF);
+ } else if (m_type_is_byref (t) && (t->attrs & PARAM_ATTRIBUTE_OUT || !(t->attrs & PARAM_ATTRIBUTE_IN))) {
+ int stind_op;
+ mono_mb_emit_ldarg (mb, argnum);
+ mono_mb_emit_ldloc (mb, conv_arg);
+ mono_mb_emit_icall_id (mb, mono_marshal_shared_conv_to_icall (conv, &stind_op));
+ mono_mb_emit_byte (mb, GINT_TO_UINT8 (stind_op));
+ need_free = TRUE;
+ }
+
+ if (need_free) {
+ mono_mb_emit_ldloc (mb, conv_arg);
+ emit_string_free_icall (mb, conv);
+ }
+ break;
+
+ case MARSHAL_ACTION_PUSH:
+ if (m_type_is_byref (t) && encoding != MONO_NATIVE_VBBYREFSTR)
+ mono_mb_emit_ldloc_addr (mb, conv_arg);
+ else
+ mono_mb_emit_ldloc (mb, conv_arg);
+ break;
+
+ case MARSHAL_ACTION_CONV_RESULT:
+ mono_mb_emit_stloc (mb, 0);
+
+ conv = mono_marshal_get_ptr_to_string_conv (m->piinfo, spec, &need_free);
+ if (conv == MONO_MARSHAL_CONV_INVALID) {
+ char *msg = g_strdup_printf ("string marshalling conversion %d not implemented", encoding);
+ mono_marshal_shared_mb_emit_exception_marshal_directive (mb, msg);
+ break;
+ }
+
+ mono_mb_emit_ldloc (mb, 0);
+ mono_mb_emit_icall_id (mb, mono_marshal_shared_conv_to_icall (conv, NULL));
+ mono_mb_emit_stloc (mb, 3);
+
+ /* free the string */
+ mono_mb_emit_ldloc (mb, 0);
+ emit_string_free_icall (mb, conv);
+ break;
+
+ case MARSHAL_ACTION_MANAGED_CONV_IN:
+ conv_arg = mono_mb_add_local (mb, object_type);
+
+ *conv_arg_type = int_type;
+
+ if (m_type_is_byref (t)) {
+ if (t->attrs & PARAM_ATTRIBUTE_OUT)
+ break;
+ }
+
+ conv = mono_marshal_get_ptr_to_string_conv (m->piinfo, spec, &need_free);
+ if (conv == MONO_MARSHAL_CONV_INVALID) {
+ char *msg = g_strdup_printf ("string marshalling conversion %d not implemented", encoding);
+ mono_marshal_shared_mb_emit_exception_marshal_directive (mb, msg);
+ break;
+ }
+
+ mono_mb_emit_ldarg (mb, argnum);
+ if (m_type_is_byref (t))
+ mono_mb_emit_byte (mb, CEE_LDIND_I);
+ mono_mb_emit_icall_id (mb, mono_marshal_shared_conv_to_icall (conv, NULL));
+ mono_mb_emit_stloc (mb, conv_arg);
+ break;
+
+ case MARSHAL_ACTION_MANAGED_CONV_OUT:
+ if (m_type_is_byref (t)) {
+ if (conv_arg) {
+ int stind_op;
+ mono_mb_emit_ldarg (mb, argnum);
+ mono_mb_emit_ldloc (mb, conv_arg);
+ mono_mb_emit_icall_id (mb, mono_marshal_shared_conv_to_icall (conv, &stind_op));
+ mono_mb_emit_byte (mb, GINT_TO_UINT8 (stind_op));
+ }
+ }
+ break;
+
+ case MARSHAL_ACTION_MANAGED_CONV_RESULT:
+ if (mono_marshal_shared_conv_to_icall (conv, NULL) == MONO_JIT_ICALL_mono_marshal_string_to_utf16)
+ /* We need to make a copy so the caller is able to free it */
+ mono_mb_emit_icall (mb, mono_marshal_string_to_utf16_copy);
+ else
+ mono_mb_emit_icall_id (mb, mono_marshal_shared_conv_to_icall (conv, NULL));
+ mono_mb_emit_stloc (mb, 3);
+ break;
+
+ default:
+ g_assert_not_reached ();
+ }
+ return conv_arg;
+}
+
+static int
+emit_marshal_safehandle_ilgen (EmitMarshalContext *m, int argnum, MonoType *t,
+ MonoMarshalSpec *spec, int conv_arg,
+ MonoType **conv_arg_type, MarshalAction action)
+{
+ MonoMethodBuilder *mb = m->mb;
+ MonoType *int_type = mono_get_int_type ();
+ MonoType *boolean_type = m_class_get_byval_arg (mono_defaults.boolean_class);
+
+ switch (action){
+ case MARSHAL_ACTION_CONV_IN: {
+ int dar_release_slot, pos;
+
+ conv_arg = mono_mb_add_local (mb, int_type);
+ *conv_arg_type = int_type;
+
+ if (!*mono_marshal_shared_get_sh_dangerous_add_ref())
+ mono_marshal_shared_init_safe_handle ();
+
+ mono_mb_emit_ldarg (mb, argnum);
+ pos = mono_mb_emit_branch (mb, CEE_BRTRUE);
+ mono_mb_emit_exception (mb, "ArgumentNullException", NULL);
+
+ mono_mb_patch_branch (mb, pos);
+
+ /* Create local to hold the ref parameter to DangerousAddRef */
+ dar_release_slot = mono_mb_add_local (mb, boolean_type);
+
+ /* set release = false; */
+ mono_mb_emit_icon (mb, 0);
+ mono_mb_emit_stloc (mb, dar_release_slot);
+
+ if (m_type_is_byref (t)) {
+ int old_handle_value_slot = mono_mb_add_local (mb, int_type);
+
+ if (!mono_marshal_shared_is_in (t)) {
+ mono_mb_emit_icon (mb, 0);
+ mono_mb_emit_stloc (mb, conv_arg);
+ } else {
+ /* safehandle.DangerousAddRef (ref release) */
+ mono_mb_emit_ldarg (mb, argnum);
+ mono_mb_emit_byte (mb, CEE_LDIND_REF);
+ mono_mb_emit_ldloc_addr (mb, dar_release_slot);
+ mono_mb_emit_managed_call (mb, *mono_marshal_shared_get_sh_dangerous_add_ref(), NULL);
+
+ /* Pull the handle field from SafeHandle */
+ mono_mb_emit_ldarg (mb, argnum);
+ mono_mb_emit_byte (mb, CEE_LDIND_REF);
+ mono_mb_emit_ldflda (mb, MONO_STRUCT_OFFSET (MonoSafeHandle, handle));
+ mono_mb_emit_byte (mb, CEE_LDIND_I);
+ mono_mb_emit_byte (mb, CEE_DUP);
+ mono_mb_emit_stloc (mb, conv_arg);
+ mono_mb_emit_stloc (mb, old_handle_value_slot);
+ }
+ } else {
+ /* safehandle.DangerousAddRef (ref release) */
+ mono_mb_emit_ldarg (mb, argnum);
+ mono_mb_emit_ldloc_addr (mb, dar_release_slot);
+ mono_mb_emit_managed_call (mb, *mono_marshal_shared_get_sh_dangerous_add_ref(), NULL);
+
+ /* Pull the handle field from SafeHandle */
+ mono_mb_emit_ldarg (mb, argnum);
+ mono_mb_emit_ldflda (mb, MONO_STRUCT_OFFSET (MonoSafeHandle, handle));
+ mono_mb_emit_byte (mb, CEE_LDIND_I);
+ mono_mb_emit_stloc (mb, conv_arg);
+ }
+
+ break;
+ }
+
+ case MARSHAL_ACTION_PUSH:
+ if (m_type_is_byref (t))
+ mono_mb_emit_ldloc_addr (mb, conv_arg);
+ else
+ mono_mb_emit_ldloc (mb, conv_arg);
+ break;
+
+ case MARSHAL_ACTION_CONV_OUT: {
+ /* The slot for the boolean is the next temporary created after conv_arg, see the CONV_IN code */
+ int dar_release_slot = conv_arg + 1;
+ int label_next = 0;
+
+ if (!*mono_marshal_shared_get_sh_dangerous_release())
+ mono_marshal_shared_init_safe_handle ();
+
+ if (m_type_is_byref (t)) {
+ /* If there was SafeHandle on input we have to release the reference to it */
+ if (mono_marshal_shared_is_in (t)) {
+ mono_mb_emit_ldloc (mb, dar_release_slot);
+ label_next = mono_mb_emit_branch (mb, CEE_BRFALSE);
+ mono_mb_emit_ldarg (mb, argnum);
+ mono_mb_emit_byte (mb, CEE_LDIND_I);
+ mono_mb_emit_managed_call (mb, *mono_marshal_shared_get_sh_dangerous_release (), NULL);
+ mono_mb_patch_branch (mb, label_next);
+ }
+
+ if (mono_marshal_shared_is_out (t)) {
+ ERROR_DECL (local_error);
+ MonoMethod *ctor;
+
+ /*
+ * If the SafeHandle was marshalled on input we can skip the marshalling on
+ * output if the handle value is identical.
+ */
+ if (mono_marshal_shared_is_in (t)) {
+ int old_handle_value_slot = dar_release_slot + 1;
+ mono_mb_emit_ldloc (mb, old_handle_value_slot);
+ mono_mb_emit_ldloc (mb, conv_arg);
+ label_next = mono_mb_emit_branch (mb, CEE_BEQ);
+ }
+
+ /*
+ * Create an empty SafeHandle (of correct derived type).
+ *
+ * FIXME: If an out-of-memory situation or exception happens here we will
+ * leak the handle. We should move the allocation of the SafeHandle to the
+ * input marshalling code to prevent that.
+ */
+ ctor = mono_class_get_method_from_name_checked (t->data.klass, ".ctor", 0, 0, local_error);
+ if (ctor == NULL || !is_ok (local_error)){
+ mono_mb_emit_exception (mb, "MissingMethodException", "parameterless constructor required");
+ mono_error_cleanup (local_error);
+ break;
+ }
+
+ /* refval = new SafeHandleDerived ()*/
+ mono_mb_emit_ldarg (mb, argnum);
+ mono_mb_emit_op (mb, CEE_NEWOBJ, ctor);
+ mono_mb_emit_byte (mb, CEE_STIND_REF);
+
+ /* refval.handle = returned_handle */
+ mono_mb_emit_ldarg (mb, argnum);
+ mono_mb_emit_byte (mb, CEE_LDIND_REF);
+ mono_mb_emit_ldflda (mb, MONO_STRUCT_OFFSET (MonoSafeHandle, handle));
+ mono_mb_emit_ldloc (mb, conv_arg);
+ mono_mb_emit_byte (mb, CEE_STIND_I);
+
+ if (mono_marshal_shared_is_in (t) && label_next) {
+ mono_mb_patch_branch (mb, label_next);
+ }
+ }
+ } else {
+ mono_mb_emit_ldloc (mb, dar_release_slot);
+ label_next = mono_mb_emit_branch (mb, CEE_BRFALSE);
+ mono_mb_emit_ldarg (mb, argnum);
+ mono_mb_emit_managed_call (mb, *mono_marshal_shared_get_sh_dangerous_release (), NULL);
+ mono_mb_patch_branch (mb, label_next);
+ }
+ break;
+ }
+
+ case MARSHAL_ACTION_CONV_RESULT: {
+ ERROR_DECL (error);
+ MonoMethod *ctor = NULL;
+ int intptr_handle_slot;
+
+ if (mono_class_is_abstract (t->data.klass)) {
+ mono_mb_emit_byte (mb, CEE_POP);
+ mono_marshal_shared_mb_emit_exception_marshal_directive (mb, g_strdup ("Returned SafeHandles should not be abstract"));
+ break;
+ }
+
+ ctor = mono_class_get_method_from_name_checked (t->data.klass, ".ctor", 0, 0, error);
+ if (ctor == NULL || !is_ok (error)){
+ mono_error_cleanup (error);
+ mono_mb_emit_byte (mb, CEE_POP);
+ mono_mb_emit_exception (mb, "MissingMethodException", "parameterless constructor required");
+ break;
+ }
+ /* Store the IntPtr results into a local */
+ intptr_handle_slot = mono_mb_add_local (mb, int_type);
+ mono_mb_emit_stloc (mb, intptr_handle_slot);
+
+ /* Create return value */
+ mono_mb_emit_op (mb, CEE_NEWOBJ, ctor);
+ mono_mb_emit_stloc (mb, 3);
+
+ /* Set the return.handle to the value, am using ldflda, not sure if thats a good idea */
+ mono_mb_emit_ldloc (mb, 3);
+ mono_mb_emit_ldflda (mb, MONO_STRUCT_OFFSET (MonoSafeHandle, handle));
+ mono_mb_emit_ldloc (mb, intptr_handle_slot);
+ mono_mb_emit_byte (mb, CEE_STIND_I);
+ break;
+ }
+
+ case MARSHAL_ACTION_MANAGED_CONV_IN:
+ fprintf (stderr, "mono/marshal: SafeHandles missing MANAGED_CONV_IN\n");
+ break;
+
+ case MARSHAL_ACTION_MANAGED_CONV_OUT:
+ fprintf (stderr, "mono/marshal: SafeHandles missing MANAGED_CONV_OUT\n");
+ break;
+
+ case MARSHAL_ACTION_MANAGED_CONV_RESULT:
+ fprintf (stderr, "mono/marshal: SafeHandles missing MANAGED_CONV_RESULT\n");
+ break;
+ default:
+ printf ("Unhandled case for MarshalAction: %d\n", action);
+ }
+ return conv_arg;
+}
+
+static int
+emit_marshal_handleref_ilgen (EmitMarshalContext *m, int argnum, MonoType *t,
+ MonoMarshalSpec *spec, int conv_arg,
+ MonoType **conv_arg_type, MarshalAction action)
+{
+ MonoMethodBuilder *mb = m->mb;
+
+ MonoType *int_type = mono_get_int_type ();
+ switch (action){
+ case MARSHAL_ACTION_CONV_IN: {
+ conv_arg = mono_mb_add_local (mb, int_type);
+ *conv_arg_type = int_type;
+
+ if (m_type_is_byref (t)) {
+ char *msg = g_strdup ("HandleRefs can not be returned from unmanaged code (or passed by ref)");
+ mono_marshal_shared_mb_emit_exception_marshal_directive (mb, msg);
+ break;
+ }
+ mono_mb_emit_ldarg_addr (mb, argnum);
+ mono_mb_emit_icon (mb, MONO_STRUCT_OFFSET (MonoHandleRef, handle));
+ mono_mb_emit_byte (mb, CEE_ADD);
+ mono_mb_emit_byte (mb, CEE_LDIND_I);
+ mono_mb_emit_stloc (mb, conv_arg);
+ break;
+ }
+
+ case MARSHAL_ACTION_PUSH:
+ mono_mb_emit_ldloc (mb, conv_arg);
+ break;
+
+ case MARSHAL_ACTION_CONV_OUT: {
+ /* no resource release required */
+ break;
+ }
+
+ case MARSHAL_ACTION_CONV_RESULT: {
+ char *msg = g_strdup ("HandleRefs can not be returned from unmanaged code (or passed by ref)");
+ mono_marshal_shared_mb_emit_exception_marshal_directive (mb, msg);
+ break;
+ }
+
+ case MARSHAL_ACTION_MANAGED_CONV_IN:
+ fprintf (stderr, "mono/marshal: SafeHandles missing MANAGED_CONV_IN\n");
+ break;
+
+ case MARSHAL_ACTION_MANAGED_CONV_OUT:
+ fprintf (stderr, "mono/marshal: SafeHandles missing MANAGED_CONV_OUT\n");
+ break;
+
+ case MARSHAL_ACTION_MANAGED_CONV_RESULT:
+ fprintf (stderr, "mono/marshal: SafeHandles missing MANAGED_CONV_RESULT\n");
+ break;
+ default:
+ fprintf (stderr, "Unhandled case for MarshalAction: %d\n", action);
+ }
+ return conv_arg;
+}
+
+static int
+emit_marshal_object_ilgen (EmitMarshalContext *m, int argnum, MonoType *t,
+ MonoMarshalSpec *spec,
+ int conv_arg, MonoType **conv_arg_type,
+ MarshalAction action)
+{
+ MonoMethodBuilder *mb = m->mb;
+ MonoClass *klass = mono_class_from_mono_type_internal (t);
+ int pos, pos2, loc;
+
+ MonoType *int_type = mono_get_int_type ();
+ switch (action) {
+ case MARSHAL_ACTION_CONV_IN:
+ *conv_arg_type = int_type;
+ conv_arg = mono_mb_add_local (mb, int_type);
+
+ m->orig_conv_args [argnum] = 0;
+
+ if (mono_class_from_mono_type_internal (t) == mono_defaults.object_class) {
+ char *msg = g_strdup_printf ("Marshalling of type object is not implemented");
+ mono_marshal_shared_mb_emit_exception_marshal_directive (mb, msg);
+ break;
+ }
+
+ if (m_class_is_delegate (klass)) {
+ if (m_type_is_byref (t)) {
+ if (!(t->attrs & PARAM_ATTRIBUTE_OUT)) {
+ char *msg = g_strdup_printf ("Byref marshalling of delegates is not implemented.");
+ mono_marshal_shared_mb_emit_exception_marshal_directive (mb, msg);
+ }
+ mono_mb_emit_byte (mb, CEE_LDNULL);
+ mono_mb_emit_stloc (mb, conv_arg);
+ } else {
+ mono_mb_emit_ldarg (mb, argnum);
+ mono_mb_emit_icall_id (mb, mono_marshal_shared_conv_to_icall (MONO_MARSHAL_CONV_DEL_FTN, NULL));
+ mono_mb_emit_stloc (mb, conv_arg);
+ }
+ } else if (klass == mono_class_try_get_stringbuilder_class ()) {
+ MonoMarshalNative encoding = mono_marshal_get_string_encoding (m->piinfo, spec);
+ MonoMarshalConv conv = mono_marshal_get_stringbuilder_to_ptr_conv (m->piinfo, spec);
+
+#if 0
+ if (m_type_is_byref (t)) {
+ if (!(t->attrs & PARAM_ATTRIBUTE_OUT)) {
+ char *msg = g_strdup_printf ("Byref marshalling of stringbuilders is not implemented.");
+ mono_marshal_shared_mb_emit_exception_marshal_directive (mb, msg);
+ }
+ break;
+ }
+#endif
+
+ if (m_type_is_byref (t) && !(t->attrs & PARAM_ATTRIBUTE_IN) && (t->attrs & PARAM_ATTRIBUTE_OUT))
+ break;
+
+ if (conv == MONO_MARSHAL_CONV_INVALID) {
+ char *msg = g_strdup_printf ("stringbuilder marshalling conversion %d not implemented", encoding);
+ mono_marshal_shared_mb_emit_exception_marshal_directive (mb, msg);
+ break;
+ }
+
+ mono_mb_emit_ldarg (mb, argnum);
+ if (m_type_is_byref (t))
+ mono_mb_emit_byte (mb, CEE_LDIND_I);
+
+ mono_mb_emit_icall_id (mb, mono_marshal_shared_conv_to_icall (conv, NULL));
+ mono_mb_emit_stloc (mb, conv_arg);
+ } else if (m_class_is_blittable (klass)) {
+ mono_mb_emit_byte (mb, CEE_LDNULL);
+ mono_mb_emit_stloc (mb, conv_arg);
+
+ mono_mb_emit_ldarg (mb, argnum);
+ pos = mono_mb_emit_branch (mb, CEE_BRFALSE);
+
+ mono_mb_emit_ldarg (mb, argnum);
+ mono_mb_emit_ldflda (mb, MONO_ABI_SIZEOF (MonoObject));
+ mono_mb_emit_stloc (mb, conv_arg);
+
+ mono_mb_patch_branch (mb, pos);
+ break;
+ } else {
+ mono_mb_emit_byte (mb, CEE_LDNULL);
+ mono_mb_emit_stloc (mb, conv_arg);
+
+ if (m_type_is_byref (t)) {
+ /* we dont need any conversions for out parameters */
+ if (t->attrs & PARAM_ATTRIBUTE_OUT)
+ break;
+
+ mono_mb_emit_ldarg (mb, argnum);
+ mono_mb_emit_byte (mb, CEE_LDIND_I);
+
+ } else {
+ mono_mb_emit_ldarg (mb, argnum);
+ mono_mb_emit_byte (mb, MONO_CUSTOM_PREFIX);
+ mono_mb_emit_byte (mb, CEE_MONO_OBJADDR);
+ }
+
+ /* store the address of the source into local variable 0 */
+ mono_mb_emit_stloc (mb, 0);
+ mono_mb_emit_ldloc (mb, 0);
+ pos = mono_mb_emit_branch (mb, CEE_BRFALSE);
+
+ /* allocate space for the native struct and store the address */
+ mono_mb_emit_icon (mb, mono_class_native_size (klass, NULL));
+ mono_mb_emit_byte (mb, CEE_PREFIX1);
+ mono_mb_emit_byte (mb, CEE_LOCALLOC);
+ mono_mb_emit_stloc (mb, conv_arg);
+
+ if (m_type_is_byref (t)) {
+ /* Need to store the original buffer so we can free it later */
+ m->orig_conv_args [argnum] = mono_mb_add_local (mb, int_type);
+ mono_mb_emit_ldloc (mb, conv_arg);
+ mono_mb_emit_stloc (mb, m->orig_conv_args [argnum]);
+ }
+
+ /* set the src_ptr */
+ mono_mb_emit_ldloc (mb, 0);
+ mono_mb_emit_ldflda (mb, MONO_ABI_SIZEOF (MonoObject));
+ mono_mb_emit_stloc (mb, 0);
+
+ /* set dst_ptr */
+ mono_mb_emit_ldloc (mb, conv_arg);
+ mono_mb_emit_stloc (mb, 1);
+
+ /* emit valuetype conversion code */
+ mono_marshal_shared_emit_struct_conv (mb, klass, FALSE);
+
+ mono_mb_patch_branch (mb, pos);
+ }
+ break;
+
+ case MARSHAL_ACTION_CONV_OUT:
+ if (klass == mono_class_try_get_stringbuilder_class ()) {
+ gboolean need_free;
+ MonoMarshalNative encoding;
+ MonoMarshalConv conv;
+
+ encoding = mono_marshal_get_string_encoding (m->piinfo, spec);
+ conv = mono_marshal_get_ptr_to_stringbuilder_conv (m->piinfo, spec, &need_free);
+
+ g_assert (encoding != -1);
+
+ if (m_type_is_byref (t)) {
+ //g_assert (!(t->attrs & PARAM_ATTRIBUTE_OUT));
+
+ need_free = TRUE;
+
+ mono_mb_emit_ldarg (mb, argnum);
+ mono_mb_emit_ldloc (mb, conv_arg);
+
+ switch (encoding) {
+ case MONO_NATIVE_LPWSTR:
+ mono_mb_emit_icall (mb, mono_string_utf16_to_builder2);
+ break;
+ case MONO_NATIVE_LPSTR:
+ mono_mb_emit_icall (mb, mono_string_utf8_to_builder2);
+ break;
+ case MONO_NATIVE_UTF8STR:
+ mono_mb_emit_icall (mb, mono_string_utf8_to_builder2);
+ break;
+ default:
+ g_assert_not_reached ();
+ }
+
+ mono_mb_emit_byte (mb, CEE_STIND_REF);
+ } else if (t->attrs & PARAM_ATTRIBUTE_OUT || !(t->attrs & PARAM_ATTRIBUTE_IN)) {
+ mono_mb_emit_ldarg (mb, argnum);
+ mono_mb_emit_ldloc (mb, conv_arg);
+
+ mono_mb_emit_icall_id (mb, mono_marshal_shared_conv_to_icall (conv, NULL));
+ }
+
+ if (need_free) {
+ mono_mb_emit_ldloc (mb, conv_arg);
+ mono_mb_emit_icall (mb, mono_marshal_free);
+ }
+ break;
+ }
+
+ if (m_class_is_delegate (klass)) {
+ if (m_type_is_byref (t)) {
+ mono_mb_emit_ldarg (mb, argnum);
+ mono_mb_emit_byte (mb, MONO_CUSTOM_PREFIX);
+ mono_mb_emit_op (mb, CEE_MONO_CLASSCONST, klass);
+ mono_mb_emit_ldloc (mb, conv_arg);
+ mono_mb_emit_icall_id (mb, mono_marshal_shared_conv_to_icall (MONO_MARSHAL_CONV_FTN_DEL, NULL));
+ mono_mb_emit_byte (mb, CEE_STIND_REF);
+ }
+ break;
+ }
+
+ if (m_type_is_byref (t) && (t->attrs & PARAM_ATTRIBUTE_OUT)) {
+ /* allocate a new object */
+ mono_mb_emit_ldarg (mb, argnum);
+ mono_mb_emit_byte (mb, MONO_CUSTOM_PREFIX);
+ mono_mb_emit_op (mb, CEE_MONO_NEWOBJ, klass);
+ mono_mb_emit_byte (mb, CEE_STIND_REF);
+ }
+
+ /* dst = *argument */
+ mono_mb_emit_ldarg (mb, argnum);
+
+ if (m_type_is_byref (t))
+ mono_mb_emit_byte (mb, CEE_LDIND_I);
+
+ mono_mb_emit_stloc (mb, 1);
+
+ mono_mb_emit_ldloc (mb, 1);
+ pos = mono_mb_emit_branch (mb, CEE_BRFALSE);
+
+ if (m_type_is_byref (t) || (t->attrs & PARAM_ATTRIBUTE_OUT)) {
+ mono_mb_emit_ldloc (mb, 1);
+ mono_mb_emit_icon (mb, MONO_ABI_SIZEOF (MonoObject));
+ mono_mb_emit_byte (mb, CEE_ADD);
+ mono_mb_emit_stloc (mb, 1);
+
+ /* src = tmp_locals [i] */
+ mono_mb_emit_ldloc (mb, conv_arg);
+ mono_mb_emit_stloc (mb, 0);
+
+ /* emit valuetype conversion code */
+ mono_marshal_shared_emit_struct_conv (mb, klass, TRUE);
+
+ /* Free the structure returned by the native code */
+ emit_struct_free (mb, klass, conv_arg);
+
+ if (m->orig_conv_args [argnum]) {
+ /*
+ * If the native function changed the pointer, then free
+ * the original structure plus the new pointer.
+ */
+ mono_mb_emit_ldloc (mb, m->orig_conv_args [argnum]);
+ mono_mb_emit_ldloc (mb, conv_arg);
+ pos2 = mono_mb_emit_branch (mb, CEE_BEQ);
+
+ if (!(t->attrs & PARAM_ATTRIBUTE_OUT)) {
+ g_assert (m->orig_conv_args [argnum]);
+
+ emit_struct_free (mb, klass, m->orig_conv_args [argnum]);
+ }
+
+ mono_mb_emit_ldloc (mb, conv_arg);
+ mono_mb_emit_icall (mb, mono_marshal_free);
+
+ mono_mb_patch_branch (mb, pos2);
+ }
+ }
+ else
+ /* Free the original structure passed to native code */
+ emit_struct_free (mb, klass, conv_arg);
+
+ mono_mb_patch_branch (mb, pos);
+ break;
+
+ case MARSHAL_ACTION_PUSH:
+ if (m_type_is_byref (t))
+ mono_mb_emit_ldloc_addr (mb, conv_arg);
+ else
+ mono_mb_emit_ldloc (mb, conv_arg);
+ break;
+
+ case MARSHAL_ACTION_CONV_RESULT:
+ if (m_class_is_delegate (klass)) {
+ g_assert (!m_type_is_byref (t));
+ mono_mb_emit_stloc (mb, 0);
+ mono_mb_emit_byte (mb, MONO_CUSTOM_PREFIX);
+ mono_mb_emit_op (mb, CEE_MONO_CLASSCONST, klass);
+ mono_mb_emit_ldloc (mb, 0);
+ mono_mb_emit_icall_id (mb, mono_marshal_shared_conv_to_icall (MONO_MARSHAL_CONV_FTN_DEL, NULL));
+ mono_mb_emit_stloc (mb, 3);
+ } else if (klass == mono_class_try_get_stringbuilder_class ()) {
+ // FIXME:
+ char *msg = g_strdup_printf ("Return marshalling of stringbuilders is not implemented.");
+ mono_marshal_shared_mb_emit_exception_marshal_directive (mb, msg);
+ } else {
+ /* set src */
+ mono_mb_emit_stloc (mb, 0);
+
+ /* Make a copy since emit_conv modifies local 0 */
+ loc = mono_mb_add_local (mb, int_type);
+ mono_mb_emit_ldloc (mb, 0);
+ mono_mb_emit_stloc (mb, loc);
+
+ mono_mb_emit_byte (mb, CEE_LDNULL);
+ mono_mb_emit_stloc (mb, 3);
+
+ mono_mb_emit_ldloc (mb, 0);
+ pos = mono_mb_emit_branch (mb, CEE_BRFALSE);
+
+ /* allocate result object */
+
+ mono_mb_emit_byte (mb, MONO_CUSTOM_PREFIX);
+ mono_mb_emit_op (mb, CEE_MONO_NEWOBJ, klass);
+ mono_mb_emit_stloc (mb, 3);
+
+ /* set dst */
+
+ mono_mb_emit_ldloc (mb, 3);
+ mono_mb_emit_ldflda (mb, MONO_ABI_SIZEOF (MonoObject));
+ mono_mb_emit_stloc (mb, 1);
+
+ /* emit conversion code */
+ mono_marshal_shared_emit_struct_conv (mb, klass, TRUE);
+
+ emit_struct_free (mb, klass, loc);
+
+ /* Free the pointer allocated by unmanaged code */
+ mono_mb_emit_ldloc (mb, loc);
+ mono_mb_emit_icall (mb, mono_marshal_free);
+ mono_mb_patch_branch (mb, pos);
+ }
+ break;
+
+ case MARSHAL_ACTION_MANAGED_CONV_IN:
+ conv_arg = mono_mb_add_local (mb, m_class_get_byval_arg (klass));
+
+ if (m_class_is_delegate (klass)) {
+ mono_mb_emit_byte (mb, MONO_CUSTOM_PREFIX);
+ mono_mb_emit_op (mb, CEE_MONO_CLASSCONST, klass);
+ mono_mb_emit_ldarg (mb, argnum);
+ if (m_type_is_byref (t))
+ mono_mb_emit_byte (mb, CEE_LDIND_I);
+ mono_mb_emit_icall_id (mb, mono_marshal_shared_conv_to_icall (MONO_MARSHAL_CONV_FTN_DEL, NULL));
+ mono_mb_emit_stloc (mb, conv_arg);
+ break;
+ }
+
+ if (klass == mono_class_try_get_stringbuilder_class ()) {
+ MonoMarshalNative encoding;
+
+ encoding = mono_marshal_get_string_encoding (m->piinfo, spec);
+
+ // FIXME:
+ g_assert (encoding == MONO_NATIVE_LPSTR || encoding == MONO_NATIVE_UTF8STR);
+
+ g_assert (!m_type_is_byref (t));
+ g_assert (encoding != -1);
+
+ mono_mb_emit_ldarg (mb, argnum);
+ mono_mb_emit_icall (mb, mono_string_utf8_to_builder2);
+ mono_mb_emit_stloc (mb, conv_arg);
+ break;
+ }
+
+ /* The class can not have an automatic layout */
+ if (mono_class_is_auto_layout (klass)) {
+ mono_mb_emit_auto_layout_exception (mb, klass);
+ break;
+ }
+
+ if (t->attrs & PARAM_ATTRIBUTE_OUT) {
+ mono_mb_emit_byte (mb, CEE_LDNULL);
+ mono_mb_emit_stloc (mb, conv_arg);
+ break;
+ }
+
+ /* Set src */
+ mono_mb_emit_ldarg (mb, argnum);
+ if (m_type_is_byref (t)) {
+ /* Check for NULL and raise an exception */
+ pos2 = mono_mb_emit_branch (mb, CEE_BRTRUE);
+
+ mono_mb_emit_exception (mb, "ArgumentNullException", NULL);
+
+ mono_mb_patch_branch (mb, pos2);
+ mono_mb_emit_ldarg (mb, argnum);
+ mono_mb_emit_byte (mb, CEE_LDIND_I);
+ }
+
+ mono_mb_emit_stloc (mb, 0);
+
+ mono_mb_emit_byte (mb, CEE_LDC_I4_0);
+ mono_mb_emit_stloc (mb, conv_arg);
+
+ mono_mb_emit_ldloc (mb, 0);
+ pos = mono_mb_emit_branch (mb, CEE_BRFALSE);
+
+ /* Create and set dst */
+ mono_mb_emit_byte (mb, MONO_CUSTOM_PREFIX);
+ mono_mb_emit_op (mb, CEE_MONO_NEWOBJ, klass);
+ mono_mb_emit_stloc (mb, conv_arg);
+ mono_mb_emit_ldloc (mb, conv_arg);
+ mono_mb_emit_ldflda (mb, MONO_ABI_SIZEOF (MonoObject));
+ mono_mb_emit_stloc (mb, 1);
+
+ /* emit valuetype conversion code */
+ mono_marshal_shared_emit_struct_conv (mb, klass, TRUE);
+
+ mono_mb_patch_branch (mb, pos);
+ break;
+
+ case MARSHAL_ACTION_MANAGED_CONV_OUT:
+ if (m_class_is_delegate (klass)) {
+ if (m_type_is_byref (t)) {
+ int stind_op;
+ mono_mb_emit_ldarg (mb, argnum);
+ mono_mb_emit_ldloc (mb, conv_arg);
+ mono_mb_emit_icall_id (mb, mono_marshal_shared_conv_to_icall (MONO_MARSHAL_CONV_DEL_FTN, &stind_op));
+ mono_mb_emit_byte (mb, GINT_TO_UINT8 (stind_op));
+ break;
+ }
+ }
+
+ if (m_type_is_byref (t)) {
+ /* Check for null */
+ mono_mb_emit_ldloc (mb, conv_arg);
+ pos = mono_mb_emit_branch (mb, CEE_BRTRUE);
+ mono_mb_emit_ldarg (mb, argnum);
+ mono_mb_emit_byte (mb, CEE_LDC_I4_0);
+ mono_mb_emit_byte (mb, CEE_STIND_I);
+ pos2 = mono_mb_emit_branch (mb, CEE_BR);
+
+ mono_mb_patch_branch (mb, pos);
+
+ /* Set src */
+ mono_mb_emit_ldloc (mb, conv_arg);
+ mono_mb_emit_ldflda (mb, MONO_ABI_SIZEOF (MonoObject));
+ mono_mb_emit_stloc (mb, 0);
+
+ /* Allocate and set dest */
+ mono_mb_emit_icon (mb, mono_class_native_size (klass, NULL));
+ mono_mb_emit_byte (mb, CEE_CONV_I);
+ mono_mb_emit_icall (mb, ves_icall_marshal_alloc);
+ mono_mb_emit_stloc (mb, 1);
+
+ /* Update argument pointer */
+ mono_mb_emit_ldarg (mb, argnum);
+ mono_mb_emit_ldloc (mb, 1);
+ mono_mb_emit_byte (mb, CEE_STIND_I);
+
+ /* emit valuetype conversion code */
+ mono_marshal_shared_emit_struct_conv (mb, klass, FALSE);
+
+ mono_mb_patch_branch (mb, pos2);
+ } else if (klass == mono_class_try_get_stringbuilder_class ()) {
+ // FIXME: What to do here ?
+ } else {
+ /* byval [Out] marshalling */
+
+ /* FIXME: Handle null */
+
+ /* Set src */
+ mono_mb_emit_ldloc (mb, conv_arg);
+ mono_mb_emit_ldflda (mb, MONO_ABI_SIZEOF (MonoObject));
+ mono_mb_emit_stloc (mb, 0);
+
+ /* Set dest */
+ mono_mb_emit_ldarg (mb, argnum);
+ mono_mb_emit_stloc (mb, 1);
+
+ /* emit valuetype conversion code */
+ mono_marshal_shared_emit_struct_conv (mb, klass, FALSE);
+ }
+ break;
+
+ case MARSHAL_ACTION_MANAGED_CONV_RESULT:
+ if (m_class_is_delegate (klass)) {
+ mono_mb_emit_icall_id (mb, mono_marshal_shared_conv_to_icall (MONO_MARSHAL_CONV_DEL_FTN, NULL));
+ mono_mb_emit_stloc (mb, 3);
+ break;
+ }
+
+ /* The class can not have an automatic layout */
+ if (mono_class_is_auto_layout (klass)) {
+ mono_mb_emit_auto_layout_exception (mb, klass);
+ break;
+ }
+
+ mono_mb_emit_stloc (mb, 0);
+ /* Check for null */
+ mono_mb_emit_ldloc (mb, 0);
+ pos = mono_mb_emit_branch (mb, CEE_BRTRUE);
+ mono_mb_emit_byte (mb, CEE_LDNULL);
+ mono_mb_emit_stloc (mb, 3);
+ pos2 = mono_mb_emit_branch (mb, CEE_BR);
+
+ mono_mb_patch_branch (mb, pos);
+
+ /* Set src */
+ mono_mb_emit_ldloc (mb, 0);
+ mono_mb_emit_ldflda (mb, MONO_ABI_SIZEOF (MonoObject));
+ mono_mb_emit_stloc (mb, 0);
+
+ /* Allocate and set dest */
+ mono_mb_emit_icon (mb, mono_class_native_size (klass, NULL));
+ mono_mb_emit_byte (mb, CEE_CONV_I);
+ mono_mb_emit_icall (mb, ves_icall_marshal_alloc);
+ mono_mb_emit_byte (mb, CEE_DUP);
+ mono_mb_emit_stloc (mb, 1);
+ mono_mb_emit_stloc (mb, 3);
+
+ mono_marshal_shared_emit_struct_conv (mb, klass, FALSE);
+
+ mono_mb_patch_branch (mb, pos2);
+ break;
+
+ default:
+ g_assert_not_reached ();
+ }
+ return conv_arg;
+}
+
+static int
+emit_marshal_variant_ilgen (EmitMarshalContext *m, int argnum, MonoType *t,
+ MonoMarshalSpec *spec,
+ int conv_arg, MonoType **conv_arg_type,
+ MarshalAction action)
+{
+#ifndef DISABLE_COM
+ MonoMethodBuilder *mb = m->mb;
+ MonoType *variant_type = m_class_get_byval_arg (mono_class_get_variant_class ());
+ MonoType *variant_type_byref = mono_class_get_byref_type (mono_class_get_variant_class ());
+ MonoType *object_type = mono_get_object_type ();
+
+ switch (action) {
+ case MARSHAL_ACTION_CONV_IN: {
+ conv_arg = mono_mb_add_local (mb, variant_type);
+
+ if (m_type_is_byref (t))
+ *conv_arg_type = variant_type_byref;
+ else
+ *conv_arg_type = variant_type;
+
+ if (m_type_is_byref (t) && !(t->attrs & PARAM_ATTRIBUTE_IN) && t->attrs & PARAM_ATTRIBUTE_OUT)
+ break;
+
+ mono_mb_emit_ldarg (mb, argnum);
+ if (m_type_is_byref (t))
+ mono_mb_emit_byte(mb, CEE_LDIND_REF);
+ mono_mb_emit_ldloc_addr (mb, conv_arg);
+ mono_mb_emit_managed_call (mb, mono_get_Marshal_GetNativeVariantForObject (), NULL);
+ break;
+ }
+
+ case MARSHAL_ACTION_CONV_OUT: {
+ if (m_type_is_byref (t) && (t->attrs & PARAM_ATTRIBUTE_OUT || !(t->attrs & PARAM_ATTRIBUTE_IN))) {
+ mono_mb_emit_ldarg (mb, argnum);
+ mono_mb_emit_ldloc_addr (mb, conv_arg);
+ mono_mb_emit_managed_call (mb, mono_get_Marshal_GetObjectForNativeVariant (), NULL);
+ mono_mb_emit_byte (mb, CEE_STIND_REF);
+ }
+
+ mono_mb_emit_ldloc_addr (mb, conv_arg);
+ mono_mb_emit_managed_call (mb, mono_get_Variant_Clear (), NULL);
+ break;
+ }
+
+ case MARSHAL_ACTION_PUSH:
+ if (m_type_is_byref (t))
+ mono_mb_emit_ldloc_addr (mb, conv_arg);
+ else
+ mono_mb_emit_ldloc (mb, conv_arg);
+ break;
+
+ case MARSHAL_ACTION_CONV_RESULT: {
+ char *msg = g_strdup ("Marshalling of VARIANT not supported as a return type.");
+ mono_marshal_shared_mb_emit_exception_marshal_directive (mb, msg);
+ break;
+ }
+
+ case MARSHAL_ACTION_MANAGED_CONV_IN: {
+ conv_arg = mono_mb_add_local (mb, object_type);
+
+ if (m_type_is_byref (t))
+ *conv_arg_type = variant_type_byref;
+ else
+ *conv_arg_type = variant_type;
+
+ if (m_type_is_byref (t) && !(t->attrs & PARAM_ATTRIBUTE_IN) && t->attrs & PARAM_ATTRIBUTE_OUT)
+ break;
+
+ if (m_type_is_byref (t))
+ mono_mb_emit_ldarg (mb, argnum);
+ else
+ mono_mb_emit_ldarg_addr (mb, argnum);
+ mono_mb_emit_managed_call (mb, mono_get_Marshal_GetObjectForNativeVariant (), NULL);
+ mono_mb_emit_stloc (mb, conv_arg);
+ break;
+ }
+
+ case MARSHAL_ACTION_MANAGED_CONV_OUT: {
+ if (m_type_is_byref (t) && (t->attrs & PARAM_ATTRIBUTE_OUT || !(t->attrs & PARAM_ATTRIBUTE_IN))) {
+ mono_mb_emit_ldloc (mb, conv_arg);
+ mono_mb_emit_ldarg (mb, argnum);
+ mono_mb_emit_managed_call (mb, mono_get_Marshal_GetNativeVariantForObject (), NULL);
+ }
+ break;
+ }
+
+ case MARSHAL_ACTION_MANAGED_CONV_RESULT: {
+ char *msg = g_strdup ("Marshalling of VARIANT not supported as a return type.");
+ mono_marshal_shared_mb_emit_exception_marshal_directive (mb, msg);
+ break;
+ }
+
+ default:
+ g_assert_not_reached ();
+ }
+#endif /* DISABLE_COM */
+
+ return conv_arg;
+}
+
+static MonoMarshalIlgenCallbacks *
+get_marshal_cb (void)
+{
+ if (G_UNLIKELY (!ilgen_cb_inited)) {
+#ifdef ENABLE_ILGEN
+ mono_marshal_ilgen_init ();
+#else
+ mono_marshal_noilgen_init_heavyweight ();
+#endif
+ }
+ return &ilgen_marshal_cb;
+}
+
+int
+mono_emit_marshal_ilgen (EmitMarshalContext *m, int argnum, MonoType *t,
+ MonoMarshalSpec *spec, int conv_arg,
+ MonoType **conv_arg_type, MarshalAction action, MonoMarshalLightweightCallbacks* lightweigth_cb)
+{
+ if (spec && spec->native == MONO_NATIVE_CUSTOM)
+ return get_marshal_cb ()->emit_marshal_custom (m, argnum, t, spec, conv_arg, conv_arg_type, action);
+
+ if (spec && spec->native == MONO_NATIVE_ASANY)
+ return get_marshal_cb ()->emit_marshal_asany (m, argnum, t, spec, conv_arg, conv_arg_type, action);
+
+ switch (t->type) {
+ case MONO_TYPE_VALUETYPE:
+ if (t->data.klass == mono_class_try_get_handleref_class ())
+ return get_marshal_cb ()->emit_marshal_handleref (m, argnum, t, spec, conv_arg, conv_arg_type, action);
+
+ return get_marshal_cb ()->emit_marshal_vtype (m, argnum, t, spec, conv_arg, conv_arg_type, action);
+ case MONO_TYPE_STRING:
+ return get_marshal_cb ()->emit_marshal_string (m, argnum, t, spec, conv_arg, conv_arg_type, action);
+ case MONO_TYPE_CLASS:
+ case MONO_TYPE_OBJECT:
+#if !defined(DISABLE_COM)
+ if (spec && spec->native == MONO_NATIVE_STRUCT)
+ return get_marshal_cb ()->emit_marshal_variant (m, argnum, t, spec, conv_arg, conv_arg_type, action);
+#endif
+
+#if !defined(DISABLE_COM)
+ if ((spec && (spec->native == MONO_NATIVE_IUNKNOWN ||
+ spec->native == MONO_NATIVE_IDISPATCH ||
+ spec->native == MONO_NATIVE_INTERFACE)) ||
+ (t->type == MONO_TYPE_CLASS && mono_cominterop_is_interface(t->data.klass)))
+ return mono_cominterop_emit_marshal_com_interface (m, argnum, t, spec, conv_arg, conv_arg_type, action);
+ if (spec && (spec->native == MONO_NATIVE_SAFEARRAY) &&
+ (spec->data.safearray_data.elem_type == MONO_VARIANT_VARIANT) &&
+ ((action == MARSHAL_ACTION_CONV_OUT) || (action == MARSHAL_ACTION_CONV_IN) || (action == MARSHAL_ACTION_PUSH)))
+ return mono_cominterop_emit_marshal_safearray (m, argnum, t, spec, conv_arg, conv_arg_type, action);
+#endif
+
+ if (mono_class_try_get_safehandle_class () != NULL && t->data.klass &&
+ mono_class_is_subclass_of_internal (t->data.klass, mono_class_try_get_safehandle_class (), FALSE))
+ return get_marshal_cb ()->emit_marshal_safehandle (m, argnum, t, spec, conv_arg, conv_arg_type, action);
+
+ return get_marshal_cb ()->emit_marshal_object (m, argnum, t, spec, conv_arg, conv_arg_type, action);
+ case MONO_TYPE_ARRAY:
+ case MONO_TYPE_SZARRAY:
+ return get_marshal_cb ()->emit_marshal_array (m, argnum, t, spec, conv_arg, conv_arg_type, action);
+ case MONO_TYPE_BOOLEAN:
+ return get_marshal_cb ()->emit_marshal_boolean (m, argnum, t, spec, conv_arg, conv_arg_type, action);
+ case MONO_TYPE_PTR:
+ return get_marshal_cb ()->emit_marshal_ptr (m, argnum, t, spec, conv_arg, conv_arg_type, action);
+ case MONO_TYPE_CHAR:
+ return get_marshal_cb ()->emit_marshal_char (m, argnum, t, spec, conv_arg, conv_arg_type, action);
+ case MONO_TYPE_I1:
+ case MONO_TYPE_U1:
+ case MONO_TYPE_I2:
+ case MONO_TYPE_U2:
+ case MONO_TYPE_I4:
+ case MONO_TYPE_U4:
+ case MONO_TYPE_I:
+ case MONO_TYPE_U:
+ case MONO_TYPE_R4:
+ case MONO_TYPE_R8:
+ case MONO_TYPE_I8:
+ case MONO_TYPE_U8:
+ case MONO_TYPE_FNPTR:
+ return lightweigth_cb->emit_marshal_scalar (m, argnum, t, spec, conv_arg, conv_arg_type, action);
+ case MONO_TYPE_GENERICINST:
+ if (mono_type_generic_inst_is_valuetype (t))
+ return get_marshal_cb ()->emit_marshal_vtype (m, argnum, t, spec, conv_arg, conv_arg_type, action);
+ else
+ return get_marshal_cb ()->emit_marshal_object (m, argnum, t, spec, conv_arg, conv_arg_type, action);
+ default:
+ return conv_arg;
+ }
+}
+
+void
+mono_marshal_ilgen_init (void)
+{
+ MonoMarshalIlgenCallbacks cb;
+ cb.version = MONO_MARSHAL_CALLBACKS_VERSION;
+ cb.emit_marshal_array = emit_marshal_array_ilgen;
+ cb.emit_marshal_ptr = emit_marshal_ptr_ilgen;
+ cb.emit_marshal_char = emit_marshal_char_ilgen;
+ cb.emit_marshal_vtype = emit_marshal_vtype_ilgen;
+ cb.emit_marshal_string = emit_marshal_string_ilgen;
+ cb.emit_marshal_variant = emit_marshal_variant_ilgen;
+ cb.emit_marshal_safehandle = emit_marshal_safehandle_ilgen;
+ cb.emit_marshal_object = emit_marshal_object_ilgen;
+ cb.emit_marshal_boolean = emit_marshal_boolean_ilgen;
+ cb.emit_marshal_custom = emit_marshal_custom_ilgen;
+ cb.emit_marshal_asany = emit_marshal_asany_ilgen;
+ cb.emit_marshal_handleref = emit_marshal_handleref_ilgen;
+
+#ifdef DISABLE_NONBLITTABLE
+ mono_marshal_noilgen_init_blittable (&cb);
+#endif
+ mono_install_marshal_callbacks_ilgen (&cb);
+}
+
+
diff --git a/src/mono/mono/component/marshal-ilgen.h b/src/mono/mono/metadata/marshal-ilgen.h
similarity index 73%
rename from src/mono/mono/component/marshal-ilgen.h
rename to src/mono/mono/metadata/marshal-ilgen.h
index 08768a374483a..1b3914588fb2e 100644
--- a/src/mono/mono/component/marshal-ilgen.h
+++ b/src/mono/mono/metadata/marshal-ilgen.h
@@ -1,24 +1,9 @@
-/**
- * \file
- * Copyright 2022 Microsoft
- * Licensed under the MIT license. See LICENSE file in the project root for full license information.
- */
+
#ifndef __MARSHAL_ILGEN_H__
#define __MARSHAL_ILGEN_H__
#include "metadata/marshal-lightweight.h"
#include "metadata/marshal.h"
-#include "mono/component/component.h"
-
-typedef struct MonoComponentMarshalILgen {
- MonoComponent component;
- void (*ilgen_init) (void);
- int (*emit_marshal_ilgen) (EmitMarshalContext *m, int argnum, MonoType *t,
- MonoMarshalSpec *spec, int conv_arg,
- MonoType **conv_arg_type, MarshalAction action, MonoMarshalLightweightCallbacks* lightweigth_cb);
- void (*install_callbacks_mono) (IlgenCallbacksToMono *callbacks);
-
-} MonoComponentMarshalILgen;
typedef struct {
int version;
@@ -34,23 +19,24 @@ typedef struct {
int (*emit_marshal_custom) (EmitMarshalContext *m, int argnum, MonoType *t, MonoMarshalSpec *spec, int conv_arg, MonoType **conv_arg_type, MarshalAction action);
int (*emit_marshal_asany) (EmitMarshalContext *m, int argnum, MonoType *t, MonoMarshalSpec *spec, int conv_arg, MonoType **conv_arg_type, MarshalAction action);
int (*emit_marshal_handleref) (EmitMarshalContext *m, int argnum, MonoType *t, MonoMarshalSpec *spec, int conv_arg, MonoType **conv_arg_type, MarshalAction action);
-} MonoMarshalILgenCallbacks;
-
-MONO_COMPONENT_EXPORT_ENTRYPOINT
-MonoComponentMarshalILgen* mono_component_marshal_ilgen_init (void);
+} MonoMarshalIlgenCallbacks;
void
-mono_install_marshal_callbacks_ilgen (MonoMarshalILgenCallbacks *cb);
+mono_install_marshal_callbacks_ilgen (MonoMarshalIlgenCallbacks *cb);
+
MONO_API void
mono_marshal_ilgen_init (void);
+void
+mono_marshal_noilgen_init_heavyweight (void);
+
+void
+mono_marshal_noilgen_init_lightweight (void);
+
int
mono_emit_marshal_ilgen (EmitMarshalContext *m, int argnum, MonoType *t,
MonoMarshalSpec *spec, int conv_arg,
MonoType **conv_arg_type, MarshalAction action, MonoMarshalLightweightCallbacks* lightweigth_cb);
-void
-mono_marshal_ilgen_install_callbacks_mono (IlgenCallbacksToMono *callbacks);
-
#endif // __MARSHAL_ILGEN_H__
\ No newline at end of file
diff --git a/src/mono/mono/metadata/marshal-lightweight.c b/src/mono/mono/metadata/marshal-lightweight.c
index 0c9a5258063ca..70a8ee0ede294 100644
--- a/src/mono/mono/metadata/marshal-lightweight.c
+++ b/src/mono/mono/metadata/marshal-lightweight.c
@@ -8,13 +8,14 @@
#include
#endif
-#include "mono/metadata/method-builder-ilgen.h"
-#include "mono/metadata/method-builder-ilgen-internals.h"
+#include "metadata/method-builder-ilgen.h"
+#include "metadata/method-builder-ilgen-internals.h"
#include
#include
#include "cil-coff.h"
#include "metadata/marshal.h"
#include "metadata/marshal-internals.h"
+#include "metadata/marshal-ilgen.h"
#include "metadata/marshal-lightweight.h"
#include "metadata/marshal-shared.h"
#include "metadata/tabledefs.h"
@@ -23,7 +24,6 @@
#include "mono/metadata/abi-details.h"
#include "mono/metadata/class-abi-details.h"
#include "mono/metadata/class-init.h"
-#include "mono/metadata/components.h"
#include "mono/metadata/debug-helpers.h"
#include "mono/metadata/threads.h"
#include "mono/metadata/monitor.h"
diff --git a/src/mono/mono/metadata/marshal-lightweight.h b/src/mono/mono/metadata/marshal-lightweight.h
index b25d9cc9f2aba..8dfd4803a9649 100644
--- a/src/mono/mono/metadata/marshal-lightweight.h
+++ b/src/mono/mono/metadata/marshal-lightweight.h
@@ -5,7 +5,6 @@
*/
#ifndef __MONO_MARSHAL_LIGHTWEIGHT_H__
#define __MONO_MARSHAL_LIGHTWEIGHT_H__
-#include
MONO_API void
mono_marshal_lightweight_init (void);
diff --git a/src/mono/mono/metadata/marshal-noilgen.c b/src/mono/mono/metadata/marshal-noilgen.c
index 8d6f75981cd87..ae073fcaf7f8e 100644
--- a/src/mono/mono/metadata/marshal-noilgen.c
+++ b/src/mono/mono/metadata/marshal-noilgen.c
@@ -1,13 +1,38 @@
#include "config.h"
+
#include
-#include
-#include
-#include
+#include "metadata/marshal-internals.h"
+#include "metadata/marshal.h"
+#include "metadata/marshal-ilgen.h"
#include "utils/mono-compiler.h"
#ifndef ENABLE_ILGEN
+static int
+emit_marshal_array_noilgen (EmitMarshalContext *m, int argnum, MonoType *t,
+ MonoMarshalSpec *spec,
+ int conv_arg, MonoType **conv_arg_type,
+ MarshalAction action)
+{
+ MonoType *int_type = mono_get_int_type ();
+ MonoType *object_type = mono_get_object_type ();
+ switch (action) {
+ case MARSHAL_ACTION_CONV_IN:
+ *conv_arg_type = object_type;
+ break;
+ case MARSHAL_ACTION_MANAGED_CONV_IN:
+ *conv_arg_type = int_type;
+ break;
+ }
+ return conv_arg;
+}
-
+static int
+emit_marshal_ptr_noilgen (EmitMarshalContext *m, int argnum, MonoType *t,
+ MonoMarshalSpec *spec, int conv_arg,
+ MonoType **conv_arg_type, MarshalAction action)
+{
+ return conv_arg;
+}
static int
emit_marshal_scalar_noilgen (EmitMarshalContext *m, int argnum, MonoType *t,
@@ -18,6 +43,136 @@ emit_marshal_scalar_noilgen (EmitMarshalContext *m, int argnum, MonoType *t,
}
#endif
+#if !defined(ENABLE_ILGEN) || defined(DISABLE_NONBLITTABLE)
+static int
+emit_marshal_boolean_noilgen (EmitMarshalContext *m, int argnum, MonoType *t,
+ MonoMarshalSpec *spec,
+ int conv_arg, MonoType **conv_arg_type,
+ MarshalAction action)
+{
+ MonoType *int_type = mono_get_int_type ();
+ switch (action) {
+ case MARSHAL_ACTION_CONV_IN:
+ if (m_type_is_byref (t))
+ *conv_arg_type = int_type;
+ else
+ *conv_arg_type = mono_marshal_boolean_conv_in_get_local_type (spec, NULL);
+ break;
+
+ case MARSHAL_ACTION_MANAGED_CONV_IN: {
+ MonoClass* conv_arg_class = mono_marshal_boolean_managed_conv_in_get_conv_arg_class (spec, NULL);
+ if (m_type_is_byref (t))
+ *conv_arg_type = m_class_get_this_arg (conv_arg_class);
+ else
+ *conv_arg_type = m_class_get_byval_arg (conv_arg_class);
+ break;
+ }
+
+ }
+ return conv_arg;
+}
+
+static int
+emit_marshal_char_noilgen (EmitMarshalContext *m, int argnum, MonoType *t,
+ MonoMarshalSpec *spec, int conv_arg,
+ MonoType **conv_arg_type, MarshalAction action)
+{
+ return conv_arg;
+}
+
+static int
+emit_marshal_custom_noilgen (EmitMarshalContext *m, int argnum, MonoType *t,
+ MonoMarshalSpec *spec,
+ int conv_arg, MonoType **conv_arg_type,
+ MarshalAction action)
+{
+ MonoType *int_type = mono_get_int_type ();
+ if (action == MARSHAL_ACTION_CONV_IN && t->type == MONO_TYPE_VALUETYPE)
+ *conv_arg_type = int_type;
+ return conv_arg;
+}
+
+static int
+emit_marshal_asany_noilgen (EmitMarshalContext *m, int argnum, MonoType *t,
+ MonoMarshalSpec *spec,
+ int conv_arg, MonoType **conv_arg_type,
+ MarshalAction action)
+{
+ return conv_arg;
+}
+
+static int
+emit_marshal_vtype_noilgen (EmitMarshalContext *m, int argnum, MonoType *t,
+ MonoMarshalSpec *spec,
+ int conv_arg, MonoType **conv_arg_type,
+ MarshalAction action)
+{
+ return conv_arg;
+}
+
+static int
+emit_marshal_string_noilgen (EmitMarshalContext *m, int argnum, MonoType *t,
+ MonoMarshalSpec *spec,
+ int conv_arg, MonoType **conv_arg_type,
+ MarshalAction action)
+{
+ MonoType *int_type = mono_get_int_type ();
+ switch (action) {
+ case MARSHAL_ACTION_CONV_IN:
+ *conv_arg_type = int_type;
+ break;
+ case MARSHAL_ACTION_MANAGED_CONV_IN:
+ *conv_arg_type = int_type;
+ break;
+ }
+ return conv_arg;
+}
+
+static int
+emit_marshal_safehandle_noilgen (EmitMarshalContext *m, int argnum, MonoType *t,
+ MonoMarshalSpec *spec, int conv_arg,
+ MonoType **conv_arg_type, MarshalAction action)
+{
+ MonoType *int_type = mono_get_int_type ();
+ if (action == MARSHAL_ACTION_CONV_IN)
+ *conv_arg_type = int_type;
+ return conv_arg;
+}
+
+
+static int
+emit_marshal_handleref_noilgen (EmitMarshalContext *m, int argnum, MonoType *t,
+ MonoMarshalSpec *spec, int conv_arg,
+ MonoType **conv_arg_type, MarshalAction action)
+{
+ MonoType *int_type = mono_get_int_type ();
+ if (action == MARSHAL_ACTION_CONV_IN)
+ *conv_arg_type = int_type;
+ return conv_arg;
+}
+
+static int
+emit_marshal_object_noilgen (EmitMarshalContext *m, int argnum, MonoType *t,
+ MonoMarshalSpec *spec,
+ int conv_arg, MonoType **conv_arg_type,
+ MarshalAction action)
+{
+ MonoType *int_type = mono_get_int_type ();
+ if (action == MARSHAL_ACTION_CONV_IN)
+ *conv_arg_type = int_type;
+ return conv_arg;
+}
+
+static int
+emit_marshal_variant_noilgen (EmitMarshalContext *m, int argnum, MonoType *t,
+ MonoMarshalSpec *spec,
+ int conv_arg, MonoType **conv_arg_type,
+ MarshalAction action)
+{
+ g_assert_not_reached ();
+}
+#endif
+
#ifndef ENABLE_ILGEN
static void
emit_managed_wrapper_noilgen (MonoMethodBuilder *mb, MonoMethodSignature *invoke_sig, MonoMarshalSpec **mspecs, EmitMarshalContext* m, MonoMethod *method, MonoGCHandle target_handle, MonoError *error)
@@ -251,13 +406,38 @@ mono_marshal_noilgen_init_lightweight (void)
}
+void
+mono_marshal_noilgen_init_heavyweight (void)
+{
+ MonoMarshalIlgenCallbacks ilgen_cb;
+
+ ilgen_cb.version = MONO_MARSHAL_CALLBACKS_VERSION;
+ ilgen_cb.emit_marshal_array = emit_marshal_array_noilgen;
+ ilgen_cb.emit_marshal_vtype = emit_marshal_vtype_noilgen;
+ ilgen_cb.emit_marshal_string = emit_marshal_string_noilgen;
+ ilgen_cb.emit_marshal_safehandle = emit_marshal_safehandle_noilgen;
+ ilgen_cb.emit_marshal_handleref = emit_marshal_handleref_noilgen;
+ ilgen_cb.emit_marshal_object = emit_marshal_object_noilgen;
+ ilgen_cb.emit_marshal_variant = emit_marshal_variant_noilgen;
+ ilgen_cb.emit_marshal_asany = emit_marshal_asany_noilgen;
+ ilgen_cb.emit_marshal_boolean = emit_marshal_boolean_noilgen;
+ ilgen_cb.emit_marshal_custom = emit_marshal_custom_noilgen;
+ ilgen_cb.emit_marshal_ptr = emit_marshal_ptr_noilgen;
+
+ ilgen_cb.emit_marshal_char = emit_marshal_char_noilgen;
+ mono_install_marshal_callbacks_ilgen(&ilgen_cb);
+}
+
#else
void
mono_marshal_noilgen_init_lightweight (void)
{
}
-
+void
+mono_marshal_noilgen_init_heavyweight (void)
+{
+}
#endif
#ifdef DISABLE_NONBLITTABLE
diff --git a/src/mono/mono/metadata/marshal-noilgen.h b/src/mono/mono/metadata/marshal-noilgen.h
deleted file mode 100644
index c9cafee09fbbd..0000000000000
--- a/src/mono/mono/metadata/marshal-noilgen.h
+++ /dev/null
@@ -1,15 +0,0 @@
-/**
- * \file
- * Copyright 2022 Microsoft
- * Licensed under the MIT license. See LICENSE file in the project root for full license information.
- */
-#ifndef __MARSHAL_NOILGEN_H__
-#define __MARSHAL_NOILGEN_H__
-
-void
-mono_marshal_noilgen_init_lightweight (void);
-
-void
-mono_marshal_noilgen_init_heavyweight (void);
-
-#endif // __MARSHAL_NOILGEN_H__
\ No newline at end of file
diff --git a/src/mono/mono/metadata/marshal.c b/src/mono/mono/metadata/marshal.c
index 47b1a66a979ca..6caac8e640b33 100644
--- a/src/mono/mono/metadata/marshal.c
+++ b/src/mono/mono/metadata/marshal.c
@@ -32,7 +32,7 @@ MONO_PRAGMA_WARNING_POP()
#include "cil-coff.h"
#include "metadata/marshal.h"
#include "metadata/marshal-internals.h"
-#include "metadata/marshal-shared.h"
+#include "metadata/marshal-ilgen.h"
#include "metadata/marshal-lightweight.h"
#include "metadata/method-builder.h"
#include "metadata/method-builder-internals.h"
@@ -41,10 +41,8 @@ MONO_PRAGMA_WARNING_POP()
#include
#include "mono/metadata/abi-details.h"
#include "mono/metadata/class-abi-details.h"
-#include "mono/metadata/components.h"
#include "mono/metadata/debug-helpers.h"
#include "mono/metadata/threads.h"
-#include "mono/metadata/marshal-noilgen.h"
#include "mono/metadata/monitor.h"
#include "mono/metadata/class-init.h"
#include "mono/metadata/class-internals.h"
@@ -129,66 +127,6 @@ static GENERATE_TRY_GET_CLASS_WITH_CACHE (unmanaged_callconv_attribute, "System.
static gboolean type_is_blittable (MonoType *type);
-static IlgenCallbacksToMono ilgenCallbacksToMono = {
- &mono_get_object_type,
- &mono_marshal_get_ptr_to_string_conv,
- &mono_class_is_subclass_of_internal,
- &mono_class_native_size,
- &mono_class_try_get_handleref_class,
- &mono_class_try_get_safehandle_class,
- &mono_class_try_get_stringbuilder_class,
- &mono_defaults,
- &mono_marshal_boolean_conv_in_get_local_type,
- &mono_marshal_boolean_managed_conv_in_get_conv_arg_class,
- &mono_marshal_get_ptr_to_stringbuilder_conv,
- &mono_marshal_get_string_encoding,
- &mono_marshal_get_string_to_ptr_conv,
- &mono_marshal_get_stringbuilder_to_ptr_conv,
- &mono_marshal_load_type_info,
- &mono_marshal_shared_conv_to_icall,
- &mono_marshal_shared_emit_marshal_custom_get_instance,
- &mono_marshal_shared_emit_struct_conv,
- &mono_marshal_shared_emit_struct_conv_full,
- &mono_marshal_shared_get_method_nofail,
- &mono_marshal_shared_get_sh_dangerous_add_ref,
- &mono_marshal_shared_get_sh_dangerous_release,
- &mono_marshal_shared_init_safe_handle,
- &mono_marshal_shared_is_in,
- &mono_marshal_shared_is_out,
- &mono_marshal_shared_mb_emit_exception_marshal_directive,
- &mono_mb_add_local,
- &mono_mb_emit_add_to_local,
- &mono_mb_emit_auto_layout_exception,
- &mono_mb_emit_branch,
- &mono_mb_emit_branch_label,
- &mono_mb_emit_byte,
- &mono_mb_emit_exception,
- &mono_mb_emit_exception_full,
- &mono_mb_emit_icall_id,
- &mono_mb_emit_icon,
- &mono_mb_emit_ldarg,
- &mono_mb_emit_ldarg_addr,
- &mono_mb_emit_ldflda,
- &mono_mb_emit_ldloc,
- &mono_mb_emit_ldloc_addr,
- &mono_mb_emit_managed_call,
- &mono_mb_emit_op,
- &mono_mb_emit_stloc,
- &mono_mb_get_label,
- &mono_mb_patch_branch,
- &mono_pinvoke_is_unicode,
- &mono_reflection_type_from_name_checked,
- &mono_memory_barrier,
- &mono_marshal_need_free,
- &mono_get_int_type
-};
-
-IlgenCallbacksToMono*
-mono_marshal_get_mono_callbacks_for_ilgen (void)
-{
- return &ilgenCallbacksToMono;
-}
-
static MonoImage*
get_method_image (MonoMethod *method)
{
@@ -3222,9 +3160,8 @@ mono_emit_marshal (EmitMarshalContext *m, int argnum, MonoType *t,
if (!m->runtime_marshalling_enabled)
return mono_emit_disabled_marshal (m, argnum, t, spec, conv_arg, conv_arg_type, action);
- mono_component_marshal_ilgen()->install_callbacks_mono(mono_marshal_get_mono_callbacks_for_ilgen());
- return mono_component_marshal_ilgen()->emit_marshal_ilgen(m, argnum, t, spec, conv_arg, conv_arg_type, action, get_marshal_cb());
-}
+ return mono_emit_marshal_ilgen(m, argnum, t, spec, conv_arg, conv_arg_type, action, get_marshal_cb());
+}
static void
mono_marshal_set_callconv_for_type(MonoType *type, MonoMethodSignature *csig, gboolean *skip_gc_trans /*out*/)
@@ -6323,6 +6260,7 @@ get_marshal_cb (void)
mono_marshal_noilgen_init_lightweight ();
#endif
}
+
return &marshal_lightweight_cb;
}
diff --git a/src/mono/mono/metadata/marshal.h b/src/mono/mono/metadata/marshal.h
index e4244ad07c7b4..93aeb28667de5 100644
--- a/src/mono/mono/metadata/marshal.h
+++ b/src/mono/mono/metadata/marshal.h
@@ -348,60 +348,6 @@ typedef struct {
int (*emit_marshal_scalar) (EmitMarshalContext *m, int argnum, MonoType *t, MonoMarshalSpec *spec, int conv_arg, MonoType **conv_arg_type, MarshalAction action);
} MonoMarshalLightweightCallbacks;
-typedef struct {
- MonoType* (*get_object_type) (void);
- MonoMarshalConv (*get_ptr_to_string_conv) (MonoMethodPInvoke *piinfo, MonoMarshalSpec *spec, gboolean *need_free);
- gboolean (*is_subclass_of_internal) (MonoClass *klass, MonoClass *klassc, gboolean check_interfaces);
- gint32 (*class_native_size) (MonoClass *klass, guint32 *align);
- MonoClass* (*class_try_get_handleref_class) (void);
- MonoClass* (*try_get_safehandle_class) (void);
- MonoClass* (*try_get_stringbuilder_class) (void);
- MonoDefaults* mono_defaults;
- MonoType* (*boolean_conv_in_get_local_type) (MonoMarshalSpec *spec, guint8 *ldc_op /*out*/);
- MonoClass* (*boolean_managed_conv_in_get_conv_arg_class) (MonoMarshalSpec *spec, guint8 *ldop/*out*/);
- MonoMarshalConv (*get_ptr_to_stringbuilder_conv) (MonoMethodPInvoke *piinfo, MonoMarshalSpec *spec, gboolean *need_free);
- MonoMarshalNative (*get_string_encoding) (MonoMethodPInvoke *piinfo, MonoMarshalSpec *spec);
- MonoMarshalConv (*get_string_to_ptr_conv) (MonoMethodPInvoke *piinfo, MonoMarshalSpec *spec);
- MonoMarshalConv (*get_stringbuilder_to_ptr_conv) (MonoMethodPInvoke *piinfo, MonoMarshalSpec *spec);
- MonoMarshalType* (*load_type_info) (MonoClass* klass);
- MonoJitICallId (*conv_to_icall) (MonoMarshalConv conv, int *ind_store_type);
- void (*emit_marshal_custom_get_instance) (MonoMethodBuilder *mb, MonoClass *klass, MonoMarshalSpec *spec);
- void (*emit_struct_conv) (MonoMethodBuilder *mb, MonoClass *klass, gboolean to_object);
- void (*emit_struct_conv_full) (MonoMethodBuilder *mb, MonoClass *klass, gboolean to_object, int offset_of_first_child_field, MonoMarshalNative string_encoding);
- MonoMethod* (*get_method_nofail) (MonoClass *klass, const char *method_name, int num_params, int flags);
- MonoMethod** (*get_sh_dangerous_add_ref) (void);
- MonoMethod** (*get_sh_dangerous_release) (void);
- void (*init_safe_handle) (void);
- gboolean (*is_in) (const MonoType *t);
- gboolean (*is_out) (const MonoType *t);
- void (*mb_emit_exception_marshal_directive) (MonoMethodBuilder *mb, char *msg);
- int (*mb_add_local) (MonoMethodBuilder *mb, MonoType *type);
- void (*mb_emit_add_to_local) (MonoMethodBuilder *mb, guint16 local, gint32 incr);
- void (*mb_emit_auto_layout_exception) (MonoMethodBuilder *mb, MonoClass *klass);
- guint32 (*mb_emit_branch) (MonoMethodBuilder *mb, guint8 op);
- void (*mb_emit_branch_label) (MonoMethodBuilder *mb, guint8 op, guint32 label);
- void (*mb_emit_byte) (MonoMethodBuilder *mb, guint8 op);
- void (*mb_emit_exception) (MonoMethodBuilder *mb, const char *exc_name, const char *msg);
- void (*mb_emit_exception_full) (MonoMethodBuilder *mb, const char *exc_nspace, const char *exc_name, const char *msg);
- void (*mb_emit_icall_id) (MonoMethodBuilder *mb, MonoJitICallId jit_icall_id);
- void (*mb_emit_icon) (MonoMethodBuilder *mb, gint32 value);
- void (*mb_emit_ldarg) (MonoMethodBuilder *mb, guint argnum);
- void (*mb_emit_ldarg_addr) (MonoMethodBuilder *mb, guint argnum);
- void (*mb_emit_ldflda) (MonoMethodBuilder *mb, gint32 offset);
- void (*mb_emit_ldloc) (MonoMethodBuilder *mb, guint num);
- void (*mb_emit_ldloc_addr) (MonoMethodBuilder *mb, guint argnum);
- void (*mb_emit_managed_call) (MonoMethodBuilder *mb, MonoMethod *method, MonoMethodSignature *opt_sig);
- void (*mb_emit_op) (MonoMethodBuilder *mb, guint8 op, gpointer data);
- void (*mb_emit_stloc) (MonoMethodBuilder *mb, guint num);
- int (*mb_get_label) (MonoMethodBuilder *mb);
- void (*mb_patch_branch) (MonoMethodBuilder *mb, guint32 pos);
- gboolean (*pinvoke_is_unicode) (MonoMethodPInvoke *piinfo);
- MonoType* (*reflection_type_from_name_checked) (char *name, MonoAssemblyLoadContext *alc, MonoImage *image, MonoError *error);
- void (*memory_barrier) (void);
- gboolean (*need_free) (MonoType *t, MonoMethodPInvoke *piinfo, MonoMarshalSpec *spec);
- MonoType* (*get_int_type) (void);
-} IlgenCallbacksToMono;
-
/*type of the function pointer of methods returned by mono_marshal_get_runtime_invoke*/
typedef MonoObject *(*RuntimeInvokeFunction) (MonoObject *this_obj, void **params, MonoObject **exc, void* compiled_method);
@@ -756,7 +702,4 @@ mono_mb_create_and_cache_full (GHashTable *cache, gpointer key,
MonoMethodBuilder *mb, MonoMethodSignature *sig,
int max_stack, WrapperInfo *info, gboolean *out_found);
-IlgenCallbacksToMono*
-mono_marshal_get_mono_callbacks_for_ilgen (void);
-
#endif /* __MONO_MARSHAL_H__ */
diff --git a/src/mono/mono/mini/CMakeLists.txt b/src/mono/mono/mini/CMakeLists.txt
index 6ef0ebf57b4ea..9e74fd9e16fb4 100644
--- a/src/mono/mono/mini/CMakeLists.txt
+++ b/src/mono/mono/mini/CMakeLists.txt
@@ -349,7 +349,7 @@ add_library(monosgen-static STATIC $;$
-
-
- marshal-ilgen
-
-
-
-
-
- marshal-ilgen
-
-
-
- marshal-ilgen
-
-
<_MonoRuntimeComponentDontLink Include="libmono-component-diagnostics_tracing-static.a" Condition="'$(FeatureWasmPerfTracing)' != 'true' and $(FeatureWasmThreads) != 'true'"/>
<_MonoRuntimeComponentDontLink Include="libmono-component-hot_reload-stub-static.a" />
- <_MonoRuntimeComponentDontLink Include="libmono-component-marshal-ilgen-stub-static.a" />
diff --git a/src/mono/wasm/build/WasmApp.Native.targets b/src/mono/wasm/build/WasmApp.Native.targets
index 14070469f0d20..dfe3a169d5604 100644
--- a/src/mono/wasm/build/WasmApp.Native.targets
+++ b/src/mono/wasm/build/WasmApp.Native.targets
@@ -31,9 +31,6 @@
<_MonoComponent Include="hot_reload;debugger" />
-
- <_MonoComponent Include="marshal-ilgen" />
-
diff --git a/src/mono/wasm/runtime/CMakeLists.txt b/src/mono/wasm/runtime/CMakeLists.txt
index 76a17f73e0cf9..c852a7df1df61 100644
--- a/src/mono/wasm/runtime/CMakeLists.txt
+++ b/src/mono/wasm/runtime/CMakeLists.txt
@@ -19,7 +19,6 @@ target_link_libraries(dotnet
${MONO_ARTIFACTS_DIR}/libmono-component-hot_reload-static.a
${MONO_ARTIFACTS_DIR}/libmono-component-debugger-static.a
${MONO_ARTIFACTS_DIR}/libmono-component-diagnostics_tracing-stub-static.a
- ${MONO_ARTIFACTS_DIR}/libmono-component-marshal-ilgen-static.a
${MONO_ARTIFACTS_DIR}/libmono-ee-interp.a
${MONO_ARTIFACTS_DIR}/libmonosgen-2.0.a
${MONO_ARTIFACTS_DIR}/libmono-ilgen.a
diff --git a/src/tests/build.proj b/src/tests/build.proj
index e2716558b9d8a..37236bad27175 100644
--- a/src/tests/build.proj
+++ b/src/tests/build.proj
@@ -185,7 +185,7 @@
$(BuildDir)\apk
$(XUnitTestBinBase)$(CategoryWithSlash)\$(Category).apk
False
- diagnostics_tracing;marshal-ilgen
+ diagnostics_tracing
127.0.0.1:9000,nosuspend,listen
True
$(ArtifactsBinDir)microsoft.netcore.app.runtime.android-$(TargetArchitecture)\$(Configuration)\runtimes\android-$(TargetArchitecture)\
@@ -272,7 +272,7 @@
$(CMDDIR_GrandParent)/$(CategoryWithSlash)/$(XUnitWrapperFileName)
$(IntermediateOutputPath)\iOSApps\$(Category)
$(XUnitTestBinBase)$(CategoryWithSlash)\$(Category).app
- diagnostics_tracing;marshal-ilgen
+ diagnostics_tracing