static void lua_code_exec (Package *pkg) { static lua_State *L = 0; xmono::LuaExecRsp rsp; xmono::LuaExecReq req; MonoThread *thread = mono_thread_attach (mono_domain_get_by_id (0)); do { if (L == 0 && !(L = lua_env_new ())) { rsp.set_level (xmono::LuaExecRsp::err); rsp.set_message ("create a lua_State err."); break; } std::string str((char*)pkg->body, pkg->all_len - sizeof (Package)); //Fixme : 修复头部all_len是总长的问题 if (!req.ParseFromString (str)) { LOGD ("xmono::LuaExecReq ParseFromString err!"); return; } if (luaL_dostring (L, req.lua_code ().c_str ())) { rsp.set_level (xmono::LuaExecRsp::err); rsp.set_message (lua_tostring (L, -1)); break; } rsp.set_level (xmono::LuaExecRsp::debug); rsp.set_message ("exec the lua string ok."); } while (0); mono_thread_detach (thread); std::string out; rsp.SerializeToString (&out); ecmd_send (XMONO_ID_LUA_EXEC_RSP, (uint8_t const*)out.c_str (), out.size ()); return; }
bool _GodotSharp::is_domain_finalizing_for_unload(int32_t p_domain_id) { return is_domain_finalizing_for_unload(mono_domain_get_by_id(p_domain_id)); }
static void replace_method (Package *pkg) { xmono::ReplaceMethodReq req; xmono::ReplaceMethodRsp rsp; std::string str((char*)pkg->body, pkg->all_len - sizeof (Package)); if (!req.ParseFromString (str)) { LOGD ("xmono::ReplaceMethodReq ParseFromString err!"); return; } std::string err; void *p, *old_p; uint8_t *code; int code_size; MonoMethodHeader *mh; MonoThread *thread; MonoMethod *new_method; MonoDomain *domain; MonoMethod * method = get_method_with_token (req.image_name ().c_str (), req.method_token ()); if (!method) { rsp.set_err (false); rsp.set_msg (helper_last_err ()); goto replace_method_end; } domain = mono_domain_get_by_id (req.domain_id ()); if (!domain) { rsp.set_err (false); rsp.set_msg ("can not get the domain from id"); goto replace_method_end; } mh = mono_method_get_header (method); if (req.ex_size () != mono_method_header_get_num_clauses (mh)) { rsp.set_err (false); rsp.set_msg ("ex size != mono_method_header_clauses size!"); goto replace_method_end; } for (int i = 0; i < req.ex_size (); i++) { xmono::ReplaceMethodReq_ExceptionClause const &e = req.ex (i); void *iter = 0; MonoExceptionClause *clauses = &mh->clauses[i]; MonoExceptionClause *old_e = (MonoExceptionClause*)iter; old_e->try_offset = e.try_offset (); old_e->try_len = e.try_len (); old_e->handler_offset = e.handler_offset (); old_e->handler_len = e.handler_len (); } code = new uint8_t[req.new_code ().size ()]; memcpy (code, req.new_code ().c_str (), req.new_code ().size ()); mh->code = code; mh->code_size = req.new_code ().size (); thread = mono_thread_attach (domain); /*128 是一个估计值, 在未来可能不稳定, 但当前只能如此*/ new_method = (MonoMethod*)calloc (128, 1); /*这个地方用malloc优于用new*/ memcpy (new_method, method, 128); pthread_mutex_lock (&replace_mutex); replace_method_dict[new_method] = true; pthread_mutex_unlock (&replace_mutex); p = mono_compile_method (new_method); memcpy (hooked_method_dict[method]->specific_hook + 4, &p, 4); pthread_mutex_lock (&hooked_mutex); old_p = mono_jit_info_get_code_start (hooked_method_dict[method]->jinfo); pthread_mutex_unlock (&hooked_mutex); mono_thread_detach (thread); LOGD ("compile method, new ptr : %p, old ptr : %p", p, old_p); rsp.set_err (true); rsp.set_msg ("replace_method successful."); replace_method_end: std::string out; rsp.SerializeToString (&out); ecmd_send (XMONO_ID_REPLACE_METHOD_RSP, (uint8_t const*)out.c_str (), out.size ()); return; }