Ejemplo n.º 1
0
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;
}
Ejemplo n.º 2
0
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;
}
Ejemplo n.º 3
0
void GDMonoMethod::_update_signature(MonoMethodSignature *p_method_sig) {
	params_count = mono_signature_get_param_count(p_method_sig);

	MonoType *ret_type = mono_signature_get_return_type(p_method_sig);
	if (ret_type) {
		return_type.type_encoding = mono_type_get_type(ret_type);

		if (return_type.type_encoding != MONO_TYPE_VOID) {
			MonoClass *ret_type_class = mono_class_from_mono_type(ret_type);
			return_type.type_class = GDMono::get_singleton()->get_class(ret_type_class);
		}
	}

	void *iter = NULL;
	MonoType *param_raw_type;
	while ((param_raw_type = mono_signature_get_params(p_method_sig, &iter)) != NULL) {
		ManagedType param_type;

		param_type.type_encoding = mono_type_get_type(param_raw_type);

		MonoClass *param_type_class = mono_class_from_mono_type(param_raw_type);
		param_type.type_class = GDMono::get_singleton()->get_class(param_type_class);

		param_types.push_back(param_type);
	}
}
Ejemplo n.º 4
0
	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;
	}
Ejemplo n.º 5
0
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);
    }
}
Ejemplo n.º 6
0
/*
 * 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, &param_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;
}
Ejemplo n.º 7
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;
}
Ejemplo n.º 8
0
/*
 * 将由lua传入的参数表转化为void *[]参数表
 * L : 含有参数表的lua_State
 * base : 参数表在lua_State中的起始位置(靠近栈底的一边)
 * method : 参数表将要应用到的MonoMethod*
 * 
 * 该调用只针对Static methods, 和 non-Static methods, 不针对generic methods
 */
