Пример #1
0
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;
}
Пример #2
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);
	}
}
Пример #3
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;
}
Пример #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;
	}
Пример #5
0
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);
}
Пример #6
0
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;
}
Пример #7
0
gpointer
mono_arch_get_gsharedvt_call_info (gpointer addr, MonoMethodSignature *normal_sig, MonoMethodSignature *gsharedvt_sig, gboolean gsharedvt_in, gint32 vcall_offset, gboolean calli)
{
	GSharedVtCallInfo *info;
	CallInfo *caller_cinfo, *callee_cinfo;
	MonoMethodSignature *caller_sig, *callee_sig;
	int aindex, i;
	gboolean var_ret = FALSE;
	CallInfo *cinfo, *gcinfo;
	MonoMethodSignature *sig, *gsig;
	GPtrArray *map;

	if (gsharedvt_in) {
		caller_sig = normal_sig;
		callee_sig = gsharedvt_sig;
		caller_cinfo = mono_arch_get_call_info (NULL, caller_sig);
		callee_cinfo = mono_arch_get_call_info (NULL, callee_sig);
	} else {
		callee_sig = normal_sig;
		caller_sig = gsharedvt_sig;
		callee_cinfo = mono_arch_get_call_info (NULL, callee_sig);
		caller_cinfo = mono_arch_get_call_info (NULL, caller_sig);
	}

	/*
	 * If GSHAREDVT_IN is true, this means we are transitioning from normal to gsharedvt code. The caller uses the
	 * normal call signature, while the callee uses the gsharedvt signature.
	 * If GSHAREDVT_IN is false, its the other way around.
	 */

	/* sig/cinfo describes the normal call, while gsig/gcinfo describes the gsharedvt call */
	if (gsharedvt_in) {
		sig = caller_sig;
		gsig = callee_sig;
		cinfo = caller_cinfo;
		gcinfo = callee_cinfo;
	} else {
		sig = callee_sig;
		gsig = caller_sig;
		cinfo = callee_cinfo;
		gcinfo = caller_cinfo;
	}

	DEBUG_AMD64_GSHAREDVT_PRINT ("source sig: (%s) return (%s)\n", mono_signature_get_desc (caller_sig, FALSE), mono_type_full_name (mono_signature_get_return_type (caller_sig))); // Leak
	DEBUG_AMD64_GSHAREDVT_PRINT ("dest sig: (%s) return (%s)\n", mono_signature_get_desc (callee_sig, FALSE), mono_type_full_name (mono_signature_get_return_type (callee_sig)));

	if (gcinfo->ret.storage == ArgGsharedvtVariableInReg) {
		/*
		 * The return type is gsharedvt
		 */
		var_ret = TRUE;
	}

	/*
	 * The stack looks like this:
	 * <arguments>
	 * <trampoline frame>
	 * <call area>
	 * We have to map the stack slots in <arguments> to the stack slots in <call area>.
	 */
	map = g_ptr_array_new ();

	for (aindex = 0; aindex < cinfo->nargs; ++aindex) {
		ArgInfo *src_info = &caller_cinfo->args [aindex];
		ArgInfo *dst_info = &callee_cinfo->args [aindex];
		int *src = NULL, *dst = NULL;
		int nsrc = -1, ndst = -1, nslots = 0;

		int arg_marshal = GSHAREDVT_ARG_NONE;
		int arg_slots = 0; // Size in quadwords
		DEBUG_AMD64_GSHAREDVT_PRINT ("-- arg %d in (%s) out (%s)\n", aindex, arg_info_desc (src_info), arg_info_desc (dst_info));

		switch (src_info->storage) {
		case ArgInIReg:
		case ArgInDoubleSSEReg:
		case ArgInFloatSSEReg:
		case ArgValuetypeInReg:
		case ArgOnStack:
			nsrc = get_arg_slots (src_info, &src, TRUE);
			break;
		case ArgGSharedVtInReg:
			handle_marshal_when_src_gsharedvt (dst_info, &arg_marshal, &arg_slots);
			handle_map_when_gsharedvt_in_reg (src_info, &nsrc, &src);
			break;
		case ArgGSharedVtOnStack:
			handle_marshal_when_src_gsharedvt (dst_info, &arg_marshal, &arg_slots);
			handle_map_when_gsharedvt_on_stack (src_info, &nsrc, &src, TRUE);
			break;
		case ArgValuetypeAddrInIReg:
		case ArgValuetypeAddrOnStack:
			nsrc = get_arg_slots (src_info, &src, TRUE);
			break;
		default:
			g_error ("Gsharedvt can't handle source arg type %d", (int)src_info->storage); // Inappropriate value: ArgValuetypeAddrInIReg is for returns only
		}

		switch (dst_info->storage) {
		case ArgInIReg:
		case ArgInDoubleSSEReg:
		case ArgInFloatSSEReg:
		case ArgOnStack:
		case ArgValuetypeInReg:
			ndst = get_arg_slots (dst_info, &dst, FALSE);
			break;
		case ArgGSharedVtInReg:
			handle_marshal_when_dst_gsharedvt (src_info, &arg_marshal);
			handle_map_when_gsharedvt_in_reg (dst_info, &ndst, &dst);
			break;
		case ArgGSharedVtOnStack:
			handle_marshal_when_dst_gsharedvt (src_info, &arg_marshal);
			handle_map_when_gsharedvt_on_stack (dst_info, &ndst, &dst, FALSE);
			break;
		case ArgValuetypeAddrInIReg:
		case ArgValuetypeAddrOnStack:
			ndst = get_arg_slots (dst_info, &dst, FALSE);
			break;
		default:
			g_error ("Gsharedvt can't handle dest arg type %d", (int)dst_info->storage); // See above
		}
		if (nsrc)
			src [0] |= (arg_marshal << SRC_DESCRIPTOR_MARSHAL_SHIFT) | (arg_slots << SLOT_COUNT_SHIFT);

		/* Merge and add to the global list*/
		nslots = MIN (nsrc, ndst);
		DEBUG_AMD64_GSHAREDVT_PRINT ("nsrc %d ndst %d\n", nsrc, ndst);

		for (i = 0; i < nslots; ++i)
			add_to_map (map, src [i], dst [i]);

		g_free (src);
		g_free (dst);
	}

	DEBUG_AMD64_GSHAREDVT_PRINT ("-- return in (%s) out (%s) var_ret %d\n", arg_info_desc (&caller_cinfo->ret),  arg_info_desc (&callee_cinfo->ret), var_ret);

	if (cinfo->ret.storage == ArgValuetypeAddrInIReg) {
		/* Both the caller and the callee pass the vtype ret address in r8 (System V) and RCX or RDX (Windows) */
		g_assert (gcinfo->ret.storage == ArgValuetypeAddrInIReg || gcinfo->ret.storage == ArgGsharedvtVariableInReg);
		add_to_map (map, map_reg (cinfo->ret.reg), map_reg (cinfo->ret.reg));
	}

	info = mono_domain_alloc0 (mono_domain_get (), sizeof (GSharedVtCallInfo) + (map->len * sizeof (int)));
	info->addr = addr;
	info->stack_usage = callee_cinfo->stack_usage;
	info->ret_marshal = GSHAREDVT_RET_NONE;
	info->gsharedvt_in = gsharedvt_in ? 1 : 0;
	info->vret_slot = -1;
	info->calli = calli;

	if (var_ret) {
		g_assert (gcinfo->ret.storage == ArgGsharedvtVariableInReg);
		info->vret_arg_reg = map_reg (gcinfo->ret.reg);
		DEBUG_AMD64_GSHAREDVT_PRINT ("mapping vreg_arg_reg to %d in reg %s\n", info->vret_arg_reg, mono_arch_regname (gcinfo->ret.reg));
	} else {
		info->vret_arg_reg = -1;
	}

#ifdef DEBUG_AMD64_GSHAREDVT
	printf ("final map:\n");
	for (i = 0; i < map->len; i += 2) {
		printf ("\t[%d] src %x dst %x\n ", 
			i / 2,
			GPOINTER_TO_UINT (g_ptr_array_index (map, i)),
			GPOINTER_TO_UINT (g_ptr_array_index (map, i + 1)));
	}
#endif

	info->vcall_offset = vcall_offset;
	info->map_count = map->len / 2;
	for (i = 0; i < map->len; ++i)
		info->map [i] = GPOINTER_TO_UINT (g_ptr_array_index (map, i));
	g_ptr_array_free (map, TRUE);

	/* Compute return value marshalling */
	if (var_ret) {
		/* Compute return value marshalling */
		switch (cinfo->ret.storage) {
		case ArgInIReg:
			if (!gsharedvt_in || sig->ret->byref) {
				info->ret_marshal = GSHAREDVT_RET_IREGS_1;
			} else {
				MonoType *ret = sig->ret;

				// Unwrap enums
				if (ret->type == MONO_TYPE_VALUETYPE)
					ret = mini_type_get_underlying_type (ret);

				switch (ret->type) {
				case MONO_TYPE_I1:
					info->ret_marshal = GSHAREDVT_RET_I1;
					break;
				case MONO_TYPE_BOOLEAN:
				case MONO_TYPE_U1:
					info->ret_marshal = GSHAREDVT_RET_U1;
					break;
				case MONO_TYPE_I2:
					info->ret_marshal = GSHAREDVT_RET_I2;
					break;
				case MONO_TYPE_CHAR:
				case MONO_TYPE_U2:
					info->ret_marshal = GSHAREDVT_RET_U2;
					break;
				case MONO_TYPE_I4:
					info->ret_marshal = GSHAREDVT_RET_I4;
					break;
				case MONO_TYPE_U4:
					info->ret_marshal = GSHAREDVT_RET_U4;
					break;
				case MONO_TYPE_I:
				case MONO_TYPE_U:
				case MONO_TYPE_PTR:
				case MONO_TYPE_FNPTR:
				case MONO_TYPE_CLASS:
				case MONO_TYPE_OBJECT:
				case MONO_TYPE_SZARRAY:
				case MONO_TYPE_ARRAY:
				case MONO_TYPE_STRING:
				case MONO_TYPE_U8:
				case MONO_TYPE_I8:
					info->ret_marshal = GSHAREDVT_RET_I8;
					break;
				case MONO_TYPE_GENERICINST:
					g_assert (!mono_type_generic_inst_is_valuetype (ret));
					info->ret_marshal = GSHAREDVT_RET_I8;
					break;
				default:
					g_error ("Gsharedvt can't handle dst type [%d]", (int)sig->ret->type);
				}
			}
			break;
		case ArgValuetypeInReg:
			info->ret_marshal = GSHAREDVT_RET_IREGS_1 - 1 + cinfo->ret.nregs;
			g_assert (cinfo->ret.nregs == 1); // ABI supports 2-register return but we do not implement this.
			break;
		case ArgInDoubleSSEReg:
		case ArgInFloatSSEReg:
			info->ret_marshal = GSHAREDVT_RET_R8;
			break;
		case ArgValuetypeAddrInIReg:
			break;
		default:
			g_error ("Can't marshal return of storage [%d] %s", (int)cinfo->ret.storage, storage_name (cinfo->ret.storage));
		}

		if (gsharedvt_in && cinfo->ret.storage != ArgValuetypeAddrInIReg) {
			/* Allocate stack space for the return value */
			info->vret_slot = map_stack_slot (info->stack_usage / sizeof (gpointer));
			info->stack_usage += mono_type_stack_size_internal (normal_sig->ret, NULL, FALSE) + sizeof (gpointer);
		}
		DEBUG_AMD64_GSHAREDVT_PRINT ("RET marshal is %s\n", ret_marshal_name [info->ret_marshal]);
	}

	info->stack_usage = ALIGN_TO (info->stack_usage, MONO_ARCH_FRAME_ALIGNMENT);

	g_free (callee_cinfo);
	g_free (caller_cinfo);

	DEBUG_AMD64_GSHAREDVT_PRINT ("allocated an info at %p stack usage %d\n", info, info->stack_usage);
	return info;
}
Пример #8
0
/*
 * ex, v = mono.call_method (obj, method, args)
 * method 被调用的method方法(MonoMethod*)
 * thiz 被调用的method的this指针, static函数请填0
 * args 参数表
 * 返回值 :
 *  ex : 若无异常发生, 该值为nil
 *  v : 函数返回值
 */
