Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.

xlua.c 30KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245
  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. #define LUA_LIB
  9. #include "lua.h"
  10. #include "lualib.h"
  11. #include "lauxlib.h"
  12. #include <string.h>
  13. #include <stdint.h>
  14. #include "i64lib.h"
  15. #if USING_LUAJIT
  16. #include "lj_obj.h"
  17. #else
  18. #include "lstate.h"
  19. #endif
  20. /*
  21. ** stdcall C function support
  22. */
  23. static int tag = 0;
  24. static const char *const hooknames[] = {"call", "return", "line", "count", "tail return"};
  25. static int hook_index = -1;
  26. LUA_API void *xlua_tag ()
  27. {
  28. return &tag;
  29. }
  30. LUA_API int xlua_get_registry_index() {
  31. return LUA_REGISTRYINDEX;
  32. }
  33. LUA_API int xlua_get_lib_version() {
  34. return 105;
  35. }
  36. LUA_API int xlua_tocsobj_safe(lua_State *L,int index) {
  37. int *udata = (int *)lua_touserdata (L,index);
  38. if (udata != NULL) {
  39. if (lua_getmetatable(L,index)) {
  40. lua_pushlightuserdata(L, &tag);
  41. lua_rawget(L,-2);
  42. if (!lua_isnil (L,-1)) {
  43. lua_pop (L, 2);
  44. return *udata;
  45. }
  46. lua_pop (L, 2);
  47. }
  48. }
  49. return -1;
  50. }
  51. LUA_API int xlua_tocsobj_fast (lua_State *L,int index) {
  52. int *udata = (int *)lua_touserdata (L,index);
  53. if(udata!=NULL)
  54. return *udata;
  55. return -1;
  56. }
  57. #if LUA_VERSION_NUM == 501
  58. #undef lua_getglobal
  59. LUA_API int lua_getglobal (lua_State *L, const char *name) {
  60. lua_getfield(L, LUA_GLOBALSINDEX, name);
  61. return 0;
  62. }
  63. #undef lua_setglobal
  64. LUA_API void lua_setglobal (lua_State *L, const char *name) {
  65. lua_setfield(L, LUA_GLOBALSINDEX, name);
  66. }
  67. LUA_API int lua_isinteger (lua_State *L, int idx) {
  68. return 0;
  69. }
  70. LUA_API uint32_t xlua_objlen (lua_State *L, int idx) {
  71. return lua_objlen (L, idx);
  72. }
  73. LUA_API uint32_t xlua_touint (lua_State *L, int idx) {
  74. return (uint32_t)lua_tonumber(L, idx);
  75. }
  76. LUA_API void xlua_pushuint (lua_State *L, uint32_t n) {
  77. lua_pushnumber(L, n);
  78. }
  79. #endif
  80. #if LUA_VERSION_NUM ==503
  81. LUA_API int lua_setfenv(lua_State *L, int idx)
  82. {
  83. int type = lua_type(L, idx);
  84. if(type == LUA_TUSERDATA || type == LUA_TFUNCTION)
  85. {
  86. lua_setupvalue(L, idx, 1);
  87. return 1;
  88. }
  89. else
  90. {
  91. return 0;
  92. }
  93. }
  94. LUA_API uint32_t xlua_objlen (lua_State *L, int idx) {
  95. return (uint32_t)lua_rawlen (L, idx);
  96. }
  97. LUA_API uint32_t xlua_touint (lua_State *L, int idx) {
  98. return lua_isinteger(L, idx) ? (uint32_t)lua_tointeger(L, idx) : (uint32_t) lua_tonumber(L, idx);
  99. }
  100. LUA_API void xlua_pushuint (lua_State *L, uint32_t n) {
  101. lua_pushinteger(L, n);
  102. }
  103. #undef lua_insert
  104. LUA_API void lua_insert (lua_State *L, int idx) {
  105. lua_rotate(L, idx, 1);
  106. }
  107. #undef lua_remove
  108. LUA_API void lua_remove (lua_State *L, int idx) {
  109. lua_rotate(L, idx, -1);
  110. lua_pop(L, 1);
  111. }
  112. #undef lua_replace
  113. LUA_API void lua_replace (lua_State *L, int idx) {
  114. lua_copy(L, -1, idx);
  115. lua_pop(L, 1);
  116. }
  117. #undef lua_pcall
  118. LUA_API int lua_pcall (lua_State *L, int nargs, int nresults, int errfunc) {
  119. return lua_pcallk(L, nargs, nresults, errfunc, 0, NULL);
  120. }
  121. #undef lua_tonumber
  122. LUA_API lua_Number lua_tonumber (lua_State *L, int idx) {
  123. return lua_tonumberx(L, idx, NULL);
  124. }
  125. #endif
  126. #if LUA_VERSION_NUM < 503
  127. #define lua_absindex(L, index) ((index > 0 || index <= LUA_REGISTRYINDEX) ? index : lua_gettop(L) + index + 1)
  128. #endif
  129. LUA_API void xlua_getloaders (lua_State *L) {
  130. lua_getglobal(L, "package");
  131. #if LUA_VERSION_NUM == 501
  132. lua_getfield(L, -1, "loaders");
  133. #else
  134. lua_getfield(L, -1, "searchers");
  135. #endif
  136. lua_remove(L, -2);
  137. }
  138. LUA_API void xlua_rawgeti (lua_State *L, int idx, int64_t n) {
  139. lua_rawgeti(L, idx, (lua_Integer)n);
  140. }
  141. LUA_API void xlua_rawseti (lua_State *L, int idx, int64_t n) {
  142. lua_rawseti(L, idx, (lua_Integer)n);
  143. }
  144. LUA_API int xlua_ref_indirect(lua_State *L, int indirectRef) {
  145. int ret = 0;
  146. lua_rawgeti(L, LUA_REGISTRYINDEX, indirectRef);
  147. lua_pushvalue(L, -2);
  148. ret = luaL_ref(L, -2);
  149. lua_pop(L, 2);
  150. return ret;
  151. }
  152. LUA_API void xlua_getref_indirect(lua_State *L, int indirectRef, int reference) {
  153. lua_rawgeti(L, LUA_REGISTRYINDEX, indirectRef);
  154. lua_rawgeti(L, -1, reference);
  155. lua_remove(L, -2);
  156. }
  157. LUA_API int xlua_tointeger (lua_State *L, int idx) {
  158. return (int)lua_tointeger(L, idx);
  159. }
  160. LUA_API void xlua_pushinteger (lua_State *L, int n) {
  161. lua_pushinteger(L, n);
  162. }
  163. LUA_API void xlua_pushlstring (lua_State *L, const char *s, int len) {
  164. lua_pushlstring(L, s, len);
  165. }
  166. LUALIB_API int xluaL_loadbuffer (lua_State *L, const char *buff, int size,
  167. const char *name) {
  168. return luaL_loadbuffer(L, buff, size, name);
  169. }
  170. static int c_lua_gettable(lua_State* L) {
  171. lua_gettable(L, 1);
  172. return 1;
  173. }
  174. LUA_API int xlua_pgettable(lua_State* L, int idx) {
  175. int top = lua_gettop(L);
  176. idx = lua_absindex(L, idx);
  177. lua_pushcfunction(L, c_lua_gettable);
  178. lua_pushvalue(L, idx);
  179. lua_pushvalue(L, top);
  180. lua_remove(L, top);
  181. return lua_pcall(L, 2, 1, 0);
  182. }
  183. static int c_lua_gettable_bypath(lua_State* L) {
  184. size_t len = 0;
  185. const char * pos = NULL;
  186. const char * path = lua_tolstring(L, 2, &len);
  187. lua_pushvalue(L, 1);
  188. do {
  189. pos = strchr(path, '.');
  190. if (NULL == pos) {
  191. lua_pushlstring(L, path, len);
  192. } else {
  193. lua_pushlstring(L, path, pos - path);
  194. len = len - (pos - path + 1);
  195. path = pos + 1;
  196. }
  197. lua_gettable(L, -2);
  198. if (lua_type(L, -1) != LUA_TTABLE) {
  199. if (NULL != pos) { // not found in path
  200. lua_pushnil(L);
  201. }
  202. break;
  203. }
  204. lua_remove(L, -2);
  205. } while(pos);
  206. return 1;
  207. }
  208. LUA_API int xlua_pgettable_bypath(lua_State* L, int idx, const char *path) {
  209. idx = lua_absindex(L, idx);
  210. lua_pushcfunction(L, c_lua_gettable_bypath);
  211. lua_pushvalue(L, idx);
  212. lua_pushstring(L, path);
  213. return lua_pcall(L, 2, 1, 0);
  214. }
  215. static int c_lua_settable(lua_State* L) {
  216. lua_settable(L, 1);
  217. return 0;
  218. }
  219. LUA_API int xlua_psettable(lua_State* L, int idx) {
  220. int top = lua_gettop(L);
  221. idx = lua_absindex(L, idx);
  222. lua_pushcfunction(L, c_lua_settable);
  223. lua_pushvalue(L, idx);
  224. lua_pushvalue(L, top - 1);
  225. lua_pushvalue(L, top);
  226. lua_remove(L, top);
  227. lua_remove(L, top - 1);
  228. return lua_pcall(L, 3, 0, 0);
  229. }
  230. static int c_lua_settable_bypath(lua_State* L) {
  231. size_t len = 0;
  232. const char * pos = NULL;
  233. const char * path = lua_tolstring(L, 2, &len);
  234. lua_pushvalue(L, 1);
  235. do {
  236. pos = strchr(path, '.');
  237. if (NULL == pos) { // last
  238. lua_pushlstring(L, path, len);
  239. lua_pushvalue(L, 3);
  240. lua_settable(L, -3);
  241. lua_pop(L, 1);
  242. break;
  243. } else {
  244. lua_pushlstring(L, path, pos - path);
  245. len = len - (pos - path + 1);
  246. path = pos + 1;
  247. }
  248. lua_gettable(L, -2);
  249. if (lua_type(L, -1) != LUA_TTABLE) {
  250. return luaL_error(L, "can not set value to %s", lua_tostring(L, 2));
  251. }
  252. lua_remove(L, -2);
  253. } while(pos);
  254. return 0;
  255. }
  256. LUA_API int xlua_psettable_bypath(lua_State* L, int idx, const char *path) {
  257. int top = lua_gettop(L);
  258. idx = lua_absindex(L, idx);
  259. lua_pushcfunction(L, c_lua_settable_bypath);
  260. lua_pushvalue(L, idx);
  261. lua_pushstring(L, path);
  262. lua_pushvalue(L, top);
  263. lua_remove(L, top);
  264. return lua_pcall(L, 3, 0, 0);
  265. }
  266. static int c_lua_getglobal(lua_State* L) {
  267. lua_getglobal(L, lua_tostring(L, 1));
  268. return 1;
  269. }
  270. LUA_API int xlua_getglobal (lua_State *L, const char *name) {
  271. lua_pushcfunction(L, c_lua_getglobal);
  272. lua_pushstring(L, name);
  273. return lua_pcall(L, 1, 1, 0);
  274. }
  275. static int c_lua_setglobal(lua_State* L) {
  276. lua_setglobal(L, lua_tostring(L, 1));
  277. return 0;
  278. }
  279. LUA_API int xlua_setglobal (lua_State *L, const char *name) {
  280. int top = lua_gettop(L);
  281. lua_pushcfunction(L, c_lua_setglobal);
  282. lua_pushstring(L, name);
  283. lua_pushvalue(L, top);
  284. lua_remove(L, top);
  285. return lua_pcall(L, 2, 0, 0);
  286. }
  287. LUA_API int xlua_tryget_cachedud(lua_State *L, int key, int cache_ref) {
  288. lua_rawgeti(L, LUA_REGISTRYINDEX, cache_ref);
  289. lua_rawgeti(L, -1, key);
  290. if (!lua_isnil(L, -1))
  291. {
  292. lua_remove(L, -2);
  293. return 1;
  294. }
  295. lua_pop(L, 2);
  296. return 0;
  297. }
  298. static void cacheud(lua_State *L, int key, int cache_ref) {
  299. lua_rawgeti(L, LUA_REGISTRYINDEX, cache_ref);
  300. lua_pushvalue(L, -2);
  301. lua_rawseti(L, -2, key);
  302. lua_pop(L, 1);
  303. }
  304. LUA_API void xlua_pushcsobj(lua_State *L, int key, int meta_ref, int need_cache, int cache_ref) {
  305. int* pointer = (int*)lua_newuserdata(L, sizeof(int));
  306. *pointer = key;
  307. if (need_cache) cacheud(L, key, cache_ref);
  308. lua_rawgeti(L, LUA_REGISTRYINDEX, meta_ref);
  309. lua_setmetatable(L, -2);
  310. }
  311. void print_top(lua_State *L) {
  312. lua_getglobal(L, "print");
  313. lua_pushvalue(L, -2);
  314. lua_call(L, 1, 0);
  315. }
  316. void print_str(lua_State *L, char *str) {
  317. lua_getglobal(L, "print");
  318. lua_pushstring(L, str);
  319. lua_call(L, 1, 0);
  320. }
  321. void print_value(lua_State *L, char *str, int idx) {
  322. idx = lua_absindex(L, idx);
  323. lua_getglobal(L, "print");
  324. lua_pushstring(L, str);
  325. lua_pushvalue(L, idx);
  326. lua_call(L, 2, 0);
  327. }
  328. //upvalue --- [1]: methods, [2]:getters, [3]:csindexer, [4]:base, [5]:indexfuncs, [6]:arrayindexer, [7]:baseindex
  329. //param --- [1]: obj, [2]: key
  330. LUA_API int obj_indexer(lua_State *L) {
  331. if (!lua_isnil(L, lua_upvalueindex(1))) {
  332. lua_pushvalue(L, 2);
  333. lua_gettable(L, lua_upvalueindex(1));
  334. if (!lua_isnil(L, -1)) {//has method
  335. return 1;
  336. }
  337. lua_pop(L, 1);
  338. }
  339. if (!lua_isnil(L, lua_upvalueindex(2))) {
  340. lua_pushvalue(L, 2);
  341. lua_gettable(L, lua_upvalueindex(2));
  342. if (!lua_isnil(L, -1)) {//has getter
  343. lua_pushvalue(L, 1);
  344. lua_call(L, 1, 1);
  345. return 1;
  346. }
  347. lua_pop(L, 1);
  348. }
  349. if (!lua_isnil(L, lua_upvalueindex(6)) && lua_type(L, 2) == LUA_TNUMBER) {
  350. lua_pushvalue(L, lua_upvalueindex(6));
  351. lua_pushvalue(L, 1);
  352. lua_pushvalue(L, 2);
  353. lua_call(L, 2, 1);
  354. return 1;
  355. }
  356. if (!lua_isnil(L, lua_upvalueindex(3))) {
  357. lua_pushvalue(L, lua_upvalueindex(3));
  358. lua_pushvalue(L, 1);
  359. lua_pushvalue(L, 2);
  360. lua_call(L, 2, 2);
  361. if (lua_toboolean(L, -2)) {
  362. return 1;
  363. }
  364. lua_pop(L, 2);
  365. }
  366. if (!lua_isnil(L, lua_upvalueindex(4))) {
  367. lua_pushvalue(L, lua_upvalueindex(4));
  368. while(!lua_isnil(L, -1)) {
  369. lua_pushvalue(L, -1);
  370. lua_gettable(L, lua_upvalueindex(5));
  371. if (!lua_isnil(L, -1)) // found
  372. {
  373. lua_replace(L, lua_upvalueindex(7)); //baseindex = indexfuncs[base]
  374. lua_pop(L, 1);
  375. break;
  376. }
  377. lua_pop(L, 1);
  378. lua_getfield(L, -1, "BaseType");
  379. lua_remove(L, -2);
  380. }
  381. lua_pushnil(L);
  382. lua_replace(L, lua_upvalueindex(4));//base = nil
  383. }
  384. if (!lua_isnil(L, lua_upvalueindex(7))) {
  385. lua_settop(L, 2);
  386. lua_pushvalue(L, lua_upvalueindex(7));
  387. lua_insert(L, 1);
  388. lua_call(L, 2, 1);
  389. return 1;
  390. } else {
  391. return 0;
  392. }
  393. }
  394. LUA_API int gen_obj_indexer(lua_State *L) {
  395. lua_pushnil(L);
  396. lua_pushcclosure(L, obj_indexer, 7);
  397. return 0;
  398. }
  399. //upvalue --- [1]:setters, [2]:csnewindexer, [3]:base, [4]:newindexfuncs, [5]:arrayindexer, [6]:basenewindex
  400. //param --- [1]: obj, [2]: key, [3]: value
  401. LUA_API int obj_newindexer(lua_State *L) {
  402. if (!lua_isnil(L, lua_upvalueindex(1))) {
  403. lua_pushvalue(L, 2);
  404. lua_gettable(L, lua_upvalueindex(1));
  405. if (!lua_isnil(L, -1)) {//has setter
  406. lua_pushvalue(L, 1);
  407. lua_pushvalue(L, 3);
  408. lua_call(L, 2, 0);
  409. return 0;
  410. }
  411. lua_pop(L, 1);
  412. }
  413. if (!lua_isnil(L, lua_upvalueindex(2))) {
  414. lua_pushvalue(L, lua_upvalueindex(2));
  415. lua_pushvalue(L, 1);
  416. lua_pushvalue(L, 2);
  417. lua_pushvalue(L, 3);
  418. lua_call(L, 3, 1);
  419. if (lua_toboolean(L, -1)) {
  420. return 0;
  421. }
  422. }
  423. if (!lua_isnil(L, lua_upvalueindex(5)) && lua_type(L, 2) == LUA_TNUMBER) {
  424. lua_pushvalue(L, lua_upvalueindex(5));
  425. lua_pushvalue(L, 1);
  426. lua_pushvalue(L, 2);
  427. lua_pushvalue(L, 3);
  428. lua_call(L, 3, 0);
  429. return 0;
  430. }
  431. if (!lua_isnil(L, lua_upvalueindex(3))) {
  432. lua_pushvalue(L, lua_upvalueindex(3));
  433. while(!lua_isnil(L, -1)) {
  434. lua_pushvalue(L, -1);
  435. lua_gettable(L, lua_upvalueindex(4));
  436. if (!lua_isnil(L, -1)) // found
  437. {
  438. lua_replace(L, lua_upvalueindex(6)); //basenewindex = newindexfuncs[base]
  439. lua_pop(L, 1);
  440. break;
  441. }
  442. lua_pop(L, 1);
  443. lua_getfield(L, -1, "BaseType");
  444. lua_remove(L, -2);
  445. }
  446. lua_pushnil(L);
  447. lua_replace(L, lua_upvalueindex(3));//base = nil
  448. }
  449. if (!lua_isnil(L, lua_upvalueindex(6))) {
  450. lua_settop(L, 3);
  451. lua_pushvalue(L, lua_upvalueindex(6));
  452. lua_insert(L, 1);
  453. lua_call(L, 3, 0);
  454. return 0;
  455. } else {
  456. return luaL_error(L, "cannot set %s, no such field", lua_tostring(L, 2));
  457. }
  458. }
  459. LUA_API int gen_obj_newindexer(lua_State *L) {
  460. lua_pushnil(L);
  461. lua_pushcclosure(L, obj_newindexer, 6);
  462. return 0;
  463. }
  464. //upvalue --- [1]:getters, [2]:feilds, [3]:base, [4]:indexfuncs, [5]:baseindex
  465. //param --- [1]: obj, [2]: key
  466. LUA_API int cls_indexer(lua_State *L) {
  467. if (!lua_isnil(L, lua_upvalueindex(1))) {
  468. lua_pushvalue(L, 2);
  469. lua_gettable(L, lua_upvalueindex(1));
  470. if (!lua_isnil(L, -1)) {//has getter
  471. lua_call(L, 0, 1);
  472. return 1;
  473. }
  474. }
  475. if (!lua_isnil(L, lua_upvalueindex(2))) {
  476. lua_pushvalue(L, 2);
  477. lua_rawget(L, lua_upvalueindex(2));
  478. if (!lua_isnil(L, -1)) {//has feild
  479. return 1;
  480. }
  481. lua_pop(L, 1);
  482. }
  483. if (!lua_isnil(L, lua_upvalueindex(3))) {
  484. lua_pushvalue(L, lua_upvalueindex(3));
  485. while(!lua_isnil(L, -1)) {
  486. lua_pushvalue(L, -1);
  487. lua_gettable(L, lua_upvalueindex(4));
  488. if (!lua_isnil(L, -1)) // found
  489. {
  490. lua_replace(L, lua_upvalueindex(5)); //baseindex = indexfuncs[base]
  491. lua_pop(L, 1);
  492. break;
  493. }
  494. lua_pop(L, 1);
  495. lua_getfield(L, -1, "BaseType");
  496. lua_remove(L, -2);
  497. }
  498. lua_pushnil(L);
  499. lua_replace(L, lua_upvalueindex(3));//base = nil
  500. }
  501. if (!lua_isnil(L, lua_upvalueindex(5))) {
  502. lua_settop(L, 2);
  503. lua_pushvalue(L, lua_upvalueindex(5));
  504. lua_insert(L, 1);
  505. lua_call(L, 2, 1);
  506. return 1;
  507. } else {
  508. lua_pushnil(L);
  509. return 1;
  510. }
  511. }
  512. LUA_API int gen_cls_indexer(lua_State *L) {
  513. lua_pushnil(L);
  514. lua_pushcclosure(L, cls_indexer, 5);
  515. return 0;
  516. }
  517. //upvalue --- [1]:setters, [2]:base, [3]:indexfuncs, [4]:baseindex
  518. //param --- [1]: obj, [2]: key, [3]: value
  519. LUA_API int cls_newindexer(lua_State *L) {
  520. if (!lua_isnil(L, lua_upvalueindex(1))) {
  521. lua_pushvalue(L, 2);
  522. lua_gettable(L, lua_upvalueindex(1));
  523. if (!lua_isnil(L, -1)) {//has setter
  524. lua_pushvalue(L, 3);
  525. lua_call(L, 1, 0);
  526. return 0;
  527. }
  528. }
  529. if (!lua_isnil(L, lua_upvalueindex(2))) {
  530. lua_pushvalue(L, lua_upvalueindex(2));
  531. while(!lua_isnil(L, -1)) {
  532. lua_pushvalue(L, -1);
  533. lua_gettable(L, lua_upvalueindex(3));
  534. if (!lua_isnil(L, -1)) // found
  535. {
  536. lua_replace(L, lua_upvalueindex(4)); //baseindex = indexfuncs[base]
  537. lua_pop(L, 1);
  538. break;
  539. }
  540. lua_pop(L, 1);
  541. lua_getfield(L, -1, "BaseType");
  542. lua_remove(L, -2);
  543. }
  544. lua_pushnil(L);
  545. lua_replace(L, lua_upvalueindex(2));//base = nil
  546. }
  547. if (!lua_isnil(L, lua_upvalueindex(4))) {
  548. lua_settop(L, 3);
  549. lua_pushvalue(L, lua_upvalueindex(4));
  550. lua_insert(L, 1);
  551. lua_call(L, 3, 0);
  552. return 0;
  553. } else {
  554. return luaL_error(L, "no static field %s", lua_tostring(L, 2));
  555. }
  556. }
  557. LUA_API int gen_cls_newindexer(lua_State *L) {
  558. lua_pushnil(L);
  559. lua_pushcclosure(L, cls_newindexer, 4);
  560. return 0;
  561. }
  562. LUA_API int errorfunc(lua_State *L) {
  563. lua_getglobal(L, "debug");
  564. lua_getfield(L, -1, "traceback");
  565. lua_remove(L, -2);
  566. lua_pushvalue(L, 1);
  567. lua_pushnumber(L, 2);
  568. lua_call(L, 2, 1);
  569. return 1;
  570. }
  571. LUA_API int get_error_func_ref(lua_State *L) {
  572. lua_pushcclosure(L, errorfunc, 0);
  573. return luaL_ref(L, LUA_REGISTRYINDEX);
  574. }
  575. LUA_API int load_error_func(lua_State *L, int ref) {
  576. lua_rawgeti(L, LUA_REGISTRYINDEX, ref);
  577. return lua_gettop(L);
  578. }
  579. LUA_API int pcall_prepare(lua_State *L, int error_func_ref, int func_ref) {
  580. lua_rawgeti(L, LUA_REGISTRYINDEX, error_func_ref);
  581. lua_rawgeti(L, LUA_REGISTRYINDEX, func_ref);
  582. return lua_gettop(L) - 1;
  583. }
  584. static void hook(lua_State *L, lua_Debug *ar)
  585. {
  586. int event;
  587. lua_pushlightuserdata(L, &hook_index);
  588. lua_rawget(L, LUA_REGISTRYINDEX);
  589. event = ar->event;
  590. lua_pushstring(L, hooknames[event]);
  591. lua_getinfo(L, "nS", ar);
  592. if (*(ar->what) == 'C') {
  593. lua_pushfstring(L, "[?%s]", ar->name);
  594. } else {
  595. lua_pushfstring(L, "%s:%d", ar->short_src, ar->linedefined > 0 ? ar->linedefined : 0);
  596. }
  597. lua_call(L, 2, 0);
  598. }
  599. static void call_ret_hook(lua_State *L) {
  600. lua_Debug ar;
  601. if (lua_gethook(L)) {
  602. lua_getstack(L, 0, &ar);
  603. lua_getinfo(L, "n", &ar);
  604. lua_pushlightuserdata(L, &hook_index);
  605. lua_rawget(L, LUA_REGISTRYINDEX);
  606. if (lua_type(L, -1) != LUA_TFUNCTION){
  607. lua_pop(L, 1);
  608. return;
  609. }
  610. lua_pushliteral(L, "return");
  611. lua_pushfstring(L, "[?%s]", ar.name);
  612. lua_pushliteral(L, "[C#]");
  613. lua_sethook(L, 0, 0, 0);
  614. lua_call(L, 3, 0);
  615. lua_sethook(L, hook, LUA_MASKCALL | LUA_MASKRET, 0);
  616. }
  617. }
  618. static int profiler_set_hook(lua_State *L) {
  619. if (lua_isnoneornil(L, 1)) {
  620. lua_pushlightuserdata(L, &hook_index);
  621. lua_pushnil(L);
  622. lua_rawset(L, LUA_REGISTRYINDEX);
  623. lua_sethook(L, 0, 0, 0);
  624. } else {
  625. luaL_checktype(L, 1, LUA_TFUNCTION);
  626. lua_pushlightuserdata(L, &hook_index);
  627. lua_pushvalue(L, 1);
  628. lua_rawset(L, LUA_REGISTRYINDEX);
  629. lua_sethook(L, hook, LUA_MASKCALL | LUA_MASKRET, 0);
  630. }
  631. return 0;
  632. }
  633. static int csharp_function_wrap(lua_State *L) {
  634. lua_CFunction fn = (lua_CFunction)lua_tocfunction(L, lua_upvalueindex(1));
  635. int ret = fn(L);
  636. if (lua_toboolean(L, lua_upvalueindex(2)))
  637. {
  638. lua_pushboolean(L, 0);
  639. lua_replace(L, lua_upvalueindex(2));
  640. return lua_error(L);
  641. }
  642. if (lua_gethook(L)) {
  643. call_ret_hook(L);
  644. }
  645. return ret;
  646. }
  647. LUA_API void xlua_push_csharp_function(lua_State* L, lua_CFunction fn, int n)
  648. {
  649. lua_pushcfunction(L, fn);
  650. if (n > 0) {
  651. lua_insert(L, -1 - n);
  652. }
  653. lua_pushboolean(L, 0);
  654. if (n > 0) {
  655. lua_insert(L, -1 - n);
  656. }
  657. lua_pushcclosure(L, csharp_function_wrap, 2 + (n > 0 ? n : 0));
  658. }
  659. typedef int (*lua_CSWrapperCaller) (lua_State *L, int wrapperid, int top);
  660. static lua_CSWrapperCaller g_csharp_wrapper_caller = NULL;
  661. LUA_API void xlua_set_csharp_wrapper_caller(lua_CSWrapperCaller wrapper_caller)
  662. {
  663. g_csharp_wrapper_caller = wrapper_caller;
  664. }
  665. static int csharp_function_wrapper_wrapper(lua_State *L) {
  666. int ret = 0;
  667. if (g_csharp_wrapper_caller == NULL) {
  668. return luaL_error(L, "g_csharp_wrapper_caller not set");
  669. }
  670. ret = g_csharp_wrapper_caller(L, xlua_tointeger(L, lua_upvalueindex(1)), lua_gettop(L));
  671. if (lua_toboolean(L, lua_upvalueindex(2)))
  672. {
  673. lua_pushboolean(L, 0);
  674. lua_replace(L, lua_upvalueindex(2));
  675. return lua_error(L);
  676. }
  677. if (lua_gethook(L)) {
  678. call_ret_hook(L);
  679. }
  680. return ret;
  681. }
  682. LUA_API void xlua_push_csharp_wrapper(lua_State* L, int wrapperid)
  683. {
  684. lua_pushinteger(L, wrapperid);
  685. lua_pushboolean(L, 0);
  686. lua_pushcclosure(L, csharp_function_wrapper_wrapper, 2);
  687. }
  688. LUALIB_API int xlua_upvalueindex(int n) {
  689. return lua_upvalueindex(2 + n);
  690. }
  691. LUALIB_API int xlua_csharp_str_error(lua_State* L, const char* msg)
  692. {
  693. lua_pushboolean(L, 1);
  694. lua_replace(L, lua_upvalueindex(2));
  695. lua_pushstring(L, msg);
  696. return 1;
  697. }
  698. LUALIB_API int xlua_csharp_error(lua_State* L)
  699. {
  700. lua_pushboolean(L, 1);
  701. lua_replace(L, lua_upvalueindex(2));
  702. return 1;
  703. }
  704. typedef struct {
  705. int fake_id;
  706. unsigned int len;
  707. char data[1];
  708. } CSharpStruct;
  709. LUA_API void *xlua_pushstruct(lua_State *L, unsigned int size, int meta_ref) {
  710. CSharpStruct *css = (CSharpStruct *)lua_newuserdata(L, size + sizeof(int) + sizeof(unsigned int));
  711. css->fake_id = -1;
  712. css->len = size;
  713. lua_rawgeti(L, LUA_REGISTRYINDEX, meta_ref);
  714. lua_setmetatable(L, -2);
  715. return css;
  716. }
  717. LUA_API void xlua_pushcstable(lua_State *L, unsigned int size, int meta_ref) {
  718. lua_createtable(L, 0, size);
  719. lua_rawgeti(L, LUA_REGISTRYINDEX, meta_ref);
  720. lua_setmetatable(L, -2);
  721. }
  722. LUA_API void *xlua_newstruct(lua_State *L, int size, int meta_ref) {
  723. CSharpStruct *css = (CSharpStruct *)lua_newuserdata(L, size + sizeof(int) + sizeof(unsigned int));
  724. css->fake_id = -1;
  725. css->len = size;
  726. lua_rawgeti(L, LUA_REGISTRYINDEX, meta_ref);
  727. lua_setmetatable(L, -2);
  728. return css->data;
  729. }
  730. LUA_API void *xlua_tostruct(lua_State *L, int idx, int meta_ref) {
  731. CSharpStruct *css = (CSharpStruct *)lua_touserdata(L, idx);
  732. if (NULL != css) {
  733. if (lua_getmetatable (L, idx)) {
  734. lua_rawgeti(L, -1, 1);
  735. if (lua_type(L, -1) == LUA_TNUMBER && (int)lua_tointeger(L, -1) == meta_ref) {
  736. lua_pop(L, 2);
  737. return css->data;
  738. }
  739. lua_pop(L, 2);
  740. }
  741. }
  742. return NULL;
  743. }
  744. LUA_API int xlua_gettypeid(lua_State *L, int idx) {
  745. int type_id = -1;
  746. if (lua_type(L, idx) == LUA_TUSERDATA) {
  747. if (lua_getmetatable (L, idx)) {
  748. lua_rawgeti(L, -1, 1);
  749. if (lua_type(L, -1) == LUA_TNUMBER) {
  750. type_id = (int)lua_tointeger(L, -1);
  751. }
  752. lua_pop(L, 2);
  753. }
  754. }
  755. return type_id;
  756. }
  757. #define PACK_UNPACK_OF(type) \
  758. LUALIB_API int xlua_pack_##type(void *p, int offset, type field) {\
  759. CSharpStruct *css = (CSharpStruct *)p;\
  760. if (css->fake_id != -1 || css->len < offset + sizeof(field)) {\
  761. return 0;\
  762. } else {\
  763. memcpy((&(css->data[0]) + offset), &field, sizeof(field));\
  764. return 1;\
  765. }\
  766. }\
  767. \
  768. LUALIB_API int xlua_unpack_##type(void *p, int offset, type *pfield) { \
  769. CSharpStruct *css = (CSharpStruct *)p;\
  770. if (css->fake_id != -1 || css->len < offset + sizeof(*pfield)) {\
  771. return 0;\
  772. } else {\
  773. memcpy(pfield, (&(css->data[0]) + offset), sizeof(*pfield));\
  774. return 1;\
  775. }\
  776. }\
  777. PACK_UNPACK_OF(int8_t);
  778. PACK_UNPACK_OF(int16_t);
  779. PACK_UNPACK_OF(int32_t);
  780. PACK_UNPACK_OF(int64_t);
  781. PACK_UNPACK_OF(float);
  782. PACK_UNPACK_OF(double);
  783. LUALIB_API int xlua_pack_float2(void *p, int offset, float f1, float f2) {
  784. CSharpStruct *css = (CSharpStruct *)p;
  785. if (css->fake_id != -1 || css->len < offset + sizeof(float) * 2) {
  786. return 0;
  787. } else {
  788. float *pos = (float *)(&(css->data[0]) + offset);
  789. pos[0] = f1;
  790. pos[1] = f2;
  791. return 1;
  792. }
  793. }
  794. LUALIB_API int xlua_unpack_float2(void *p, int offset, float *f1, float *f2) {
  795. CSharpStruct *css = (CSharpStruct *)p;
  796. if (css->fake_id != -1 || css->len < offset + sizeof(float) * 2) {
  797. return 0;
  798. } else {
  799. float *pos = (float *)(&(css->data[0]) + offset);
  800. *f1 = pos[0];
  801. *f2 = pos[1];
  802. return 1;
  803. }
  804. }
  805. LUALIB_API int xlua_pack_float3(void *p, int offset, float f1, float f2, float f3) {
  806. CSharpStruct *css = (CSharpStruct *)p;
  807. if (css->fake_id != -1 || css->len < offset + sizeof(float) * 3) {
  808. return 0;
  809. } else {
  810. float *pos = (float *)(&(css->data[0]) + offset);
  811. pos[0] = f1;
  812. pos[1] = f2;
  813. pos[2] = f3;
  814. return 1;
  815. }
  816. }
  817. LUALIB_API int xlua_unpack_float3(void *p, int offset, float *f1, float *f2, float *f3) {
  818. CSharpStruct *css = (CSharpStruct *)p;
  819. if (css->fake_id != -1 || css->len < offset + sizeof(float) * 3) {
  820. return 0;
  821. } else {
  822. float *pos = (float *)(&(css->data[0]) + offset);
  823. *f1 = pos[0];
  824. *f2 = pos[1];
  825. *f3 = pos[2];
  826. return 1;
  827. }
  828. }
  829. LUALIB_API int xlua_pack_float4(void *p, int offset, float f1, float f2, float f3, float f4) {
  830. CSharpStruct *css = (CSharpStruct *)p;
  831. if (css->fake_id != -1 || css->len < offset + sizeof(float) * 4) {
  832. return 0;
  833. } else {
  834. float *pos = (float *)(&(css->data[0]) + offset);
  835. pos[0] = f1;
  836. pos[1] = f2;
  837. pos[2] = f3;
  838. pos[3] = f4;
  839. return 1;
  840. }
  841. }
  842. LUALIB_API int xlua_unpack_float4(void *p, int offset, float *f1, float *f2, float *f3, float *f4) {
  843. CSharpStruct *css = (CSharpStruct *)p;
  844. if (css->fake_id != -1 || css->len < offset + sizeof(float) * 4) {
  845. return 0;
  846. } else {
  847. float *pos = (float *)(&(css->data[0]) + offset);
  848. *f1 = pos[0];
  849. *f2 = pos[1];
  850. *f3 = pos[2];
  851. *f4 = pos[3];
  852. return 1;
  853. }
  854. }
  855. LUALIB_API int xlua_pack_float5(void *p, int offset, float f1, float f2, float f3, float f4, float f5) {
  856. CSharpStruct *css = (CSharpStruct *)p;
  857. if (css->fake_id != -1 || css->len < offset + sizeof(float) * 5) {
  858. return 0;
  859. } else {
  860. float *pos = (float *)(&(css->data[0]) + offset);
  861. pos[0] = f1;
  862. pos[1] = f2;
  863. pos[2] = f3;
  864. pos[3] = f4;
  865. pos[4] = f5;
  866. return 1;
  867. }
  868. }
  869. LUALIB_API int xlua_unpack_float5(void *p, int offset, float *f1, float *f2, float *f3, float *f4, float *f5) {
  870. CSharpStruct *css = (CSharpStruct *)p;
  871. if (css->fake_id != -1 || css->len < offset + sizeof(float) * 5) {
  872. return 0;
  873. } else {
  874. float *pos = (float *)(&(css->data[0]) + offset);
  875. *f1 = pos[0];
  876. *f2 = pos[1];
  877. *f3 = pos[2];
  878. *f4 = pos[3];
  879. *f5 = pos[4];
  880. return 1;
  881. }
  882. }
  883. LUALIB_API int xlua_pack_float6(void *p, int offset, float f1, float f2, float f3, float f4, float f5, float f6) {
  884. CSharpStruct *css = (CSharpStruct *)p;
  885. if (css->fake_id != -1 || css->len < offset + sizeof(float) * 6) {
  886. return 0;
  887. } else {
  888. float *pos = (float *)(&(css->data[0]) + offset);
  889. pos[0] = f1;
  890. pos[1] = f2;
  891. pos[2] = f3;
  892. pos[3] = f4;
  893. pos[4] = f5;
  894. pos[5] = f6;
  895. return 1;
  896. }
  897. }
  898. LUALIB_API int xlua_unpack_float6(void *p, int offset, float *f1, float *f2, float *f3, float *f4, float *f5, float *f6) {
  899. CSharpStruct *css = (CSharpStruct *)p;
  900. if (css->fake_id != -1 || css->len < offset + sizeof(float) * 6) {
  901. return 0;
  902. } else {
  903. float *pos = (float *)(&(css->data[0]) + offset);
  904. *f1 = pos[0];
  905. *f2 = pos[1];
  906. *f3 = pos[2];
  907. *f4 = pos[3];
  908. *f5 = pos[4];
  909. *f6 = pos[5];
  910. return 1;
  911. }
  912. }
  913. LUALIB_API int xlua_pack_decimal(void *p, int offset, const int * decimal) {
  914. CSharpStruct *css = (CSharpStruct *)p;
  915. if (css->fake_id != -1 || css->len < sizeof(int) * 4) {
  916. return 0;
  917. } else {
  918. int *pos = (int *)(&(css->data[0]) + offset);
  919. pos[0] = decimal[0];
  920. pos[1] = decimal[1];
  921. pos[2] = decimal[2];
  922. pos[3] = decimal[3];
  923. return 1;
  924. }
  925. }
  926. typedef struct tagDEC {
  927. uint16_t wReserved;
  928. uint8_t scale;
  929. uint8_t sign;
  930. int Hi32;
  931. uint64_t Lo64;
  932. } DECIMAL;
  933. LUALIB_API int xlua_unpack_decimal(void *p, int offset, uint8_t *scale, uint8_t *sign, int *hi32, uint64_t *lo64) {
  934. CSharpStruct *css = (CSharpStruct *)p;
  935. if (css->fake_id != -1 || css->len < sizeof(int) * 4) {
  936. return 0;
  937. } else {
  938. DECIMAL *dec = (DECIMAL *)(&(css->data[0]) + offset);
  939. *scale = dec->scale;
  940. *sign = dec->sign;
  941. *hi32 = dec->Hi32;
  942. *lo64 = dec->Lo64;
  943. return 1;
  944. }
  945. }
  946. LUA_API int xlua_is_eq_str(lua_State *L, int idx, const char* str, int str_len) {
  947. size_t lmsg;
  948. const char *msg;
  949. if (lua_type(L, idx) == LUA_TSTRING) {
  950. msg = lua_tolstring(L, idx, &lmsg);
  951. return (lmsg == str_len) && (memcmp(msg, str, lmsg) == 0);
  952. } else {
  953. return 0;
  954. }
  955. }
  956. #define T_INT8 0
  957. #define T_UINT8 1
  958. #define T_INT16 2
  959. #define T_UINT16 3
  960. #define T_INT32 4
  961. #define T_UINT32 5
  962. #define T_INT64 6
  963. #define T_UINT64 7
  964. #define T_FLOAT 8
  965. #define T_DOUBLE 9
  966. #define DIRECT_ACCESS(type, push_func, to_func) \
  967. int xlua_struct_get_##type(lua_State *L) {\
  968. CSharpStruct *css = (CSharpStruct *)lua_touserdata(L, 1);\
  969. int offset = xlua_tointeger(L, lua_upvalueindex(1));\
  970. type val;\
  971. if (css == NULL || css->fake_id != -1 || css->len < offset + sizeof(type)) {\
  972. return luaL_error(L, "invalid c# struct!");\
  973. } else {\
  974. memcpy(&val, (&(css->data[0]) + offset), sizeof(type));\
  975. push_func(L, val);\
  976. return 1;\
  977. }\
  978. }\
  979. \
  980. int xlua_struct_set_##type(lua_State *L) { \
  981. CSharpStruct *css = (CSharpStruct *)lua_touserdata(L, 1);\
  982. int offset = xlua_tointeger(L, lua_upvalueindex(1));\
  983. type val;\
  984. if (css == NULL || css->fake_id != -1 || css->len < offset + sizeof(type)) {\
  985. return luaL_error(L, "invalid c# struct!");\
  986. } else {\
  987. val = (type)to_func(L, 2);\
  988. memcpy((&(css->data[0]) + offset), &val, sizeof(type));\
  989. return 0;\
  990. }\
  991. }\
  992. DIRECT_ACCESS(int8_t, xlua_pushinteger, xlua_tointeger);
  993. DIRECT_ACCESS(uint8_t, xlua_pushinteger, xlua_tointeger);
  994. DIRECT_ACCESS(int16_t, xlua_pushinteger, xlua_tointeger);
  995. DIRECT_ACCESS(uint16_t, xlua_pushinteger, xlua_tointeger);
  996. DIRECT_ACCESS(int32_t, xlua_pushinteger, xlua_tointeger);
  997. DIRECT_ACCESS(uint32_t, xlua_pushuint, xlua_touint);
  998. DIRECT_ACCESS(int64_t, lua_pushint64, lua_toint64);
  999. DIRECT_ACCESS(uint64_t, lua_pushuint64, lua_touint64);
  1000. DIRECT_ACCESS(float, lua_pushnumber, lua_tonumber);
  1001. DIRECT_ACCESS(double, lua_pushnumber, lua_tonumber);
  1002. static const lua_CFunction direct_getters[10] = {
  1003. xlua_struct_get_int8_t,
  1004. xlua_struct_get_uint8_t,
  1005. xlua_struct_get_int16_t,
  1006. xlua_struct_get_uint16_t,
  1007. xlua_struct_get_int32_t,
  1008. xlua_struct_get_uint32_t,
  1009. xlua_struct_get_int64_t,
  1010. xlua_struct_get_uint64_t,
  1011. xlua_struct_get_float,
  1012. xlua_struct_get_double
  1013. };
  1014. static const lua_CFunction direct_setters[10] = {
  1015. xlua_struct_set_int8_t,
  1016. xlua_struct_set_uint8_t,
  1017. xlua_struct_set_int16_t,
  1018. xlua_struct_set_uint16_t,
  1019. xlua_struct_set_int32_t,
  1020. xlua_struct_set_uint32_t,
  1021. xlua_struct_set_int64_t,
  1022. xlua_struct_set_uint64_t,
  1023. xlua_struct_set_float,
  1024. xlua_struct_set_double
  1025. };
  1026. int nop(lua_State *L) {
  1027. return 0;
  1028. }
  1029. LUA_API int gen_css_access(lua_State *L) {
  1030. int offset = xlua_tointeger(L, 1);
  1031. int type = xlua_tointeger(L, 2);
  1032. if (offset < 0) {
  1033. return luaL_error(L, "offset must larger than 0");
  1034. }
  1035. if (type < T_INT8 || type > T_DOUBLE) {
  1036. return luaL_error(L, "unknow tag[%d]", type);
  1037. }
  1038. lua_pushvalue(L, 1);
  1039. lua_pushcclosure(L, direct_getters[type], 1);
  1040. lua_pushvalue(L, 1);
  1041. lua_pushcclosure(L, direct_setters[type], 1);
  1042. lua_pushcclosure(L, nop, 0);
  1043. return 3;
  1044. }
  1045. static int is_cs_data(lua_State *L, int idx) {
  1046. if (LUA_TUSERDATA == lua_type(L, idx) && lua_getmetatable(L, idx)) {
  1047. lua_pushlightuserdata(L, &tag);
  1048. lua_rawget(L,-2);
  1049. if (!lua_isnil (L,-1)) {
  1050. lua_pop (L, 2);
  1051. return 1;
  1052. }
  1053. lua_pop (L, 2);
  1054. }
  1055. return 0;
  1056. }
  1057. LUA_API int css_clone(lua_State *L) {
  1058. CSharpStruct *from = (CSharpStruct *)lua_touserdata(L, 1);
  1059. CSharpStruct *to = NULL;
  1060. if (!is_cs_data(L, 1) || from->fake_id != -1) {
  1061. return luaL_error(L, "invalid c# struct!");
  1062. }
  1063. to = (CSharpStruct *)lua_newuserdata(L, from->len + sizeof(int) + sizeof(unsigned int));
  1064. to->fake_id = -1;
  1065. to->len = from->len;
  1066. memcpy(&(to->data[0]), &(from->data[0]), from->len);
  1067. lua_getmetatable(L, 1);
  1068. lua_setmetatable(L, -2);
  1069. return 1;
  1070. }
  1071. LUA_API void* xlua_gl(lua_State *L) {
  1072. return G(L);
  1073. }
  1074. static const luaL_Reg xlualib[] = {
  1075. {"sethook", profiler_set_hook},
  1076. {"genaccessor", gen_css_access},
  1077. {"structclone", css_clone},
  1078. {NULL, NULL}
  1079. };
  1080. LUA_API void luaopen_xlua(lua_State *L) {
  1081. luaL_openlibs(L);
  1082. #if LUA_VERSION_NUM == 503
  1083. luaL_newlib(L, xlualib);
  1084. lua_setglobal(L, "xlua");
  1085. #else
  1086. luaL_register(L, "xlua", xlualib);
  1087. lua_pop(L, 1);
  1088. #endif
  1089. }