| [1129] | 1 | /* tolua: functions to push C values. | 
|---|
 | 2 | ** Support code for Lua bindings. | 
|---|
 | 3 | ** Written by Waldemar Celes | 
|---|
 | 4 | ** TeCGraf/PUC-Rio | 
|---|
 | 5 | ** Apr 2003 | 
|---|
 | 6 | ** $Id: $ | 
|---|
 | 7 | */ | 
|---|
 | 8 |  | 
|---|
 | 9 | /* This code is free software; you can redistribute it and/or modify it. | 
|---|
 | 10 | ** The software provided hereunder is on an "as is" basis, and | 
|---|
 | 11 | ** the author has no obligation to provide maintenance, support, updates, | 
|---|
 | 12 | ** enhancements, or modifications. | 
|---|
 | 13 | */ | 
|---|
 | 14 |  | 
|---|
 | 15 | #include "tolua++.h" | 
|---|
| [1804] | 16 | #include "lua/lauxlib.h" | 
|---|
| [1129] | 17 |  | 
|---|
 | 18 | #include <stdlib.h> | 
|---|
 | 19 |  | 
|---|
 | 20 | TOLUA_API void tolua_pushvalue (lua_State* L, int lo) | 
|---|
 | 21 | { | 
|---|
 | 22 |  lua_pushvalue(L,lo); | 
|---|
 | 23 | } | 
|---|
 | 24 |  | 
|---|
 | 25 | TOLUA_API void tolua_pushboolean (lua_State* L, int value) | 
|---|
 | 26 | { | 
|---|
 | 27 |  lua_pushboolean(L,value); | 
|---|
 | 28 | } | 
|---|
 | 29 |  | 
|---|
 | 30 | TOLUA_API void tolua_pushnumber (lua_State* L, double value) | 
|---|
 | 31 | { | 
|---|
 | 32 |  lua_pushnumber(L,value); | 
|---|
 | 33 | } | 
|---|
 | 34 |  | 
|---|
 | 35 | TOLUA_API void tolua_pushstring (lua_State* L, const char* value) | 
|---|
 | 36 | { | 
|---|
 | 37 |  if (value == NULL) | 
|---|
 | 38 |   lua_pushnil(L); | 
|---|
 | 39 |  else | 
|---|
 | 40 |   lua_pushstring(L,value); | 
|---|
 | 41 | } | 
|---|
 | 42 |  | 
|---|
 | 43 | TOLUA_API void tolua_pushuserdata (lua_State* L, void* value) | 
|---|
 | 44 | { | 
|---|
 | 45 |  if (value == NULL) | 
|---|
 | 46 |   lua_pushnil(L); | 
|---|
 | 47 |  else | 
|---|
 | 48 |   lua_pushlightuserdata(L,value); | 
|---|
 | 49 | } | 
|---|
 | 50 |  | 
|---|
 | 51 | TOLUA_API void tolua_pushusertype (lua_State* L, void* value, const char* type) | 
