Utils.cs 47 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539
  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. using System.Collections.Generic;
  9. using System;
  10. using System.Reflection;
  11. using System.Linq;
  12. using System.Runtime.CompilerServices;
  13. #if USE_UNI_LUA
  14. using LuaAPI = UniLua.Lua;
  15. using RealStatePtr = UniLua.ILuaState;
  16. using LuaCSFunction = UniLua.CSharpFunctionDelegate;
  17. #else
  18. using LuaAPI = XLua.LuaDLL.Lua;
  19. using RealStatePtr = System.IntPtr;
  20. using LuaCSFunction = XLua.LuaDLL.lua_CSFunction;
  21. #endif
  22. namespace XLua
  23. {
  24. public enum LazyMemberTypes
  25. {
  26. Method,
  27. FieldGet,
  28. FieldSet,
  29. PropertyGet,
  30. PropertySet,
  31. Event,
  32. }
  33. public static partial class Utils
  34. {
  35. public static bool LoadField(RealStatePtr L, int idx, string field_name)
  36. {
  37. idx = idx > 0 ? idx : LuaAPI.lua_gettop(L) + idx + 1;// abs of index
  38. LuaAPI.xlua_pushasciistring(L, field_name);
  39. LuaAPI.lua_rawget(L, idx);
  40. return !LuaAPI.lua_isnil(L, -1);
  41. }
  42. public static RealStatePtr GetMainState(RealStatePtr L)
  43. {
  44. RealStatePtr ret = default(RealStatePtr);
  45. LuaAPI.xlua_pushasciistring(L, LuaEnv.MAIN_SHREAD);
  46. LuaAPI.lua_rawget(L, LuaIndexes.LUA_REGISTRYINDEX);
  47. if (LuaAPI.lua_isthread(L, -1))
  48. {
  49. ret = LuaAPI.lua_tothread(L, -1);
  50. }
  51. LuaAPI.lua_pop(L, 1);
  52. return ret;
  53. }
  54. #if (UNITY_WSA && !ENABLE_IL2CPP) && !UNITY_EDITOR
  55. public static List<Assembly> _assemblies;
  56. public static List<Assembly> GetAssemblies()
  57. {
  58. if (_assemblies == null)
  59. {
  60. System.Threading.Tasks.Task t = new System.Threading.Tasks.Task(() =>
  61. {
  62. _assemblies = GetAssemblyList().Result;
  63. });
  64. t.Start();
  65. t.Wait();
  66. }
  67. return _assemblies;
  68. }
  69. public static async System.Threading.Tasks.Task<List<Assembly>> GetAssemblyList()
  70. {
  71. List<Assembly> assemblies = new List<Assembly>();
  72. //return assemblies;
  73. var files = await Windows.ApplicationModel.Package.Current.InstalledLocation.GetFilesAsync();
  74. if (files == null)
  75. return assemblies;
  76. foreach (var file in files.Where(file => file.FileType == ".dll" || file.FileType == ".exe"))
  77. {
  78. try
  79. {
  80. assemblies.Add(Assembly.Load(new AssemblyName(file.DisplayName)));
  81. }
  82. catch (Exception ex)
  83. {
  84. System.Diagnostics.Debug.WriteLine(ex.Message);
  85. }
  86. }
  87. return assemblies;
  88. }
  89. public static IEnumerable<Type> GetAllTypes(bool exclude_generic_definition = true)
  90. {
  91. var assemblies = GetAssemblies();
  92. return from assembly in assemblies
  93. where !(assembly.IsDynamic)
  94. from type in assembly.GetTypes()
  95. where exclude_generic_definition ? !type.GetTypeInfo().IsGenericTypeDefinition : true
  96. select type;
  97. }
  98. #else
  99. public static List<Type> GetAllTypes(bool exclude_generic_definition = true)
  100. {
  101. List<Type> allTypes = new List<Type>();
  102. var assemblies = AppDomain.CurrentDomain.GetAssemblies();
  103. for (int i = 0; i < assemblies.Length; i++)
  104. {
  105. try
  106. {
  107. #if (UNITY_EDITOR || XLUA_GENERAL) && !NET_STANDARD_2_0
  108. if (!(assemblies[i].ManifestModule is System.Reflection.Emit.ModuleBuilder))
  109. {
  110. #endif
  111. allTypes.AddRange(assemblies[i].GetTypes()
  112. .Where(type => exclude_generic_definition ? !type.IsGenericTypeDefinition() : true)
  113. );
  114. #if (UNITY_EDITOR || XLUA_GENERAL) && !NET_STANDARD_2_0
  115. }
  116. #endif
  117. }
  118. catch (Exception)
  119. {
  120. }
  121. }
  122. return allTypes;
  123. }
  124. #endif
  125. static LuaCSFunction genFieldGetter(Type type, FieldInfo field)
  126. {
  127. if (field.IsStatic)
  128. {
  129. return (RealStatePtr L) =>
  130. {
  131. ObjectTranslator translator = ObjectTranslatorPool.Instance.Find(L);
  132. translator.PushAny(L, field.GetValue(null));
  133. return 1;
  134. };
  135. }
  136. else
  137. {
  138. return (RealStatePtr L) =>
  139. {
  140. ObjectTranslator translator = ObjectTranslatorPool.Instance.Find(L);
  141. object obj = translator.FastGetCSObj(L, 1);
  142. if (obj == null || !type.IsInstanceOfType(obj))
  143. {
  144. return LuaAPI.luaL_error(L, "Expected type " + type + ", but got " + (obj == null ? "null" : obj.GetType().ToString()) + ", while get field " + field);
  145. }
  146. translator.PushAny(L, field.GetValue(obj));
  147. return 1;
  148. };
  149. }
  150. }
  151. static LuaCSFunction genFieldSetter(Type type, FieldInfo field)
  152. {
  153. if (field.IsStatic)
  154. {
  155. return (RealStatePtr L) =>
  156. {
  157. ObjectTranslator translator = ObjectTranslatorPool.Instance.Find(L);
  158. object val = translator.GetObject(L, 1, field.FieldType);
  159. if (field.FieldType.IsValueType() && Nullable.GetUnderlyingType(field.FieldType) == null && val == null)
  160. {
  161. return LuaAPI.luaL_error(L, type.Name + "." + field.Name + " Expected type " + field.FieldType);
  162. }
  163. field.SetValue(null, val);
  164. return 0;
  165. };
  166. }
  167. else
  168. {
  169. return (RealStatePtr L) =>
  170. {
  171. ObjectTranslator translator = ObjectTranslatorPool.Instance.Find(L);
  172. object obj = translator.FastGetCSObj(L, 1);
  173. if (obj == null || !type.IsInstanceOfType(obj))
  174. {
  175. return LuaAPI.luaL_error(L, "Expected type " + type + ", but got " + (obj == null ? "null" : obj.GetType().ToString()) + ", while set field " + field);
  176. }
  177. object val = translator.GetObject(L, 2, field.FieldType);
  178. if (field.FieldType.IsValueType() && Nullable.GetUnderlyingType(field.FieldType) == null && val == null)
  179. {
  180. return LuaAPI.luaL_error(L, type.Name + "." + field.Name + " Expected type " + field.FieldType);
  181. }
  182. field.SetValue(obj, val);
  183. if (type.IsValueType())
  184. {
  185. translator.Update(L, 1, obj);
  186. }
  187. return 0;
  188. };
  189. }
  190. }
  191. static LuaCSFunction genItemGetter(Type type, PropertyInfo[] props)
  192. {
  193. props = props.Where(prop => !prop.GetIndexParameters()[0].ParameterType.IsAssignableFrom(typeof(string))).ToArray();
  194. if (props.Length == 0)
  195. {
  196. return null;
  197. }
  198. Type[] params_type = new Type[props.Length];
  199. for (int i = 0; i < props.Length; i++)
  200. {
  201. params_type[i] = props[i].GetIndexParameters()[0].ParameterType;
  202. }
  203. object[] arg = new object[1] { null };
  204. return (RealStatePtr L) =>
  205. {
  206. ObjectTranslator translator = ObjectTranslatorPool.Instance.Find(L);
  207. object obj = translator.FastGetCSObj(L, 1);
  208. if (obj == null || !type.IsInstanceOfType(obj))
  209. {
  210. return LuaAPI.luaL_error(L, "Expected type " + type + ", but got " + (obj == null ? "null" : obj.GetType().ToString()) + ", while get prop " + props[0].Name);
  211. }
  212. for (int i = 0; i < props.Length; i++)
  213. {
  214. if (!translator.Assignable(L, 2, params_type[i]))
  215. {
  216. continue;
  217. }
  218. else
  219. {
  220. PropertyInfo prop = props[i];
  221. try
  222. {
  223. object index = translator.GetObject(L, 2, params_type[i]);
  224. arg[0] = index;
  225. object ret = prop.GetValue(obj, arg);
  226. LuaAPI.lua_pushboolean(L, true);
  227. translator.PushAny(L, ret);
  228. return 2;
  229. }
  230. catch (Exception e)
  231. {
  232. return LuaAPI.luaL_error(L, "try to get " + type + "." + prop.Name + " throw a exception:" + e + ",stack:" + e.StackTrace);
  233. }
  234. }
  235. }
  236. LuaAPI.lua_pushboolean(L, false);
  237. return 1;
  238. };
  239. }
  240. static LuaCSFunction genItemSetter(Type type, PropertyInfo[] props)
  241. {
  242. props = props.Where(prop => !prop.GetIndexParameters()[0].ParameterType.IsAssignableFrom(typeof(string))).ToArray();
  243. if (props.Length == 0)
  244. {
  245. return null;
  246. }
  247. Type[] params_type = new Type[props.Length];
  248. for (int i = 0; i < props.Length; i++)
  249. {
  250. params_type[i] = props[i].GetIndexParameters()[0].ParameterType;
  251. }
  252. object[] arg = new object[1] { null };
  253. return (RealStatePtr L) =>
  254. {
  255. ObjectTranslator translator = ObjectTranslatorPool.Instance.Find(L);
  256. object obj = translator.FastGetCSObj(L, 1);
  257. if (obj == null || !type.IsInstanceOfType(obj))
  258. {
  259. return LuaAPI.luaL_error(L, "Expected type " + type + ", but got " + (obj == null ? "null" : obj.GetType().ToString()) + ", while set prop " + props[0].Name);
  260. }
  261. for (int i = 0; i < props.Length; i++)
  262. {
  263. if (!translator.Assignable(L, 2, params_type[i]))
  264. {
  265. continue;
  266. }
  267. else
  268. {
  269. PropertyInfo prop = props[i];
  270. try
  271. {
  272. arg[0] = translator.GetObject(L, 2, params_type[i]);
  273. object val = translator.GetObject(L, 3, prop.PropertyType);
  274. if (val == null)
  275. {
  276. return LuaAPI.luaL_error(L, type.Name + "." + prop.Name + " Expected type " + prop.PropertyType);
  277. }
  278. prop.SetValue(obj, val, arg);
  279. LuaAPI.lua_pushboolean(L, true);
  280. return 1;
  281. }
  282. catch (Exception e)
  283. {
  284. return LuaAPI.luaL_error(L, "try to set " + type + "." + prop.Name + " throw a exception:" + e + ",stack:" + e.StackTrace);
  285. }
  286. }
  287. }
  288. LuaAPI.lua_pushboolean(L, false);
  289. return 1;
  290. };
  291. }
  292. static LuaCSFunction genEnumCastFrom(Type type)
  293. {
  294. return (RealStatePtr L) =>
  295. {
  296. try
  297. {
  298. ObjectTranslator translator = ObjectTranslatorPool.Instance.Find(L);
  299. return translator.TranslateToEnumToTop(L, type, 1);
  300. }
  301. catch (Exception e)
  302. {
  303. return LuaAPI.luaL_error(L, "cast to " + type + " exception:" + e);
  304. }
  305. };
  306. }
  307. internal static IEnumerable<MethodInfo> GetExtensionMethodsOf(Type type_to_be_extend)
  308. {
  309. if (InternalGlobals.extensionMethodMap == null)
  310. {
  311. List<Type> type_def_extention_method = new List<Type>();
  312. IEnumerator<Type> enumerator = GetAllTypes().GetEnumerator();
  313. while (enumerator.MoveNext())
  314. {
  315. Type type = enumerator.Current;
  316. if (type.IsDefined(typeof(ExtensionAttribute), false) && (
  317. type.IsDefined(typeof(ReflectionUseAttribute), false)
  318. #if UNITY_EDITOR || XLUA_GENERAL
  319. || type.IsDefined(typeof(LuaCallCSharpAttribute), false)
  320. #endif
  321. ))
  322. {
  323. type_def_extention_method.Add(type);
  324. }
  325. if (!type.IsAbstract() || !type.IsSealed()) continue;
  326. var fields = type.GetFields(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.DeclaredOnly);
  327. for (int i = 0; i < fields.Length; i++)
  328. {
  329. var field = fields[i];
  330. if ((field.IsDefined(typeof(ReflectionUseAttribute), false)
  331. #if UNITY_EDITOR || XLUA_GENERAL
  332. || field.IsDefined(typeof(LuaCallCSharpAttribute), false)
  333. #endif
  334. ) && (typeof(IEnumerable<Type>)).IsAssignableFrom(field.FieldType))
  335. {
  336. type_def_extention_method.AddRange((field.GetValue(null) as IEnumerable<Type>)
  337. .Where(t => t.IsDefined(typeof(ExtensionAttribute), false)));
  338. }
  339. }
  340. var props = type.GetProperties(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.DeclaredOnly);
  341. for (int i = 0; i < props.Length; i++)
  342. {
  343. var prop = props[i];
  344. if ((prop.IsDefined(typeof(ReflectionUseAttribute), false)
  345. #if UNITY_EDITOR || XLUA_GENERAL
  346. || prop.IsDefined(typeof(LuaCallCSharpAttribute), false)
  347. #endif
  348. ) && (typeof(IEnumerable<Type>)).IsAssignableFrom(prop.PropertyType))
  349. {
  350. type_def_extention_method.AddRange((prop.GetValue(null, null) as IEnumerable<Type>)
  351. .Where(t => t.IsDefined(typeof(ExtensionAttribute), false)));
  352. }
  353. }
  354. }
  355. enumerator.Dispose();
  356. InternalGlobals.extensionMethodMap = (from type in type_def_extention_method
  357. from method in type.GetMethods(BindingFlags.Static | BindingFlags.Public)
  358. where method.IsDefined(typeof(ExtensionAttribute), false) && IsSupportedMethod(method)
  359. group method by getExtendedType(method)).ToDictionary(g => g.Key, g => g as IEnumerable<MethodInfo>);
  360. }
  361. IEnumerable<MethodInfo> ret = null;
  362. InternalGlobals.extensionMethodMap.TryGetValue(type_to_be_extend, out ret);
  363. return ret;
  364. }
  365. struct MethodKey
  366. {
  367. public string Name;
  368. public bool IsStatic;
  369. }
  370. static void makeReflectionWrap(RealStatePtr L, Type type, int cls_field, int cls_getter, int cls_setter,
  371. int obj_field, int obj_getter, int obj_setter, int obj_meta, out LuaCSFunction item_getter, out LuaCSFunction item_setter, BindingFlags access)
  372. {
  373. ObjectTranslator translator = ObjectTranslatorPool.Instance.Find(L);
  374. BindingFlags flag = BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Static | access;
  375. FieldInfo[] fields = type.GetFields(flag);
  376. EventInfo[] all_events = type.GetEvents(flag | BindingFlags.Public | BindingFlags.NonPublic);
  377. LuaAPI.lua_checkstack(L, 2);
  378. for (int i = 0; i < fields.Length; ++i)
  379. {
  380. FieldInfo field = fields[i];
  381. string fieldName = field.Name;
  382. // skip hotfix inject field
  383. if (field.IsStatic && (field.Name.StartsWith("__Hotfix") || field.Name.StartsWith("_c__Hotfix")) && typeof(Delegate).IsAssignableFrom(field.FieldType))
  384. {
  385. continue;
  386. }
  387. if (all_events.Any(e => e.Name == fieldName))
  388. {
  389. fieldName = "&" + fieldName;
  390. }
  391. if (field.IsStatic && (field.IsInitOnly || field.IsLiteral))
  392. {
  393. LuaAPI.xlua_pushasciistring(L, fieldName);
  394. translator.PushAny(L, field.GetValue(null));
  395. LuaAPI.lua_rawset(L, cls_field);
  396. }
  397. else
  398. {
  399. LuaAPI.xlua_pushasciistring(L, fieldName);
  400. translator.PushFixCSFunction(L, genFieldGetter(type, field));
  401. LuaAPI.lua_rawset(L, field.IsStatic ? cls_getter : obj_getter);
  402. LuaAPI.xlua_pushasciistring(L, fieldName);
  403. translator.PushFixCSFunction(L, genFieldSetter(type, field));
  404. LuaAPI.lua_rawset(L, field.IsStatic ? cls_setter : obj_setter);
  405. }
  406. }
  407. EventInfo[] events = type.GetEvents(flag);
  408. for (int i = 0; i < events.Length; ++i)
  409. {
  410. EventInfo eventInfo = events[i];
  411. LuaAPI.xlua_pushasciistring(L, eventInfo.Name);
  412. translator.PushFixCSFunction(L, translator.methodWrapsCache.GetEventWrap(type, eventInfo.Name));
  413. bool is_static = (eventInfo.GetAddMethod(true) != null) ? eventInfo.GetAddMethod(true).IsStatic : eventInfo.GetRemoveMethod(true).IsStatic;
  414. LuaAPI.lua_rawset(L, is_static ? cls_field : obj_field);
  415. }
  416. List<PropertyInfo> items = new List<PropertyInfo>();
  417. PropertyInfo[] props = type.GetProperties(flag);
  418. for (int i = 0; i < props.Length; ++i)
  419. {
  420. PropertyInfo prop = props[i];
  421. if (prop.GetIndexParameters().Length > 0)
  422. {
  423. items.Add(prop);
  424. }
  425. }
  426. var item_array = items.ToArray();
  427. item_getter = item_array.Length > 0 ? genItemGetter(type, item_array) : null;
  428. item_setter = item_array.Length > 0 ? genItemSetter(type, item_array) : null;
  429. MethodInfo[] methods = type.GetMethods(flag);
  430. if (access == BindingFlags.NonPublic)
  431. {
  432. methods = type.GetMethods(flag | BindingFlags.Public).Join(methods, p => p.Name, q => q.Name, (p, q) => p).ToArray();
  433. }
  434. Dictionary<MethodKey, List<MemberInfo>> pending_methods = new Dictionary<MethodKey, List<MemberInfo>>();
  435. for (int i = 0; i < methods.Length; ++i)
  436. {
  437. MethodInfo method = methods[i];
  438. string method_name = method.Name;
  439. MethodKey method_key = new MethodKey { Name = method_name, IsStatic = method.IsStatic };
  440. List<MemberInfo> overloads;
  441. if (pending_methods.TryGetValue(method_key, out overloads))
  442. {
  443. overloads.Add(method);
  444. continue;
  445. }
  446. //indexer
  447. if (method.IsSpecialName && ((method.Name == "get_Item" && method.GetParameters().Length == 1) || (method.Name == "set_Item" && method.GetParameters().Length == 2)))
  448. {
  449. if (!method.GetParameters()[0].ParameterType.IsAssignableFrom(typeof(string)))
  450. {
  451. continue;
  452. }
  453. }
  454. if ((method_name.StartsWith("add_") || method_name.StartsWith("remove_")) && method.IsSpecialName)
  455. {
  456. continue;
  457. }
  458. if (method_name.StartsWith("op_") && method.IsSpecialName) // 操作符
  459. {
  460. if (InternalGlobals.supportOp.ContainsKey(method_name))
  461. {
  462. if (overloads == null)
  463. {
  464. overloads = new List<MemberInfo>();
  465. pending_methods.Add(method_key, overloads);
  466. }
  467. overloads.Add(method);
  468. }
  469. continue;
  470. }
  471. else if (method_name.StartsWith("get_") && method.IsSpecialName && method.GetParameters().Length != 1) // getter of property
  472. {
  473. string prop_name = method.Name.Substring(4);
  474. LuaAPI.xlua_pushasciistring(L, prop_name);
  475. translator.PushFixCSFunction(L, translator.methodWrapsCache._GenMethodWrap(method.DeclaringType, prop_name, new MethodBase[] { method }).Call);
  476. LuaAPI.lua_rawset(L, method.IsStatic ? cls_getter : obj_getter);
  477. }
  478. else if (method_name.StartsWith("set_") && method.IsSpecialName && method.GetParameters().Length != 2) // setter of property
  479. {
  480. string prop_name = method.Name.Substring(4);
  481. LuaAPI.xlua_pushasciistring(L, prop_name);
  482. translator.PushFixCSFunction(L, translator.methodWrapsCache._GenMethodWrap(method.DeclaringType, prop_name, new MethodBase[] { method }).Call);
  483. LuaAPI.lua_rawset(L, method.IsStatic ? cls_setter : obj_setter);
  484. }
  485. else if (method_name == ".ctor" && method.IsConstructor)
  486. {
  487. continue;
  488. }
  489. else
  490. {
  491. if (overloads == null)
  492. {
  493. overloads = new List<MemberInfo>();
  494. pending_methods.Add(method_key, overloads);
  495. }
  496. overloads.Add(method);
  497. }
  498. }
  499. IEnumerable<MethodInfo> extend_methods = GetExtensionMethodsOf(type);
  500. if (extend_methods != null)
  501. {
  502. foreach (var extend_method in extend_methods)
  503. {
  504. MethodKey method_key = new MethodKey { Name = extend_method.Name, IsStatic = false };
  505. List<MemberInfo> overloads;
  506. if (pending_methods.TryGetValue(method_key, out overloads))
  507. {
  508. overloads.Add(extend_method);
  509. continue;
  510. }
  511. else
  512. {
  513. overloads = new List<MemberInfo>() { extend_method };
  514. pending_methods.Add(method_key, overloads);
  515. }
  516. }
  517. }
  518. foreach (var kv in pending_methods)
  519. {
  520. if (kv.Key.Name.StartsWith("op_")) // 操作符
  521. {
  522. LuaAPI.xlua_pushasciistring(L, InternalGlobals.supportOp[kv.Key.Name]);
  523. translator.PushFixCSFunction(L,
  524. new LuaCSFunction(translator.methodWrapsCache._GenMethodWrap(type, kv.Key.Name, kv.Value.ToArray()).Call));
  525. LuaAPI.lua_rawset(L, obj_meta);
  526. }
  527. else
  528. {
  529. LuaAPI.xlua_pushasciistring(L, kv.Key.Name);
  530. translator.PushFixCSFunction(L,
  531. new LuaCSFunction(translator.methodWrapsCache._GenMethodWrap(type, kv.Key.Name, kv.Value.ToArray()).Call));
  532. LuaAPI.lua_rawset(L, kv.Key.IsStatic ? cls_field : obj_field);
  533. }
  534. }
  535. }
  536. public static void loadUpvalue(RealStatePtr L, Type type, string metafunc, int index)
  537. {
  538. ObjectTranslator translator = ObjectTranslatorPool.Instance.Find(L);
  539. LuaAPI.xlua_pushasciistring(L, metafunc);
  540. LuaAPI.lua_rawget(L, LuaIndexes.LUA_REGISTRYINDEX);
  541. translator.Push(L, type);
  542. LuaAPI.lua_rawget(L, -2);
  543. LuaAPI.lua_remove(L, -2);
  544. for (int i = 1; i <= index; i++)
  545. {
  546. LuaAPI.lua_getupvalue(L, -i, i);
  547. if (LuaAPI.lua_isnil(L, -1))
  548. {
  549. LuaAPI.lua_pop(L, 1);
  550. LuaAPI.lua_newtable(L);
  551. LuaAPI.lua_pushvalue(L, -1);
  552. LuaAPI.lua_setupvalue(L, -i - 2, i);
  553. }
  554. }
  555. for (int i = 0; i < index; i++)
  556. {
  557. LuaAPI.lua_remove(L, -2);
  558. }
  559. }
  560. public static void RegisterEnumType(RealStatePtr L, Type type)
  561. {
  562. ObjectTranslator translator = ObjectTranslatorPool.Instance.Find(L);
  563. foreach (var name in Enum.GetNames(type))
  564. {
  565. RegisterObject(L, translator, Utils.CLS_IDX, name, Enum.Parse(type, name));
  566. }
  567. }
  568. public static void MakePrivateAccessible(RealStatePtr L, Type type)
  569. {
  570. LuaAPI.lua_checkstack(L, 20);
  571. int oldTop = LuaAPI.lua_gettop(L);
  572. LuaAPI.luaL_getmetatable(L, type.FullName);
  573. if (LuaAPI.lua_isnil(L, -1))
  574. {
  575. LuaAPI.lua_settop(L, oldTop);
  576. throw new Exception("can not find the metatable for " + type);
  577. }
  578. int obj_meta = LuaAPI.lua_gettop(L);
  579. LoadCSTable(L, type);
  580. if (LuaAPI.lua_isnil(L, -1))
  581. {
  582. LuaAPI.lua_settop(L, oldTop);
  583. throw new Exception("can not find the class for " + type);
  584. }
  585. int cls_field = LuaAPI.lua_gettop(L);
  586. loadUpvalue(L, type, LuaIndexsFieldName, 2);
  587. int obj_getter = LuaAPI.lua_gettop(L);
  588. loadUpvalue(L, type, LuaIndexsFieldName, 1);
  589. int obj_field = LuaAPI.lua_gettop(L);
  590. loadUpvalue(L, type, LuaNewIndexsFieldName, 1);
  591. int obj_setter = LuaAPI.lua_gettop(L);
  592. loadUpvalue(L, type, LuaClassIndexsFieldName, 1);
  593. int cls_getter = LuaAPI.lua_gettop(L);
  594. loadUpvalue(L, type, LuaClassNewIndexsFieldName, 1);
  595. int cls_setter = LuaAPI.lua_gettop(L);
  596. LuaCSFunction item_getter;
  597. LuaCSFunction item_setter;
  598. makeReflectionWrap(L, type, cls_field, cls_getter, cls_setter, obj_field, obj_getter, obj_setter, obj_meta,
  599. out item_getter, out item_setter, BindingFlags.NonPublic);
  600. LuaAPI.lua_settop(L, oldTop);
  601. foreach (var nested_type in type.GetNestedTypes(BindingFlags.NonPublic))
  602. {
  603. if ((!nested_type.IsAbstract() && typeof(Delegate).IsAssignableFrom(nested_type))
  604. || nested_type.IsGenericTypeDefinition())
  605. {
  606. continue;
  607. }
  608. ObjectTranslatorPool.Instance.Find(L).TryDelayWrapLoader(L, nested_type);
  609. MakePrivateAccessible(L, nested_type);
  610. }
  611. }
  612. [MonoPInvokeCallback(typeof(LuaCSFunction))]
  613. internal static int LazyReflectionCall(RealStatePtr L)
  614. {
  615. try
  616. {
  617. ObjectTranslator translator = ObjectTranslatorPool.Instance.Find(L);
  618. Type type;
  619. translator.Get(L, LuaAPI.xlua_upvalueindex(1), out type);
  620. LazyMemberTypes memberType = (LazyMemberTypes)LuaAPI.xlua_tointeger(L, LuaAPI.xlua_upvalueindex(2));
  621. string memberName = LuaAPI.lua_tostring(L, LuaAPI.xlua_upvalueindex(3));
  622. bool isStatic = LuaAPI.lua_toboolean(L, LuaAPI.xlua_upvalueindex(4));
  623. LuaCSFunction wrap = null;
  624. //UnityEngine.Debug.Log(">>>>> " + type + " " + memberName);
  625. switch (memberType)
  626. {
  627. case LazyMemberTypes.Method:
  628. var members = type.GetMember(memberName);
  629. if (members == null || members.Length == 0)
  630. {
  631. return LuaAPI.luaL_error(L, "can not find " + memberName + " for " + type);
  632. }
  633. IEnumerable<MemberInfo> methods = members;
  634. if (!isStatic)
  635. {
  636. var extensionMethods = GetExtensionMethodsOf(type);
  637. if (extensionMethods != null)
  638. {
  639. methods = methods.Concat(extensionMethods.Where(m => m.Name == memberName).Cast<MemberInfo>());
  640. }
  641. }
  642. wrap = new LuaCSFunction(translator.methodWrapsCache._GenMethodWrap(type, memberName, methods.ToArray()).Call);
  643. if (isStatic)
  644. {
  645. LoadCSTable(L, type);
  646. }
  647. else
  648. {
  649. loadUpvalue(L, type, LuaIndexsFieldName, 1);
  650. }
  651. if (LuaAPI.lua_isnil(L, -1))
  652. {
  653. return LuaAPI.luaL_error(L, "can not find the meta info for " + type);
  654. }
  655. break;
  656. case LazyMemberTypes.FieldGet:
  657. case LazyMemberTypes.FieldSet:
  658. var field = type.GetField(memberName);
  659. if (field == null)
  660. {
  661. return LuaAPI.luaL_error(L, "can not find " + memberName + " for " + type);
  662. }
  663. if (isStatic)
  664. {
  665. if (memberType == LazyMemberTypes.FieldGet)
  666. {
  667. loadUpvalue(L, type, LuaClassIndexsFieldName, 1);
  668. }
  669. else
  670. {
  671. loadUpvalue(L, type, LuaClassNewIndexsFieldName, 1);
  672. }
  673. }
  674. else
  675. {
  676. if (memberType == LazyMemberTypes.FieldGet)
  677. {
  678. loadUpvalue(L, type, LuaIndexsFieldName, 2);
  679. }
  680. else
  681. {
  682. loadUpvalue(L, type, LuaNewIndexsFieldName, 1);
  683. }
  684. }
  685. wrap = (memberType == LazyMemberTypes.FieldGet) ? genFieldGetter(type, field) : genFieldSetter(type, field);
  686. break;
  687. case LazyMemberTypes.PropertyGet:
  688. case LazyMemberTypes.PropertySet:
  689. var prop = type.GetProperty(memberName);
  690. if (prop == null)
  691. {
  692. return LuaAPI.luaL_error(L, "can not find " + memberName + " for " + type);
  693. }
  694. if (isStatic)
  695. {
  696. if (memberType == LazyMemberTypes.PropertyGet)
  697. {
  698. loadUpvalue(L, type, LuaClassIndexsFieldName, 1);
  699. }
  700. else
  701. {
  702. loadUpvalue(L, type, LuaClassNewIndexsFieldName, 1);
  703. }
  704. }
  705. else
  706. {
  707. if (memberType == LazyMemberTypes.PropertyGet)
  708. {
  709. loadUpvalue(L, type, LuaIndexsFieldName, 2);
  710. }
  711. else
  712. {
  713. loadUpvalue(L, type, LuaNewIndexsFieldName, 1);
  714. }
  715. }
  716. if (LuaAPI.lua_isnil(L, -1))
  717. {
  718. return LuaAPI.luaL_error(L, "can not find the meta info for " + type);
  719. }
  720. wrap = translator.methodWrapsCache._GenMethodWrap(prop.DeclaringType, prop.Name, new MethodBase[] { (memberType == LazyMemberTypes.PropertyGet) ? prop.GetGetMethod() : prop.GetSetMethod() }).Call;
  721. break;
  722. case LazyMemberTypes.Event:
  723. var eventInfo = type.GetEvent(memberName);
  724. if (eventInfo == null)
  725. {
  726. return LuaAPI.luaL_error(L, "can not find " + memberName + " for " + type);
  727. }
  728. if (isStatic)
  729. {
  730. LoadCSTable(L, type);
  731. }
  732. else
  733. {
  734. loadUpvalue(L, type, LuaIndexsFieldName, 1);
  735. }
  736. if (LuaAPI.lua_isnil(L, -1))
  737. {
  738. return LuaAPI.luaL_error(L, "can not find the meta info for " + type);
  739. }
  740. wrap = translator.methodWrapsCache.GetEventWrap(type, eventInfo.Name);
  741. break;
  742. default:
  743. return LuaAPI.luaL_error(L, "unsupport member type" + memberType);
  744. }
  745. LuaAPI.xlua_pushasciistring(L, memberName);
  746. translator.PushFixCSFunction(L, wrap);
  747. LuaAPI.lua_rawset(L, -3);
  748. LuaAPI.lua_pop(L, 1);
  749. return wrap(L);
  750. }
  751. catch (Exception e)
  752. {
  753. return LuaAPI.luaL_error(L, "c# exception in LazyReflectionCall:" + e);
  754. }
  755. }
  756. public static void ReflectionWrap(RealStatePtr L, Type type, bool privateAccessible)
  757. {
  758. LuaAPI.lua_checkstack(L, 20);
  759. int top_enter = LuaAPI.lua_gettop(L);
  760. ObjectTranslator translator = ObjectTranslatorPool.Instance.Find(L);
  761. //create obj meta table
  762. LuaAPI.luaL_getmetatable(L, type.FullName);
  763. if (LuaAPI.lua_isnil(L, -1))
  764. {
  765. LuaAPI.lua_pop(L, 1);
  766. LuaAPI.luaL_newmetatable(L, type.FullName);
  767. }
  768. LuaAPI.lua_pushlightuserdata(L, LuaAPI.xlua_tag());
  769. LuaAPI.lua_pushnumber(L, 1);
  770. LuaAPI.lua_rawset(L, -3);
  771. int obj_meta = LuaAPI.lua_gettop(L);
  772. LuaAPI.lua_newtable(L);
  773. int cls_meta = LuaAPI.lua_gettop(L);
  774. LuaAPI.lua_newtable(L);
  775. int obj_field = LuaAPI.lua_gettop(L);
  776. LuaAPI.lua_newtable(L);
  777. int obj_getter = LuaAPI.lua_gettop(L);
  778. LuaAPI.lua_newtable(L);
  779. int obj_setter = LuaAPI.lua_gettop(L);
  780. LuaAPI.lua_newtable(L);
  781. int cls_field = LuaAPI.lua_gettop(L);
  782. //set cls_field to namespace
  783. SetCSTable(L, type, cls_field);
  784. //finish set cls_field to namespace
  785. LuaAPI.lua_newtable(L);
  786. int cls_getter = LuaAPI.lua_gettop(L);
  787. LuaAPI.lua_newtable(L);
  788. int cls_setter = LuaAPI.lua_gettop(L);
  789. LuaCSFunction item_getter;
  790. LuaCSFunction item_setter;
  791. makeReflectionWrap(L, type, cls_field, cls_getter, cls_setter, obj_field, obj_getter, obj_setter, obj_meta,
  792. out item_getter, out item_setter, privateAccessible ? (BindingFlags.Public | BindingFlags.NonPublic) : BindingFlags.Public);
  793. // init obj metatable
  794. LuaAPI.xlua_pushasciistring(L, "__gc");
  795. LuaAPI.lua_pushstdcallcfunction(L, translator.metaFunctions.GcMeta);
  796. LuaAPI.lua_rawset(L, obj_meta);
  797. LuaAPI.xlua_pushasciistring(L, "__tostring");
  798. LuaAPI.lua_pushstdcallcfunction(L, translator.metaFunctions.ToStringMeta);
  799. LuaAPI.lua_rawset(L, obj_meta);
  800. LuaAPI.xlua_pushasciistring(L, "__index");
  801. LuaAPI.lua_pushvalue(L, obj_field);
  802. LuaAPI.lua_pushvalue(L, obj_getter);
  803. translator.PushFixCSFunction(L, item_getter);
  804. translator.PushAny(L, type.BaseType());
  805. LuaAPI.xlua_pushasciistring(L, LuaIndexsFieldName);
  806. LuaAPI.lua_rawget(L, LuaIndexes.LUA_REGISTRYINDEX);
  807. LuaAPI.lua_pushnil(L);
  808. LuaAPI.gen_obj_indexer(L);
  809. //store in lua indexs function tables
  810. LuaAPI.xlua_pushasciistring(L, LuaIndexsFieldName);
  811. LuaAPI.lua_rawget(L, LuaIndexes.LUA_REGISTRYINDEX);
  812. translator.Push(L, type);
  813. LuaAPI.lua_pushvalue(L, -3);
  814. LuaAPI.lua_rawset(L, -3);
  815. LuaAPI.lua_pop(L, 1);
  816. LuaAPI.lua_rawset(L, obj_meta); // set __index
  817. LuaAPI.xlua_pushasciistring(L, "__newindex");
  818. LuaAPI.lua_pushvalue(L, obj_setter);
  819. translator.PushFixCSFunction(L, item_setter);
  820. translator.Push(L, type.BaseType());
  821. LuaAPI.xlua_pushasciistring(L, LuaNewIndexsFieldName);
  822. LuaAPI.lua_rawget(L, LuaIndexes.LUA_REGISTRYINDEX);
  823. LuaAPI.lua_pushnil(L);
  824. LuaAPI.gen_obj_newindexer(L);
  825. //store in lua newindexs function tables
  826. LuaAPI.xlua_pushasciistring(L, LuaNewIndexsFieldName);
  827. LuaAPI.lua_rawget(L, LuaIndexes.LUA_REGISTRYINDEX);
  828. translator.Push(L, type);
  829. LuaAPI.lua_pushvalue(L, -3);
  830. LuaAPI.lua_rawset(L, -3);
  831. LuaAPI.lua_pop(L, 1);
  832. LuaAPI.lua_rawset(L, obj_meta); // set __newindex
  833. //finish init obj metatable
  834. LuaAPI.xlua_pushasciistring(L, "UnderlyingSystemType");
  835. translator.PushAny(L, type);
  836. LuaAPI.lua_rawset(L, cls_field);
  837. if (type != null && type.IsEnum())
  838. {
  839. LuaAPI.xlua_pushasciistring(L, "__CastFrom");
  840. translator.PushFixCSFunction(L, genEnumCastFrom(type));
  841. LuaAPI.lua_rawset(L, cls_field);
  842. }
  843. //init class meta
  844. LuaAPI.xlua_pushasciistring(L, "__index");
  845. LuaAPI.lua_pushvalue(L, cls_getter);
  846. LuaAPI.lua_pushvalue(L, cls_field);
  847. translator.Push(L, type.BaseType());
  848. LuaAPI.xlua_pushasciistring(L, LuaClassIndexsFieldName);
  849. LuaAPI.lua_rawget(L, LuaIndexes.LUA_REGISTRYINDEX);
  850. LuaAPI.gen_cls_indexer(L);
  851. //store in lua indexs function tables
  852. LuaAPI.xlua_pushasciistring(L, LuaClassIndexsFieldName);
  853. LuaAPI.lua_rawget(L, LuaIndexes.LUA_REGISTRYINDEX);
  854. translator.Push(L, type);
  855. LuaAPI.lua_pushvalue(L, -3);
  856. LuaAPI.lua_rawset(L, -3);
  857. LuaAPI.lua_pop(L, 1);
  858. LuaAPI.lua_rawset(L, cls_meta); // set __index
  859. LuaAPI.xlua_pushasciistring(L, "__newindex");
  860. LuaAPI.lua_pushvalue(L, cls_setter);
  861. translator.Push(L, type.BaseType());
  862. LuaAPI.xlua_pushasciistring(L, LuaClassNewIndexsFieldName);
  863. LuaAPI.lua_rawget(L, LuaIndexes.LUA_REGISTRYINDEX);
  864. LuaAPI.gen_cls_newindexer(L);
  865. //store in lua newindexs function tables
  866. LuaAPI.xlua_pushasciistring(L, LuaClassNewIndexsFieldName);
  867. LuaAPI.lua_rawget(L, LuaIndexes.LUA_REGISTRYINDEX);
  868. translator.Push(L, type);
  869. LuaAPI.lua_pushvalue(L, -3);
  870. LuaAPI.lua_rawset(L, -3);
  871. LuaAPI.lua_pop(L, 1);
  872. LuaAPI.lua_rawset(L, cls_meta); // set __newindex
  873. LuaCSFunction constructor = typeof(Delegate).IsAssignableFrom(type) ? translator.metaFunctions.DelegateCtor : translator.methodWrapsCache.GetConstructorWrap(type);
  874. if (constructor == null)
  875. {
  876. constructor = (RealStatePtr LL) =>
  877. {
  878. return LuaAPI.luaL_error(LL, "No constructor for " + type);
  879. };
  880. }
  881. LuaAPI.xlua_pushasciistring(L, "__call");
  882. translator.PushFixCSFunction(L, constructor);
  883. LuaAPI.lua_rawset(L, cls_meta);
  884. LuaAPI.lua_pushvalue(L, cls_meta);
  885. LuaAPI.lua_setmetatable(L, cls_field);
  886. LuaAPI.lua_pop(L, 8);
  887. System.Diagnostics.Debug.Assert(top_enter == LuaAPI.lua_gettop(L));
  888. }
  889. //meta: -4, method:-3, getter: -2, setter: -1
  890. public static void BeginObjectRegister(Type type, RealStatePtr L, ObjectTranslator translator, int meta_count, int method_count, int getter_count,
  891. int setter_count, int type_id = -1)
  892. {
  893. if (type == null)
  894. {
  895. if (type_id == -1) throw new Exception("Fatal: must provide a type of type_id");
  896. LuaAPI.xlua_rawgeti(L, LuaIndexes.LUA_REGISTRYINDEX, type_id);
  897. }
  898. else
  899. {
  900. LuaAPI.luaL_getmetatable(L, type.FullName);
  901. if (LuaAPI.lua_isnil(L, -1))
  902. {
  903. LuaAPI.lua_pop(L, 1);
  904. LuaAPI.luaL_newmetatable(L, type.FullName);
  905. }
  906. }
  907. LuaAPI.lua_pushlightuserdata(L, LuaAPI.xlua_tag());
  908. LuaAPI.lua_pushnumber(L, 1);
  909. LuaAPI.lua_rawset(L, -3);
  910. if ((type == null || !translator.HasCustomOp(type)) && type != typeof(decimal))
  911. {
  912. LuaAPI.xlua_pushasciistring(L, "__gc");
  913. LuaAPI.lua_pushstdcallcfunction(L, translator.metaFunctions.GcMeta);
  914. LuaAPI.lua_rawset(L, -3);
  915. }
  916. LuaAPI.xlua_pushasciistring(L, "__tostring");
  917. LuaAPI.lua_pushstdcallcfunction(L, translator.metaFunctions.ToStringMeta);
  918. LuaAPI.lua_rawset(L, -3);
  919. if (method_count == 0)
  920. {
  921. LuaAPI.lua_pushnil(L);
  922. }
  923. else
  924. {
  925. LuaAPI.lua_createtable(L, 0, method_count);
  926. }
  927. if (getter_count == 0)
  928. {
  929. LuaAPI.lua_pushnil(L);
  930. }
  931. else
  932. {
  933. LuaAPI.lua_createtable(L, 0, getter_count);
  934. }
  935. if (setter_count == 0)
  936. {
  937. LuaAPI.lua_pushnil(L);
  938. }
  939. else
  940. {
  941. LuaAPI.lua_createtable(L, 0, setter_count);
  942. }
  943. }
  944. static int abs_idx(int top, int idx)
  945. {
  946. return idx > 0 ? idx : top + idx + 1;
  947. }
  948. public const int OBJ_META_IDX = -4;
  949. public const int METHOD_IDX = -3;
  950. public const int GETTER_IDX = -2;
  951. public const int SETTER_IDX = -1;
  952. #if GEN_CODE_MINIMIZE
  953. public static void EndObjectRegister(Type type, RealStatePtr L, ObjectTranslator translator, CSharpWrapper csIndexer,
  954. CSharpWrapper csNewIndexer, Type base_type, CSharpWrapper arrayIndexer, CSharpWrapper arrayNewIndexer)
  955. #else
  956. public static void EndObjectRegister(Type type, RealStatePtr L, ObjectTranslator translator, LuaCSFunction csIndexer,
  957. LuaCSFunction csNewIndexer, Type base_type, LuaCSFunction arrayIndexer, LuaCSFunction arrayNewIndexer)
  958. #endif
  959. {
  960. int top = LuaAPI.lua_gettop(L);
  961. int meta_idx = abs_idx(top, OBJ_META_IDX);
  962. int method_idx = abs_idx(top, METHOD_IDX);
  963. int getter_idx = abs_idx(top, GETTER_IDX);
  964. int setter_idx = abs_idx(top, SETTER_IDX);
  965. //begin index gen
  966. LuaAPI.xlua_pushasciistring(L, "__index");
  967. LuaAPI.lua_pushvalue(L, method_idx);
  968. LuaAPI.lua_pushvalue(L, getter_idx);
  969. if (csIndexer == null)
  970. {
  971. LuaAPI.lua_pushnil(L);
  972. }
  973. else
  974. {
  975. #if GEN_CODE_MINIMIZE
  976. translator.PushCSharpWrapper(L, csIndexer);
  977. #else
  978. LuaAPI.lua_pushstdcallcfunction(L, csIndexer);
  979. #endif
  980. }
  981. translator.Push(L, type == null ? base_type : type.BaseType());
  982. LuaAPI.xlua_pushasciistring(L, LuaIndexsFieldName);
  983. LuaAPI.lua_rawget(L, LuaIndexes.LUA_REGISTRYINDEX);
  984. if (arrayIndexer == null)
  985. {
  986. LuaAPI.lua_pushnil(L);
  987. }
  988. else
  989. {
  990. #if GEN_CODE_MINIMIZE
  991. translator.PushCSharpWrapper(L, arrayIndexer);
  992. #else
  993. LuaAPI.lua_pushstdcallcfunction(L, arrayIndexer);
  994. #endif
  995. }
  996. LuaAPI.gen_obj_indexer(L);
  997. if (type != null)
  998. {
  999. LuaAPI.xlua_pushasciistring(L, LuaIndexsFieldName);
  1000. LuaAPI.lua_rawget(L, LuaIndexes.LUA_REGISTRYINDEX);//store in lua indexs function tables
  1001. translator.Push(L, type);
  1002. LuaAPI.lua_pushvalue(L, -3);
  1003. LuaAPI.lua_rawset(L, -3);
  1004. LuaAPI.lua_pop(L, 1);
  1005. }
  1006. LuaAPI.lua_rawset(L, meta_idx);
  1007. //end index gen
  1008. //begin newindex gen
  1009. LuaAPI.xlua_pushasciistring(L, "__newindex");
  1010. LuaAPI.lua_pushvalue(L, setter_idx);
  1011. if (csNewIndexer == null)
  1012. {
  1013. LuaAPI.lua_pushnil(L);
  1014. }
  1015. else
  1016. {
  1017. #if GEN_CODE_MINIMIZE
  1018. translator.PushCSharpWrapper(L, csNewIndexer);
  1019. #else
  1020. LuaAPI.lua_pushstdcallcfunction(L, csNewIndexer);
  1021. #endif
  1022. }
  1023. translator.Push(L, type == null ? base_type : type.BaseType());
  1024. LuaAPI.xlua_pushasciistring(L, LuaNewIndexsFieldName);
  1025. LuaAPI.lua_rawget(L, LuaIndexes.LUA_REGISTRYINDEX);
  1026. if (arrayNewIndexer == null)
  1027. {
  1028. LuaAPI.lua_pushnil(L);
  1029. }
  1030. else
  1031. {
  1032. #if GEN_CODE_MINIMIZE
  1033. translator.PushCSharpWrapper(L, arrayNewIndexer);
  1034. #else
  1035. LuaAPI.lua_pushstdcallcfunction(L, arrayNewIndexer);
  1036. #endif
  1037. }
  1038. LuaAPI.gen_obj_newindexer(L);
  1039. if (type != null)
  1040. {
  1041. LuaAPI.xlua_pushasciistring(L, LuaNewIndexsFieldName);
  1042. LuaAPI.lua_rawget(L, LuaIndexes.LUA_REGISTRYINDEX);//store in lua newindexs function tables
  1043. translator.Push(L, type);
  1044. LuaAPI.lua_pushvalue(L, -3);
  1045. LuaAPI.lua_rawset(L, -3);
  1046. LuaAPI.lua_pop(L, 1);
  1047. }
  1048. LuaAPI.lua_rawset(L, meta_idx);
  1049. //end new index gen
  1050. LuaAPI.lua_pop(L, 4);
  1051. }
  1052. #if GEN_CODE_MINIMIZE
  1053. public static void RegisterFunc(RealStatePtr L, int idx, string name, CSharpWrapper func)
  1054. {
  1055. ObjectTranslator translator = ObjectTranslatorPool.Instance.Find(L);
  1056. idx = abs_idx(LuaAPI.lua_gettop(L), idx);
  1057. LuaAPI.xlua_pushasciistring(L, name);
  1058. translator.PushCSharpWrapper(L, func);
  1059. LuaAPI.lua_rawset(L, idx);
  1060. }
  1061. #else
  1062. public static void RegisterFunc(RealStatePtr L, int idx, string name, LuaCSFunction func)
  1063. {
  1064. idx = abs_idx(LuaAPI.lua_gettop(L), idx);
  1065. LuaAPI.xlua_pushasciistring(L, name);
  1066. LuaAPI.lua_pushstdcallcfunction(L, func);
  1067. LuaAPI.lua_rawset(L, idx);
  1068. }
  1069. #endif
  1070. public static void RegisterLazyFunc(RealStatePtr L, int idx, string name, Type type, LazyMemberTypes memberType, bool isStatic)
  1071. {
  1072. idx = abs_idx(LuaAPI.lua_gettop(L), idx);
  1073. LuaAPI.xlua_pushasciistring(L, name);
  1074. ObjectTranslator translator = ObjectTranslatorPool.Instance.Find(L);
  1075. translator.PushAny(L, type);
  1076. LuaAPI.xlua_pushinteger(L, (int)memberType);
  1077. LuaAPI.lua_pushstring(L, name);
  1078. LuaAPI.lua_pushboolean(L, isStatic);
  1079. LuaAPI.lua_pushstdcallcfunction(L, InternalGlobals.LazyReflectionWrap, 4);
  1080. LuaAPI.lua_rawset(L, idx);
  1081. }
  1082. public static void RegisterObject(RealStatePtr L, ObjectTranslator translator, int idx, string name, object obj)
  1083. {
  1084. idx = abs_idx(LuaAPI.lua_gettop(L), idx);
  1085. LuaAPI.xlua_pushasciistring(L, name);
  1086. translator.PushAny(L, obj);
  1087. LuaAPI.lua_rawset(L, idx);
  1088. }
  1089. #if GEN_CODE_MINIMIZE
  1090. public static void BeginClassRegister(Type type, RealStatePtr L, CSharpWrapper creator, int class_field_count,
  1091. int static_getter_count, int static_setter_count)
  1092. #else
  1093. public static void BeginClassRegister(Type type, RealStatePtr L, LuaCSFunction creator, int class_field_count,
  1094. int static_getter_count, int static_setter_count)
  1095. #endif
  1096. {
  1097. ObjectTranslator translator = ObjectTranslatorPool.Instance.Find(L);
  1098. LuaAPI.lua_createtable(L, 0, class_field_count);
  1099. LuaAPI.xlua_pushasciistring(L, "UnderlyingSystemType");
  1100. translator.PushAny(L, type);
  1101. LuaAPI.lua_rawset(L, -3);
  1102. int cls_table = LuaAPI.lua_gettop(L);
  1103. SetCSTable(L, type, cls_table);
  1104. LuaAPI.lua_createtable(L, 0, 3);
  1105. int meta_table = LuaAPI.lua_gettop(L);
  1106. if (creator != null)
  1107. {
  1108. LuaAPI.xlua_pushasciistring(L, "__call");
  1109. #if GEN_CODE_MINIMIZE
  1110. translator.PushCSharpWrapper(L, creator);
  1111. #else
  1112. LuaAPI.lua_pushstdcallcfunction(L, creator);
  1113. #endif
  1114. LuaAPI.lua_rawset(L, -3);
  1115. }
  1116. if (static_getter_count == 0)
  1117. {
  1118. LuaAPI.lua_pushnil(L);
  1119. }
  1120. else
  1121. {
  1122. LuaAPI.lua_createtable(L, 0, static_getter_count);
  1123. }
  1124. if (static_setter_count == 0)
  1125. {
  1126. LuaAPI.lua_pushnil(L);
  1127. }
  1128. else
  1129. {
  1130. LuaAPI.lua_createtable(L, 0, static_setter_count);
  1131. }
  1132. LuaAPI.lua_pushvalue(L, meta_table);
  1133. LuaAPI.lua_setmetatable(L, cls_table);
  1134. }
  1135. public const int CLS_IDX = -4;
  1136. public const int CLS_META_IDX = -3;
  1137. public const int CLS_GETTER_IDX = -2;
  1138. public const int CLS_SETTER_IDX = -1;
  1139. public static void EndClassRegister(Type type, RealStatePtr L, ObjectTranslator translator)
  1140. {
  1141. int top = LuaAPI.lua_gettop(L);
  1142. int cls_idx = abs_idx(top, CLS_IDX);
  1143. int cls_getter_idx = abs_idx(top, CLS_GETTER_IDX);
  1144. int cls_setter_idx = abs_idx(top, CLS_SETTER_IDX);
  1145. int cls_meta_idx = abs_idx(top, CLS_META_IDX);
  1146. //begin cls index
  1147. LuaAPI.xlua_pushasciistring(L, "__index");
  1148. LuaAPI.lua_pushvalue(L, cls_getter_idx);
  1149. LuaAPI.lua_pushvalue(L, cls_idx);
  1150. translator.Push(L, type.BaseType());
  1151. LuaAPI.xlua_pushasciistring(L, LuaClassIndexsFieldName);
  1152. LuaAPI.lua_rawget(L, LuaIndexes.LUA_REGISTRYINDEX);
  1153. LuaAPI.gen_cls_indexer(L);
  1154. LuaAPI.xlua_pushasciistring(L, LuaClassIndexsFieldName);
  1155. LuaAPI.lua_rawget(L, LuaIndexes.LUA_REGISTRYINDEX);//store in lua indexs function tables
  1156. translator.Push(L, type);
  1157. LuaAPI.lua_pushvalue(L, -3);
  1158. LuaAPI.lua_rawset(L, -3);
  1159. LuaAPI.lua_pop(L, 1);
  1160. LuaAPI.lua_rawset(L, cls_meta_idx);
  1161. //end cls index
  1162. //begin cls newindex
  1163. LuaAPI.xlua_pushasciistring(L, "__newindex");
  1164. LuaAPI.lua_pushvalue(L, cls_setter_idx);
  1165. translator.Push(L, type.BaseType());
  1166. LuaAPI.xlua_pushasciistring(L, LuaClassNewIndexsFieldName);
  1167. LuaAPI.lua_rawget(L, LuaIndexes.LUA_REGISTRYINDEX);
  1168. LuaAPI.gen_cls_newindexer(L);
  1169. LuaAPI.xlua_pushasciistring(L, LuaClassNewIndexsFieldName);
  1170. LuaAPI.lua_rawget(L, LuaIndexes.LUA_REGISTRYINDEX);//store in lua newindexs function tables
  1171. translator.Push(L, type);
  1172. LuaAPI.lua_pushvalue(L, -3);
  1173. LuaAPI.lua_rawset(L, -3);
  1174. LuaAPI.lua_pop(L, 1);
  1175. LuaAPI.lua_rawset(L, cls_meta_idx);
  1176. //end cls newindex
  1177. LuaAPI.lua_pop(L, 4);
  1178. }
  1179. static List<string> getPathOfType(Type type)
  1180. {
  1181. List<string> path = new List<string>();
  1182. if (type.Namespace != null)
  1183. {
  1184. path.AddRange(type.Namespace.Split(new char[] { '.' }));
  1185. }
  1186. string class_name = type.ToString().Substring(type.Namespace == null ? 0 : type.Namespace.Length + 1);
  1187. if (type.IsNested)
  1188. {
  1189. path.AddRange(class_name.Split(new char[] { '+' }));
  1190. }
  1191. else
  1192. {
  1193. path.Add(class_name);
  1194. }
  1195. return path;
  1196. }
  1197. public static void LoadCSTable(RealStatePtr L, Type type)
  1198. {
  1199. int oldTop = LuaAPI.lua_gettop(L);
  1200. LuaAPI.xlua_pushasciistring(L, LuaEnv.CSHARP_NAMESPACE);
  1201. LuaAPI.lua_rawget(L, LuaIndexes.LUA_REGISTRYINDEX);
  1202. List<string> path = getPathOfType(type);
  1203. for (int i = 0; i < path.Count; ++i)
  1204. {
  1205. LuaAPI.xlua_pushasciistring(L, path[i]);
  1206. if (0 != LuaAPI.xlua_pgettable(L, -2))
  1207. {
  1208. LuaAPI.lua_settop(L, oldTop);
  1209. LuaAPI.lua_pushnil(L);
  1210. return;
  1211. }
  1212. if (!LuaAPI.lua_istable(L, -1) && i < path.Count - 1)
  1213. {
  1214. LuaAPI.lua_settop(L, oldTop);
  1215. LuaAPI.lua_pushnil(L);
  1216. return;
  1217. }
  1218. LuaAPI.lua_remove(L, -2);
  1219. }
  1220. }
  1221. public static void SetCSTable(RealStatePtr L, Type type, int cls_table)
  1222. {
  1223. int oldTop = LuaAPI.lua_gettop(L);
  1224. cls_table = abs_idx(oldTop, cls_table);
  1225. LuaAPI.xlua_pushasciistring(L, LuaEnv.CSHARP_NAMESPACE);
  1226. LuaAPI.lua_rawget(L, LuaIndexes.LUA_REGISTRYINDEX);
  1227. List<string> path = getPathOfType(type);
  1228. for (int i = 0; i < path.Count - 1; ++i)
  1229. {
  1230. LuaAPI.xlua_pushasciistring(L, path[i]);
  1231. if (0 != LuaAPI.xlua_pgettable(L, -2))
  1232. {
  1233. var err = LuaAPI.lua_tostring(L, -1);
  1234. LuaAPI.lua_settop(L, oldTop);
  1235. throw new Exception("SetCSTable for [" + type + "] error: " + err);
  1236. }
  1237. if (LuaAPI.lua_isnil(L, -1))
  1238. {
  1239. LuaAPI.lua_pop(L, 1);
  1240. LuaAPI.lua_createtable(L, 0, 0);
  1241. LuaAPI.xlua_pushasciistring(L, path[i]);
  1242. LuaAPI.lua_pushvalue(L, -2);
  1243. LuaAPI.lua_rawset(L, -4);
  1244. }
  1245. else if (!LuaAPI.lua_istable(L, -1))
  1246. {
  1247. LuaAPI.lua_settop(L, oldTop);
  1248. throw new Exception("SetCSTable for [" + type + "] error: ancestors is not a table!");
  1249. }
  1250. LuaAPI.lua_remove(L, -2);
  1251. }
  1252. LuaAPI.xlua_pushasciistring(L, path[path.Count - 1]);
  1253. LuaAPI.lua_pushvalue(L, cls_table);
  1254. LuaAPI.lua_rawset(L, -3);
  1255. LuaAPI.lua_pop(L, 1);
  1256. LuaAPI.xlua_pushasciistring(L, LuaEnv.CSHARP_NAMESPACE);
  1257. LuaAPI.lua_rawget(L, LuaIndexes.LUA_REGISTRYINDEX);
  1258. ObjectTranslatorPool.Instance.Find(L).PushAny(L, type);
  1259. LuaAPI.lua_pushvalue(L, cls_table);
  1260. LuaAPI.lua_rawset(L, -3);
  1261. LuaAPI.lua_pop(L, 1);
  1262. }
  1263. public const string LuaIndexsFieldName = "LuaIndexs";
  1264. public const string LuaNewIndexsFieldName = "LuaNewIndexs";
  1265. public const string LuaClassIndexsFieldName = "LuaClassIndexs";
  1266. public const string LuaClassNewIndexsFieldName = "LuaClassNewIndexs";
  1267. public static bool IsParamsMatch(MethodInfo delegateMethod, MethodInfo bridgeMethod)
  1268. {
  1269. if (delegateMethod == null || bridgeMethod == null)
  1270. {
  1271. return false;
  1272. }
  1273. if (delegateMethod.ReturnType != bridgeMethod.ReturnType)
  1274. {
  1275. return false;
  1276. }
  1277. ParameterInfo[] delegateParams = delegateMethod.GetParameters();
  1278. ParameterInfo[] bridgeParams = bridgeMethod.GetParameters();
  1279. if (delegateParams.Length != bridgeParams.Length)
  1280. {
  1281. return false;
  1282. }
  1283. for (int i = 0; i < delegateParams.Length; i++)
  1284. {
  1285. if (delegateParams[i].ParameterType != bridgeParams[i].ParameterType || delegateParams[i].IsOut != bridgeParams[i].IsOut)
  1286. {
  1287. return false;
  1288. }
  1289. }
  1290. var lastPos = delegateParams.Length - 1;
  1291. return lastPos < 0 || delegateParams[lastPos].IsDefined(typeof(ParamArrayAttribute), false) == bridgeParams[lastPos].IsDefined(typeof(ParamArrayAttribute), false);
  1292. }
  1293. public static bool IsSupportedMethod(MethodInfo method)
  1294. {
  1295. if (!method.ContainsGenericParameters)
  1296. return true;
  1297. var methodParameters = method.GetParameters();
  1298. var returnType = method.ReturnType;
  1299. var hasValidGenericParameter = false;
  1300. var returnTypeValid = !returnType.IsGenericParameter;
  1301. for (var i = 0; i < methodParameters.Length; i++)
  1302. {
  1303. var parameterType = methodParameters[i].ParameterType;
  1304. if (parameterType.IsGenericParameter)
  1305. {
  1306. var parameterConstraints = parameterType.GetGenericParameterConstraints();
  1307. if (parameterConstraints.Length == 0) return false;
  1308. foreach (var parameterConstraint in parameterConstraints)
  1309. {
  1310. if (!parameterConstraint.IsClass() || (parameterConstraint == typeof(ValueType)))
  1311. return false;
  1312. }
  1313. hasValidGenericParameter = true;
  1314. if (!returnTypeValid)
  1315. {
  1316. if (parameterType == returnType)
  1317. {
  1318. returnTypeValid = true;
  1319. }
  1320. }
  1321. }
  1322. }
  1323. return hasValidGenericParameter && returnTypeValid;
  1324. }
  1325. public static MethodInfo MakeGenericMethodWithConstraints(MethodInfo method)
  1326. {
  1327. try
  1328. {
  1329. var genericArguments = method.GetGenericArguments();
  1330. var constraintedArgumentTypes = new Type[genericArguments.Length];
  1331. for (var i = 0; i < genericArguments.Length; i++)
  1332. {
  1333. var argumentType = genericArguments[i];
  1334. var parameterConstraints = argumentType.GetGenericParameterConstraints();
  1335. constraintedArgumentTypes[i] = parameterConstraints[0];
  1336. }
  1337. return method.MakeGenericMethod(constraintedArgumentTypes);
  1338. }
  1339. catch (Exception)
  1340. {
  1341. return null;
  1342. }
  1343. }
  1344. private static Type getExtendedType(MethodInfo method)
  1345. {
  1346. var type = method.GetParameters()[0].ParameterType;
  1347. if (!type.IsGenericParameter)
  1348. return type;
  1349. var parameterConstraints = type.GetGenericParameterConstraints();
  1350. if (parameterConstraints.Length == 0)
  1351. throw new InvalidOperationException();
  1352. var firstParameterConstraint = parameterConstraints[0];
  1353. if (!firstParameterConstraint.IsClass())
  1354. throw new InvalidOperationException();
  1355. return firstParameterConstraint;
  1356. }
  1357. public static bool IsStaticPInvokeCSFunction(LuaCSFunction csFunction)
  1358. {
  1359. #if UNITY_WSA && !UNITY_EDITOR
  1360. return csFunction.GetMethodInfo().IsStatic && csFunction.GetMethodInfo().GetCustomAttribute<MonoPInvokeCallbackAttribute>() != null;
  1361. #else
  1362. return csFunction.Method.IsStatic && Attribute.IsDefined(csFunction.Method, typeof(MonoPInvokeCallbackAttribute));
  1363. #endif
  1364. }
  1365. public static bool IsPublic(Type type)
  1366. {
  1367. if (type.IsNested)
  1368. {
  1369. if (!type.IsNestedPublic()) return false;
  1370. return IsPublic(type.DeclaringType);
  1371. }
  1372. if (type.IsGenericType())
  1373. {
  1374. var gas = type.GetGenericArguments();
  1375. for (int i = 0; i < gas.Length; i++)
  1376. {
  1377. if (!IsPublic(gas[i]))
  1378. {
  1379. return false;
  1380. }
  1381. }
  1382. }
  1383. return type.IsPublic();
  1384. }
  1385. }
  1386. }