static void *call_method (lua_State *L, int base, MonoObject *thiz, MonoMethod *method, MonoObject **ex) {
    MonoMethodSignature *sig = mono_method_signature (method);
    if (!sig)
        luaL_error (L, "can not get the method's signature.");
    int n = mono_signature_get_param_count (sig);
    int cur_n = lua_gettop (L) - base + 1;
    if (cur_n != n) {
        /*Fixme : mono_method_full_name 的返回值需要显示 g_free*/
        luaL_error (L, "%s need %d arguments, but get %d.", 
            mono_method_full_name (method, 1), n, cur_n);
    }
    void **args = 0;
    if (n > 0)
        args = new void*[n];
    void *iter = 0;
    MonoType *param_type;
    for (int i = 0; (param_type = mono_signature_get_params (sig, &iter)) != 0; i++) {
        /*reference 类型的参数 无论是否加ref关键字, 都是传递改类型对象指针的指针*/
        if (mono_type_is_reference (param_type) || mono_type_is_byref (param_type)) {
            void *p = lua_touserdata (L, base + i);
            if (!p)
                luaL_error (L, "%s : %d arg need a reference type.", mono_method_full_name (method, 1), i);
            args[i] = p;
            continue;
        }
        /*剩下的都是value类型*/
        switch (mono_type_get_type (param_type)) {
            case MONO_TYPE_BOOLEAN: {
                int b = lua_toboolean (L, base + i);
                MonoObject *obj = mono_value_box (mono_domain_get (), mono_get_boolean_class (), &b);
                args[i] = mono_object_unbox (obj);
                break;
            }
            case MONO_TYPE_CHAR: {
                /*char 用int来表示*/
                int b = luaL_checkint (L, base + i);
                MonoObject *obj = mono_value_box (mono_domain_get (), mono_get_char_class (), &b);
                args[i] = mono_object_unbox (obj);
                break;
            }
            case MONO_TYPE_I1: {
                int b = luaL_checkint (L, base + i);
                MonoObject *obj = mono_value_box (mono_domain_get (), mono_get_sbyte_class (), &b);
                args[i] = mono_object_unbox (obj);
                break;
            }
            case MONO_TYPE_U1: {
                unsigned long l = luaL_checkunsigned (L, base + i);
                MonoObject *obj = mono_value_box (mono_domain_get (), mono_get_byte_class (), &l);
                args[i] = mono_object_unbox (obj);
                break;
            }
            case MONO_TYPE_I2: {
                int b = luaL_checkint (L, base + i);
                MonoObject *obj = mono_value_box (mono_domain_get (), mono_get_int16_class (), &b);
                args[i] = mono_object_unbox (obj);
                break;
            }
            case MONO_TYPE_U2: {
                unsigned long l = luaL_checkunsigned (L, base + i);
                MonoObject *obj = mono_value_box (mono_domain_get (), mono_get_uint16_class (), &l);
                args[i] = mono_object_unbox (obj);
                break;
            }
            case MONO_TYPE_I4: {
                int b = luaL_checkint (L, base + i);
                MonoObject *obj = mono_value_box (mono_domain_get (), mono_get_int32_class (), &b);
                args[i] = mono_object_unbox (obj);
                break;
            }
            case MONO_TYPE_VALUETYPE:
            case MONO_TYPE_U4: {
                unsigned long l = luaL_checkunsigned (L, base + i);
                MonoObject *obj = mono_value_box (mono_domain_get (), mono_get_uint32_class (), &l);
                args[i] = mono_object_unbox (obj);
                break;
            }
            case MONO_TYPE_I8: {
                void *u = lua_touserdata (L, base + i);
                if (!u)
                    luaL_error (L, "%s : %d arg need Int64.", mono_method_full_name (method, 1), i);
                MonoObject *obj = mono_value_box (mono_domain_get (), mono_get_int64_class (), u);
                args[i] = mono_object_unbox (obj);
                break;
            }
            case MONO_TYPE_U8: {
                void *u = lua_touserdata (L, base + i);
                if (!u)
                    luaL_error (L, "%s : %d arg need UInt64.", mono_method_full_name (method, 1), i);
                MonoObject *obj = mono_value_box (mono_domain_get (), mono_get_uint64_class (), u);
                args[i] = mono_object_unbox (obj);
                break;
            }
            case MONO_TYPE_R4: {
                /*这里的精度损失由使用lua的人负责*/
                float f = (float)lua_tonumber (L, base + i);
                MonoObject *obj = mono_value_box (mono_domain_get (), mono_get_single_class (), &f);
                args[i] = mono_object_unbox (obj);
                break;
            }
            case MONO_TYPE_R8: {
                double d = (double)lua_tonumber (L, base + i);
                MonoObject *obj = mono_value_box (mono_domain_get (), mono_get_double_class (), &d);
                args[i] = mono_object_unbox (obj);
                break;
            }
            case MONO_TYPE_I: {
                void *u = lua_touserdata (L, base + i);
                if (!u)
                    luaL_error (L, "%s : %d arg need IntPtr.", mono_method_full_name (method, 1), i);
                MonoObject *obj = mono_value_box (mono_domain_get (), mono_get_intptr_class (), u);
                args[i] = mono_object_unbox (obj);
                break;
            }
            case MONO_TYPE_U: {
                void *u = lua_touserdata (L, base + i);
                if (!u)
                    luaL_error (L, "%s : %d arg need UIntPtr.", mono_method_full_name (method, 1), i);
                MonoObject *obj = mono_value_box (mono_domain_get (), mono_get_uintptr_class (), u);
                args[i] = mono_object_unbox (obj);
                break;
            }
            case MONO_TYPE_MVAR:
                luaL_error (L, "generic method dont be supported.");
            case MONO_TYPE_PTR:
                luaL_error (L, "dont support the ptr type.");
            default:
                luaL_error (L, "unknow method args type : 0x%02X", mono_type_get_type (param_type));
        }
    }
    MonoObject *ret = mono_runtime_invoke (method, thiz, args, ex);
    //MonoType *ret_type = mono_signature_get_return_type (sig);
    LOGD ("call_method be called!");
    return ret;
}