Beispiel #1
0
const Vector<GDMonoClass *> &GDMonoClass::get_all_delegates() {
	if (delegates_fetched)
		return delegates_list;

	void *iter = NULL;
	MonoClass *raw_class = NULL;
	while ((raw_class = mono_class_get_nested_types(mono_class, &iter)) != NULL) {
		if (mono_class_is_delegate(raw_class)) {
			StringName name = mono_class_get_name(raw_class);

			Map<StringName, GDMonoClass *>::Element *match = delegates.find(name);

			if (match) {
				delegates_list.push_back(match->get());
			} else {
				GDMonoClass *delegate = memnew(GDMonoClass(mono_class_get_namespace(raw_class), mono_class_get_name(raw_class), raw_class, assembly));
				delegates.insert(name, delegate);
				delegates_list.push_back(delegate);
			}
		}
	}

	delegates_fetched = true;

	return delegates_list;
}
Beispiel #2
0
static void
output_type_edge (MonoClass *first, MonoClass *second) {
	if (include_namespace)
		fprintf (output, "\t\"%s.%s\" -> \"%s.%s\"\n", mono_class_get_namespace (first), mono_class_get_name (first), mono_class_get_namespace (second), mono_class_get_name (second));
	else
		fprintf (output, "\t\"%s\" -> \"%s\"\n", mono_class_get_name (first), mono_class_get_name (second));
}
Beispiel #3
0
void CPipeServer::EnumClassesInImage()
{
	int i;
	void *image=(void *)ReadQword();
	void *tdef=mono_image_get_table_info (image, MONO_TABLE_TYPEDEF);
	int tdefcount=mono_table_info_get_rows(tdef);


	WriteDword(tdefcount);

	for (i = 0; i < tdefcount; i++)
	{		
		void *c = mono_class_get(image, MONO_TOKEN_TYPE_DEF | i+1);
		char *name=mono_class_get_name(c);

		WriteQword((UINT_PTR)c);

		WriteWord(strlen(name));
		Write(name, strlen(name));	

		name=mono_class_get_namespace(c);
		WriteWord(strlen(name));
		Write(name, strlen(name));	



	}
}
Beispiel #4
0
bool CScriptClass::ImplementsInterface(const char *interfaceName, const char *nameSpace, bool bSearchDerivedClasses)
{
	void *pIterator = 0;

	MonoClass *pClass = (MonoClass *)m_pObject;

	while (pClass != nullptr)
	{
		MonoClass *pCurInterface = mono_class_get_interfaces(pClass, &pIterator);
		if(pCurInterface == nullptr)
		{
			if(!bSearchDerivedClasses)
				return false;

			pClass = mono_class_get_parent(pClass);
			if(pClass == mono_get_object_class())
				break;

			pIterator = 0;
			continue;
		}

		if(!strcmp(mono_class_get_name(pCurInterface), interfaceName) 
			&& (nameSpace == nullptr || !strcmp(mono_class_get_namespace(pCurInterface), nameSpace)))
			return true;
	}

	return false;
}
Beispiel #5
0
void CPipeServer::GetKlassName()
{
	void *klass=(void *)ReadQword();
	char *methodname=mono_class_get_name(klass);

	WriteWord(strlen(methodname));
	Write(methodname, strlen(methodname));	
}
	const Vector<MonoClass*>& MonoAssembly::getAllClasses() const
	{
		if(mHaveCachedClassList)
			return mCachedClassList;
		
		mCachedClassList.clear();
		Stack<MonoClass*> todo;

		int numRows = mono_image_get_table_rows (mMonoImage, MONO_TABLE_TYPEDEF);

		for(int i = 1; i < numRows; i++) // Skip Module
		{
			::MonoClass* monoClass = mono_class_get (mMonoImage, (i + 1) | MONO_TOKEN_TYPE_DEF);

			String ns;
			String type;
			MonoUtil::getClassName(monoClass, ns, type);

			MonoClass* curClass = getClass(ns, type);

			if (curClass != nullptr)
			{
				// Get nested types if it has any
				todo.push(curClass);
				while (!todo.empty())
				{
					MonoClass* curNestedClass = todo.top();
					todo.pop();

					void* iter = nullptr;
					do
					{
						::MonoClass* rawNestedClass = rawNestedClass = mono_class_get_nested_types(curNestedClass->_getInternalClass(), &iter);
						if (rawNestedClass == nullptr)
							break;

						String nestedType = curNestedClass->getTypeName() + "+" + mono_class_get_name(rawNestedClass);

						MonoClass* nestedClass = getClass(ns, nestedType, rawNestedClass);
						if (nestedClass != nullptr)
						{
							mCachedClassList.push_back(nestedClass);
							todo.push(nestedClass);
						}

					} while (true);					
				}

				mCachedClassList.push_back(curClass);
			}
		}

		mHaveCachedClassList = true;

		return mCachedClassList;
	}
