00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #include <stdio.h>
00015
00016 #include "tolua++.h"
00017
00018
00019
00020
00021
00022 static void storeatubox (lua_State* L, int lo)
00023 {
00024 #ifdef LUA_VERSION_NUM
00025 lua_getfenv(L, lo);
00026 if (lua_rawequal(L, -1, TOLUA_NOPEER)) {
00027 lua_pop(L, 1);
00028 lua_newtable(L);
00029 lua_pushvalue(L, -1);
00030 lua_setfenv(L, lo);
00031 };
00032 lua_insert(L, -3);
00033 lua_settable(L, -3);
00034 lua_pop(L, 1);
00035 #else
00036
00037 lua_pushstring(L,"tolua_peers");
00038 lua_rawget(L,LUA_REGISTRYINDEX);
00039 lua_pushvalue(L,lo);
00040 lua_rawget(L,-2);
00041 if (!lua_istable(L,-1))
00042 {
00043 lua_pop(L,1);
00044 lua_newtable(L);
00045 lua_pushvalue(L,1);
00046 lua_pushvalue(L,-2);
00047 lua_rawset(L,-4);
00048 }
00049 lua_insert(L,-4);
00050 lua_pop(L,1);
00051 lua_rawset(L,-3);
00052 lua_pop(L,1);
00053 #endif
00054 }
00055
00056
00057
00058 static int module_index_event (lua_State* L)
00059 {
00060 lua_pushstring(L,".get");
00061 lua_rawget(L,-3);
00062 if (lua_istable(L,-1))
00063 {
00064 lua_pushvalue(L,2);
00065 lua_rawget(L,-2);
00066 if (lua_iscfunction(L,-1))
00067 {
00068 lua_call(L,0,1);
00069 return 1;
00070 }
00071 else if (lua_istable(L,-1))
00072 return 1;
00073 }
00074
00075 if (lua_getmetatable(L,1))
00076 {
00077 lua_pushstring(L,"__index");
00078 lua_rawget(L,-2);
00079 lua_pushvalue(L,1);
00080 lua_pushvalue(L,2);
00081 if (lua_isfunction(L,-1))
00082 {
00083 lua_call(L,2,1);
00084 return 1;
00085 }
00086 else if (lua_istable(L,-1))
00087 {
00088 lua_gettable(L,-3);
00089 return 1;
00090 }
00091 }
00092 lua_pushnil(L);
00093 return 1;
00094 }
00095
00096
00097
00098 static int module_newindex_event (lua_State* L)
00099 {
00100 lua_pushstring(L,".set");
00101 lua_rawget(L,-4);
00102 if (lua_istable(L,-1))
00103 {
00104 lua_pushvalue(L,2);
00105 lua_rawget(L,-2);
00106 if (lua_iscfunction(L,-1))
00107 {
00108 lua_pushvalue(L,1);
00109 lua_pushvalue(L,3);
00110 lua_call(L,2,0);
00111 return 0;
00112 }
00113 }
00114
00115 if (lua_getmetatable(L,1) && lua_getmetatable(L,-1))
00116 {
00117 lua_pushstring(L,"__newindex");
00118 lua_rawget(L,-2);
00119 if (lua_isfunction(L,-1))
00120 {
00121 lua_pushvalue(L,1);
00122 lua_pushvalue(L,2);
00123 lua_pushvalue(L,3);
00124 lua_call(L,3,0);
00125 }
00126 }
00127 lua_settop(L,3);
00128 lua_rawset(L,-3);
00129 return 0;
00130 }
00131
00132
00133
00134
00135
00136 static int class_index_event (lua_State* L)
00137 {
00138 int t = lua_type(L,1);
00139 if (t == LUA_TUSERDATA)
00140 {
00141
00142 #ifdef LUA_VERSION_NUM
00143 lua_getfenv(L,1);
00144 if (!lua_rawequal(L, -1, TOLUA_NOPEER)) {
00145 lua_pushvalue(L, 2);
00146 lua_gettable(L, -2);
00147 if (!lua_isnil(L, -1))
00148 return 1;
00149 };
00150 #else
00151 lua_pushstring(L,"tolua_peers");
00152 lua_rawget(L,LUA_REGISTRYINDEX);
00153 lua_pushvalue(L,1);
00154 lua_rawget(L,-2);
00155 if (lua_istable(L,-1))
00156 {
00157 lua_pushvalue(L,2);
00158 lua_rawget(L,-2);
00159 if (!lua_isnil(L,-1))
00160 return 1;
00161 }
00162 #endif
00163 lua_settop(L,2);
00164
00165 lua_pushvalue(L,1);
00166 while (lua_getmetatable(L,-1))
00167 {
00168 lua_remove(L,-2);
00169 if (lua_isnumber(L,2))
00170 {
00171
00172 lua_pushstring(L,".geti");
00173 lua_rawget(L,-2);
00174 if (lua_isfunction(L,-1))
00175 {
00176 lua_pushvalue(L,1);
00177 lua_pushvalue(L,2);
00178 lua_call(L,2,1);
00179 return 1;
00180 }
00181 }
00182 else
00183 {
00184 lua_pushvalue(L,2);
00185 lua_rawget(L,-2);
00186 if (!lua_isnil(L,-1))
00187 return 1;
00188 else
00189 lua_pop(L,1);
00190
00191 lua_pushstring(L,".get");
00192 lua_rawget(L,-2);
00193 if (lua_istable(L,-1))
00194 {
00195 lua_pushvalue(L,2);
00196 lua_rawget(L,-2);
00197 if (lua_iscfunction(L,-1))
00198 {
00199 lua_pushvalue(L,1);
00200 lua_pushvalue(L,2);
00201 lua_call(L,2,1);
00202 return 1;
00203 }
00204 else if (lua_istable(L,-1))
00205 {
00206
00207 void* u = *((void**)lua_touserdata(L,1));
00208 lua_newtable(L);
00209 lua_pushstring(L,".self");
00210 lua_pushlightuserdata(L,u);
00211 lua_rawset(L,-3);
00212 lua_insert(L,-2);
00213 lua_setmetatable(L,-2);
00214 lua_pushvalue(L,-1);
00215 lua_pushvalue(L,2);
00216 lua_insert(L,-2);
00217 storeatubox(L,1);
00218 return 1;
00219 }
00220 }
00221 }
00222 lua_settop(L,3);
00223 }
00224 lua_pushnil(L);
00225 return 1;
00226 }
00227 else if (t== LUA_TTABLE)
00228 {
00229 module_index_event(L);
00230 return 1;
00231 }
00232 lua_pushnil(L);
00233 return 1;
00234 }
00235
00236
00237
00238
00239
00240
00241 static int class_newindex_event (lua_State* L)
00242 {
00243 int t = lua_type(L,1);
00244 if (t == LUA_TUSERDATA)
00245 {
00246
00247 lua_getmetatable(L,1);
00248 while (lua_istable(L,-1))
00249 {
00250 if (lua_isnumber(L,2))
00251 {
00252
00253 lua_pushstring(L,".seti");
00254 lua_rawget(L,-2);
00255 if (lua_isfunction(L,-1))
00256 {
00257 lua_pushvalue(L,1);
00258 lua_pushvalue(L,2);
00259 lua_pushvalue(L,3);
00260 lua_call(L,3,0);
00261 return 0;
00262 }
00263 }
00264 else
00265 {
00266 lua_pushstring(L,".set");
00267 lua_rawget(L,-2);
00268 if (lua_istable(L,-1))
00269 {
00270 lua_pushvalue(L,2);
00271 lua_rawget(L,-2);
00272 if (lua_iscfunction(L,-1))
00273 {
00274 lua_pushvalue(L,1);
00275 lua_pushvalue(L,3);
00276 lua_call(L,2,0);
00277 return 0;
00278 }
00279 lua_pop(L,1);
00280 }
00281 lua_pop(L,1);
00282 if (!lua_getmetatable(L,-1))
00283 lua_pushnil(L);
00284 lua_remove(L,-2);
00285 }
00286 }
00287 lua_settop(L,3);
00288
00289
00290 storeatubox(L,1);
00291 }
00292 else if (t== LUA_TTABLE)
00293 {
00294 module_newindex_event(L);
00295 }
00296 return 0;
00297 }
00298
00299 static int class_call_event(lua_State* L) {
00300
00301 if (lua_istable(L, 1)) {
00302 lua_pushstring(L, ".call");
00303 lua_rawget(L, 1);
00304 if (lua_isfunction(L, -1)) {
00305
00306 lua_insert(L, 1);
00307 lua_call(L, lua_gettop(L)-1, 1);
00308
00309 return 1;
00310 };
00311 };
00312 tolua_error(L,"Attempt to call a non-callable object.",NULL);
00313 return 0;
00314 };
00315
00316 static int do_operator (lua_State* L, const char* op)
00317 {
00318 if (lua_isuserdata(L,1))
00319 {
00320
00321 lua_pushvalue(L,1);
00322 while (lua_getmetatable(L,-1))
00323 {
00324 lua_remove(L,-2);
00325 lua_pushstring(L,op);
00326 lua_rawget(L,-2);
00327 if (lua_isfunction(L,-1))
00328 {
00329 lua_pushvalue(L,1);
00330 lua_pushvalue(L,2);
00331 lua_call(L,2,1);
00332 return 1;
00333 }
00334 lua_settop(L,3);
00335 }
00336 }
00337 tolua_error(L,"Attempt to perform operation on an invalid operand",NULL);
00338 return 0;
00339 }
00340
00341 static int class_add_event (lua_State* L)
00342 {
00343 return do_operator(L,".add");
00344 }
00345
00346 static int class_sub_event (lua_State* L)
00347 {
00348 return do_operator(L,".sub");
00349 }
00350
00351 static int class_mul_event (lua_State* L)
00352 {
00353 return do_operator(L,".mul");
00354 }
00355
00356 static int class_div_event (lua_State* L)
00357 {
00358 return do_operator(L,".div");
00359 }
00360
00361 static int class_lt_event (lua_State* L)
00362 {
00363 return do_operator(L,".lt");
00364 }
00365
00366 static int class_le_event (lua_State* L)
00367 {
00368 return do_operator(L,".le");
00369 }
00370
00371 static int class_eq_event (lua_State* L)
00372 {
00373 return do_operator(L,".eq");
00374 }
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397 TOLUA_API int class_gc_event (lua_State* L)
00398 {
00399 void* u = *((void**)lua_touserdata(L,1));
00400 int top;
00401
00402
00403
00404
00405
00406 lua_pushvalue(L, lua_upvalueindex(1));
00407 lua_pushlightuserdata(L,u);
00408 lua_rawget(L,-2);
00409 lua_getmetatable(L,1);
00410
00411 top = lua_gettop(L);
00412 if (tolua_fast_isa(L,top,top-1, lua_upvalueindex(2)))
00413 {
00414
00415
00416 lua_pushliteral(L,".collector");
00417 lua_rawget(L,-2);
00418 if (lua_isfunction(L,-1)) {
00419
00420 }
00421 else {
00422 lua_pop(L,1);
00423
00424 lua_pushcfunction(L,tolua_default_collect);
00425 }
00426
00427 lua_pushvalue(L,1);
00428 lua_call(L,1,0);
00429
00430 lua_pushlightuserdata(L,u);
00431 lua_pushnil(L);
00432 lua_rawset(L,-5);
00433 }
00434 lua_pop(L,3);
00435 return 0;
00436 }
00437
00438
00439
00440
00441
00442 TOLUA_API void tolua_moduleevents (lua_State* L)
00443 {
00444 lua_pushstring(L,"__index");
00445 lua_pushcfunction(L,module_index_event);
00446 lua_rawset(L,-3);
00447 lua_pushstring(L,"__newindex");
00448 lua_pushcfunction(L,module_newindex_event);
00449 lua_rawset(L,-3);
00450 }
00451
00452
00453
00454 TOLUA_API int tolua_ismodulemetatable (lua_State* L)
00455 {
00456 int r = 0;
00457 if (lua_getmetatable(L,-1))
00458 {
00459 lua_pushstring(L,"__index");
00460 lua_rawget(L,-2);
00461 r = (lua_tocfunction(L,-1) == module_index_event);
00462 lua_pop(L,2);
00463 }
00464 return r;
00465 }
00466
00467
00468
00469
00470 TOLUA_API void tolua_classevents (lua_State* L)
00471 {
00472 lua_pushstring(L,"__index");
00473 lua_pushcfunction(L,class_index_event);
00474 lua_rawset(L,-3);
00475 lua_pushstring(L,"__newindex");
00476 lua_pushcfunction(L,class_newindex_event);
00477 lua_rawset(L,-3);
00478
00479 lua_pushstring(L,"__add");
00480 lua_pushcfunction(L,class_add_event);
00481 lua_rawset(L,-3);
00482 lua_pushstring(L,"__sub");
00483 lua_pushcfunction(L,class_sub_event);
00484 lua_rawset(L,-3);
00485 lua_pushstring(L,"__mul");
00486 lua_pushcfunction(L,class_mul_event);
00487 lua_rawset(L,-3);
00488 lua_pushstring(L,"__div");
00489 lua_pushcfunction(L,class_div_event);
00490 lua_rawset(L,-3);
00491
00492 lua_pushstring(L,"__lt");
00493 lua_pushcfunction(L,class_lt_event);
00494 lua_rawset(L,-3);
00495 lua_pushstring(L,"__le");
00496 lua_pushcfunction(L,class_le_event);
00497 lua_rawset(L,-3);
00498 lua_pushstring(L,"__eq");
00499 lua_pushcfunction(L,class_eq_event);
00500 lua_rawset(L,-3);
00501
00502 lua_pushstring(L,"__call");
00503 lua_pushcfunction(L,class_call_event);
00504 lua_rawset(L,-3);
00505
00506 lua_pushstring(L,"__gc");
00507 lua_pushstring(L, "tolua_gc_event");
00508 lua_rawget(L, LUA_REGISTRYINDEX);
00509
00510 lua_rawset(L,-3);
00511 }
00512