diff options
author | Zoltan Varga <vargaz@gmail.com> | 2004-09-09 15:22:08 +0400 |
---|---|---|
committer | Zoltan Varga <vargaz@gmail.com> | 2004-09-09 15:22:08 +0400 |
commit | 6182f42e5557a68f5aab0bbee0b182cf03f70e0e (patch) | |
tree | cd62e91c1fc4e0a662b852028d38963b3dcfb0e9 | |
parent | e1b7e8c457247c6a89c805cf1ce3eb98b8a74d36 (diff) |
Merge from HEAD.
svn path=/branches/mono-1-0/mono/; revision=33645
-rw-r--r-- | mono/metadata/ChangeLog | 5 | ||||
-rw-r--r-- | mono/metadata/loader.c | 39 | ||||
-rw-r--r-- | mono/metadata/reflection.c | 22 | ||||
-rw-r--r-- | mono/metadata/reflection.h | 1 |
4 files changed, 54 insertions, 13 deletions
diff --git a/mono/metadata/ChangeLog b/mono/metadata/ChangeLog index 5912343b15e..290a12448d9 100644 --- a/mono/metadata/ChangeLog +++ b/mono/metadata/ChangeLog @@ -1,3 +1,8 @@ +2004-09-09 Zoltan Varga <vargaz@freemail.hu> + + * reflection.h reflection.c loader.c: Allow dynamic construction of + pinvoke methods. Fixes #65571. + 2004-09-08 Lluis Sanchez Gual <lluis@novell.com> * object.c: In mono_message_invoke, fill the output parameter array after diff --git a/mono/metadata/loader.c b/mono/metadata/loader.c index 81f2af3fa7c..5521d6f3299 100644 --- a/mono/metadata/loader.c +++ b/mono/metadata/loader.c @@ -580,28 +580,41 @@ mono_lookup_pinvoke_call (MonoMethod *method, const char **exc_class, const char g_assert (method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL); - if (exc_class) { - *exc_class = NULL; - *exc_arg = NULL; - } - if (method->addr) return method->addr; - if (!piinfo->implmap_idx) - return NULL; - - mono_metadata_decode_row (im, piinfo->implmap_idx - 1, im_cols, MONO_IMPLMAP_SIZE); - piinfo->piflags = im_cols [MONO_IMPLMAP_FLAGS]; - import = mono_metadata_string_heap (image, im_cols [MONO_IMPLMAP_NAME]); - scope_token = mono_metadata_decode_row_col (mr, im_cols [MONO_IMPLMAP_SCOPE] - 1, MONO_MODULEREF_NAME); - orig_scope = mono_metadata_string_heap (image, scope_token); + if (method->klass->image->dynamic) { + MonoReflectionMethodAux *method_aux = + mono_g_hash_table_lookup ( + ((MonoDynamicImage*)method->klass->image)->method_aux_hash, method); + if (!method_aux) + return NULL; + + import = method_aux->dllentry; + orig_scope = method_aux->dll; + } + else { + if (!piinfo->implmap_idx) + return NULL; + + mono_metadata_decode_row (im, piinfo->implmap_idx - 1, im_cols, MONO_IMPLMAP_SIZE); + + piinfo->piflags = im_cols [MONO_IMPLMAP_FLAGS]; + import = mono_metadata_string_heap (image, im_cols [MONO_IMPLMAP_NAME]); + scope_token = mono_metadata_decode_row_col (mr, im_cols [MONO_IMPLMAP_SCOPE] - 1, MONO_MODULEREF_NAME); + orig_scope = mono_metadata_string_heap (image, scope_token); + } mono_dllmap_lookup (image, orig_scope, import, &new_scope, &import); mono_trace (G_LOG_LEVEL_INFO, MONO_TRACE_DLLIMPORT, "DllImport attempting to load: '%s'.", new_scope); + if (exc_class) { + *exc_class = NULL; + *exc_arg = NULL; + } + #ifndef PLATFORM_WIN32 /* * If we are P/Invoking a library from System.Windows.Forms, load Wine diff --git a/mono/metadata/reflection.c b/mono/metadata/reflection.c index bf22f1f6d4a..d8335dbdf2f 100644 --- a/mono/metadata/reflection.c +++ b/mono/metadata/reflection.c @@ -61,6 +61,9 @@ typedef struct { MonoMethod *mhandle; guint32 nrefs; gpointer *refs; + /* for PInvoke */ + int charset, lasterr, native_cc; + MonoString *dll, *dllentry; } ReflectionMethodBuilder; const unsigned char table_sizes [64] = { @@ -1260,6 +1263,14 @@ reflection_methodbuilder_from_method_builder (ReflectionMethodBuilder *rmb, rmb->mhandle = mb->mhandle; rmb->nrefs = 0; rmb->refs = NULL; + + if (mb->dll) { + rmb->charset = rmb->charset & 0xf; + rmb->lasterr = rmb->charset & 0x40; + rmb->native_cc = rmb->native_cc; + rmb->dllentry = mb->dllentry; + rmb->dll = mb->dll; + } } static void @@ -7016,6 +7027,17 @@ reflection_methodbuilder_to_mono_method (MonoClass *klass, } else if (m->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL) { /* TODO */ m->signature->pinvoke = 1; + + method_aux = g_new0 (MonoReflectionMethodAux, 1); + + method_aux->dllentry = g_strdup (mono_string_to_utf8 (rmb->dllentry)); + method_aux->dll = g_strdup (mono_string_to_utf8 (rmb->dll)); + + ((MonoMethodPInvoke*)m)->piflags = (rmb->native_cc << 8) | (rmb->charset ? (rmb->charset - 1) * 2 : 1) | rmb->lasterr; + + if (klass->image->dynamic) + mono_g_hash_table_insert (((MonoDynamicImage*)klass->image)->method_aux_hash, m, method_aux); + return m; } else if (!m->klass->dummy && !(m->flags & METHOD_ATTRIBUTE_ABSTRACT) && diff --git a/mono/metadata/reflection.h b/mono/metadata/reflection.h index e44243f3d66..f365047c3b6 100644 --- a/mono/metadata/reflection.h +++ b/mono/metadata/reflection.h @@ -34,6 +34,7 @@ typedef struct { char **param_names; MonoMarshalSpec **param_marshall; MonoCustomAttrInfo **param_cattr; + char *dllentry, *dll; } MonoReflectionMethodAux; int mono_reflection_parse_type (char *name, MonoTypeNameParse *info); |