PageRenderTime 73ms CodeModel.GetById 9ms RepoModel.GetById 0ms app.codeStats 0ms

/luabind/src/class_rep.cpp

http://luaboost.googlecode.com/
C++ | 1678 lines | 1167 code | 297 blank | 214 comment | 159 complexity | 778dcf98cd691019ae9117d7aa1c08c2 MD5 | raw file
  1. // Copyright (c) 2003 Daniel Wallin and Arvid Norberg
  2. // Permission is hereby granted, free of charge, to any person obtaining a
  3. // copy of this software and associated documentation files (the "Software"),
  4. // to deal in the Software without restriction, including without limitation
  5. // the rights to use, copy, modify, merge, publish, distribute, sublicense,
  6. // and/or sell copies of the Software, and to permit persons to whom the
  7. // Software is furnished to do so, subject to the following conditions:
  8. // The above copyright notice and this permission notice shall be included
  9. // in all copies or substantial portions of the Software.
  10. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
  11. // ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
  12. // TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
  13. // PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
  14. // SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
  15. // ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
  16. // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  17. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
  18. // OR OTHER DEALINGS IN THE SOFTWARE.
  19. #include <luabind/lua_include.hpp>
  20. #include <luabind/detail/stack_utils.hpp>
  21. #include <luabind/luabind.hpp>
  22. #include <utility>
  23. using namespace luabind::detail;
  24. namespace luabind { namespace detail
  25. {
  26. struct method_name
  27. {
  28. method_name(char const* n): name(n) {}
  29. bool operator()(method_rep const& o) const
  30. { return std::strcmp(o.name, name) == 0; }
  31. char const* name;
  32. };
  33. }}
  34. #ifndef LUABIND_NO_ERROR_CHECKING
  35. std::string luabind::detail::get_overload_signatures_candidates(
  36. lua_State* L
  37. , std::vector<const overload_rep_base*>::iterator start
  38. , std::vector<const overload_rep_base*>::iterator end
  39. , std::string name)
  40. {
  41. std::string s;
  42. for (; start != end; ++start)
  43. {
  44. s += name;
  45. (*start)->get_signature(L, s);
  46. s += "\n";
  47. }
  48. return s;
  49. }
  50. #endif
  51. luabind::detail::class_rep::class_rep(LUABIND_TYPE_INFO type
  52. , const char* name
  53. , lua_State* L
  54. , void(*destructor)(void*)
  55. , void(*const_holder_destructor)(void*)
  56. , LUABIND_TYPE_INFO holder_type
  57. , LUABIND_TYPE_INFO const_holder_type
  58. , void*(*extractor)(void*)
  59. , const void*(*const_extractor)(void*)
  60. , void(*const_converter)(void*,void*)
  61. , void(*construct_holder)(void*,void*)
  62. , void(*construct_const_holder)(void*,void*)
  63. , void(*default_construct_holder)(void*)
  64. , void(*default_construct_const_holder)(void*)
  65. , void(*adopt_fun)(void*)
  66. , int holder_size
  67. , int holder_alignment)
  68. : m_type(type)
  69. , m_holder_type(holder_type)
  70. , m_const_holder_type(const_holder_type)
  71. , m_extractor(extractor)
  72. , m_const_extractor(const_extractor)
  73. , m_const_converter(const_converter)
  74. , m_construct_holder(construct_holder)
  75. , m_construct_const_holder(construct_const_holder)
  76. , m_default_construct_holder(default_construct_holder)
  77. , m_default_construct_const_holder(default_construct_const_holder)
  78. , m_adopt_fun(adopt_fun)
  79. , m_holder_size(holder_size)
  80. , m_holder_alignment(holder_alignment)
  81. , m_name(name)
  82. , m_class_type(cpp_class)
  83. , m_destructor(destructor)
  84. , m_const_holder_destructor(const_holder_destructor)
  85. , m_operator_cache(0)
  86. {
  87. assert(m_holder_alignment >= 1 && "internal error");
  88. lua_newtable(L);
  89. handle(L, -1).swap(m_table);
  90. lua_newtable(L);
  91. handle(L, -1).swap(m_default_table);
  92. lua_pop(L, 2);
  93. class_registry* r = class_registry::get_registry(L);
  94. assert((r->cpp_class() != LUA_NOREF) && "you must call luabind::open()");
  95. detail::getref(L, r->cpp_class());
  96. lua_setmetatable(L, -2);
  97. lua_pushvalue(L, -1); // duplicate our user data
  98. m_self_ref.set(L);
  99. m_instance_metatable = r->cpp_instance();
  100. }
  101. luabind::detail::class_rep::class_rep(lua_State* L, const char* name)
  102. : m_type(LUABIND_INVALID_TYPE_INFO)
  103. , m_holder_type(LUABIND_INVALID_TYPE_INFO)
  104. , m_const_holder_type(LUABIND_INVALID_TYPE_INFO)
  105. , m_extractor(0)
  106. , m_const_extractor(0)
  107. , m_const_converter(0)
  108. , m_construct_holder(0)
  109. , m_construct_const_holder(0)
  110. , m_default_construct_holder(0)
  111. , m_default_construct_const_holder(0)
  112. , m_adopt_fun(0)
  113. , m_holder_size(0)
  114. , m_holder_alignment(1)
  115. , m_name(name)
  116. , m_class_type(lua_class)
  117. , m_destructor(0)
  118. , m_const_holder_destructor(0)
  119. , m_operator_cache(0)
  120. {
  121. lua_newtable(L);
  122. handle(L, -1).swap(m_table);
  123. lua_newtable(L);
  124. handle(L, -1).swap(m_default_table);
  125. lua_pop(L, 2);
  126. class_registry* r = class_registry::get_registry(L);
  127. assert((r->cpp_class() != LUA_NOREF) && "you must call luabind::open()");
  128. detail::getref(L, r->lua_class());
  129. lua_setmetatable(L, -2);
  130. lua_pushvalue(L, -1); // duplicate our user data
  131. m_self_ref.set(L);
  132. m_instance_metatable = r->lua_instance();
  133. }
  134. luabind::detail::class_rep::~class_rep()
  135. {
  136. }
  137. // leaves object on lua stack
  138. std::pair<void*,void*>
  139. luabind::detail::class_rep::allocate(lua_State* L) const
  140. {
  141. const int overlap = sizeof(object_rep)&(m_holder_alignment-1);
  142. const int padding = overlap==0?0:m_holder_alignment-overlap;
  143. const int size = sizeof(object_rep) + padding + m_holder_size;
  144. char* mem = static_cast<char*>(lua_newuserdata(L, size));
  145. char* ptr = mem + sizeof(object_rep) + padding;
  146. return std::pair<void*,void*>(mem,ptr);
  147. }
  148. /*
  149. #include <iostream>
  150. namespace
  151. {
  152. void dump_stack(lua_State* L)
  153. {
  154. for (int i = 1; i <= lua_gettop(L); ++i)
  155. {
  156. int t = lua_type(L, i);
  157. switch (t)
  158. {
  159. case LUA_TNUMBER:
  160. std::cout << "[" << i << "] number: " << lua_tonumber(L, i) << "\n";
  161. break;
  162. case LUA_TSTRING:
  163. std::cout << "[" << i << "] string: " << lua_tostring(L, i) << "\n";
  164. break;
  165. case LUA_TUSERDATA:
  166. std::cout << "[" << i << "] userdata: " << lua_touserdata(L, i) << "\n";
  167. break;
  168. case LUA_TTABLE:
  169. std::cout << "[" << i << "] table:\n";
  170. break;
  171. case LUA_TNIL:
  172. std::cout << "[" << i << "] nil:\n";
  173. break;
  174. }
  175. }
  176. }
  177. }
  178. */
  179. void luabind::detail::class_rep::adopt(bool const_obj, void* obj)
  180. {
  181. if (m_adopt_fun == 0) return;
  182. if (m_extractor)
  183. {
  184. assert(m_const_extractor);
  185. if (const_obj)
  186. m_adopt_fun(const_cast<void*>(m_const_extractor(obj)));
  187. else
  188. m_adopt_fun(m_extractor(obj));
  189. }
  190. else
  191. {
  192. m_adopt_fun(obj);
  193. }
  194. }
  195. // lua stack: userdata, key
  196. int luabind::detail::class_rep::gettable(lua_State* L)
  197. {
  198. // if key is nil, return nil
  199. if (lua_isnil(L, 2))
  200. {
  201. lua_pushnil(L);
  202. return 1;
  203. }
  204. object_rep* obj = static_cast<object_rep*>(lua_touserdata(L, 1));
  205. // we have to ignore the first argument since this may point to
  206. // a method that is not present in this class (but in a subclass)
  207. const char* key = lua_tostring(L, 2);
  208. #ifndef LUABIND_NO_ERROR_CHECKING
  209. if (std::strlen(key) != lua_strlen(L, 2))
  210. {
  211. {
  212. std::string msg("luabind does not support "
  213. "member names with extra nulls:\n");
  214. msg += std::string(lua_tostring(L, 2), lua_strlen(L, 2));
  215. lua_pushstring(L, msg.c_str());
  216. }
  217. lua_error(L);
  218. }
  219. #endif
  220. // special case to see if this is a null-pointer
  221. if (key && !std::strcmp(key, "__ok"))
  222. {
  223. class_rep* crep = obj->crep();
  224. void* p = crep->extractor() ? crep->extractor()(obj->ptr())
  225. : obj->ptr();
  226. lua_pushboolean(L, p != 0);
  227. return 1;
  228. }
  229. // First, look in the instance's table
  230. detail::lua_reference const& tbl = obj->get_lua_table();
  231. if (tbl.is_valid())
  232. {
  233. tbl.get(L);
  234. lua_pushvalue(L, 2);
  235. lua_gettable(L, -2);
  236. if (!lua_isnil(L, -1))
  237. {
  238. lua_remove(L, -2); // remove table
  239. return 1;
  240. }
  241. lua_pop(L, 2);
  242. }
  243. // Then look in the class' table for this member
  244. obj->crep()->get_table(L);
  245. lua_pushvalue(L, 2);
  246. lua_gettable(L, -2);
  247. if (!lua_isnil(L, -1))
  248. {
  249. lua_remove(L, -2); // remove table
  250. return 1;
  251. }
  252. lua_pop(L, 2);
  253. std::map<const char*, callback, ltstr>::iterator j = m_getters.find(key);
  254. if (j != m_getters.end())
  255. {
  256. // the name is a data member
  257. return j->second.func(L, j->second.pointer_offset);
  258. }
  259. lua_pushnil(L);
  260. return 1;
  261. }
  262. // called from the metamethod for __newindex
  263. // the object pointer is passed on the lua stack
  264. // lua stack: userdata, key, value
  265. bool luabind::detail::class_rep::settable(lua_State* L)
  266. {
  267. // if the key is 'nil' fail
  268. if (lua_isnil(L, 2)) return false;
  269. // we have to ignore the first argument since this may point to
  270. // a method that is not present in this class (but in a subclass)
  271. const char* key = lua_tostring(L, 2);
  272. if (std::strlen(key) == lua_strlen(L, 2))
  273. {
  274. std::map<const char*, callback, ltstr>::iterator j = m_setters.find(key);
  275. if (j != m_setters.end())
  276. {
  277. // the name is a data member
  278. #ifndef LUABIND_NO_ERROR_CHECKING
  279. if (j->second.match(L, 3) < 0)
  280. {
  281. std::string msg("the attribute '");
  282. msg += m_name;
  283. msg += ".";
  284. msg += key;
  285. msg += "' is of type: ";
  286. j->second.sig(L, msg);
  287. msg += "\nand does not match: (";
  288. msg += stack_content_by_name(L, 3);
  289. msg += ")";
  290. lua_pushstring(L, msg.c_str());
  291. return false;
  292. }
  293. #endif
  294. j->second.func(L, j->second.pointer_offset);
  295. return true;
  296. }
  297. if (m_getters.find(key) != m_getters.end())
  298. {
  299. // this means that we have a getter but no
  300. // setter for an attribute. We will then fail
  301. // because that attribute is read-only
  302. std::string msg("the attribute '");
  303. msg += m_name;
  304. msg += ".";
  305. msg += key;
  306. msg += "' is read only";
  307. lua_pushstring(L, msg.c_str());
  308. return false;
  309. }
  310. }
  311. // set the attribute to the object's table
  312. object_rep* obj = static_cast<object_rep*>(lua_touserdata(L, 1));
  313. detail::lua_reference& tbl = obj->get_lua_table();
  314. if (!tbl.is_valid())
  315. {
  316. // this is the first time we are trying to add
  317. // a member to this instance, create the table.
  318. lua_newtable(L);
  319. lua_pushvalue(L, -1);
  320. tbl.set(L);
  321. }
  322. else
  323. {
  324. tbl.get(L);
  325. }
  326. lua_pushvalue(L, 2);
  327. lua_pushvalue(L, 3);
  328. lua_settable(L, 4);
  329. lua_pop(L, 3);
  330. return true;
  331. }
  332. int class_rep::gettable_dispatcher(lua_State* L)
  333. {
  334. object_rep* obj = static_cast<object_rep*>(lua_touserdata(L, 1));
  335. return obj->crep()->gettable(L);
  336. }
  337. // this is called as __newindex metamethod on every instance of this class
  338. int luabind::detail::class_rep::settable_dispatcher(lua_State* L)
  339. {
  340. object_rep* obj = static_cast<object_rep*>(lua_touserdata(L, 1));
  341. bool success = obj->crep()->settable(L);
  342. #ifndef LUABIND_NO_ERROR_CHECKING
  343. if (!success)
  344. {
  345. // class_rep::settable() will leave
  346. // error message on the stack in case
  347. // of failure
  348. lua_error(L);
  349. }
  350. #endif
  351. return 0;
  352. }
  353. int luabind::detail::class_rep::operator_dispatcher(lua_State* L)
  354. {
  355. for (int i = 0; i < 2; ++i)
  356. {
  357. if (is_class_object(L, 1 + i))
  358. {
  359. int nargs = lua_gettop(L);
  360. lua_pushvalue(L, lua_upvalueindex(1));
  361. lua_gettable(L, 1 + i);
  362. if (lua_isnil(L, -1))
  363. {
  364. lua_pop(L, 1);
  365. continue;
  366. }
  367. lua_insert(L, 1); // move the function to the bottom
  368. nargs = lua_toboolean(L, lua_upvalueindex(2)) ? 1 : nargs;
  369. if (lua_toboolean(L, lua_upvalueindex(2))) // remove trailing nil
  370. lua_remove(L, 3);
  371. lua_call(L, nargs, 1);
  372. return 1;
  373. }
  374. }
  375. lua_pop(L, lua_gettop(L));
  376. lua_pushstring(L, "No such operator defined");
  377. lua_error(L);
  378. return 0;
  379. }
  380. // this is called as metamethod __call on the class_rep.
  381. int luabind::detail::class_rep::constructor_dispatcher(lua_State* L)
  382. {
  383. class_rep* crep = static_cast<class_rep*>(lua_touserdata(L, 1));
  384. construct_rep* rep = &crep->m_constructor;
  385. bool ambiguous = false;
  386. int match_index = -1;
  387. int min_match = std::numeric_limits<int>::max();
  388. bool found;
  389. #ifdef LUABIND_NO_ERROR_CHECKING
  390. if (rep->overloads.size() == 1)
  391. {
  392. match_index = 0;
  393. found = true;
  394. }
  395. else
  396. {
  397. #endif
  398. int num_params = lua_gettop(L) - 1;
  399. overload_rep_base const* first =
  400. rep->overloads.empty() ? 0 : &rep->overloads.front();
  401. found = find_best_match(L, first, rep->overloads.size(), sizeof(construct_rep::overload_t), ambiguous, min_match, match_index, num_params);
  402. #ifdef LUABIND_NO_ERROR_CHECKING
  403. }
  404. #else
  405. if (!found)
  406. {
  407. {
  408. std::string msg("no constructor of '");
  409. msg += crep->name();
  410. msg += "' matched the arguments (";
  411. msg += stack_content_by_name(L, 2);
  412. msg += ")\n candidates are:\n";
  413. msg += get_overload_signatures(L, rep->overloads.begin(), rep->overloads.end(), crep->name());
  414. lua_pushstring(L, msg.c_str());
  415. }
  416. lua_error(L);
  417. }
  418. else if (ambiguous)
  419. {
  420. {
  421. std::string msg("call of overloaded constructor '");
  422. msg += crep->m_name;
  423. msg += "(";
  424. msg += stack_content_by_name(L, 2);
  425. msg += ")' is ambiguous\nnone of the overloads have a best conversion:\n";
  426. std::vector<const overload_rep_base*> candidates;
  427. find_exact_match(L, &rep->overloads.front(), rep->overloads.size(), sizeof(construct_rep::overload_t), min_match, num_params, candidates);
  428. msg += get_overload_signatures_candidates(L, candidates.begin(), candidates.end(), crep->name());
  429. lua_pushstring(L, msg.c_str());
  430. }
  431. lua_error(L);
  432. }
  433. #endif
  434. #ifndef LUABIND_NO_EXCEPTIONS
  435. try
  436. {
  437. #endif
  438. void* obj_rep;
  439. void* held;
  440. boost::tie(obj_rep,held) = crep->allocate(L);
  441. weak_ref backref(L, -1);
  442. void* object_ptr = rep->overloads[match_index].construct(L, backref);
  443. if (crep->has_holder())
  444. {
  445. crep->m_construct_holder(held, object_ptr);
  446. object_ptr = held;
  447. }
  448. new(obj_rep) object_rep(object_ptr, crep, object_rep::owner, crep->destructor());
  449. detail::getref(L, crep->m_instance_metatable);
  450. lua_setmetatable(L, -2);
  451. return 1;
  452. #ifndef LUABIND_NO_EXCEPTIONS
  453. }
  454. catch(const error&)
  455. {
  456. }
  457. catch(const std::exception& e)
  458. {
  459. lua_pushstring(L, e.what());
  460. }
  461. catch(const char* s)
  462. {
  463. lua_pushstring(L, s);
  464. }
  465. catch(...)
  466. {
  467. {
  468. std::string msg = crep->name();
  469. msg += "() threw an exception";
  470. lua_pushstring(L, msg.c_str());
  471. }
  472. }
  473. // we can only reach this line if an exception was thrown
  474. lua_error(L);
  475. return 0; // will never be reached
  476. #endif
  477. }
  478. /*
  479. the functions dispatcher assumes the following:
  480. upvalues:
  481. 1: method_rep* method, points to the method_rep that this dispatcher is to call
  482. 2: boolean force_static, is true if this is to be a static call
  483. and false if it is a normal call (= virtual if possible).
  484. stack:
  485. 1: object_rep* self, points to the object the call is being made on
  486. */
  487. int luabind::detail::class_rep::function_dispatcher(lua_State* L)
  488. {
  489. #ifndef NDEBUG
  490. /* lua_Debug tmp_;
  491. assert(lua_getinfo(L, "u", &tmp_));
  492. assert(tmp_.nups == 2);*/
  493. assert(lua_type(L, lua_upvalueindex(1)) == LUA_TLIGHTUSERDATA);
  494. assert(lua_type(L, lua_upvalueindex(2)) == LUA_TBOOLEAN);
  495. assert(lua_type(L, lua_upvalueindex(3)) == LUA_TLIGHTUSERDATA);
  496. assert(lua_touserdata(L, lua_upvalueindex(3)) == reinterpret_cast<void*>(0x1337));
  497. // assert(lua_type(L, 1) == LUA_TUSERDATA);
  498. #endif
  499. method_rep* rep = static_cast<method_rep*>(lua_touserdata(L, lua_upvalueindex(1)));
  500. int force_static_call = lua_toboolean(L, lua_upvalueindex(2));
  501. bool ambiguous = false;
  502. int match_index = -1;
  503. int min_match = std::numeric_limits<int>::max();
  504. bool found;
  505. #ifdef LUABIND_NO_ERROR_CHECKING
  506. if (rep->overloads().size() == 1)
  507. {
  508. match_index = 0;
  509. }
  510. else
  511. {
  512. #endif
  513. int num_params = lua_gettop(L) /*- 1*/;
  514. found = find_best_match(L, &rep->overloads().front(), rep->overloads().size()
  515. , sizeof(overload_rep), ambiguous, min_match, match_index, num_params);
  516. #ifdef LUABIND_NO_ERROR_CHECKING
  517. }
  518. #else
  519. if (!found)
  520. {
  521. {
  522. std::string msg = "no overload of '";
  523. msg += rep->crep->name();
  524. msg += ":";
  525. msg += rep->name;
  526. msg += "' matched the arguments (";
  527. msg += stack_content_by_name(L, 1);
  528. msg += ")\ncandidates are:\n";
  529. std::string function_name;
  530. function_name += rep->crep->name();
  531. function_name += ":";
  532. function_name += rep->name;
  533. msg += get_overload_signatures(L, rep->overloads().begin()
  534. , rep->overloads().end(), function_name);
  535. lua_pushstring(L, msg.c_str());
  536. }
  537. lua_error(L);
  538. }
  539. else if (ambiguous)
  540. {
  541. {
  542. std::string msg = "call of overloaded '";
  543. msg += rep->crep->name();
  544. msg += ":";
  545. msg += rep->name;
  546. msg += "(";
  547. msg += stack_content_by_name(L, 1);
  548. msg += ")' is ambiguous\nnone of the overloads have a best conversion:\n";
  549. std::vector<const overload_rep_base*> candidates;
  550. find_exact_match(L, &rep->overloads().front(), rep->overloads().size()
  551. , sizeof(overload_rep), min_match, num_params, candidates);
  552. std::string function_name;
  553. function_name += rep->crep->name();
  554. function_name += ":";
  555. function_name += rep->name;
  556. msg += get_overload_signatures_candidates(L, candidates.begin()
  557. , candidates.end(), function_name);
  558. lua_pushstring(L, msg.c_str());
  559. }
  560. lua_error(L);
  561. }
  562. #endif
  563. #ifndef LUABIND_NO_EXCEPTIONS
  564. try
  565. {
  566. #endif
  567. const overload_rep& o = rep->overloads()[match_index];
  568. if (force_static_call && !o.has_static())
  569. {
  570. lua_pushstring(L, "pure virtual function called");
  571. }
  572. else
  573. {
  574. return o.call(L, force_static_call != 0);
  575. }
  576. #ifndef LUABIND_NO_EXCEPTIONS
  577. }
  578. catch(const error&)
  579. {
  580. }
  581. catch(const std::exception& e)
  582. {
  583. lua_pushstring(L, e.what());
  584. }
  585. catch (const char* s)
  586. {
  587. lua_pushstring(L, s);
  588. }
  589. catch(...)
  590. {
  591. std::string msg = rep->crep->name();
  592. msg += ":";
  593. msg += rep->name;
  594. msg += "() threw an exception";
  595. lua_pushstring(L, msg.c_str());
  596. }
  597. #endif
  598. // we can only reach this line if an error occured
  599. lua_error(L);
  600. return 0; // will never be reached
  601. }
  602. #ifndef NDEBUG
  603. #ifndef BOOST_NO_STRINGSTREAM
  604. #include <sstream>
  605. #else
  606. #include <strstream>
  607. #endif
  608. namespace
  609. {
  610. std::string to_string(luabind::object const& o)
  611. {
  612. using namespace luabind;
  613. if (type(o) == LUA_TSTRING) return object_cast<std::string>(o);
  614. lua_State* L = o.interpreter();
  615. LUABIND_CHECK_STACK(L);
  616. #ifdef BOOST_NO_STRINGSTREAM
  617. std::strstream s;
  618. #else
  619. std::stringstream s;
  620. #endif
  621. if (type(o) == LUA_TNUMBER)
  622. {
  623. s << object_cast<float>(o);
  624. return s.str();
  625. }
  626. s << "<" << lua_typename(L, type(o)) << ">";
  627. #ifdef BOOST_NO_STRINGSTREAM
  628. s << std::ends;
  629. #endif
  630. return s.str();
  631. }
  632. std::string member_to_string(luabind::object const& e)
  633. {
  634. #if !defined(LUABIND_NO_ERROR_CHECKING)
  635. using namespace luabind;
  636. lua_State* L = e.interpreter();
  637. LUABIND_CHECK_STACK(L);
  638. if (type(e) == LUA_TFUNCTION)
  639. {
  640. e.push(L);
  641. detail::stack_pop p(L, 1);
  642. {
  643. if (lua_getupvalue(L, -1, 3) == 0) return to_string(e);
  644. detail::stack_pop p2(L, 1);
  645. if (lua_touserdata(L, -1) != reinterpret_cast<void*>(0x1337)) return to_string(e);
  646. }
  647. #ifdef BOOST_NO_STRINGSTREAM
  648. std::strstream s;
  649. #else
  650. std::stringstream s;
  651. #endif
  652. {
  653. lua_getupvalue(L, -1, 2);
  654. detail::stack_pop p2(L, 1);
  655. int b = lua_toboolean(L, -1);
  656. s << "<c++ function";
  657. if (b) s << " (default)";
  658. s << "> ";
  659. }
  660. {
  661. lua_getupvalue(L, -1, 1);
  662. detail::stack_pop p2(L, 1);
  663. method_rep* m = static_cast<method_rep*>(lua_touserdata(L, -1));
  664. s << m << "\n";
  665. for (std::vector<overload_rep>::const_iterator i = m->overloads().begin();
  666. i != m->overloads().end(); ++i)
  667. {
  668. std::string str;
  669. i->get_signature(L, str);
  670. s << " " << str << "\n";
  671. }
  672. }
  673. #ifdef BOOST_NO_STRINGSTREAM
  674. s << std::ends;
  675. #endif
  676. return s.str();
  677. }
  678. return to_string(e);
  679. #else
  680. return "";
  681. #endif
  682. }
  683. }
  684. std::string luabind::detail::class_rep::class_info_string(lua_State* L) const
  685. {
  686. #ifdef BOOST_NO_STRINGSTREAM
  687. std::strstream ret;
  688. #else
  689. std::stringstream ret;
  690. #endif
  691. ret << "CLASS: " << m_name << "\n";
  692. ret << "dynamic dispatch functions:\n------------------\n";
  693. for (luabind::iterator i(m_table), end; i != end; ++i)
  694. {
  695. luabind::object e = *i;
  696. ret << " " << to_string(i.key()) << ": " << member_to_string(e) << "\n";
  697. }
  698. ret << "default implementations:\n------------------\n";
  699. for (luabind::iterator i(m_default_table), end; i != end; ++i)
  700. {
  701. luabind::object e = *i;
  702. ret << " " << to_string(i.key()) << ": " << member_to_string(e) << "\n";
  703. }
  704. #ifdef BOOST_NO_STRINGSTREAM
  705. ret << std::ends;
  706. #endif
  707. return ret.str();
  708. }
  709. #endif
  710. void luabind::detail::class_rep::add_base_class(const luabind::detail::class_rep::base_info& binfo)
  711. {
  712. // If you hit this assert you are deriving from a type that is not registered
  713. // in lua. That is, in the class_<> you are giving a baseclass that isn't registered.
  714. // Please note that if you don't need to have access to the base class or the
  715. // conversion from the derived class to the base class, you don't need
  716. // to tell luabind that it derives.
  717. assert(binfo.base && "You cannot derive from an unregistered type");
  718. class_rep* bcrep = binfo.base;
  719. // import all functions from the base
  720. typedef std::list<detail::method_rep> methods_t;
  721. for (methods_t::const_iterator i = bcrep->m_methods.begin();
  722. i != bcrep->m_methods.end(); ++i)
  723. {
  724. add_method(*i);
  725. }
  726. // import all getters from the base
  727. for (std::map<const char*, callback, ltstr>::const_iterator i = bcrep->m_getters.begin();
  728. i != bcrep->m_getters.end(); ++i)
  729. {
  730. callback& m = m_getters[i->first];
  731. m.pointer_offset = i->second.pointer_offset + binfo.pointer_offset;
  732. m.func = i->second.func;
  733. #ifndef LUABIND_NO_ERROR_CHECKING
  734. m.match = i->second.match;
  735. m.sig = i->second.sig;
  736. #endif
  737. }
  738. // import all setters from the base
  739. for (std::map<const char*, callback, ltstr>::const_iterator i = bcrep->m_setters.begin();
  740. i != bcrep->m_setters.end(); ++i)
  741. {
  742. callback& m = m_setters[i->first];
  743. m.pointer_offset = i->second.pointer_offset + binfo.pointer_offset;
  744. m.func = i->second.func;
  745. #ifndef LUABIND_NO_ERROR_CHECKING
  746. m.match = i->second.match;
  747. m.sig = i->second.sig;
  748. #endif
  749. }
  750. // import all static constants
  751. for (std::map<const char*, int, ltstr>::const_iterator i = bcrep->m_static_constants.begin();
  752. i != bcrep->m_static_constants.end(); ++i)
  753. {
  754. int& v = m_static_constants[i->first];
  755. v = i->second;
  756. }
  757. // import all operators
  758. for (int i = 0; i < number_of_operators; ++i)
  759. {
  760. for (std::vector<operator_callback>::const_iterator j = bcrep->m_operators[i].begin();
  761. j != bcrep->m_operators[i].end(); ++j)
  762. m_operators[i].push_back(*j);
  763. }
  764. // also, save the baseclass info to be used for typecasts
  765. m_bases.push_back(binfo);
  766. }
  767. int luabind::detail::class_rep::super_callback(lua_State* L)
  768. {
  769. int args = lua_gettop(L);
  770. object_rep* obj = static_cast<object_rep*>(lua_touserdata(L, lua_upvalueindex(2)));
  771. class_rep* crep = static_cast<class_rep*>(lua_touserdata(L, lua_upvalueindex(1)));
  772. class_rep* base = crep->bases()[0].base;
  773. if (base->get_class_type() == class_rep::lua_class)
  774. {
  775. if (base->bases().empty())
  776. {
  777. obj->set_flags(obj->flags() & ~object_rep::call_super);
  778. lua_pushstring(L, "super");
  779. lua_pushnil(L);
  780. lua_settable(L, LUA_GLOBALSINDEX);
  781. }
  782. else
  783. {
  784. lua_pushstring(L, "super");
  785. lua_pushlightuserdata(L, base);
  786. lua_pushvalue(L, lua_upvalueindex(2));
  787. lua_pushcclosure(L, super_callback, 2);
  788. lua_settable(L, LUA_GLOBALSINDEX);
  789. }
  790. base->get_table(L);
  791. lua_pushstring(L, "__init");
  792. lua_gettable(L, -2);
  793. lua_insert(L, 1);
  794. lua_pop(L, 1);
  795. lua_pushvalue(L, lua_upvalueindex(2));
  796. lua_insert(L, 2);
  797. lua_call(L, args + 1, 0);
  798. // TODO: instead of clearing the global variable "super"
  799. // store it temporarily in the registry. maybe we should
  800. // have some kind of warning if the super global is used?
  801. lua_pushstring(L, "super");
  802. lua_pushnil(L);
  803. lua_settable(L, LUA_GLOBALSINDEX);
  804. }
  805. else
  806. {
  807. obj->set_flags(obj->flags() & ~object_rep::call_super);
  808. // we need to push some garbage at index 1 to make the construction work
  809. lua_pushboolean(L, 1);
  810. lua_insert(L, 1);
  811. construct_rep* rep = &base->m_constructor;
  812. bool ambiguous = false;
  813. int match_index = -1;
  814. int min_match = std::numeric_limits<int>::max();
  815. bool found;
  816. #ifdef LUABIND_NO_ERROR_CHECKING
  817. if (rep->overloads.size() == 1)
  818. {
  819. match_index = 0;
  820. }
  821. else
  822. {
  823. #endif
  824. int num_params = lua_gettop(L) - 1;
  825. found = find_best_match(L, &rep->overloads.front(), rep->overloads.size(), sizeof(construct_rep::overload_t), ambiguous, min_match, match_index, num_params);
  826. #ifdef LUABIND_NO_ERROR_CHECKING
  827. }
  828. #else
  829. if (!found)
  830. {
  831. {
  832. std::string msg = "no constructor of '";
  833. msg += base->m_name;
  834. msg += "' matched the arguments (";
  835. msg += stack_content_by_name(L, 2);
  836. msg += ")";
  837. lua_pushstring(L, msg.c_str());
  838. }
  839. lua_error(L);
  840. }
  841. else if (ambiguous)
  842. {
  843. {
  844. std::string msg = "call of overloaded constructor '";
  845. msg += base->m_name;
  846. msg += "(";
  847. msg += stack_content_by_name(L, 2);
  848. msg += ")' is ambiguous";
  849. lua_pushstring(L, msg.c_str());
  850. }
  851. lua_error(L);
  852. }
  853. // TODO: should this be a warning or something?
  854. /*
  855. // since the derived class is a lua class
  856. // it may have reimplemented virtual functions
  857. // therefore, we have to instantiate the Basewrapper
  858. // if there is no basewrapper, throw a run-time error
  859. if (!rep->overloads[match_index].has_wrapped_construct())
  860. {
  861. {
  862. std::string msg = "Cannot derive from C++ class '";
  863. msg += base->name();
  864. msg += "'. It does not have a wrapped type";
  865. lua_pushstring(L, msg.c_str());
  866. }
  867. lua_error(L);
  868. }
  869. */
  870. #endif
  871. #ifndef LUABIND_NO_EXCEPTIONS
  872. try
  873. {
  874. #endif
  875. lua_pushvalue(L, lua_upvalueindex(2));
  876. weak_ref backref(L, -1);
  877. lua_pop(L, 1);
  878. void* storage_ptr = obj->ptr();
  879. if (!rep->overloads[match_index].has_wrapped_construct())
  880. {
  881. // if the type doesn't have a wrapped type, use the ordinary constructor
  882. void* instance = rep->overloads[match_index].construct(L, backref);
  883. if (crep->has_holder())
  884. {
  885. crep->m_construct_holder(storage_ptr, instance);
  886. }
  887. else
  888. {
  889. obj->set_object(instance);
  890. }
  891. }
  892. else
  893. {
  894. // get reference to lua object
  895. /* lua_pushvalue(L, lua_upvalueindex(2));
  896. detail::lua_reference ref;
  897. ref.set(L);
  898. void* instance = rep->overloads[match_index].construct_wrapped(L, ref);*/
  899. void* instance = rep->overloads[match_index].construct_wrapped(L, backref);
  900. if (crep->has_holder())
  901. {
  902. crep->m_construct_holder(storage_ptr, instance);
  903. }
  904. else
  905. {
  906. obj->set_object(instance);
  907. }
  908. }
  909. // TODO: is the wrapped type destructed correctly?
  910. // it should, since the destructor is either the wrapped type's
  911. // destructor or the base type's destructor, depending on wether
  912. // the type has a wrapped type or not.
  913. obj->set_destructor(base->destructor());
  914. return 0;
  915. #ifndef LUABIND_NO_EXCEPTIONS
  916. }
  917. catch(const error&)
  918. {
  919. }
  920. catch(const std::exception& e)
  921. {
  922. lua_pushstring(L, e.what());
  923. }
  924. catch(const char* s)
  925. {
  926. lua_pushstring(L, s);
  927. }
  928. catch(...)
  929. {
  930. std::string msg = base->m_name;
  931. msg += "() threw an exception";
  932. lua_pushstring(L, msg.c_str());
  933. }
  934. // can only be reached if an exception was thrown
  935. lua_error(L);
  936. #endif
  937. }
  938. return 0;
  939. }
  940. int luabind::detail::class_rep::lua_settable_dispatcher(lua_State* L)
  941. {
  942. class_rep* crep = static_cast<class_rep*>(lua_touserdata(L, 1));
  943. // get first table
  944. crep->get_table(L);
  945. // copy key, value
  946. lua_pushvalue(L, -3);
  947. lua_pushvalue(L, -3);
  948. lua_rawset(L, -3);
  949. // pop table
  950. lua_pop(L, 1);
  951. // get default table
  952. crep->get_default_table(L);
  953. lua_replace(L, 1);
  954. lua_rawset(L, -3);
  955. crep->m_operator_cache = 0; // invalidate cache
  956. return 0;
  957. }
  958. int luabind::detail::class_rep::construct_lua_class_callback(lua_State* L)
  959. {
  960. class_rep* crep = static_cast<class_rep*>(lua_touserdata(L, 1));
  961. int args = lua_gettop(L);
  962. // lua stack: crep <arguments>
  963. lua_newtable(L);
  964. detail::lua_reference ref;
  965. ref.set(L);
  966. bool has_bases = !crep->bases().empty();
  967. if (has_bases)
  968. {
  969. lua_pushstring(L, "super");
  970. lua_pushvalue(L, 1); // crep
  971. }
  972. // lua stack: crep <arguments> "super" crep
  973. // or
  974. // lua stack: crep <arguments>
  975. // if we have a baseclass we set the flag to say that the super has not yet been called
  976. // we will use this flag later to check that it actually was called from __init()
  977. int flags = object_rep::lua_class | object_rep::owner | (has_bases ? object_rep::call_super : 0);
  978. // void* obj_ptr = lua_newuserdata(L, sizeof(object_rep));
  979. void* obj_ptr;
  980. void* held_storage;
  981. boost::tie(obj_ptr, held_storage) = crep->allocate(L);
  982. (new(obj_ptr) object_rep(crep, flags, ref))->set_object(held_storage);
  983. detail::getref(L, crep->metatable_ref());
  984. lua_setmetatable(L, -2);
  985. // lua stack: crep <arguments> "super" crep obj_ptr
  986. // or
  987. // lua stack: crep <arguments> obj_ptr
  988. if (has_bases) lua_pushvalue(L, -1); // obj_ptr
  989. lua_replace(L, 1); // obj_ptr
  990. // lua stack: obj_ptr <arguments> "super" crep obj_ptr
  991. // or
  992. // lua stack: obj_ptr <arguments>
  993. if (has_bases)
  994. {
  995. lua_pushcclosure(L, super_callback, 2);
  996. // lua stack: crep <arguments> "super" function
  997. lua_settable(L, LUA_GLOBALSINDEX);
  998. }
  999. // lua stack: crep <arguments>
  1000. lua_pushvalue(L, 1);
  1001. lua_insert(L, 1);
  1002. crep->get_table(L);
  1003. lua_pushstring(L, "__init");
  1004. lua_gettable(L, -2);
  1005. #ifndef LUABIND_NO_ERROR_CHECKING
  1006. // TODO: should this be a run-time error?
  1007. // maybe the default behavior should be to just call
  1008. // the base calss' constructor. We should register
  1009. // the super callback funktion as __init
  1010. if (!lua_isfunction(L, -1))
  1011. {
  1012. {
  1013. std::string msg = crep->name();
  1014. msg += ":__init is not defined";
  1015. lua_pushstring(L, msg.c_str());
  1016. }
  1017. lua_error(L);
  1018. }
  1019. #endif
  1020. lua_insert(L, 2); // function first on stack
  1021. lua_pop(L, 1);
  1022. // TODO: lua_call may invoke longjump! make sure we don't have any memory leaks!
  1023. // we don't have any stack objects here
  1024. lua_call(L, args, 0);
  1025. #ifndef LUABIND_NO_ERROR_CHECKING
  1026. object_rep* obj = static_cast<object_rep*>(obj_ptr);
  1027. if (obj->flags() & object_rep::call_super)
  1028. {
  1029. lua_pushstring(L, "derived class must call super on base");
  1030. lua_error(L);
  1031. }
  1032. #endif
  1033. return 1;
  1034. }
  1035. // called from the metamethod for __index
  1036. // obj is the object pointer
  1037. int luabind::detail::class_rep::lua_class_gettable(lua_State* L)
  1038. {
  1039. object_rep* obj = static_cast<object_rep*>(lua_touserdata(L, 1));
  1040. class_rep* crep = obj->crep();
  1041. #ifndef LUABIND_NO_ERROR_CHECKING
  1042. if (obj->flags() & object_rep::call_super)
  1043. {
  1044. lua_pushstring(L, "derived class must call super on base");
  1045. lua_error(L);
  1046. }
  1047. #endif
  1048. // we have to ignore the first argument since this may point to
  1049. // a method that is not present in this class (but in a subclass)
  1050. // BUG: This might catch members called "__ok\0foobar"
  1051. const char* key = lua_tostring(L, 2);
  1052. if (key && !std::strcmp(key, "__ok"))
  1053. {
  1054. class_rep* crep = obj->crep();
  1055. void* p = crep->extractor() ? crep->extractor()(obj->ptr())
  1056. : obj->ptr();
  1057. lua_pushboolean(L, p != 0);
  1058. return 1;
  1059. }
  1060. // first look in the instance's table
  1061. detail::lua_reference const& tbl = obj->get_lua_table();
  1062. assert(tbl.is_valid());
  1063. tbl.get(L);
  1064. lua_pushvalue(L, 2);
  1065. lua_gettable(L, -2);
  1066. if (!lua_isnil(L, -1))
  1067. {
  1068. lua_remove(L, -2); // remove table
  1069. return 1;
  1070. }
  1071. lua_pop(L, 2);
  1072. // then look in the class' table
  1073. crep->get_table(L);
  1074. lua_pushvalue(L, 2);
  1075. lua_gettable(L, -2);
  1076. if (!lua_isnil(L, -1))
  1077. {
  1078. lua_remove(L, -2); // more table
  1079. return 1;
  1080. }
  1081. lua_pop(L, 2);
  1082. if (lua_isnil(L, 2))
  1083. {
  1084. lua_pushnil(L);
  1085. return 1;
  1086. }
  1087. std::map<const char*, class_rep::callback, ltstr>::iterator j = crep->m_getters.find(key);
  1088. if (j != crep->m_getters.end())
  1089. {
  1090. // the name is a data member
  1091. return j->second.func(L, j->second.pointer_offset);
  1092. }
  1093. lua_pushnil(L);
  1094. return 1;
  1095. }
  1096. // called from the metamethod for __newindex
  1097. // obj is the object pointer
  1098. int luabind::detail::class_rep::lua_class_settable(lua_State* L)
  1099. {
  1100. object_rep* obj = static_cast<object_rep*>(lua_touserdata(L, 1));
  1101. class_rep* crep = obj->crep();
  1102. #ifndef LUABIND_NO_ERROR_CHECKING
  1103. if (obj->flags() & object_rep::call_super)
  1104. {
  1105. // this block makes sure the std::string is destructed
  1106. // before lua_error is called
  1107. {
  1108. std::string msg = "derived class '";
  1109. msg += crep->name();
  1110. msg += "'must call super on base";
  1111. lua_pushstring(L, msg.c_str());
  1112. }
  1113. lua_error(L);
  1114. }
  1115. #endif
  1116. // we have to ignore the first argument since this may point to
  1117. // a method that is not present in this class (but in a subclass)
  1118. // BUG: This will not work with keys with extra nulls in them
  1119. const char* key = lua_tostring(L, 2);
  1120. std::map<const char*, class_rep::callback, ltstr>::iterator j = crep->m_setters.find(key);
  1121. // if the strlen(key) is not the true length,
  1122. // it means that the member-name contains
  1123. // extra nulls. luabind does not support such
  1124. // names as member names. So, use the lua
  1125. // table as fall-back
  1126. if (j == crep->m_setters.end()
  1127. || std::strlen(key) != lua_strlen(L, 2))
  1128. {
  1129. std::map<const char*, class_rep::callback, ltstr>::iterator k = crep->m_getters.find(key);
  1130. #ifndef LUABIND_NO_ERROR_CHECKING
  1131. if (k != crep->m_getters.end())
  1132. {
  1133. {
  1134. std::string msg = "cannot set property '";
  1135. msg += crep->name();
  1136. msg += ".";
  1137. msg += key;
  1138. msg += "', because it's read only";
  1139. lua_pushstring(L, msg.c_str());
  1140. }
  1141. lua_error(L);
  1142. }
  1143. #endif
  1144. detail::lua_reference const& tbl = obj->get_lua_table();
  1145. assert(tbl.is_valid());
  1146. tbl.get(L);
  1147. lua_replace(L, 1);
  1148. lua_settable(L, 1);
  1149. }
  1150. else
  1151. {
  1152. // the name is a data member
  1153. j->second.func(L, j->second.pointer_offset);
  1154. }
  1155. return 0;
  1156. }
  1157. /*
  1158. stack:
  1159. 1: class_rep
  1160. 2: member name
  1161. */
  1162. int luabind::detail::class_rep::static_class_gettable(lua_State* L)
  1163. {
  1164. class_rep* crep = static_cast<class_rep*>(lua_touserdata(L, 1));
  1165. // look in the static function table
  1166. crep->get_default_table(L);
  1167. lua_pushvalue(L, 2);
  1168. lua_gettable(L, -2);
  1169. if (!lua_isnil(L, -1)) return 1;
  1170. else lua_pop(L, 2);
  1171. const char* key = lua_tostring(L, 2);
  1172. if (std::strlen(key) != lua_strlen(L, 2))
  1173. {
  1174. lua_pushnil(L);
  1175. return 1;
  1176. }
  1177. std::map<const char*, int, ltstr>::const_iterator j = crep->m_static_constants.find(key);
  1178. if (j != crep->m_static_constants.end())
  1179. {
  1180. lua_pushnumber(L, j->second);
  1181. return 1;
  1182. }
  1183. #ifndef LUABIND_NO_ERROR_CHECKING
  1184. {
  1185. std::string msg = "no static '";
  1186. msg += key;
  1187. msg += "' in class '";
  1188. msg += crep->name();
  1189. msg += "'";
  1190. lua_pushstring(L, msg.c_str());
  1191. }
  1192. lua_error(L);
  1193. #endif
  1194. lua_pushnil(L);
  1195. return 1;
  1196. }
  1197. bool luabind::detail::is_class_rep(lua_State* L, int index)
  1198. {
  1199. if (lua_getmetatable(L, index) == 0) return false;
  1200. lua_pushstring(L, "__luabind_classrep");
  1201. lua_gettable(L, -2);
  1202. if (lua_toboolean(L, -1))
  1203. {
  1204. lua_pop(L, 2);
  1205. return true;
  1206. }
  1207. lua_pop(L, 2);
  1208. return false;
  1209. }
  1210. void luabind::detail::finalize(lua_State* L, class_rep* crep)
  1211. {
  1212. if (crep->get_class_type() != class_rep::lua_class) return;
  1213. // lua_pushvalue(L, -1); // copy the object ref
  1214. crep->get_table(L);
  1215. lua_pushstring(L, "__finalize");
  1216. lua_gettable(L, -2);
  1217. lua_remove(L, -2);
  1218. if (lua_isnil(L, -1))
  1219. {
  1220. lua_pop(L, 1);
  1221. }
  1222. else
  1223. {
  1224. lua_pushvalue(L, -2);
  1225. lua_call(L, 1, 0);
  1226. }
  1227. for (std::vector<class_rep::base_info>::const_iterator
  1228. i = crep->bases().begin(); i != crep->bases().end(); ++i)
  1229. {
  1230. if (i->base) finalize(L, i->base);
  1231. }
  1232. }
  1233. void* luabind::detail::class_rep::convert_to(
  1234. LUABIND_TYPE_INFO target_type
  1235. , const object_rep* obj
  1236. , void* target_memory) const
  1237. {
  1238. // TODO: since this is a member function, we don't have to use the accesor functions for
  1239. // the types and the extractor
  1240. assert(obj == 0 || obj->crep() == this);
  1241. int steps = 0;
  1242. int offset = 0;
  1243. if (!(LUABIND_TYPE_INFO_EQUAL(holder_type(), target_type))
  1244. && !(LUABIND_TYPE_INFO_EQUAL(const_holder_type(), target_type)))
  1245. {
  1246. steps = implicit_cast(this, target_type, offset);
  1247. }
  1248. // should never be called with a type that can't be cast
  1249. assert((steps >= 0) && "internal error, please report");
  1250. if (LUABIND_TYPE_INFO_EQUAL(target_type, holder_type()))
  1251. {
  1252. if (obj == 0)
  1253. {
  1254. // we are trying to convert nil to a holder type
  1255. m_default_construct_holder(target_memory);
  1256. return target_memory;
  1257. }
  1258. // if the type we are trying to convert to is the holder_type
  1259. // it means that his crep has a holder_type (since it would have
  1260. // been invalid otherwise, and T cannot be invalid). It also means
  1261. // that we need no conversion, since the holder_type is what the
  1262. // object points to.
  1263. return obj->ptr();
  1264. }
  1265. if (LUABIND_TYPE_INFO_EQUAL(target_type, const_holder_type()))
  1266. {
  1267. if (obj == 0)
  1268. {
  1269. // we are trying to convert nil to a const holder type
  1270. m_default_construct_const_holder(target_memory);
  1271. return target_memory;
  1272. }
  1273. if (obj->flags() & object_rep::constant)
  1274. {
  1275. // we are holding a constant
  1276. return obj->ptr();
  1277. }
  1278. else
  1279. {
  1280. // we are holding a non-constant, we need to convert it
  1281. // to a const_holder.
  1282. m_const_converter(obj->ptr(), target_memory);
  1283. return target_memory;
  1284. }
  1285. }
  1286. void* raw_pointer;
  1287. if (has_holder())
  1288. {
  1289. assert(obj);
  1290. // this means that we have a holder type where the
  1291. // raw-pointer needs to be extracted
  1292. raw_pointer = extractor()(obj->ptr());
  1293. }
  1294. else
  1295. {
  1296. if (obj == 0) raw_pointer = 0;
  1297. else raw_pointer = obj->ptr();
  1298. }
  1299. return static_cast<char*>(raw_pointer) + offset;
  1300. }
  1301. void luabind::detail::class_rep::cache_operators(lua_State* L)
  1302. {
  1303. m_operator_cache = 0x1;
  1304. for (int i = 0; i < number_of_operators; ++i)
  1305. {
  1306. get_table(L);
  1307. lua_pushstring(L, get_operator_name(i));
  1308. lua_rawget(L, -2);
  1309. if (lua_isfunction(L, -1)) m_operator_cache |= 1 << (i + 1);
  1310. lua_pop(L, 2);
  1311. }
  1312. }
  1313. bool luabind::detail::class_rep::has_operator_in_lua(lua_State* L, int id)
  1314. {
  1315. if ((m_operator_cache & 0x1) == 0)
  1316. cache_operators(L);
  1317. const int mask = 1 << (id + 1);
  1318. return (m_operator_cache & mask) != 0;
  1319. }
  1320. // this will merge all overloads of fun into the list of
  1321. // overloads in this class
  1322. void luabind::detail::class_rep::add_method(luabind::detail::method_rep const& fun)
  1323. {
  1324. typedef std::list<detail::method_rep> methods_t;
  1325. methods_t::iterator m = std::find_if(
  1326. m_methods.begin()
  1327. , m_methods.end()
  1328. , method_name(fun.name));
  1329. if (m == m_methods.end())
  1330. {
  1331. m_methods.push_back(method_rep());
  1332. m = m_methods.end();
  1333. std::advance(m, -1);
  1334. m->name = fun.name;
  1335. }
  1336. m->crep = this;
  1337. typedef std::vector<detail::overload_rep> overloads_t;
  1338. for (overloads_t::const_iterator j = fun.overloads().begin();
  1339. j != fun.overloads().end(); ++j)
  1340. {
  1341. detail::overload_rep o = *j;
  1342. m->add_overload(o);
  1343. }
  1344. }
  1345. // this function will add all the overloads in method rep to
  1346. // this class' lua tables. If there already are overloads with this
  1347. // name, thses will simply be appended to the overload list
  1348. void luabind::detail::class_rep::register_methods(lua_State* L)
  1349. {
  1350. LUABIND_CHECK_STACK(L);
  1351. // insert the function in the normal member table
  1352. // and in the default member table
  1353. m_default_table.push(L);
  1354. m_table.push(L);
  1355. // pops the tables
  1356. detail::stack_pop pop_tables(L, 2);
  1357. for (std::list<method_rep>::const_iterator m = m_methods.begin();
  1358. m != m_methods.end(); ++m)
  1359. {
  1360. // create the function closure in m_table
  1361. lua_pushstring(L, m->name);
  1362. lua_pushlightuserdata(L, const_cast<void*>((const void*)&(*m)));
  1363. lua_pushboolean(L, 0);
  1364. lua_pushlightuserdata(L, reinterpret_cast<void*>(0x1337));
  1365. lua_pushcclosure(L, function_dispatcher, 3);
  1366. lua_settable(L, -3);
  1367. // create the function closure in m_default_table
  1368. lua_pushstring(L, m->name);
  1369. lua_pushlightuserdata(L, const_cast<void*>((const void*)&(*m)));
  1370. lua_pushboolean(L, 1);
  1371. lua_pushlightuserdata(L, reinterpret_cast<void*>(0x1337));
  1372. lua_pushcclosure(L, function_dispatcher, 3);
  1373. lua_settable(L, -4);
  1374. }
  1375. }
  1376. const class_rep::property_map& luabind::detail::class_rep::properties() const
  1377. {
  1378. return m_getters;
  1379. }