|---|
 | 52 | { | 
|---|
 | 53 |  if (value == NULL) | 
|---|
 | 54 |   lua_pushnil(L); | 
|---|
 | 55 |  else | 
|---|
 | 56 |  { | 
|---|
 | 57 |   luaL_getmetatable(L, type); | 
|---|
 | 58 |   lua_pushstring(L,"tolua_ubox"); | 
|---|
 | 59 |   lua_rawget(L,-2);        /* stack: mt ubox */ | 
|---|
 | 60 |   if (lua_isnil(L, -1)) { | 
|---|
 | 61 |           lua_pop(L, 1); | 
|---|
 | 62 |           lua_pushstring(L, "tolua_ubox"); | 
|---|
 | 63 |           lua_rawget(L, LUA_REGISTRYINDEX); | 
|---|
 | 64 |   }; | 
|---|
 | 65 |   lua_pushlightuserdata(L,value); | 
|---|
 | 66 |   lua_rawget(L,-2);                       /* stack: mt ubox ubox[u] */ | 
|---|
 | 67 |   if (lua_isnil(L,-1)) | 
|---|
 | 68 |   { | 
|---|
 | 69 |    lua_pop(L,1);                          /* stack: mt ubox */ | 
|---|
 | 70 |    lua_pushlightuserdata(L,value); | 
|---|
 | 71 |    *(void**)lua_newuserdata(L,sizeof(void *)) = value;   /* stack: mt ubox u newud */ | 
|---|
 | 72 |    lua_pushvalue(L,-1);                   /* stack: mt ubox u newud newud */ | 
|---|
 | 73 |    lua_insert(L,-4);                      /* stack: mt newud ubox u newud */ | 
|---|
 | 74 |    lua_rawset(L,-3);                      /* stack: mt newud ubox */ | 
|---|
 | 75 |    lua_pop(L,1);                          /* stack: mt newud */ | 
|---|
 | 76 |    /*luaL_getmetatable(L,type);*/ | 
|---|
 | 77 |    lua_pushvalue(L, -2);                        /* stack: mt newud mt */ | 
|---|
 | 78 |    lua_setmetatable(L,-2);                      /* stack: mt newud */ | 
|---|
 | 79 |  | 
|---|
 | 80 |    #ifdef LUA_VERSION_NUM | 
|---|
 | 81 |    lua_pushvalue(L, TOLUA_NOPEER); | 
|---|
 | 82 |    lua_setfenv(L, -2); | 
|---|
 | 83 |    #endif | 
|---|
 | 84 |   } | 
|---|
 | 85 |   else | 
|---|
 | 86 |   { | 
|---|
 | 87 |    /* check the need of updating the metatable to a more specialized class */ | 
|---|
 | 88 |    lua_insert(L,-2);                       /* stack: mt ubox[u] ubox */ | 
|---|
 | 89 |    lua_pop(L,1);                           /* stack: mt ubox[u] */ | 
|---|
 | 90 |    lua_pushstring(L,"tolua_super"); | 
|---|
 | 91 |    lua_rawget(L,LUA_REGISTRYINDEX);        /* stack: mt ubox[u] super */ | 
|---|
 | 92 |    lua_getmetatable(L,-2);                 /* stack: mt ubox[u] super mt */ | 
|---|
 | 93 |    lua_rawget(L,-2);                       /* stack: mt ubox[u] super super[mt] */ | 
|---|
 | 94 |                         if (lua_istable(L,-1)) | 
|---|
 | 95 |                         { | 
|---|
 | 96 |                                 lua_pushstring(L,type);                 /* stack: mt ubox[u] super super[mt] type */ | 
|---|
 | 97 |                                 lua_rawget(L,-2);                       /* stack: mt ubox[u] super super[mt] flag */ | 
|---|
 | 98 |                                 if (lua_toboolean(L,-1) == 1)   /* if true */ | 
|---|
 | 99 |                                 { | 
|---|
 | 100 |                                         lua_pop(L,3);   /* mt ubox[u]*/ | 
|---|
 | 101 |                                         lua_remove(L, -2); | 
|---|
 | 102 |                                         return; | 
|---|
 | 103 |                                 } | 
|---|
 | 104 |                         } | 
|---|
 | 105 |                         /* type represents a more specilized type */ | 
|---|
 | 106 |                         /*luaL_getmetatable(L,type);             // stack: mt ubox[u] super super[mt] flag mt */ | 
|---|
 | 107 |                         lua_pushvalue(L, -5);                                   /* stack: mt ubox[u] super super[mt] flag mt */ | 
|---|
 | 108 |                         lua_setmetatable(L,-5);                /* stack: mt ubox[u] super super[mt] flag */ | 
|---|
 | 109 |                         lua_pop(L,3);                          /* stack: mt ubox[u] */ | 
|---|
 | 110 |   } | 
|---|
 | 111 |   lua_remove(L, -2);    /* stack: ubox[u]*/ | 
|---|
 | 112 |  } | 
|---|
 | 113 | } | 