Beispiel #7
0
bool CScriptClass::ImplementsClass(const char *className, const char *nameSpace)
{
	MonoClass *pClass = (MonoClass *)m_pObject;

	while (pClass != nullptr)
	{
		if(!strcmp(mono_class_get_name(pClass), className) 
			&& (nameSpace == nullptr || !strcmp(mono_class_get_namespace(pClass), nameSpace)))
			return true;
		else
			CryLogAlways("%s did not match pattern %s", mono_class_get_name(pClass), className);

		pClass = mono_class_get_parent(pClass);
		if(pClass == mono_get_object_class())
			break;
	}

	return false;
}
Beispiel #8
0
int main()
{
#if LOADDYNAMIC
	SetupMono();
#endif

#if WIN32
	SetEnvironmentVariable(L"MONO_PATH",L"..\\..\\..\\builds\\monodistribution\\lib\\mono\\2.0");
#else
	setenv("MONO_PATH","../../../builds/monodistribution/lib/mono/2.0",1);
#endif

        MonoDomain* domain = mono_jit_init_version ("Unity Root Domain","v2.0.50727");

        //create and set child domain
        MonoDomain* child = mono_domain_create_appdomain("Unity Child Domain",NULL);
        mono_domain_set(child,0);

        //load assembly and call entrypoint
        MonoAssembly* ass = mono_domain_assembly_open (mono_domain_get (),"lucas.exe");
        MonoImage* img = mono_assembly_get_image(ass);
        printf("image %p\n",img);
        MonoMethodDesc* desc = mono_method_desc_new("Main2:Main",1);
        MonoMethod* m = mono_method_desc_search_in_image(desc,img);
        printf("method %p\n",m);
        MonoObject* exc;
        MonoObject* newinst = mono_object_new(mono_domain_get(),mono_method_get_class(m));
        MonoObject* ret = mono_runtime_invoke(m,newinst,0,&exc);
        printf ("Exception: %p\n",exc);
        if (exc)
        {
                MonoException* exc2 = (MonoException*) exc;
                printf ("exc msg:%s\n",mono_class_get_name(mono_object_get_class((MonoObject*)exc)));
        }
        printf ("ret: %p\n",ret);

		Sleep(0);

        //switch back to root domain
        mono_domain_set(domain,0);
        mono_domain_unload(child);
		mono_runtime_set_shutting_down ();
		mono_threads_set_shutting_down ();
		mono_thread_pool_cleanup ();
		mono_domain_finalize(mono_get_root_domain(),2000);
		mono_runtime_cleanup(mono_get_root_domain());

		printf("Unloading mono\n");
#if LOADDYNAMIC
	CleanupMono();
#endif

		while(1){} //sleep so stale monothreads have a chance to crash
        return 0;
}
Beispiel #9
0
MonoObject* ml_invoke(MonoMethod *method, void *obj, void **params)
{
	MonoObject *ret, *exception;

	ret = mono_runtime_invoke(method, obj, params, &exception);
	if (exception) {
		purple_debug(PURPLE_DEBUG_ERROR, "mono", "caught exception: %s\n", mono_class_get_name(mono_object_get_class(exception)));
	}

	return ret;
}
Beispiel #10
0
CScriptClass::CScriptClass(MonoClass *pClass, CScriptAssembly *pDeclaringAssembly)
	: m_pDeclaringAssembly(pDeclaringAssembly)
	, m_refs(0)
{
	CRY_ASSERT(pClass);

	m_pObject = (MonoObject *)pClass; 
	m_objectHandle = -1;
	m_pClass = NULL;

	m_name = string(mono_class_get_name(pClass));
	m_namespace = string(mono_class_get_namespace(pClass));
}
static int gc_find_big(MonoObject *obj, MonoClass *klass, uintptr_t size, uintptr_t num,
        MonoObject **refs, uintptr_t *offsets, void *data) {
        // account for object alignment in the heap 
        size += 7; size &= ~7;
        if (size < 1000 * 1000) return 0;
        
        big[big_count] = obj; big_count++;
        puts("  ## BIG OBJECT DETECTED ##");
		
        const char *name = mono_class_get_name (klass);
        const char *nspace = mono_class_get_namespace (klass);
        printf("%s.%s of %i bytes\n", nspace, name, size);
        return 0;
}
Beispiel #12
0
/*
 * mono.new(class, "ctor_sig", ...)
 * class 为MonoClass指针(userdata)
 * "ctor_sig" : 带有函数签名的.ctor 比如 : .ctor(int, int), 
 *              若使用默认构造函数(无参数), 该参数为空字符串
 * ... : 为构造函数所需实参
 * 返回 : MonoObject*(userdata)
 */
