LuaEnv.cs 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747
  1. /*
  2. * Tencent is pleased to support the open source community by making xLua available.
  3. * Copyright (C) 2016 THL A29 Limited, a Tencent company. All rights reserved.
  4. * Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
  5. * http://opensource.org/licenses/MIT
  6. * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
  7. */
  8. #if USE_UNI_LUA
  9. using LuaAPI = UniLua.Lua;
  10. using RealStatePtr = UniLua.ILuaState;
  11. using LuaCSFunction = UniLua.CSharpFunctionDelegate;
  12. #else
  13. using LuaAPI = XLua.LuaDLL.Lua;
  14. using RealStatePtr = System.IntPtr;
  15. using LuaCSFunction = XLua.LuaDLL.lua_CSFunction;
  16. #endif
  17. namespace XLua
  18. {
  19. using System;
  20. using System.Collections.Generic;
  21. public class LuaEnv : IDisposable
  22. {
  23. public const string CSHARP_NAMESPACE = "xlua_csharp_namespace";
  24. public const string MAIN_SHREAD = "xlua_main_thread";
  25. internal RealStatePtr rawL;
  26. internal RealStatePtr L
  27. {
  28. get
  29. {
  30. if (rawL == RealStatePtr.Zero)
  31. {
  32. throw new InvalidOperationException("this lua env had disposed!");
  33. }
  34. return rawL;
  35. }
  36. }
  37. private LuaTable _G;
  38. internal ObjectTranslator translator;
  39. internal int errorFuncRef = -1;
  40. #if THREAD_SAFE || HOTFIX_ENABLE
  41. internal /*static*/ object luaLock = new object();
  42. internal object luaEnvLock
  43. {
  44. get
  45. {
  46. return luaLock;
  47. }
  48. }
  49. #endif
  50. const int LIB_VERSION_EXPECT = 105;
  51. public LuaEnv()
  52. {
  53. if (LuaAPI.xlua_get_lib_version() != LIB_VERSION_EXPECT)
  54. {
  55. throw new InvalidProgramException("wrong lib version expect:"
  56. + LIB_VERSION_EXPECT + " but got:" + LuaAPI.xlua_get_lib_version());
  57. }
  58. #if THREAD_SAFE || HOTFIX_ENABLE
  59. lock(luaEnvLock)
  60. #endif
  61. {
  62. LuaIndexes.LUA_REGISTRYINDEX = LuaAPI.xlua_get_registry_index();
  63. #if GEN_CODE_MINIMIZE
  64. LuaAPI.xlua_set_csharp_wrapper_caller(InternalGlobals.CSharpWrapperCallerPtr);
  65. #endif
  66. // Create State
  67. rawL = LuaAPI.luaL_newstate();
  68. //Init Base Libs
  69. LuaAPI.luaopen_xlua(rawL);
  70. LuaAPI.luaopen_i64lib(rawL);
  71. translator = new ObjectTranslator(this, rawL);
  72. translator.createFunctionMetatable(rawL);
  73. translator.OpenLib(rawL);
  74. ObjectTranslatorPool.Instance.Add(rawL, translator);
  75. LuaAPI.lua_atpanic(rawL, StaticLuaCallbacks.Panic);
  76. #if !XLUA_GENERAL
  77. LuaAPI.lua_pushstdcallcfunction(rawL, StaticLuaCallbacks.Print);
  78. if (0 != LuaAPI.xlua_setglobal(rawL, "print"))
  79. {
  80. throw new Exception("call xlua_setglobal fail!");
  81. }
  82. #endif
  83. //template engine lib register
  84. TemplateEngine.LuaTemplate.OpenLib(rawL);
  85. AddSearcher(StaticLuaCallbacks.LoadBuiltinLib, 2); // just after the preload searcher
  86. AddSearcher(StaticLuaCallbacks.LoadFromCustomLoaders, 3);
  87. #if !XLUA_GENERAL
  88. AddSearcher(StaticLuaCallbacks.LoadFromResource, 4);
  89. AddSearcher(StaticLuaCallbacks.LoadFromStreamingAssetsPath, -1);
  90. #endif
  91. DoString(init_xlua, "Init");
  92. init_xlua = null;
  93. #if (!UNITY_SWITCH && !UNITY_WEBGL) || UNITY_EDITOR
  94. AddBuildin("socket.core", StaticLuaCallbacks.LoadSocketCore);
  95. AddBuildin("socket", StaticLuaCallbacks.LoadSocketCore);
  96. #endif
  97. AddBuildin("CS", StaticLuaCallbacks.LoadCS);
  98. LuaAPI.lua_newtable(rawL); //metatable of indexs and newindexs functions
  99. LuaAPI.xlua_pushasciistring(rawL, "__index");
  100. LuaAPI.lua_pushstdcallcfunction(rawL, StaticLuaCallbacks.MetaFuncIndex);
  101. LuaAPI.lua_rawset(rawL, -3);
  102. LuaAPI.xlua_pushasciistring(rawL, Utils.LuaIndexsFieldName);
  103. LuaAPI.lua_newtable(rawL);
  104. LuaAPI.lua_pushvalue(rawL, -3);
  105. LuaAPI.lua_setmetatable(rawL, -2);
  106. LuaAPI.lua_rawset(rawL, LuaIndexes.LUA_REGISTRYINDEX);
  107. LuaAPI.xlua_pushasciistring(rawL, Utils.LuaNewIndexsFieldName);
  108. LuaAPI.lua_newtable(rawL);
  109. LuaAPI.lua_pushvalue(rawL, -3);
  110. LuaAPI.lua_setmetatable(rawL, -2);
  111. LuaAPI.lua_rawset(rawL, LuaIndexes.LUA_REGISTRYINDEX);
  112. LuaAPI.xlua_pushasciistring(rawL, Utils.LuaClassIndexsFieldName);
  113. LuaAPI.lua_newtable(rawL);
  114. LuaAPI.lua_pushvalue(rawL, -3);
  115. LuaAPI.lua_setmetatable(rawL, -2);
  116. LuaAPI.lua_rawset(rawL, LuaIndexes.LUA_REGISTRYINDEX);
  117. LuaAPI.xlua_pushasciistring(rawL, Utils.LuaClassNewIndexsFieldName);
  118. LuaAPI.lua_newtable(rawL);
  119. LuaAPI.lua_pushvalue(rawL, -3);
  120. LuaAPI.lua_setmetatable(rawL, -2);
  121. LuaAPI.lua_rawset(rawL, LuaIndexes.LUA_REGISTRYINDEX);
  122. LuaAPI.lua_pop(rawL, 1); // pop metatable of indexs and newindexs functions
  123. LuaAPI.xlua_pushasciistring(rawL, MAIN_SHREAD);
  124. LuaAPI.lua_pushthread(rawL);
  125. LuaAPI.lua_rawset(rawL, LuaIndexes.LUA_REGISTRYINDEX);
  126. LuaAPI.xlua_pushasciistring(rawL, CSHARP_NAMESPACE);
  127. if (0 != LuaAPI.xlua_getglobal(rawL, "CS"))
  128. {
  129. throw new Exception("get CS fail!");
  130. }
  131. LuaAPI.lua_rawset(rawL, LuaIndexes.LUA_REGISTRYINDEX);
  132. #if !XLUA_GENERAL && (!UNITY_WSA || UNITY_EDITOR)
  133. translator.Alias(typeof(Type), "System.MonoType");
  134. #endif
  135. if (0 != LuaAPI.xlua_getglobal(rawL, "_G"))
  136. {
  137. throw new Exception("get _G fail!");
  138. }
  139. translator.Get(rawL, -1, out _G);
  140. LuaAPI.lua_pop(rawL, 1);
  141. errorFuncRef = LuaAPI.get_error_func_ref(rawL);
  142. if (initers != null)
  143. {
  144. for (int i = 0; i < initers.Count; i++)
  145. {
  146. initers[i](this, translator);
  147. }
  148. }
  149. translator.CreateArrayMetatable(rawL);
  150. translator.CreateDelegateMetatable(rawL);
  151. translator.CreateEnumerablePairs(rawL);
  152. }
  153. }
  154. private static List<Action<LuaEnv, ObjectTranslator>> initers = null;
  155. public static void AddIniter(Action<LuaEnv, ObjectTranslator> initer)
  156. {
  157. if (initers == null)
  158. {
  159. initers = new List<Action<LuaEnv, ObjectTranslator>>();
  160. }
  161. initers.Add(initer);
  162. }
  163. public LuaTable Global
  164. {
  165. get
  166. {
  167. return _G;
  168. }
  169. }
  170. public T LoadString<T>(byte[] chunk, string chunkName = "chunk", LuaTable env = null)
  171. {
  172. #if THREAD_SAFE || HOTFIX_ENABLE
  173. lock (luaEnvLock)
  174. {
  175. #endif
  176. if (typeof(T) != typeof(LuaFunction) && !typeof(T).IsSubclassOf(typeof(Delegate)))
  177. {
  178. throw new InvalidOperationException(typeof(T).Name + " is not a delegate type nor LuaFunction");
  179. }
  180. var _L = L;
  181. int oldTop = LuaAPI.lua_gettop(_L);
  182. if (LuaAPI.xluaL_loadbuffer(_L, chunk, chunk.Length, chunkName) != 0)
  183. ThrowExceptionFromError(oldTop);
  184. if (env != null)
  185. {
  186. env.push(_L);
  187. LuaAPI.lua_setfenv(_L, -2);
  188. }
  189. T result = (T)translator.GetObject(_L, -1, typeof(T));
  190. LuaAPI.lua_settop(_L, oldTop);
  191. return result;
  192. #if THREAD_SAFE || HOTFIX_ENABLE
  193. }
  194. #endif
  195. }
  196. public T LoadString<T>(string chunk, string chunkName = "chunk", LuaTable env = null)
  197. {
  198. byte[] bytes = System.Text.Encoding.UTF8.GetBytes(chunk);
  199. return LoadString<T>(bytes, chunkName, env);
  200. }
  201. public LuaFunction LoadString(string chunk, string chunkName = "chunk", LuaTable env = null)
  202. {
  203. return LoadString<LuaFunction>(chunk, chunkName, env);
  204. }
  205. public object[] DoString(byte[] chunk, string chunkName = "chunk", LuaTable env = null)
  206. {
  207. #if THREAD_SAFE || HOTFIX_ENABLE
  208. lock (luaEnvLock)
  209. {
  210. #endif
  211. var _L = L;
  212. int oldTop = LuaAPI.lua_gettop(_L);
  213. int errFunc = LuaAPI.load_error_func(_L, errorFuncRef);
  214. if (LuaAPI.xluaL_loadbuffer(_L, chunk, chunk.Length, chunkName) == 0)
  215. {
  216. if (env != null)
  217. {
  218. env.push(_L);
  219. LuaAPI.lua_setfenv(_L, -2);
  220. }
  221. if (LuaAPI.lua_pcall(_L, 0, -1, errFunc) == 0)
  222. {
  223. LuaAPI.lua_remove(_L, errFunc);
  224. return translator.popValues(_L, oldTop);
  225. }
  226. else
  227. ThrowExceptionFromError(oldTop);
  228. }
  229. else
  230. ThrowExceptionFromError(oldTop);
  231. return null;
  232. #if THREAD_SAFE || HOTFIX_ENABLE
  233. }
  234. #endif
  235. }
  236. public object[] DoString(string chunk, string chunkName = "chunk", LuaTable env = null)
  237. {
  238. byte[] bytes = System.Text.Encoding.UTF8.GetBytes(chunk);
  239. return DoString(bytes, chunkName, env);
  240. }
  241. private void AddSearcher(LuaCSFunction searcher, int index)
  242. {
  243. #if THREAD_SAFE || HOTFIX_ENABLE
  244. lock (luaEnvLock)
  245. {
  246. #endif
  247. var _L = L;
  248. //insert the loader
  249. LuaAPI.xlua_getloaders(_L);
  250. if (!LuaAPI.lua_istable(_L, -1))
  251. {
  252. throw new Exception("Can not set searcher!");
  253. }
  254. uint len = LuaAPI.xlua_objlen(_L, -1);
  255. index = index < 0 ? (int)(len + index + 2) : index;
  256. for (int e = (int)len + 1; e > index; e--)
  257. {
  258. LuaAPI.xlua_rawgeti(_L, -1, e - 1);
  259. LuaAPI.xlua_rawseti(_L, -2, e);
  260. }
  261. LuaAPI.lua_pushstdcallcfunction(_L, searcher);
  262. LuaAPI.xlua_rawseti(_L, -2, index);
  263. LuaAPI.lua_pop(_L, 1);
  264. #if THREAD_SAFE || HOTFIX_ENABLE
  265. }
  266. #endif
  267. }
  268. public void Alias(Type type, string alias)
  269. {
  270. translator.Alias(type, alias);
  271. }
  272. #if !XLUA_GENERAL
  273. int last_check_point = 0;
  274. int max_check_per_tick = 20;
  275. static bool ObjectValidCheck(object obj)
  276. {
  277. return (!(obj is UnityEngine.Object)) || ((obj as UnityEngine.Object) != null);
  278. }
  279. Func<object, bool> object_valid_checker = new Func<object, bool>(ObjectValidCheck);
  280. #endif
  281. public void Tick()
  282. {
  283. #if THREAD_SAFE || HOTFIX_ENABLE
  284. lock (luaEnvLock)
  285. {
  286. #endif
  287. var _L = L;
  288. lock (refQueue)
  289. {
  290. while (refQueue.Count > 0)
  291. {
  292. GCAction gca = refQueue.Dequeue();
  293. translator.ReleaseLuaBase(_L, gca.Reference, gca.IsDelegate);
  294. }
  295. }
  296. #if !XLUA_GENERAL
  297. last_check_point = translator.objects.Check(last_check_point, max_check_per_tick, object_valid_checker, translator.reverseMap);
  298. #endif
  299. #if THREAD_SAFE || HOTFIX_ENABLE
  300. }
  301. #endif
  302. }
  303. //兼容API
  304. public void GC()
  305. {
  306. Tick();
  307. }
  308. public LuaTable NewTable()
  309. {
  310. #if THREAD_SAFE || HOTFIX_ENABLE
  311. lock (luaEnvLock)
  312. {
  313. #endif
  314. var _L = L;
  315. int oldTop = LuaAPI.lua_gettop(_L);
  316. LuaAPI.lua_newtable(_L);
  317. LuaTable returnVal = (LuaTable)translator.GetObject(_L, -1, typeof(LuaTable));
  318. LuaAPI.lua_settop(_L, oldTop);
  319. return returnVal;
  320. #if THREAD_SAFE || HOTFIX_ENABLE
  321. }
  322. #endif
  323. }
  324. private bool disposed = false;
  325. public void Dispose()
  326. {
  327. FullGc();
  328. System.GC.Collect();
  329. System.GC.WaitForPendingFinalizers();
  330. Dispose(true);
  331. System.GC.Collect();
  332. System.GC.WaitForPendingFinalizers();
  333. }
  334. public virtual void Dispose(bool dispose)
  335. {
  336. #if THREAD_SAFE || HOTFIX_ENABLE
  337. lock (luaEnvLock)
  338. {
  339. #endif
  340. if (disposed) return;
  341. Tick();
  342. if (!translator.AllDelegateBridgeReleased())
  343. {
  344. throw new InvalidOperationException("try to dispose a LuaEnv with C# callback!");
  345. }
  346. ObjectTranslatorPool.Instance.Remove(L);
  347. LuaAPI.lua_close(L);
  348. translator = null;
  349. rawL = IntPtr.Zero;
  350. disposed = true;
  351. #if THREAD_SAFE || HOTFIX_ENABLE
  352. }
  353. #endif
  354. }
  355. public void ThrowExceptionFromError(int oldTop)
  356. {
  357. #if THREAD_SAFE || HOTFIX_ENABLE
  358. lock (luaEnvLock)
  359. {
  360. #endif
  361. object err = translator.GetObject(L, -1);
  362. LuaAPI.lua_settop(L, oldTop);
  363. // A pre-wrapped exception - just rethrow it (stack trace of InnerException will be preserved)
  364. Exception ex = err as Exception;
  365. if (ex != null) throw ex;
  366. // A non-wrapped Lua error (best interpreted as a string) - wrap it and throw it
  367. if (err == null) err = "Unknown Lua Error";
  368. throw new LuaException(err.ToString());
  369. #if THREAD_SAFE || HOTFIX_ENABLE
  370. }
  371. #endif
  372. }
  373. internal struct GCAction
  374. {
  375. public int Reference;
  376. public bool IsDelegate;
  377. }
  378. Queue<GCAction> refQueue = new Queue<GCAction>();
  379. internal void equeueGCAction(GCAction action)
  380. {
  381. lock (refQueue)
  382. {
  383. refQueue.Enqueue(action);
  384. }
  385. }
  386. private string init_xlua = @"
  387. local metatable = {}
  388. local rawget = rawget
  389. local setmetatable = setmetatable
  390. local import_type = xlua.import_type
  391. local import_generic_type = xlua.import_generic_type
  392. local load_assembly = xlua.load_assembly
  393. function metatable:__index(key)
  394. local fqn = rawget(self,'.fqn')
  395. fqn = ((fqn and fqn .. '.') or '') .. key
  396. local obj = import_type(fqn)
  397. if obj == nil then
  398. -- It might be an assembly, so we load it too.
  399. obj = { ['.fqn'] = fqn }
  400. setmetatable(obj, metatable)
  401. elseif obj == true then
  402. return rawget(self, key)
  403. end
  404. -- Cache this lookup
  405. rawset(self, key, obj)
  406. return obj
  407. end
  408. function metatable:__newindex()
  409. error('No such type: ' .. rawget(self,'.fqn'), 2)
  410. end
  411. -- A non-type has been called; e.g. foo = System.Foo()
  412. function metatable:__call(...)
  413. local n = select('#', ...)
  414. local fqn = rawget(self,'.fqn')
  415. if n > 0 then
  416. local gt = import_generic_type(fqn, ...)
  417. if gt then
  418. return rawget(CS, gt)
  419. end
  420. end
  421. error('No such type: ' .. fqn, 2)
  422. end
  423. CS = CS or {}
  424. setmetatable(CS, metatable)
  425. typeof = function(t) return t.UnderlyingSystemType end
  426. cast = xlua.cast
  427. if not setfenv or not getfenv then
  428. local function getfunction(level)
  429. local info = debug.getinfo(level + 1, 'f')
  430. return info and info.func
  431. end
  432. function setfenv(fn, env)
  433. if type(fn) == 'number' then fn = getfunction(fn + 1) end
  434. local i = 1
  435. while true do
  436. local name = debug.getupvalue(fn, i)
  437. if name == '_ENV' then
  438. debug.upvaluejoin(fn, i, (function()
  439. return env
  440. end), 1)
  441. break
  442. elseif not name then
  443. break
  444. end
  445. i = i + 1
  446. end
  447. return fn
  448. end
  449. function getfenv(fn)
  450. if type(fn) == 'number' then fn = getfunction(fn + 1) end
  451. local i = 1
  452. while true do
  453. local name, val = debug.getupvalue(fn, i)
  454. if name == '_ENV' then
  455. return val
  456. elseif not name then
  457. break
  458. end
  459. i = i + 1
  460. end
  461. end
  462. end
  463. xlua.hotfix = function(cs, field, func)
  464. if func == nil then func = false end
  465. local tbl = (type(field) == 'table') and field or {[field] = func}
  466. for k, v in pairs(tbl) do
  467. local cflag = ''
  468. if k == '.ctor' then
  469. cflag = '_c'
  470. k = 'ctor'
  471. end
  472. local f = type(v) == 'function' and v or nil
  473. xlua.access(cs, cflag .. '__Hotfix0_'..k, f) -- at least one
  474. pcall(function()
  475. for i = 1, 99 do
  476. xlua.access(cs, cflag .. '__Hotfix'..i..'_'..k, f)
  477. end
  478. end)
  479. end
  480. xlua.private_accessible(cs)
  481. end
  482. xlua.getmetatable = function(cs)
  483. return xlua.metatable_operation(cs)
  484. end
  485. xlua.setmetatable = function(cs, mt)
  486. return xlua.metatable_operation(cs, mt)
  487. end
  488. xlua.setclass = function(parent, name, impl)
  489. impl.UnderlyingSystemType = parent[name].UnderlyingSystemType
  490. rawset(parent, name, impl)
  491. end
  492. local base_mt = {
  493. __index = function(t, k)
  494. local csobj = t['__csobj']
  495. local func = csobj['<>xLuaBaseProxy_'..k]
  496. return function(_, ...)
  497. return func(csobj, ...)
  498. end
  499. end
  500. }
  501. base = function(csobj)
  502. return setmetatable({__csobj = csobj}, base_mt)
  503. end
  504. ";
  505. public delegate byte[] CustomLoader(ref string filepath);
  506. internal List<CustomLoader> customLoaders = new List<CustomLoader>();
  507. //loader : CustomLoader, filepath参数:(ref类型)输入是require的参数,如果需要支持调试,需要输出真实路径。
  508. // 返回值:如果返回null,代表加载该源下无合适的文件,否则返回UTF8编码的byte[]
  509. public void AddLoader(CustomLoader loader)
  510. {
  511. customLoaders.Add(loader);
  512. }
  513. internal Dictionary<string, LuaCSFunction> buildin_initer = new Dictionary<string, LuaCSFunction>();
  514. public void AddBuildin(string name, LuaCSFunction initer)
  515. {
  516. if (!Utils.IsStaticPInvokeCSFunction(initer))
  517. {
  518. throw new Exception("initer must be static and has MonoPInvokeCallback Attribute!");
  519. }
  520. buildin_initer.Add(name, initer);
  521. }
  522. //The garbage-collector pause controls how long the collector waits before starting a new cycle.
  523. //Larger values make the collector less aggressive. Values smaller than 100 mean the collector
  524. //will not wait to start a new cycle. A value of 200 means that the collector waits for the total
  525. //memory in use to double before starting a new cycle.
  526. public int GcPause
  527. {
  528. get
  529. {
  530. #if THREAD_SAFE || HOTFIX_ENABLE
  531. lock (luaEnvLock)
  532. {
  533. #endif
  534. int val = LuaAPI.lua_gc(L, LuaGCOptions.LUA_GCSETPAUSE, 200);
  535. LuaAPI.lua_gc(L, LuaGCOptions.LUA_GCSETPAUSE, val);
  536. return val;
  537. #if THREAD_SAFE || HOTFIX_ENABLE
  538. }
  539. #endif
  540. }
  541. set
  542. {
  543. #if THREAD_SAFE || HOTFIX_ENABLE
  544. lock (luaEnvLock)
  545. {
  546. #endif
  547. LuaAPI.lua_gc(L, LuaGCOptions.LUA_GCSETPAUSE, value);
  548. #if THREAD_SAFE || HOTFIX_ENABLE
  549. }
  550. #endif
  551. }
  552. }
  553. //The step multiplier controls the relative speed of the collector relative to memory allocation.
  554. //Larger values make the collector more aggressive but also increase the size of each incremental
  555. //step. Values smaller than 100 make the collector too slow and can result in the collector never
  556. //finishing a cycle. The default, 200, means that the collector runs at "twice" the speed of memory
  557. //allocation.
  558. public int GcStepmul
  559. {
  560. get
  561. {
  562. #if THREAD_SAFE || HOTFIX_ENABLE
  563. lock (luaEnvLock)
  564. {
  565. #endif
  566. int val = LuaAPI.lua_gc(L, LuaGCOptions.LUA_GCSETSTEPMUL, 200);
  567. LuaAPI.lua_gc(L, LuaGCOptions.LUA_GCSETSTEPMUL, val);
  568. return val;
  569. #if THREAD_SAFE || HOTFIX_ENABLE
  570. }
  571. #endif
  572. }
  573. set
  574. {
  575. #if THREAD_SAFE || HOTFIX_ENABLE
  576. lock (luaEnvLock)
  577. {
  578. #endif
  579. LuaAPI.lua_gc(L, LuaGCOptions.LUA_GCSETSTEPMUL, value);
  580. #if THREAD_SAFE || HOTFIX_ENABLE
  581. }
  582. #endif
  583. }
  584. }
  585. public void FullGc()
  586. {
  587. #if THREAD_SAFE || HOTFIX_ENABLE
  588. lock (luaEnvLock)
  589. {
  590. #endif
  591. LuaAPI.lua_gc(L, LuaGCOptions.LUA_GCCOLLECT, 0);
  592. #if THREAD_SAFE || HOTFIX_ENABLE
  593. }
  594. #endif
  595. }
  596. public void StopGc()
  597. {
  598. #if THREAD_SAFE || HOTFIX_ENABLE
  599. lock (luaEnvLock)
  600. {
  601. #endif
  602. LuaAPI.lua_gc(L, LuaGCOptions.LUA_GCSTOP, 0);
  603. #if THREAD_SAFE || HOTFIX_ENABLE
  604. }
  605. #endif
  606. }
  607. public void RestartGc()
  608. {
  609. #if THREAD_SAFE || HOTFIX_ENABLE
  610. lock (luaEnvLock)
  611. {
  612. #endif
  613. LuaAPI.lua_gc(L, LuaGCOptions.LUA_GCRESTART, 0);
  614. #if THREAD_SAFE || HOTFIX_ENABLE
  615. }
  616. #endif
  617. }
  618. public bool GcStep(int data)
  619. {
  620. #if THREAD_SAFE || HOTFIX_ENABLE
  621. lock (luaEnvLock)
  622. {
  623. #endif
  624. return LuaAPI.lua_gc(L, LuaGCOptions.LUA_GCSTEP, data) != 0;
  625. #if THREAD_SAFE || HOTFIX_ENABLE
  626. }
  627. #endif
  628. }
  629. public int Memroy
  630. {
  631. get
  632. {
  633. #if THREAD_SAFE || HOTFIX_ENABLE
  634. lock (luaEnvLock)
  635. {
  636. #endif
  637. return LuaAPI.lua_gc(L, LuaGCOptions.LUA_GCCOUNT, 0);
  638. #if THREAD_SAFE || HOTFIX_ENABLE
  639. }
  640. #endif
  641. }
  642. }
  643. }
  644. }