|---|
 | 114 |  | 
|---|
 | 115 | TOLUA_API void tolua_pushusertype_and_takeownership (lua_State* L, void* value, const char* type) | 
|---|
 | 116 | { | 
|---|
 | 117 |         tolua_pushusertype(L,value,type); | 
|---|
 | 118 |         tolua_register_gc(L,lua_gettop(L)); | 
|---|
 | 119 | } | 
|---|
 | 120 |  | 
|---|
 | 121 | TOLUA_API void tolua_pushfieldvalue (lua_State* L, int lo, int index, int v) | 
|---|
 | 122 | { | 
|---|
 | 123 |  lua_pushnumber(L,index); | 
|---|
 | 124 |  lua_pushvalue(L,v); | 
|---|
 | 125 |  lua_settable(L,lo); | 
|---|
 | 126 | } | 
|---|
 | 127 |  | 
|---|
 | 128 | TOLUA_API void tolua_pushfieldboolean (lua_State* L, int lo, int index, int v) | 
|---|
 | 129 | { | 
|---|
 | 130 |  lua_pushnumber(L,index); | 
|---|
 | 131 |  lua_pushboolean(L,v); | 
|---|
 | 132 |  lua_settable(L,lo); | 
|---|
 | 133 | } | 
|---|
 | 134 |  | 
|---|
 | 135 |  | 
|---|
 | 136 | TOLUA_API void tolua_pushfieldnumber (lua_State* L, int lo, int index, double v) | 
|---|
 | 137 | { | 
|---|
 | 138 |  lua_pushnumber(L,index); | 
|---|
 | 139 |  tolua_pushnumber(L,v); | 
|---|
 | 140 |  lua_settable(L,lo); | 
|---|
 | 141 | } | 
|---|
 | 142 |  | 
|---|
 | 143 | TOLUA_API void tolua_pushfieldstring (lua_State* L, int lo, int index, const char* v) | 
|---|
 | 144 | { | 
|---|
 | 145 |  lua_pushnumber(L,index); | 
|---|
 | 146 |  tolua_pushstring(L,v); | 
|---|
 | 147 |  lua_settable(L,lo); | 
|---|
 | 148 | } | 
|---|
 | 149 |  | 
|---|
 | 150 | TOLUA_API void tolua_pushfielduserdata (lua_State* L, int lo, int index, void* v) | 
|---|
 | 151 | { | 
|---|
 | 152 |  lua_pushnumber(L,index); | 
|---|
 | 153 |  tolua_pushuserdata(L,v); | 
|---|
 | 154 |  lua_settable(L,lo); | 
|---|
 | 155 | } | 
|---|
 | 156 |  | 
|---|
 | 157 | TOLUA_API void tolua_pushfieldusertype (lua_State* L, int lo, int index, void* v, const char* type) | 
|---|
 | 158 | { | 
|---|
 | 159 |  lua_pushnumber(L,index); | 
|---|
 | 160 |  tolua_pushusertype(L,v,type); | 
|---|
 | 161 |  lua_settable(L,lo); | 
|---|
 | 162 | } | 
|---|
 | 163 |  | 
|---|
 | 164 | TOLUA_API void tolua_pushfieldusertype_and_takeownership (lua_State* L, int lo, int index, void* v, const char* type) | 
|---|
 | 165 | { | 
|---|
 | 166 |  lua_pushnumber(L,index); | 
|---|
 | 167 |  tolua_pushusertype(L,v,type); | 
|---|
 | 168 |         tolua_register_gc(L,lua_gettop(L)); | 
|---|
 | 169 |  lua_settable(L,lo); | 
|---|
 | 170 | } | 
|---|
 | 171 |  | 
|---|