static int l_newobj (lua_State *L) {
    MonoClass *clazz = (MonoClass*)lua_touserdata (L, 1);
    luaL_argcheck (L, clazz != 0, 1, "class is null.");
    char const *ctor_sig = luaL_checkstring (L, 2);
    MonoMethod *ctor = get_class_method (clazz, ctor_sig);
    if (!ctor)
        luaL_error (L, "class %s can not find the %s.", mono_class_get_name (clazz), ctor_sig);
    MonoObject *obj = mono_object_new (mono_domain_get (), clazz);
    MonoObject *ex = 0;
    call_method (L, 3, obj, ctor, &ex);
    if (ex)
        luaL_error (L, "init the obj cause an exception!");
    lua_pushlightuserdata (L, obj);
    return 1;
}
Beispiel #13
0
void CPipeServer::Object_GetClass()
{
	void *object=(void *)ReadQword();
	char *classname;
	void *klass;

	//OutputDebugStringA("MONOCMD_OBJECT_GETCLASS");

	
	ExpectingAccessViolations=TRUE; //cause access violations to throw an exception
	try
	{
		unsigned int i;
		
		klass=mono_object_get_class(object);
		classname=mono_class_get_name(klass);

		//small test to see if the classname is readable
		for (i=0; i<strlen(classname); i++)
		{
			char x=classname[i];
			if (x=='\0')
				break;			
		}		

		if (klass!=0)
		{		
			WriteQword((UINT64)klass);
			WriteWord(strlen(classname));
			Write(classname, strlen(classname));
		}
		else
		{
			WriteQword(0);
		}


	}
	catch (char *e)	
	{
		OutputDebugStringA("Error getting the class:\n");
		OutputDebugStringA(e);
		WriteQword(0); //failure. Invalid object
	}

	ExpectingAccessViolations=FALSE; //back to normal behaviour
}
Beispiel #14
0
gboolean ml_is_api_dll(MonoImage *image)
{
	MonoClass *klass;
	int i, total;

	total = mono_image_get_table_rows (image, MONO_TABLE_TYPEDEF);
	for (i = 1; i <= total; ++i) {
		klass = mono_class_get (image, MONO_TOKEN_TYPE_DEF | i);
		if (strcmp(mono_class_get_name(klass), "Debug") == 0)
			if (strcmp(mono_class_get_namespace(klass), "Purple") == 0) {
				ml_set_api_image(image);
				return TRUE;
			}
	}

	return FALSE;
}
Beispiel #15
0
GDMonoClass *GDMonoAssembly::get_class(MonoClass *p_mono_class) {

	ERR_FAIL_COND_V(!loaded, NULL);

	Map<MonoClass *, GDMonoClass *>::Element *match = cached_raw.find(p_mono_class);

	if (match)
		return match->value();

	StringName namespace_name = mono_class_get_namespace(p_mono_class);
	StringName class_name = mono_class_get_name(p_mono_class);

	GDMonoClass *wrapped_class = memnew(GDMonoClass(namespace_name, class_name, p_mono_class, this));

	cached_classes[ClassKey(namespace_name, class_name)] = wrapped_class;
	cached_raw[p_mono_class] = wrapped_class;

	return wrapped_class;
}
Beispiel #16
0
MonoClass* ml_find_plugin_class(MonoImage *image)
{
	MonoClass *klass, *pklass = NULL;
	int i, total;

	total = mono_image_get_table_rows (image, MONO_TABLE_TYPEDEF);
	for (i = 1; i <= total; ++i) {
		klass = mono_class_get (image, MONO_TOKEN_TYPE_DEF | i);

		pklass = mono_class_get_parent(klass);
		if (pklass) {

			if (strcmp("Plugin", mono_class_get_name(pklass)) == 0)
				return klass;
		}
	}

	return NULL;
}
static int gc_dump_big_refs(MonoObject *obj, MonoClass *klass, uintptr_t size, uintptr_t num,
        MonoObject **refs, uintptr_t *offsets, void *data) {    
		if (num == 0) return 0;
		int i, j;
		
		for (i = 0; i < num; i++) {
			for (j = 0; j < big_count; j++) {
				if (refs[i] == big[j]) { goto found; }
			}
		}
		
		return 0;    
    found:
        puts("  ## REFERENCING BIG OBJECT DETECTED ##");
		
        const char *name = mono_class_get_name (klass);
        const char *nspace = mono_class_get_namespace (klass);
        printf("    %s.%s\n", nspace, name);
        return 0;
}
Beispiel #18
0
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);
	}
}
Beispiel #19
0
static gboolean
collect_coverage_for (MonoProfiler *prof, MonoMethod *method)
{
	int i;
	char *classname;
	char *fqn;
	MonoMethodHeader *header;
	gboolean has_positive, found;
	guint32 iflags, flags, code_size;
	MonoClass *klass;
	MonoImage *image;

	flags = mono_method_get_flags (method, &iflags);
	if ((iflags & 0x1000 /*METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL*/) ||
	    (flags & 0x2000 /*METHOD_ATTRIBUTE_PINVOKE_IMPL*/))
		return FALSE;

	//if (method->wrapper_type != MONO_WRAPPER_NONE)
	//	return FALSE;

	klass = mono_method_get_class (method);
	image = mono_class_get_image (klass);
	/* Hacky way of determining the executing assembly */
	if (! prof->outfile_name && (strcmp (mono_method_get_name (method), "Main") == 0)) {
		prof->outfile_name = g_strdup_printf ("%s.cov", mono_image_get_filename (image));
	}

	/* Check filters */
	if (prof->filters) {
		/* Check already filtered classes first */
		if (g_hash_table_lookup (prof->filtered_classes, klass))
			return FALSE;

		classname = mono_type_get_name (mono_class_get_type (klass));

		fqn = g_strdup_printf ("[%s]%s", mono_image_get_name (image), classname);

		// Check positive filters first
		has_positive = FALSE;
		found = FALSE;
		for (i = 0; i < prof->filters->len; ++i) {
			char *filter = g_ptr_array_index (prof->filters_as_str, i);
			if (filter [0] == '+') {
				filter = &filter [1];
				if (strstr (fqn, filter) != NULL)
					found = TRUE;
				has_positive = TRUE;
			}
		}
		if (has_positive && !found)
			return FALSE;

		for (i = 0; i < prof->filters->len; ++i) {
			// Is substring search suffices ???
//			GPatternSpec *spec = g_ptr_array_index (filters, i);
//			if (g_pattern_match_string (spec, classname)) {
			char *filter = g_ptr_array_index (prof->filters_as_str, i);
			if (filter [0] == '+')
				continue;

			// Skip '-'
			filter = &filter [1];
			if (strstr (fqn, filter) != NULL) {
				g_hash_table_insert (prof->filtered_classes, klass, klass);
				return FALSE;
			}
		}
		g_free (fqn);
		g_free (classname);
	}

	header = mono_method_get_header (method);

	mono_method_header_get_code (header, &code_size, NULL);
	if (code_size > 20000) {
		exit (1);
		g_warning ("Unable to instrument method %s:%s since it is too complex.", mono_class_get_name (klass), mono_method_get_name (method));
		return FALSE;
	}

	g_hash_table_insert (prof->methods, method, method);

	g_hash_table_insert (prof->classes, klass, klass);

	g_hash_table_insert (prof->assemblies, mono_image_get_assembly (image), mono_image_get_assembly (image));

	return TRUE;
}
Beispiel #20
0
void
virt_mono_throw_unhandled_exception (MonoObject *exc)
{
  caddr_t err;
  char *message = (char *) "";
  const char *name = (const char *) "";
  MonoString *str;
  MonoMethod *method;
  MonoClass *klass;
  gboolean free_message = FALSE;
  gint i;

  if (mono_object_isinst (exc, mono_get_exception_class ()))
    {
      klass = mono_object_get_class (exc);
      method = NULL;
      while (klass && method == NULL)
	{
	  gpointer m_iter = NULL;
	  for (method = mono_class_get_methods (klass, &m_iter); method != NULL;
	      method = mono_class_get_methods (klass, &m_iter))
	    {
	      MonoMethodSignature *sig = mono_method_signature (method);
	      guint32 flags = 0;
	      const char *name = mono_method_get_name (method);

	      mono_method_get_flags (method, &flags);
	      if (!strcmp ("ToString", name) &&
		  sig->param_count == 0
#ifdef OLD_KIT_1_1_5
		  && (flags & METHOD_ATTRIBUTE_VIRTUAL)
		  && (flags & METHOD_ATTRIBUTE_PUBLIC)
#endif
		  )
		{
		  break;
		}
	      method = NULL;
	    }

	  if (method == NULL)
	    klass = mono_class_get_parent (klass);
	}

      g_assert (method);

      str = (MonoString *) mono_runtime_invoke (method, exc, NULL, NULL);
      if (str) {
	message = mono_string_to_utf8 (str);
	free_message = TRUE;
	name = mono_class_get_name (klass);
      }
    }

  /*
   * g_printerr ("\nUnhandled Exception: %s.%s: %s\n", exc->vtable->klass->name_space,
   *	   exc->vtable->klass->name, message);
   */
  g_printerr ("\nUnhandled Exception: %s\n", message);


  err = srv_make_new_error ("42000", "MN001", "Unhandled Mono Exception [%.200s]: %.200s",
      name, message);
  if (free_message)
    g_free (message);
  sqlr_resignal (err);
}
Beispiel #21
0
static caddr_t
sa_to_dk (MonoArray *mono_list, int ofs, int mode, void *udt)
{
  guint32 ret_type;
  int clr_object = 0;
  MonoObject *type, *value;
  caddr_t ret = NULL;
  MonoClass *cls;
  int len = mono_array_length (mono_list), inx;
  dk_set_t ret_set = NULL;

  type = (MonoObject *)mono_array_get (mono_list, gpointer, ofs + 0);

  ret_type = *(guint32 *)((char *)type + sizeof (MonoObject));

  if (!ret_type)
    {
      char *error_text;
      caddr_t err = NULL;

      value = (MonoObject *)mono_array_get (mono_list, gpointer, ofs + 1);
      error_text = mono_string_to_utf8 ((MonoString *)value);
      if (error_text)
	err = srv_make_new_error ("42000", "MN002", "Mono error : %.200s",
	    mono_class_get_name (mono_object_get_class (value)), error_text);
      else
	err = srv_make_new_error ("42000", "MN003", "Unknown mono error");
      g_free (error_text);
      sqlr_resignal (err);
    }

  /* get type of object */
  clr_object = 0;
  if (ret_type == 5 || ret_type == 6)
    clr_object = 1;

  for (inx = 1; inx < len; inx++)
    {
      value = (MonoObject *)mono_array_get (mono_list, gpointer, ofs + inx);
      if (value)
	{
	  cls = mono_object_get_class (value);
	  if (cls == mono_get_int32_class ())
	    {
	      gint32 v = *(gint32 *)((char *)value + sizeof (MonoObject));
	      if (clr_object)
		{
		  void * what_udt;

		  if (mode)
		    {
		      /*add_id (v);*/
		      ret = box_num (v);
		    }
		  else
		    {
		      what_udt = udt_find_class_for_clr_instance (v, udt);
		      if (what_udt)
			{
			  /*add_id (v);*/
			  ret = cpp_udt_clr_instance_allocate (v, what_udt);
			}
		      else
			{
			  sqlr_new_error ("22023", "MN005", "Can't map Mono result to PL type");
			}
		    }
		}
	      else
		ret = box_num (v);
	    }
	  else if (cls == mono_get_uint32_class())
	    ret = box_num (*(guint32 *)((char *)value + sizeof (MonoObject)));
	  else if (cls == mono_get_single_class ())
	    ret = box_float (*(float *)((char *)value + sizeof (MonoObject)));
	  else if (cls == mono_get_double_class ())
	    ret = box_double (*(double *)((char *)value + sizeof (MonoObject)));
	  else if (cls == mono_get_boolean_class ())
	    ret = box_num (*(guint8 *)((guint8 *)value + sizeof (MonoObject)));
	  else if (cls == mono_get_string_class ())
	    {
	      char *utf8 = mono_string_to_utf8 ((MonoString *)value);
	      ret = box_utf8_as_wide_char (utf8, NULL, strlen (utf8), 0, DV_WIDE);
	      g_free (utf8);
	    }
	  else
	    {
	      const char *name = mono_class_get_name (cls);
	      sqlr_new_error ("22023", "MN006", "Can't map CLR result of type (%s) to PL type",
		  name ? name : "<unknown>");
	    }
	}
      else
	ret = NULL;
    if (ret_type != 3 && ret_type != 4 && ret_type != 5)
  	return ret;
      else
	dk_set_push (&ret_set, ret);
    }
  return list_to_array (dk_set_nreverse (ret_set));
}
Beispiel #22
0
IMonoMethod *CScriptClass::GetMethod(const char *name, IMonoArray *pArgs, bool throwOnFail)
{
	MonoMethodSignature *pSignature = nullptr;

	void *pIterator = 0;

	MonoClass *pClass = (MonoClass *)m_pObject;
	MonoType *pClassType = mono_class_get_type(pClass);
	MonoMethod *pCurMethod = nullptr;

	int suppliedArgsCount = pArgs ? pArgs->GetSize() : 0;

	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 == 0 && suppliedArgsCount == 0)
			return new CScriptMethod(pCurMethod);
		else if(bCorrectName && signatureParamCount >= suppliedArgsCount && suppliedArgsCount != 0)
		{
			//if(bStatic != (mono_method_get_flags(pCurMethod, nullptr) & METHOD_ATTRIBUTE_STATIC) > 0)
				//continue;

			void *pIter = nullptr;

			MonoType *pType = nullptr;
			for(int i = 0; i < signatureParamCount; i++)
			{
				pType = mono_signature_get_params(pSignature, &pIter);

				if(mono::object item = pArgs->GetItem(i))
				{
					MonoClass *pItemClass = mono_object_get_class((MonoObject *)item);
					MonoType *pItemType = mono_class_get_type(pItemClass);

					MonoTypeEnum itemMonoType = (MonoTypeEnum)mono_type_get_type(pItemType);

					MonoTypeEnum monoType = (MonoTypeEnum)mono_type_get_type(pType);

					if(itemMonoType != monoType)
					{
						// exceptions:
						// Anything can be treated as object.
						if(monoType == MONO_TYPE_OBJECT) {}
						// The runtime confuses things with value types a lot, so ignore parameters that appear with that type.
						else if(itemMonoType == MONO_TYPE_VALUETYPE || monoType == MONO_TYPE_VALUETYPE) {}
						else
						{
							if(MonoClass *pMethodParameterClass = mono_type_get_class(pType))
							{
								MonoWarning("Parameter mismatch when searching for method %s in class %s.%s, on parameter %i: Provided type %s.%s does not match expected parameter type %s.%s.", 
									name, mono_class_get_namespace(pClass), mono_class_get_name(pClass), i + 1, mono_class_get_namespace(pItemClass), mono_class_get_name(pItemClass), mono_class_get_namespace(pMethodParameterClass), mono_class_get_name(pMethodParameterClass));
							}
							else
							{
								MonoWarning("Parameter mismatch when searching for method %s in class %s.%s, on parameter %i: Provided type %s.%s does not match parameter type.", 
									name, mono_class_get_namespace(pClass), mono_class_get_name(pClass), i + 1, mono_class_get_namespace(pItemClass), mono_class_get_name(pItemClass));
							}
							break;
						}
					}
				}

				if(i + 1 == suppliedArgsCount)
					return new CScriptMethod(pCurMethod);
			}
		}
	}

	if(throwOnFail)
	{
		if(IMonoException *pException = GetMonoScriptSystem()->GetCorlibAssembly()->GetException("System", "MissingMethodException", "Failed to locate method %s in class %s", name, GetName()))
			pException->Throw();
	}

	return nullptr;
}
Beispiel #23
0
const char* mioClass::getName() const
{
    if (!mclass) { return nullptr; }
    return mono_class_get_name(mclass);
}