| 262 | } // namespace unnamed |
| 263 | |
| 264 | LUABIND_API void push_instance_metatable(lua_State* L) |
| 265 | { |
| 266 | // One sequence entry for the tag, 4 non-sequence entries for |
| 267 | // __gc, __index, __newindex and __metatable and |
| 268 | // one more for each operator. |
| 269 | lua_createtable(L, 1, 4 + number_of_operators); |
| 270 | |
| 271 | // This is used as a tag to determine if a userdata is a luabind |
| 272 | // instance. We use a numeric key and a cclosure for fast comparision. |
| 273 | lua_pushcfunction(L, get_instance_value); |
| 274 | lua_rawseti(L, -2, 1); |
| 275 | |
| 276 | lua_pushliteral(L, "__gc"); |
| 277 | lua_pushcfunction(L, destroy_instance); |
| 278 | lua_rawset(L, -3); |
| 279 | |
| 280 | lua_pushliteral(L, "__index"); |
| 281 | lua_pushcfunction(L, get_instance_value); |
| 282 | lua_rawset(L, -3); |
| 283 | |
| 284 | lua_pushliteral(L, "__newindex"); |
| 285 | lua_pushcfunction(L, set_instance_value); |
| 286 | lua_rawset(L, -3); |
| 287 | |
| 288 | // Direct calls to metamethods cannot be allowed, because the |
| 289 | // callee trusts the caller to pass arguments of the right type. |
| 290 | lua_pushliteral(L, "__metatable"); |
| 291 | lua_pushboolean(L, true); |
| 292 | lua_rawset(L, -3); |
| 293 | |
| 294 | for (int op = 0; op < number_of_operators; ++op) |
| 295 | { |
| 296 | lua_pushstring(L, get_operator_name(op)); |
| 297 | lua_pushvalue(L, -1); |
| 298 | lua_pushboolean(L, op == op_unm || op == op_len); // Unary? |
| 299 | lua_pushcclosure(L, &dispatch_operator, 2); |
| 300 | lua_rawset(L, -3); |
| 301 | } |
| 302 | } |
| 303 | |
| 304 | LUABIND_API object_rep* get_instance(lua_State* L, int index) |
| 305 | { |
no test coverage detected