static int l_call_method (lua_State *L) {
    if (lua_gettop (L) < 2)
        luaL_error (L, "call_method need lest 2 args.");
    MonoObject *obj = (MonoObject*)lua_touserdata (L, 1);
    MonoMethod *method = (MonoMethod*)lua_touserdata (L, 2);
    if (!method)
        luaL_error (L, "call_method need 2th arg not nil.");
    MonoObject *ex = 0;
    void *ret = call_method (L, 3, obj, method, &ex);
    if (ex)
        lua_pushlightuserdata (L, ex);
    else
        lua_pushnil (L);
    MonoMethodSignature *sig = mono_method_signature (method);
    MonoType *ret_type = mono_signature_get_return_type (sig);
    if (mono_type_is_reference (ret_type)) {
        lua_pushlightuserdata (L, ret);
    } else {
        switch (mono_type_get_type (ret_type)) {
            case MONO_TYPE_VOID:
                lua_pushnil (L);
                break;
            case MONO_TYPE_BOOLEAN:
                lua_pushboolean (L, *(bool*)mono_object_unbox (obj));
                break;
            case MONO_TYPE_U2:
            case MONO_TYPE_CHAR:
                /*char 用int来表示*/
                lua_pushinteger (L, *(uint16_t*)mono_object_unbox (obj));
                break;
            case MONO_TYPE_I1:
                lua_pushinteger(L, *(int8_t*)mono_object_unbox (obj));
                break;
            case MONO_TYPE_U1:
                lua_pushinteger(L, *(uint8_t*)mono_object_unbox (obj));
                break;
            case MONO_TYPE_I2:
                lua_pushinteger (L, *(int16_t*)mono_object_unbox (obj));
                break;
            case MONO_TYPE_I4:
                lua_pushinteger(L, *(int32_t*)mono_object_unbox (obj));
                break;
            case MONO_TYPE_VALUETYPE:
            case MONO_TYPE_U4:
                lua_pushinteger(L, *(uint32_t*)mono_object_unbox (obj));
                break;
            case MONO_TYPE_I8:
            case MONO_TYPE_U8: {
                void *v = mono_object_unbox (obj);
                memcpy (lua_newuserdata (L, sizeof (int64_t)), v, sizeof (int64_t));
                break;
            }
            case MONO_TYPE_R4:
                lua_pushnumber(L, *(float*)mono_object_unbox (obj));
                break;
            case MONO_TYPE_R8:
                lua_pushnumber(L, *(double*)mono_object_unbox (obj));
                break;
            case MONO_TYPE_I:
            case MONO_TYPE_U:
                luaL_error (L, "donot support the intptr & uintptr.");
            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 (ret_type));
        }
    }
    return 2;
}
Пример #9
0
mioType mioMethod::getReturnType() const
{
    if (!mmethod) { return nullptr; }
    MonoMethodSignature *sig = mono_method_signature(mmethod);
    return mono_signature_get_return_type(sig);
}