GDMonoProperty::GDMonoProperty(MonoProperty *p_mono_property, GDMonoClass *p_owner) { owner = p_owner; mono_property = p_mono_property; name = mono_property_get_name(mono_property); MonoMethod *prop_method = mono_property_get_get_method(mono_property); if (prop_method) { MonoMethodSignature *getter_sig = mono_method_signature(prop_method); MonoType *ret_type = mono_signature_get_return_type(getter_sig); type.type_encoding = mono_type_get_type(ret_type); MonoClass *ret_type_class = mono_class_from_mono_type(ret_type); type.type_class = GDMono::get_singleton()->get_class(ret_type_class); } else { prop_method = mono_property_get_set_method(mono_property); MonoMethodSignature *setter_sig = mono_method_signature(prop_method); void *iter = NULL; MonoType *param_raw_type = mono_signature_get_params(setter_sig, &iter); type.type_encoding = mono_type_get_type(param_raw_type); MonoClass *param_type_class = mono_class_from_mono_type(param_raw_type); type.type_class = GDMono::get_singleton()->get_class(param_type_class); } attrs_fetched = false; attributes = NULL; }
/* * namespace and class are supposed to match already if this function is used. */ gboolean mono_method_desc_match (MonoMethodDesc *desc, MonoMethod *method) { char *sig; gboolean name_match; name_match = strcmp (desc->name, method->name) == 0; #ifndef _EGLIB_MAJOR if (!name_match && desc->name_glob) name_match = g_pattern_match_simple (desc->name, method->name); #endif if (!name_match) return FALSE; if (!desc->args) return TRUE; if (desc->num_args != mono_method_signature (method)->param_count) return FALSE; sig = mono_signature_get_desc (mono_method_signature (method), desc->include_namespace); if (strcmp (sig, desc->args)) { g_free (sig); return FALSE; } g_free (sig); return TRUE; }
static int dump_verify_info (MonoImage *image, int flags) { GSList *errors, *tmp; int count = 0, verifiable = 0; const char* desc [] = { "Ok", "Error", "Warning", NULL, "CLS", NULL, NULL, NULL, "Not Verifiable" }; if (verify_code) { /* verify code */ int i; MonoTableInfo *m = &image->tables [MONO_TABLE_METHOD]; for (i = 0; i < m->rows; ++i) { MonoMethod *method; MonoError error; method = mono_get_method_checked (image, MONO_TOKEN_METHOD_DEF | (i+1), NULL, NULL, &error); if (!method) { g_print ("Warning: Cannot lookup method with token 0x%08x due to %s\n", i + 1, mono_error_get_message (&error)); mono_error_cleanup (&error); continue; } errors = mono_method_verify (method, flags); if (errors) { MonoClass *klass = mono_method_get_class (method); char *name = mono_type_full_name (&klass->byval_arg); if (mono_method_signature (method) == NULL) { g_print ("In method: %s::%s(ERROR)\n", name, mono_method_get_name (method)); } else { char *sig; sig = mono_signature_get_desc (mono_method_signature (method), FALSE); g_print ("In method: %s::%s(%s)\n", name, mono_method_get_name (method), sig); g_free (sig); } g_free (name); } for (tmp = errors; tmp; tmp = tmp->next) { MonoVerifyInfo *info = (MonoVerifyInfo *)tmp->data; g_print ("%s: %s\n", desc [info->status], info->message); if (info->status == MONO_VERIFY_ERROR) { count++; verifiable = 3; } if(info->status == MONO_VERIFY_NOT_VERIFIABLE) { if (verifiable < 2) verifiable = 2; } } mono_free_verify_list (errors); } } if (count) g_print ("Error count: %d\n", count); return verifiable; }
void mono_trace_enter_method (MonoMethod *method, char *ebp) { int i, j; MonoClass *klass; MonoObject *o; MonoJitArgumentInfo *arg_info; MonoMethodSignature *sig; char *fname; MonoGenericSharingContext *gsctx = NULL; if (!trace_spec.enabled) return; while (output_lock != 0 || InterlockedCompareExchange (&output_lock, 1, 0) != 0) mono_thread_info_yield (); fname = mono_method_full_name (method, TRUE); indent (1); printf ("ENTER: %s(", fname); g_free (fname); if (!ebp) { printf (") ip: %p\n", RETURN_ADDRESS_N (1)); goto unlock; } sig = mono_method_signature (method); arg_info = alloca (sizeof (MonoJitArgumentInfo) * (sig->param_count + 1)); if (method->is_inflated) { /* FIXME: Might be better to pass the ji itself */ MonoJitInfo *ji = mini_jit_info_table_find (mono_domain_get (), RETURN_ADDRESS (), NULL); if (ji) { gsctx = mono_jit_info_get_generic_sharing_context (ji); if (gsctx && gsctx->is_gsharedvt) { /* Needs a ctx to get precise method */ printf (") <gsharedvt>\n"); goto unlock; } } } mono_arch_get_argument_info (sig, sig->param_count, arg_info); if (MONO_TYPE_ISSTRUCT (mono_method_signature (method)->ret)) { g_assert (!mono_method_signature (method)->ret->byref); printf ("VALUERET:%p, ", *((gpointer *)(ebp + 8))); } if (mono_method_signature (method)->hasthis) { gpointer *this = (gpointer *)(ebp + arg_info [0].offset); if (method->klass->valuetype) { printf ("value:%p, ", *arg_in_stack_slot(this, gpointer *)); } else {
gpointer mono_arch_get_unbox_trampoline (MonoGenericSharingContext *gsctx, MonoMethod *method, gpointer addr) { guint8 *code, *start; int this_pos = s390_r2; MonoDomain *domain = mono_domain_get (); start = addr; if (MONO_TYPE_ISSTRUCT (mono_method_signature (method)->ret)) this_pos = s390_r3; start = code = mono_domain_code_reserve (domain, 28); s390_basr (code, s390_r13, 0); s390_j (code, 4); s390_word (code, addr); s390_l (code, s390_r1, 0, s390_r13, 4); s390_ahi (code, this_pos, sizeof(MonoObject)); s390_br (code, s390_r1); g_assert ((code - start) <= 28); mono_arch_flush_icache (start, code - start); return start; }
MonoMethod *CScriptClass::GetMonoMethod(const char *methodName, int numParams) { MonoMethodSignature *pSignature = nullptr; void *pIterator = 0; MonoClass *pClass = (MonoClass *)m_pObject; MonoType *pClassType = mono_class_get_type(pClass); MonoMethod *pCurMethod = nullptr; while (pClass != nullptr) { pCurMethod = mono_class_get_methods(pClass, &pIterator); if(pCurMethod == nullptr) { pClass = mono_class_get_parent(pClass); if(pClass == mono_get_object_class()) break; pIterator = 0; continue; } pSignature = mono_method_signature(pCurMethod); int signatureParamCount = mono_signature_get_param_count(pSignature); bool bCorrectName = !strcmp(mono_method_get_name(pCurMethod), methodName); if(bCorrectName && signatureParamCount == numParams) return pCurMethod; } return nullptr; }
String GDMonoMethod::get_signature_desc(bool p_namespaces) const { MonoMethodSignature *method_sig = mono_method_signature(mono_method); char *sig_desc = mono_signature_get_desc(method_sig, p_namespaces); String res = sig_desc; mono_free(sig_desc); return res; }
void GDMonoMethod::_update_signature() { // Apparently MonoMethodSignature needs not to be freed. // mono_method_signature caches the result, we don't need to cache it ourselves. MonoMethodSignature *method_sig = mono_method_signature(mono_method); _update_signature(method_sig); }
void mono_debug_close_method (MonoCompile *cfg) { MiniDebugMethodInfo *info; MonoDebugMethodJitInfo *jit; MonoMethodHeader *header; MonoMethodSignature *sig; MonoDebugMethodAddress *debug_info; MonoMethod *method; int i; info = (MiniDebugMethodInfo *) cfg->debug_info; if (!info || !info->jit) { if (info) g_free (info); return; } method = cfg->method; header = mono_method_get_header (method); sig = mono_method_signature (method); jit = info->jit; jit->code_start = cfg->native_code; jit->epilogue_begin = cfg->epilog_begin; jit->code_size = cfg->code_len; if (jit->epilogue_begin) record_line_number (info, jit->epilogue_begin, header->code_size); jit->num_params = sig->param_count; jit->params = g_new0 (MonoDebugVarInfo, jit->num_params); for (i = 0; i < jit->num_locals; i++) write_variable (cfg->locals [i], &jit->locals [i]); if (sig->hasthis) { jit->this_var = g_new0 (MonoDebugVarInfo, 1); write_variable (cfg->args [0], jit->this_var); } for (i = 0; i < jit->num_params; i++) write_variable (cfg->args [i + sig->hasthis], &jit->params [i]); jit->num_line_numbers = info->line_numbers->len; jit->line_numbers = g_new0 (MonoDebugLineNumberEntry, jit->num_line_numbers); for (i = 0; i < jit->num_line_numbers; i++) jit->line_numbers [i] = g_array_index (info->line_numbers, MonoDebugLineNumberEntry, i); debug_info = mono_debug_add_method (cfg->method_to_register, jit, cfg->domain); mono_debug_add_vg_method (method, jit); mono_debugger_check_breakpoints (method, debug_info); mono_debug_free_method_jit_info (jit); g_array_free (info->line_numbers, TRUE); g_free (info); }
void MonoMethod::cacheSignature() const { MonoMethodSignature* methodSignature = mono_method_signature(mMethod); MonoType* returnType = mono_signature_get_return_type(methodSignature); if (returnType != nullptr) { ::MonoClass* returnClass = mono_class_from_mono_type(returnType); if (returnClass != nullptr) mCachedReturnType = MonoManager::instance().findClass(returnClass); } mCachedNumParameters = (UINT32)mono_signature_get_param_count(methodSignature); if (mCachedParameters != nullptr) { bs_free(mCachedParameters); mCachedParameters = nullptr; } if (mCachedNumParameters > 0) { mCachedParameters = (MonoClass**)bs_alloc(mCachedNumParameters * sizeof(MonoClass*)); void* iter = nullptr; for (UINT32 i = 0; i < mCachedNumParameters; i++) { MonoType* curParamType = mono_signature_get_params(methodSignature, &iter); ::MonoClass* rawClass = mono_class_from_mono_type(curParamType); mCachedParameters[i] = MonoManager::instance().findClass(rawClass); } } mIsStatic = !mono_signature_is_instance(methodSignature); mHasCachedSignature = true; }
String GDMonoMethod::get_ret_type_full_name() const { MonoMethodSignature *method_sig = mono_method_signature(mono_method); char *ret_str = mono_type_full_name(mono_signature_get_return_type(method_sig)); String res = ret_str; mono_free(ret_str); return res; }
int CScriptMethod::GetParameterCount() { if(m_pMonoMethodSignature == nullptr) m_pMonoMethodSignature = mono_method_signature(m_pMonoMethod); return mono_signature_get_param_count(m_pMonoMethodSignature); }
/** * mono_get_exception_type_initialization: * @type_name: the name of the type that failed to initialize. * @inner: the inner exception. * * Returns: a new instance of the System.TypeInitializationException */ MonoException * mono_get_exception_type_initialization (const gchar *type_name, MonoException *inner) { MonoClass *klass; gpointer args [2]; MonoObject *exc; MonoMethod *method; gpointer iter; klass = mono_class_from_name (mono_get_corlib (), "System", "TypeInitializationException"); g_assert (klass); mono_class_init (klass); /* TypeInitializationException only has 1 ctor with 2 args */ iter = NULL; while ((method = mono_class_get_methods (klass, &iter))) { if (!strcmp (".ctor", mono_method_get_name (method)) && mono_method_signature (method)->param_count == 2) break; method = NULL; } g_assert (method); args [0] = mono_string_new (mono_domain_get (), type_name); args [1] = inner; exc = mono_object_new (mono_domain_get (), klass); mono_runtime_invoke (method, exc, args, NULL); return (MonoException *) exc; }
static void method_jit_result (MonoProfiler *prof, MonoMethod *method, MonoJitInfo* jinfo, int result) { if (result == MONO_PROFILE_OK) { int i; MonoDebugSourceLocation *sourceLoc; MonoDebugMethodJitInfo *dmji; MonoClass *klass = mono_method_get_class (method); char *signature = mono_signature_get_desc (mono_method_signature (method), TRUE); char *name = g_strdup_printf ("%s(%s)", mono_method_get_name (method), signature); char *classname = g_strdup_printf ("%s%s%s", mono_class_get_namespace (klass), mono_class_get_namespace (klass)[0] != 0 ? "::" : "", mono_class_get_name (klass)); gpointer code_start = mono_jit_info_get_code_start (jinfo); int code_size = mono_jit_info_get_code_size (jinfo); iJIT_Method_Load vtuneMethod; memset(&vtuneMethod, 0, sizeof(vtuneMethod)); vtuneMethod.method_id = iJIT_GetNewMethodID(); vtuneMethod.method_name = name; vtuneMethod.method_load_address = code_start; vtuneMethod.method_size = code_size; vtuneMethod.class_file_name = classname; dmji = mono_debug_find_method (method, mono_domain_get()); if (dmji != NULL) { vtuneMethod.line_number_size = dmji->num_line_numbers; vtuneMethod.line_number_table = (vtuneMethod.line_number_size != 0) ? (LineNumberInfo*)malloc(sizeof(LineNumberInfo) * vtuneMethod.line_number_size) : NULL; for (i = 0; i < dmji->num_line_numbers; ++i) { sourceLoc = mono_debug_lookup_source_location (method, dmji->line_numbers[i].native_offset, mono_domain_get()); if (sourceLoc == NULL) { g_free (vtuneMethod.line_number_table); vtuneMethod.line_number_table = NULL; vtuneMethod.line_number_size = 0; break; } if (i == 0) vtuneMethod.source_file_name = strdup(sourceLoc->source_file); vtuneMethod.line_number_table[i].Offset = dmji->line_numbers[i].native_offset; vtuneMethod.line_number_table[i].LineNumber = sourceLoc->row; mono_debug_free_source_location (sourceLoc); } mono_debug_free_method_jit_info (dmji); } iJIT_NotifyEvent(iJVM_EVENT_TYPE_METHOD_LOAD_FINISHED, &vtuneMethod); if (vtuneMethod.source_file_name != NULL) g_free (vtuneMethod.source_file_name); if (vtuneMethod.line_number_table != NULL) g_free (vtuneMethod.line_number_table); g_free (signature); g_free (name); g_free (classname); } }
MonoObject *create_managed_from(const Dictionary &p_from, GDMonoClass *p_class) { MonoObject *mono_object = mono_object_new(SCRIPTS_DOMAIN, p_class->get_mono_ptr()); ERR_FAIL_NULL_V(mono_object, NULL); // Search constructor that takes a pointer as parameter MonoMethod *m; void *iter = NULL; while ((m = mono_class_get_methods(p_class->get_mono_ptr(), &iter))) { if (strcmp(mono_method_get_name(m), ".ctor") == 0) { MonoMethodSignature *sig = mono_method_signature(m); void *front = NULL; if (mono_signature_get_param_count(sig) == 1 && mono_class_from_mono_type(mono_signature_get_params(sig, &front)) == CACHED_CLASS(IntPtr)->get_mono_ptr()) { break; } } } CRASH_COND(m == NULL); Dictionary *new_dict = memnew(Dictionary(p_from)); void *args[1] = { &new_dict }; MonoException *exc = NULL; GDMonoUtils::runtime_invoke(m, mono_object, args, &exc); UNLIKELY_UNHANDLED_EXCEPTION(exc); return mono_object; }
GDMonoMethod *GDMonoClass::get_method(MonoMethod *p_raw_method) { MonoMethodSignature *sig = mono_method_signature(p_raw_method); int params_count = mono_signature_get_param_count(sig); StringName method_name = mono_method_get_name(p_raw_method); return get_method(p_raw_method, method_name, params_count); }
static guint64 debugger_get_method_signature (guint64 method_arg, G_GNUC_UNUSED guint64 dummy) { MonoMethod *method = (MonoMethod *) GUINT_TO_POINTER ((gsize) method_arg); MonoMethodSignature *sig; sig = mono_method_signature (method); return (guint64) (gsize) sig; }
void mioMethod::eachArgTypes(const std::function<void(mioType&)>& f) const { if (!mmethod) { return; } MonoMethodSignature *sig = mono_method_signature(mmethod); MonoType *mt = nullptr; gpointer iter = nullptr; while (mt = mono_signature_get_params(sig, &iter)) { mioType miot = mt; f(miot); } }
void mono_trace_enter_method (MonoMethod *method, char *ebp) { int i, j; MonoClass *class; MonoObject *o; MonoJitArgumentInfo *arg_info; MonoMethodSignature *sig; char *fname; if (!trace_spec.enabled) return; fname = mono_method_full_name (method, TRUE); indent (1); printf ("ENTER: %s(", fname); g_free (fname); if (!ebp) { printf (") ip: %p\n", __builtin_return_address (1)); return; } sig = mono_method_signature (method); arg_info = alloca (sizeof (MonoJitArgumentInfo) * (sig->param_count + 1)); mono_arch_get_argument_info (sig, sig->param_count, arg_info); if (MONO_TYPE_ISSTRUCT (mono_method_signature (method)->ret)) { g_assert (!mono_method_signature (method)->ret->byref); printf ("VALUERET:%p, ", *((gpointer *)(ebp + 8))); } if (mono_method_signature (method)->hasthis) { gpointer *this = (gpointer *)(ebp + arg_info [0].offset); if (method->klass->valuetype) { printf ("value:%p, ", *arg_in_stack_slot(this, gpointer *)); } else {
void CPipeServer::GetMethodSignature() { void *method = (void *)ReadQword(); void *methodsignature = mono_method_signature(method); char *sig = mono_signature_get_desc(methodsignature, TRUE); int paramcount = mono_signature_get_param_count(methodsignature); char **names=(char **)calloc(sizeof(char *), paramcount); int i; mono_method_get_param_names(method, (const char **)names); WriteByte(paramcount); for (i = 0; i < paramcount; i++) { if (names[i]) { WriteByte(strlen(names[i])); Write(names[i], strlen(names[i])); } else WriteByte(0); } free(names); WriteWord(strlen(sig)); Write(sig, strlen(sig)); g_free(sig); //12/5/2014:send the returntype as well void *returntype = mono_signature_get_return_type(methodsignature); if (returntype) { char *tname = mono_type_get_name(returntype); if (tname) { WriteByte(strlen(tname)); Write(tname, strlen(tname)); g_free(tname); } else WriteByte(0); } else WriteByte(0); }
IMonoMethod *CScriptClass::GetMethod(const char *name, int numParams, bool throwOnFail) { MonoMethodSignature *pSignature = nullptr; void *pIterator = 0; MonoClass *pClass = (MonoClass *)m_pObject; MonoType *pClassType = mono_class_get_type(pClass); MonoMethod *pCurMethod = nullptr; while (pClass != nullptr) { pCurMethod = mono_class_get_methods(pClass, &pIterator); if(pCurMethod == nullptr) { pClass = mono_class_get_parent(pClass); if(pClass == mono_get_object_class()) break; pIterator = 0; continue; } pSignature = mono_method_signature(pCurMethod); int signatureParamCount = mono_signature_get_param_count(pSignature); bool bCorrectName = !strcmp(mono_method_get_name(pCurMethod), name); if(bCorrectName && signatureParamCount == numParams) return new CScriptMethod(pCurMethod); } if(throwOnFail) { if(!GetMonoScriptSystem()->IsInitialized()) { CryLogAlways("Failed to locate method %s in class %s", name, GetName()); } else if(IMonoAssembly *pCorlibAssembly = GetMonoScriptSystem()->GetCorlibAssembly()) { if(IMonoException *pException = GetMonoScriptSystem()->GetCorlibAssembly()->GetException("System", "MissingMethodException", "Failed to locate method %s in class %s", name, GetName())) pException->Throw(); } } return nullptr; }
static MonoException * create_exception_two_strings (MonoClass *klass, MonoString *a1, MonoString *a2) { MonoError error; MonoDomain *domain = mono_domain_get (); MonoMethod *method = NULL; MonoObject *o; int count = 1; gpointer args [2]; gpointer iter; MonoMethod *m; if (a2 != NULL) count++; o = mono_object_new_checked (domain, klass, &error); mono_error_assert_ok (&error); iter = NULL; while ((m = mono_class_get_methods (klass, &iter))) { MonoMethodSignature *sig; if (strcmp (".ctor", mono_method_get_name (m))) continue; sig = mono_method_signature (m); if (sig->param_count != count) continue; if (sig->params [0]->type != MONO_TYPE_STRING) continue; if (count == 2 && sig->params [1]->type != MONO_TYPE_STRING) continue; method = m; break; } args [0] = a1; args [1] = a2; mono_runtime_invoke_checked (method, o, args, &error); mono_error_raise_exception (&error); /* FIXME don't raise here */ return (MonoException *) o; }
String GDMonoMethod::get_full_name_no_class() const { String res; MonoMethodSignature *method_sig = mono_method_signature(mono_method); char *ret_str = mono_type_full_name(mono_signature_get_return_type(method_sig)); res += ret_str; mono_free(ret_str); res += " "; res += name; res += "("; char *sig_desc = mono_signature_get_desc(method_sig, true); res += sig_desc; mono_free(sig_desc); res += ")"; return res; }
/* * mono_method_find * * Get method by its name and argument types */ MonoMethod* mono_method_find(MonoClass *klass, char *name, MonoType **params, int nparams) { MonoMethod *method = NULL; MonoType *param_type; MonoMethodSignature *sig; gpointer method_iter = NULL; gpointer param_iter = NULL; int i; while ((method = mono_class_get_methods(klass, &method_iter))) { if (strcmp(mono_method_get_name(method), name)) continue; sig = mono_method_signature(method); if (mono_signature_get_param_count(sig) != nparams) continue; i = 0; while ((param_type = mono_signature_get_params(sig, ¶m_iter))) { if (mono_class_from_mono_type(param_type) != mono_class_from_mono_type(params[i])) break; if (mono_type_is_byref(param_type) != mono_type_is_byref(params[i])) break; i++; } if (i == nparams) { return method; } } return NULL; }
static void output_method (MonoMethod *method, gpointer dummy, MonoProfiler *prof) { MonoMethodHeader *header; char *classname; char *tmpsig; char *tmpname; FILE *outfile; MonoClass *klass; MonoImage *image; outfile = prof->outfile; header = mono_method_get_header (method); tmpsig = mono_signature_get_desc (mono_method_signature (method), TRUE); tmpsig = g_markup_escape_text (tmpsig, strlen (tmpsig)); klass = mono_method_get_class (method); classname = mono_type_get_name (mono_class_get_type (klass)); image = mono_class_get_image (klass); tmpname = mono_method_get_name (method); tmpname = g_markup_escape_text (tmpname, strlen (tmpname)); fprintf (outfile, "\t<method assembly=\"%s\" class=\"%s\" name=\"%s (%s)\" token=\"%d\">\n", mono_image_get_name (image), classname, tmpname, tmpsig, mono_method_get_token (method)); g_free (tmpsig); g_free (tmpname); fprintf (outfile, "\t\t"); count = 0; prev_offset = 0; mono_profiler_coverage_get (prof, method, output_entry); fprintf (outfile, "\n"); fprintf (outfile, "\t</method>\n"); }
int CScriptClass::GetMethods(const char *name, int numParams, IMonoMethod ***pMethodsOut, int maxMethods, bool throwOnFail) { MonoMethodSignature *pSignature = nullptr; void *pIterator = 0; int i = 0; MonoClass *pClass = (MonoClass *)m_pObject; MonoType *pClassType = mono_class_get_type(pClass); MonoMethod *pCurMethod = nullptr; while (pClass != nullptr) { pCurMethod = mono_class_get_methods(pClass, &pIterator); if(pCurMethod == nullptr) { pClass = mono_class_get_parent(pClass); if(pClass == mono_get_object_class()) break; pIterator = 0; continue; } pSignature = mono_method_signature(pCurMethod); int signatureParamCount = mono_signature_get_param_count(pSignature); bool bCorrectName = !strcmp(mono_method_get_name(pCurMethod), name); if(bCorrectName && signatureParamCount == numParams) { *pMethodsOut[i] = new CScriptMethod(pCurMethod); i++; if(i == maxMethods) return i + 1; } } return i + 1; }
/** * mono_get_exception_reflection_type_load: * @types: an array of types that were defined in the moduled loaded. * @exceptions: an array of exceptions that were thrown during the type loading. * * Returns: a new instance of the `System.Reflection.ReflectionTypeLoadException` */ MonoException * mono_get_exception_reflection_type_load (MonoArray *types, MonoArray *exceptions) { MonoError error; MonoClass *klass; gpointer args [2]; MonoObject *exc; MonoMethod *method; gpointer iter; klass = mono_class_load_from_name (mono_get_corlib (), "System.Reflection", "ReflectionTypeLoadException"); mono_class_init (klass); /* Find the Type[], Exception[] ctor */ iter = NULL; while ((method = mono_class_get_methods (klass, &iter))) { if (!strcmp (".ctor", mono_method_get_name (method))) { MonoMethodSignature *sig = mono_method_signature (method); if (sig->param_count == 2 && sig->params [0]->type == MONO_TYPE_SZARRAY && sig->params [1]->type == MONO_TYPE_SZARRAY) break; } method = NULL; } g_assert (method); args [0] = types; args [1] = exceptions; exc = mono_object_new_checked (mono_domain_get (), klass, &error); mono_error_assert_ok (&error); mono_runtime_invoke_checked (method, exc, args, &error); mono_error_raise_exception (&error); /* FIXME don't raise here */ return (MonoException *) exc; }
/** * mono_get_exception_type_initialization: * @type_name: the name of the type that failed to initialize. * @inner: the inner exception. * * Returns: a new instance of the `System.TypeInitializationException` */ MonoException * mono_get_exception_type_initialization (const gchar *type_name, MonoException *inner) { MonoError error; MonoClass *klass; gpointer args [2]; MonoObject *exc; MonoMethod *method; gpointer iter; klass = mono_class_load_from_name (mono_get_corlib (), "System", "TypeInitializationException"); mono_class_init (klass); iter = NULL; while ((method = mono_class_get_methods (klass, &iter))) { if (!strcmp (".ctor", mono_method_get_name (method))) { MonoMethodSignature *sig = mono_method_signature (method); if (sig->param_count == 2 && sig->params [0]->type == MONO_TYPE_STRING && mono_class_from_mono_type (sig->params [1]) == mono_defaults.exception_class) break; } method = NULL; } g_assert (method); args [0] = mono_string_new (mono_domain_get (), type_name); args [1] = inner; exc = mono_object_new_checked (mono_domain_get (), klass, &error); mono_error_assert_ok (&error); mono_runtime_invoke_checked (method, exc, args, &error); mono_error_raise_exception (&error); /* FIXME don't raise here */ return (MonoException *) exc; }
/* * mini_add_method_trampoline: * * Add static rgctx/gsharedvt_in trampoline to M/COMPILED_METHOD if needed. Return the trampoline address, or * COMPILED_METHOD if no trampoline is needed. * ORIG_METHOD is the method the caller originally called i.e. an iface method, or NULL. */ gpointer mini_add_method_trampoline (MonoMethod *orig_method, MonoMethod *m, gpointer compiled_method, gboolean add_static_rgctx_tramp) { gpointer addr = compiled_method; gboolean callee_gsharedvt, callee_array_helper; MonoJitInfo *ji = mini_jit_info_table_find (mono_domain_get (), mono_get_addr_from_ftnptr (compiled_method), NULL); // FIXME: This loads information from AOT callee_gsharedvt = ji_is_gsharedvt (ji); callee_array_helper = FALSE; if (m->wrapper_type == MONO_WRAPPER_MANAGED_TO_MANAGED) { WrapperInfo *info = mono_marshal_get_wrapper_info (m); /* * generic array helpers. * Have to replace the wrappers with the original generic instances. */ if (info && info->subtype == WRAPPER_SUBTYPE_GENERIC_ARRAY_HELPER) { callee_array_helper = TRUE; m = info->d.generic_array_helper.method; } } else if (m->wrapper_type == MONO_WRAPPER_UNKNOWN) { WrapperInfo *info = mono_marshal_get_wrapper_info (m); /* Same for synchronized inner wrappers */ if (info && info->subtype == WRAPPER_SUBTYPE_SYNCHRONIZED_INNER) { m = info->d.synchronized_inner.method; } } if (!orig_method) orig_method = m; if (callee_gsharedvt) g_assert (m->is_inflated); addr = compiled_method; if (callee_gsharedvt && mini_is_gsharedvt_variable_signature (mono_method_signature (ji->method))) { MonoGenericSharingContext *gsctx; MonoMethodSignature *sig, *gsig; /* Here m is a generic instance, while ji->method is the gsharedvt method implementing it */ /* Call from normal/gshared code to gsharedvt code with variable signature */ gsctx = mono_jit_info_get_generic_sharing_context (ji); sig = mono_method_signature (m); gsig = mono_method_signature (ji->method); addr = mini_get_gsharedvt_wrapper (TRUE, compiled_method, sig, gsig, gsctx, -1, FALSE); //printf ("IN: %s\n", mono_method_full_name (m, TRUE)); } if (add_static_rgctx_tramp && !callee_array_helper) addr = mono_create_static_rgctx_trampoline (m, addr); return addr; }
/* * mono_arch_find_jit_info: * * See exceptions-amd64.c for docs. */ gboolean mono_arch_find_jit_info (MonoDomain *domain, MonoJitTlsData *jit_tls, MonoJitInfo *ji, MonoContext *ctx, MonoContext *new_ctx, MonoLMF **lmf, mgreg_t **save_locations, StackFrameInfo *frame) { gpointer ip = MONO_CONTEXT_GET_IP (ctx); memset (frame, 0, sizeof (StackFrameInfo)); frame->ji = ji; *new_ctx = *ctx; if (ji != NULL) { gssize regs [MONO_MAX_IREGS + 1]; guint8 *cfa; guint32 unwind_info_len; guint8 *unwind_info; frame->type = FRAME_TYPE_MANAGED; if (ji->from_aot) unwind_info = mono_aot_get_unwind_info (ji, &unwind_info_len); else unwind_info = mono_get_cached_unwind_info (ji->used_regs, &unwind_info_len); regs [X86_EAX] = new_ctx->eax; regs [X86_EBX] = new_ctx->ebx; regs [X86_ECX] = new_ctx->ecx; regs [X86_EDX] = new_ctx->edx; regs [X86_ESP] = new_ctx->esp; regs [X86_EBP] = new_ctx->ebp; regs [X86_ESI] = new_ctx->esi; regs [X86_EDI] = new_ctx->edi; regs [X86_NREG] = new_ctx->eip; mono_unwind_frame (unwind_info, unwind_info_len, ji->code_start, (guint8*)ji->code_start + ji->code_size, ip, regs, MONO_MAX_IREGS + 1, save_locations, MONO_MAX_IREGS, &cfa); new_ctx->eax = regs [X86_EAX]; new_ctx->ebx = regs [X86_EBX]; new_ctx->ecx = regs [X86_ECX]; new_ctx->edx = regs [X86_EDX]; new_ctx->esp = regs [X86_ESP]; new_ctx->ebp = regs [X86_EBP]; new_ctx->esi = regs [X86_ESI]; new_ctx->edi = regs [X86_EDI]; new_ctx->eip = regs [X86_NREG]; /* The CFA becomes the new SP value */ new_ctx->esp = (gssize)cfa; /* Adjust IP */ new_ctx->eip --; if (*lmf && (MONO_CONTEXT_GET_BP (ctx) >= (gpointer)(*lmf)->ebp)) { /* remove any unused lmf */ *lmf = (gpointer)(((gsize)(*lmf)->previous_lmf) & ~3); } /* Pop arguments off the stack */ /* * FIXME: LLVM doesn't push these, we can't use ji->from_llvm as it describes * the callee. */ #ifndef ENABLE_LLVM if (ji->has_arch_eh_info) new_ctx->esp += mono_jit_info_get_arch_eh_info (ji)->stack_size; #endif return TRUE; } else if (*lmf) { if (((guint64)(*lmf)->previous_lmf) & 2) { /* * This LMF entry is created by the soft debug code to mark transitions to * managed code done during invokes. */ MonoLMFExt *ext = (MonoLMFExt*)(*lmf); g_assert (ext->debugger_invoke); memcpy (new_ctx, &ext->ctx, sizeof (MonoContext)); *lmf = (gpointer)(((gsize)(*lmf)->previous_lmf) & ~3); frame->type = FRAME_TYPE_DEBUGGER_INVOKE; return TRUE; } if ((ji = mini_jit_info_table_find (domain, (gpointer)(*lmf)->eip, NULL))) { } else { if (!((guint32)((*lmf)->previous_lmf) & 1)) /* Top LMF entry */ return FALSE; g_assert_not_reached (); /* Trampoline lmf frame */ frame->method = (*lmf)->method; } new_ctx->esi = (*lmf)->esi; new_ctx->edi = (*lmf)->edi; new_ctx->ebx = (*lmf)->ebx; new_ctx->ebp = (*lmf)->ebp; new_ctx->eip = (*lmf)->eip; /* Adjust IP */ new_ctx->eip --; frame->ji = ji; frame->type = FRAME_TYPE_MANAGED_TO_NATIVE; /* Check if we are in a trampoline LMF frame */ if ((guint32)((*lmf)->previous_lmf) & 1) { /* lmf->esp is set by the trampoline code */ new_ctx->esp = (*lmf)->esp; /* Pop arguments off the stack */ /* FIXME: Handle the delegate case too ((*lmf)->method == NULL) */ /* FIXME: Handle the IMT/vtable case too */ #if 0 #ifndef ENABLE_LLVM if ((*lmf)->method) { MonoMethod *method = (*lmf)->method; MonoJitArgumentInfo *arg_info = g_newa (MonoJitArgumentInfo, mono_method_signature (method)->param_count + 1); guint32 stack_to_pop = mono_arch_get_argument_info (NULL, mono_method_signature (method), mono_method_signature (method)->param_count, arg_info); new_ctx->esp += stack_to_pop; } #endif #endif } else /* the lmf is always stored on the stack, so the following * expression points to a stack location which can be used as ESP */ new_ctx->esp = (unsigned long)&((*lmf)->eip); *lmf = (gpointer)(((gsize)(*lmf)->previous_lmf) & ~3); return TRUE; } return FALSE; }