FunctionBinding.cpp 41 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032
  1. #include "FunctionBinding.h"
  2. #include "Generator.h"
  3. // Helper functions.
  4. static inline void outputLuaTypeCheckInstance(ostream& o);
  5. static inline void outputLuaTypeCheck(ostream& o, int index, const FunctionBinding::Param& p =
  6. FunctionBinding::Param(FunctionBinding::Param::TYPE_OBJECT, FunctionBinding::Param::KIND_POINTER));
  7. static inline void indent(ostream& o, int indentLevel);
  8. static inline void outputBindingInvocation(ostream& o, const FunctionBinding& b, unsigned int paramCount, unsigned int indentLevel, int numBindings);
  9. static inline void outputGetParam(ostream& o, const FunctionBinding::Param& p, int i, int indentLevel, bool offsetIndex, int numBindings);
  10. static inline void outputMatchedBinding(ostream& o, const FunctionBinding& b, unsigned int paramCount, unsigned int indentLevel, int numBindings);
  11. static inline void outputReturnValue(ostream& o, const FunctionBinding& b, int indentLevel);
  12. static inline std::string getTypeName(const FunctionBinding::Param& param);
  13. FunctionBinding::Param::Param(FunctionBinding::Param::Type type, Kind kind, const string& info) :
  14. type(type), kind(kind), info(info), hasDefaultValue(false), levelsOfIndirection(0)
  15. {
  16. }
  17. bool FunctionBinding::Param::operator==(const Param& p) const
  18. {
  19. return this->type == p.type && this->kind == p.kind && this->info == p.info;
  20. }
  21. bool FunctionBinding::Param::operator!=(const Param& p) const
  22. {
  23. return !(*this == p);
  24. }
  25. FunctionBinding::FunctionBinding(string classname, string uniquename) : classname(classname), uniquename(uniquename), name(""), own(false)
  26. {
  27. }
  28. string FunctionBinding::getFunctionName() const
  29. {
  30. if (functionName.length() == 0)
  31. {
  32. functionName = "lua_";
  33. functionName += uniquename;
  34. if (type == STATIC_FUNCTION ||
  35. type == STATIC_CONSTANT ||
  36. type == STATIC_VARIABLE)
  37. functionName += "_static";
  38. functionName += "_";
  39. if (returnParam.type == Param::TYPE_CONSTRUCTOR)
  40. functionName += "_init";
  41. else if (returnParam.type == Param::TYPE_DESTRUCTOR)
  42. functionName += "_gc";
  43. else
  44. {
  45. size_t i = name.rfind("::");
  46. if (i != name.npos)
  47. functionName += name.substr(i + 2);
  48. else
  49. functionName += name;
  50. }
  51. }
  52. return functionName;
  53. }
  54. unsigned int FunctionBinding::getMinParamCount() const
  55. {
  56. for (unsigned int i = 0; i < paramTypes.size(); i++)
  57. {
  58. if (paramTypes[i].hasDefaultValue)
  59. return i;
  60. }
  61. return paramTypes.size();
  62. }
  63. void FunctionBinding::write(ostream& o, const vector<FunctionBinding>& bindings)
  64. {
  65. GP_ASSERT(bindings.size() > 0);
  66. if (bindings[0].getFunctionName() == "lua_AudioListener_static_getInstance")
  67. {
  68. int i = 0;
  69. }
  70. // Print the function signature.
  71. o << "int " << bindings[0].getFunctionName() << "(lua_State* state)\n";
  72. o << "{\n";
  73. if (bindings.size() == 1 && bindings[0].type == FunctionBinding::MEMBER_VARIABLE)
  74. {
  75. // Validate the parameter count.
  76. o << " // Validate the number of parameters.\n";
  77. o << " if (lua_gettop(state) > 2)\n";
  78. o << " {\n";
  79. o << " lua_pushstring(state, \"Invalid number of parameters (expected 1 or 2).\");\n";
  80. o << " lua_error(state);\n";
  81. o << " }\n\n";
  82. // Get or set the member variable depending on the number of parameters.
  83. o << " " << bindings[0].classname << "* instance = getInstance(state);\n";
  84. o << " if (lua_gettop(state) == 2)\n";
  85. o << " {\n";
  86. outputGetParam(o, bindings[0].returnParam, 1, 2, false, 1);
  87. if (bindings[0].returnParam.kind == FunctionBinding::Param::KIND_POINTER &&
  88. bindings[0].returnParam.type != FunctionBinding::Param::TYPE_OBJECT &&
  89. bindings[0].returnParam.info.size() > 0)
  90. {
  91. o << " memcpy(instance->" << bindings[0].name << ", param2, sizeof(";
  92. o << FunctionBinding::Param(bindings[0].returnParam.type) << ") * " << bindings[0].returnParam.info << ");\n";
  93. }
  94. else
  95. {
  96. o << " instance->" << bindings[0].name << " = ";
  97. if (bindings[0].returnParam.type == FunctionBinding::Param::TYPE_OBJECT &&
  98. bindings[0].returnParam.kind != FunctionBinding::Param::KIND_POINTER)
  99. {
  100. o << "*";
  101. }
  102. o << "param2;\n";
  103. }
  104. o << " return 0;\n";
  105. o << " }\n";
  106. o << " else\n";
  107. o << " {\n";
  108. // Pass the return value back to Lua.
  109. if (bindings[0].returnParam.type == FunctionBinding::Param::TYPE_OBJECT)
  110. {
  111. switch (bindings[0].returnParam.kind)
  112. {
  113. case FunctionBinding::Param::KIND_POINTER:
  114. o << " void* returnPtr = (void*)instance->" << bindings[0].name << ";\n";
  115. break;
  116. case FunctionBinding::Param::KIND_VALUE:
  117. o << " void* returnPtr = (void*)new " << bindings[0].returnParam << "(instance->" << bindings[0].name << ");\n";
  118. break;
  119. case FunctionBinding::Param::KIND_REFERENCE:
  120. o << " void* returnPtr = (void*)&(instance->" << bindings[0].name << ");\n";
  121. break;
  122. default:
  123. GP_ERROR("Invalid return value kind '%d'.", bindings[0].returnParam.kind);
  124. break;
  125. }
  126. }
  127. else
  128. {
  129. o << " " << bindings[0].returnParam << " result = instance->" << bindings[0].name << ";\n";
  130. }
  131. outputReturnValue(o, bindings[0], 2);
  132. o << " }\n";
  133. o << "}\n\n";
  134. }
  135. else if (bindings.size() == 1 &&
  136. (bindings[0].type == FunctionBinding::STATIC_VARIABLE ||
  137. bindings[0].type == FunctionBinding::GLOBAL_VARIABLE))
  138. {
  139. // Validate the parameter count.
  140. o << " // Validate the number of parameters.\n";
  141. o << " if (lua_gettop(state) > 1)\n";
  142. o << " {\n";
  143. o << " lua_pushstring(state, \"Invalid number of parameters (expected 0 or 1).\");\n";
  144. o << " lua_error(state);\n";
  145. o << " }\n\n";
  146. // Get or set the static variable depending on the number of parameters.
  147. o << " if (lua_gettop(state) == 1)\n";
  148. o << " {\n";
  149. outputGetParam(o, bindings[0].returnParam, 0, 2, false, 1);
  150. if (bindings[0].returnParam.kind == FunctionBinding::Param::KIND_POINTER &&
  151. bindings[0].returnParam.type != FunctionBinding::Param::TYPE_OBJECT &&
  152. bindings[0].returnParam.info.size() > 0)
  153. {
  154. o << " memcpy(";
  155. if (bindings[0].classname.size() > 0)
  156. o << bindings[0].classname << "::";
  157. o << bindings[0].name << ", param1, sizeof(";
  158. o << FunctionBinding::Param(bindings[0].returnParam.type) << ") * " << bindings[0].returnParam.info << ");\n";
  159. }
  160. else
  161. {
  162. o << " ";
  163. if (bindings[0].classname.size() > 0)
  164. o << bindings[0].classname << "::";
  165. o << bindings[0].name << " = ";
  166. if (bindings[0].returnParam.type == FunctionBinding::Param::TYPE_OBJECT &&
  167. bindings[0].returnParam.kind != FunctionBinding::Param::KIND_POINTER)
  168. {
  169. o << "*";
  170. }
  171. o << "param1;\n";
  172. }
  173. o << " return 0;\n";
  174. o << " }\n";
  175. o << " else\n";
  176. o << " {\n";
  177. // Pass the return value back to Lua.
  178. if (bindings[0].returnParam.type == FunctionBinding::Param::TYPE_OBJECT)
  179. {
  180. switch (bindings[0].returnParam.kind)
  181. {
  182. case FunctionBinding::Param::KIND_POINTER:
  183. o << " void* returnPtr = (void*)";
  184. if (bindings[0].classname.size() > 0)
  185. o << bindings[0].classname << "::";
  186. o << bindings[0].name << ";\n";
  187. break;
  188. case FunctionBinding::Param::KIND_VALUE:
  189. o << " void* returnPtr = (void*)new " << bindings[0].returnParam << "(";
  190. if (bindings[0].classname.size() > 0)
  191. o << bindings[0].classname << "::";
  192. o << bindings[0].name << ");\n";
  193. break;
  194. case FunctionBinding::Param::KIND_REFERENCE:
  195. o << " void* returnPtr = (void*)&(";
  196. if (bindings[0].classname.size() > 0)
  197. o << bindings[0].classname << "::";
  198. o << bindings[0].name << ");\n";
  199. break;
  200. default:
  201. GP_ERROR("Invalid return value kind '%d'.", bindings[0].returnParam.kind);
  202. break;
  203. }
  204. }
  205. else
  206. {
  207. o << " " << bindings[0].returnParam << " result = ";
  208. if (bindings[0].classname.size() > 0)
  209. o << bindings[0].classname << "::";
  210. o << bindings[0].name << ";\n";
  211. }
  212. outputReturnValue(o, bindings[0], 2);
  213. o << " }\n";
  214. o << "}\n\n";
  215. }
  216. else if (bindings.size() == 1 && bindings[0].type == FunctionBinding::MEMBER_CONSTANT)
  217. {
  218. // Validate the parameter count.
  219. o << " // Validate the number of parameters.\n";
  220. o << " if (lua_gettop(state) > 1)\n";
  221. o << " {\n";
  222. o << " lua_pushstring(state, \"Invalid number of parameters (expected 1).\");\n";
  223. o << " lua_error(state);\n";
  224. o << " }\n\n";
  225. // Pass the return value back to Lua.
  226. o << " " << bindings[0].classname << "* instance = getInstance(state);\n";
  227. if (bindings[0].returnParam.type == FunctionBinding::Param::TYPE_OBJECT)
  228. {
  229. switch (bindings[0].returnParam.kind)
  230. {
  231. case FunctionBinding::Param::KIND_POINTER:
  232. o << " void* returnPtr = (void*)instance->" << bindings[0].name << ";\n";
  233. break;
  234. case FunctionBinding::Param::KIND_VALUE:
  235. o << " void* returnPtr = (void*)new " << bindings[0].returnParam << "(instance->" << bindings[0].name << ");\n";
  236. break;
  237. case FunctionBinding::Param::KIND_REFERENCE:
  238. o << " void* returnPtr = (void*)&(instance->" << bindings[0].name << ");\n";
  239. break;
  240. default:
  241. GP_ERROR("Invalid return value kind '%d'.", bindings[0].returnParam.kind);
  242. break;
  243. }
  244. }
  245. else
  246. {
  247. o << " " << bindings[0].returnParam << " result = instance->" << bindings[0].name << ";\n";
  248. }
  249. outputReturnValue(o, bindings[0], 1);
  250. o << "}\n\n";
  251. }
  252. else if (bindings.size() == 1 &&
  253. (bindings[0].type == FunctionBinding::STATIC_CONSTANT ||
  254. bindings[0].type == FunctionBinding::GLOBAL_CONSTANT))
  255. {
  256. // Validate the parameter count.
  257. o << " // Validate the number of parameters.\n";
  258. o << " if (lua_gettop(state) > 0)\n";
  259. o << " {\n";
  260. o << " lua_pushstring(state, \"Invalid number of parameters (expected 0).\");\n";
  261. o << " lua_error(state);\n";
  262. o << " }\n\n";
  263. // Pass the return value back to Lua.
  264. if (bindings[0].returnParam.type == FunctionBinding::Param::TYPE_OBJECT)
  265. {
  266. switch (bindings[0].returnParam.kind)
  267. {
  268. case FunctionBinding::Param::KIND_POINTER:
  269. o << " void* returnPtr = (void*)";
  270. if (bindings[0].classname.size() > 0)
  271. o << bindings[0].classname << "::";
  272. o << bindings[0].name << ";\n";
  273. break;
  274. case FunctionBinding::Param::KIND_VALUE:
  275. o << " void* returnPtr = (void*)new " << bindings[0].returnParam << "(";
  276. if (bindings[0].classname.size() > 0)
  277. o << bindings[0].classname << "::";
  278. o << bindings[0].name << ");\n";
  279. break;
  280. case FunctionBinding::Param::KIND_REFERENCE:
  281. o << " void* returnPtr = (void*)&(";
  282. if (bindings[0].classname.size() > 0)
  283. o << bindings[0].classname << "::";
  284. o << bindings[0].name << ");\n";
  285. break;
  286. default:
  287. GP_ERROR("Invalid return value kind '%d'.", bindings[0].returnParam.kind);
  288. break;
  289. }
  290. }
  291. else
  292. {
  293. o << " " << bindings[0].returnParam << " result = ";
  294. if (bindings[0].classname.size() > 0)
  295. o << bindings[0].classname << "::";
  296. o << bindings[0].name << ";\n";
  297. }
  298. outputReturnValue(o, bindings[0], 1);
  299. o << "}\n\n";
  300. }
  301. else
  302. {
  303. // Get all valid parameter counts.
  304. unsigned int paramCountOffset;
  305. map<unsigned int, vector<const FunctionBinding*> > paramCounts;
  306. for (unsigned int i = 0, count = bindings.size(); i < count; i++)
  307. {
  308. unsigned int minParamCount = bindings[i].getMinParamCount();
  309. paramCountOffset = (bindings[i].type == FunctionBinding::MEMBER_FUNCTION && bindings[i].returnParam.type != FunctionBinding::Param::TYPE_CONSTRUCTOR) ? 1 : 0;
  310. paramCounts[minParamCount + paramCountOffset].push_back(&bindings[i]);
  311. if (minParamCount < bindings[i].paramTypes.size())
  312. {
  313. for (unsigned int c = minParamCount + 1; c <= bindings[i].paramTypes.size(); c++)
  314. {
  315. paramCounts[c + paramCountOffset].push_back(&bindings[i]);
  316. }
  317. }
  318. }
  319. // Get the parameter count.
  320. o << " // Get the number of parameters.\n";
  321. o << " int paramCount = lua_gettop(state);\n\n";
  322. // Retrieve all the parameters and attempt to match them to a valid binding,
  323. // notifying the user if the number of parameters is invalid.
  324. o << " // Attempt to match the parameters to a valid binding.\n";
  325. o << " switch (paramCount)\n";
  326. o << " {\n";
  327. map<unsigned int, vector<const FunctionBinding*> >::iterator iter;
  328. unsigned int checkCount = 0;
  329. for (iter = paramCounts.begin(); iter != paramCounts.end(); iter++)
  330. {
  331. o << " case " << iter->first << ":\n";
  332. o << " {\n";
  333. for (unsigned int i = 0, count = iter->second.size(); i < count; i++)
  334. {
  335. // Only indent if there are parameters.
  336. if (iter->first > 0)
  337. indent(o, 3);
  338. outputMatchedBinding(o, *(iter->second[i]), iter->first, 3, bindings.size());
  339. }
  340. // Only print an else clause with error report if there are parameters.
  341. if (iter->first > 0)
  342. {
  343. indent(o, 3);
  344. o << "lua_pushstring(state, \"" << bindings[0].getFunctionName();
  345. o << " - Failed to match the given parameters to a valid function signature.\");\n";
  346. indent(o, 3);
  347. o << "lua_error(state);\n";
  348. }
  349. o << " break;\n";
  350. o << " }\n";
  351. }
  352. o << " default:\n";
  353. o << " {\n";
  354. o << " lua_pushstring(state, \"Invalid number of parameters (expected ";
  355. for (iter = paramCounts.begin(), checkCount = 1; iter != paramCounts.end(); iter++)
  356. {
  357. if (checkCount == paramCounts.size() && paramCounts.size() > 1)
  358. o << " or ";
  359. o << iter->first;
  360. checkCount++;
  361. if (checkCount < paramCounts.size())
  362. o << ", ";
  363. }
  364. o << ").\");\n";
  365. o << " lua_error(state);\n";
  366. o << " break;\n";
  367. o << " }\n";
  368. o << " }\n";
  369. o << " return 0;\n";
  370. o << "}\n\n";
  371. }
  372. }
  373. bool FunctionBinding::signaturesMatch(const FunctionBinding& b1, const FunctionBinding& b2)
  374. {
  375. if (b1.type == b2.type)
  376. {
  377. bool namesMatch = b1.name == b2.name;
  378. // Ignore class qualifiers on member function bindings (to support inherited overloaded bindings).
  379. if (b1.type == FunctionBinding::MEMBER_CONSTANT ||
  380. b1.type == FunctionBinding::MEMBER_FUNCTION ||
  381. b1.type == FunctionBinding::MEMBER_VARIABLE)
  382. {
  383. string b1name = b1.name;
  384. string b2name = b2.name;
  385. size_t i = b1name.rfind("::");
  386. if (i != b1name.npos)
  387. b1name = b1name.substr(i + 2);
  388. i = b2name.rfind("::");
  389. if (i != b2name.npos)
  390. b2name = b2name.substr(i + 2);
  391. namesMatch = b1name == b2name;
  392. }
  393. // Check the binding's name, parameter types and return value type.
  394. if (namesMatch)
  395. {
  396. if (b1.paramTypes.size() != b2.paramTypes.size())
  397. return false;
  398. for (unsigned int i = 0, count = b1.paramTypes.size(); i < count; i++)
  399. {
  400. if (b1.paramTypes[i] != b2.paramTypes[i])
  401. return false;
  402. }
  403. return true;
  404. }
  405. }
  406. return false;
  407. }
  408. static inline std::string getTypeName(const FunctionBinding::Param& param)
  409. {
  410. switch (param.type)
  411. {
  412. case FunctionBinding::Param::TYPE_VOID:
  413. return "void";
  414. case FunctionBinding::Param::TYPE_BOOL:
  415. return "bool";
  416. case FunctionBinding::Param::TYPE_CHAR:
  417. return "char";
  418. case FunctionBinding::Param::TYPE_SHORT:
  419. return "short";
  420. case FunctionBinding::Param::TYPE_INT:
  421. return "int";
  422. case FunctionBinding::Param::TYPE_LONG:
  423. return "long";
  424. case FunctionBinding::Param::TYPE_UCHAR:
  425. return "unsigned char";
  426. case FunctionBinding::Param::TYPE_USHORT:
  427. return "unsigned short";
  428. case FunctionBinding::Param::TYPE_UINT:
  429. return "unsigned int";
  430. case FunctionBinding::Param::TYPE_ULONG:
  431. return "unsigned long";
  432. case FunctionBinding::Param::TYPE_FLOAT:
  433. return "float";
  434. case FunctionBinding::Param::TYPE_DOUBLE:
  435. return "double";
  436. case FunctionBinding::Param::TYPE_ENUM:
  437. return Generator::getInstance()->getIdentifier(param.info).c_str();
  438. case FunctionBinding::Param::TYPE_STRING:
  439. if (param.info == "string")
  440. return "std::string";
  441. else
  442. return "const char";
  443. case FunctionBinding::Param::TYPE_OBJECT:
  444. case FunctionBinding::Param::TYPE_CONSTRUCTOR:
  445. return Generator::getInstance()->getIdentifier(param.info).c_str();
  446. case FunctionBinding::Param::TYPE_UNRECOGNIZED:
  447. return param.info.c_str();
  448. case FunctionBinding::Param::TYPE_DESTRUCTOR:
  449. default:
  450. return "";
  451. }
  452. }
  453. ostream& operator<<(ostream& o, const FunctionBinding::Param& param)
  454. {
  455. o << getTypeName(param);
  456. if (param.kind == FunctionBinding::Param::KIND_POINTER)
  457. {
  458. for (int i = 0; i < param.levelsOfIndirection; ++i)
  459. o << "*";
  460. }
  461. return o;
  462. }
  463. // ---------------------------------------------
  464. // Helper functions
  465. static inline void outputLuaTypeCheckInstance(ostream& o)
  466. {
  467. o << "(lua_type(state, 1) == LUA_TUSERDATA)";
  468. }
  469. static inline void outputLuaTypeCheck(ostream& o, int index, const FunctionBinding::Param& p)
  470. {
  471. switch (p.type)
  472. {
  473. case FunctionBinding::Param::TYPE_BOOL:
  474. if (p.kind == FunctionBinding::Param::KIND_POINTER)
  475. {
  476. o << "(lua_type(state, " << index << ") == LUA_TTABLE || ";
  477. o << "lua_type(state, " << index << ") == LUA_TLIGHTUSERDATA)";
  478. }
  479. else
  480. {
  481. o << "lua_type(state, " << index << ") == LUA_TBOOLEAN";
  482. }
  483. break;
  484. case FunctionBinding::Param::TYPE_CHAR:
  485. case FunctionBinding::Param::TYPE_SHORT:
  486. case FunctionBinding::Param::TYPE_INT:
  487. case FunctionBinding::Param::TYPE_LONG:
  488. case FunctionBinding::Param::TYPE_UCHAR:
  489. case FunctionBinding::Param::TYPE_USHORT:
  490. case FunctionBinding::Param::TYPE_UINT:
  491. case FunctionBinding::Param::TYPE_ULONG:
  492. case FunctionBinding::Param::TYPE_FLOAT:
  493. case FunctionBinding::Param::TYPE_DOUBLE:
  494. if (p.kind == FunctionBinding::Param::KIND_POINTER)
  495. {
  496. o << "(lua_type(state, " << index << ") == LUA_TTABLE || ";
  497. o << "lua_type(state, " << index << ") == LUA_TLIGHTUSERDATA)";
  498. }
  499. else
  500. {
  501. o << "lua_type(state, " << index << ") == LUA_TNUMBER";
  502. }
  503. break;
  504. case FunctionBinding::Param::TYPE_STRING:
  505. case FunctionBinding::Param::TYPE_ENUM:
  506. o << "(lua_type(state, " << index << ") == LUA_TSTRING || ";
  507. o << "lua_type(state, " << index << ") == LUA_TNIL)";
  508. break;
  509. case FunctionBinding::Param::TYPE_OBJECT:
  510. o << "(lua_type(state, " << index << ") == LUA_TUSERDATA || ";
  511. if (p.kind == FunctionBinding::Param::KIND_POINTER)
  512. o << "lua_type(state, " << index << ") == LUA_TTABLE || ";
  513. o << "lua_type(state, " << index << ") == LUA_TNIL)";
  514. break;
  515. case FunctionBinding::Param::TYPE_CONSTRUCTOR:
  516. case FunctionBinding::Param::TYPE_DESTRUCTOR:
  517. case FunctionBinding::Param::TYPE_VOID:
  518. case FunctionBinding::Param::TYPE_VARARGS:
  519. default:
  520. o << "lua_type(state, " << index << ") == LUA_TNONE";
  521. }
  522. }
  523. static inline void indent(ostream& o, int indentLevel)
  524. {
  525. for (int k = 0; k < indentLevel; k++)
  526. o << " ";
  527. }
  528. static inline void outputBindingInvocation(ostream& o, const FunctionBinding& b, unsigned int paramCount, unsigned int indentLevel, int numBindings)
  529. {
  530. bool isNonStatic = (b.type == FunctionBinding::MEMBER_FUNCTION && b.returnParam.type != FunctionBinding::Param::TYPE_CONSTRUCTOR);
  531. // Get the passed in parameters.
  532. for (unsigned int i = 0, count = paramCount - (isNonStatic ? 1 : 0); i < count; i++)
  533. {
  534. outputGetParam(o, b.paramTypes[i], i, indentLevel, isNonStatic, numBindings);
  535. }
  536. // Get the instance for member functions.
  537. if ((b.type == FunctionBinding::MEMBER_FUNCTION) &&
  538. b.returnParam.type != FunctionBinding::Param::TYPE_CONSTRUCTOR &&
  539. b.returnParam.type != FunctionBinding::Param::TYPE_DESTRUCTOR)
  540. {
  541. indent(o, indentLevel);
  542. o << b.classname << "* instance = getInstance(state);\n";
  543. }
  544. if (b.returnParam.type == FunctionBinding::Param::TYPE_DESTRUCTOR)
  545. {
  546. indent(o, indentLevel);
  547. o << "void* userdata = luaL_checkudata(state, 1, \"" << Generator::getUniqueName(b.classname) << "\");\n";
  548. indent(o, indentLevel);
  549. o << "luaL_argcheck(state, userdata != NULL, 1, \"\'" << Generator::getUniqueName(b.classname) << "\' expected.\");\n";
  550. indent(o, indentLevel);
  551. o << LUA_OBJECT << "* object = (" << LUA_OBJECT << "*)userdata;\n";
  552. indent(o, indentLevel);
  553. o << "if (object->owns)\n";
  554. indent(o, indentLevel);
  555. o << "{\n";
  556. indent(o, indentLevel + 1);
  557. o << b.classname << "* instance = (" << b.classname << "*)object->instance;\n";
  558. if (Generator::getInstance()->isRef(b.classname))
  559. {
  560. indent(o, indentLevel + 1);
  561. o << "SAFE_RELEASE(instance);\n";
  562. }
  563. else
  564. {
  565. indent(o, indentLevel + 1);
  566. o << "SAFE_DELETE(instance);\n";
  567. }
  568. indent(o, indentLevel);
  569. o << "}\n";
  570. }
  571. else
  572. {
  573. // Create a variable to hold the return type (if appropriate).
  574. if (!(b.returnParam.type == FunctionBinding::Param::TYPE_CONSTRUCTOR ||
  575. b.returnParam.type == FunctionBinding::Param::TYPE_VOID ||
  576. b.returnParam.type == FunctionBinding::Param::TYPE_OBJECT))
  577. {
  578. indent(o, indentLevel);
  579. o << b.returnParam << " result = ";
  580. }
  581. // For functions that return objects, create the appropriate user data in Lua.
  582. if (b.returnParam.type == FunctionBinding::Param::TYPE_CONSTRUCTOR || b.returnParam.type == FunctionBinding::Param::TYPE_OBJECT)
  583. {
  584. indent(o, indentLevel);
  585. switch (b.returnParam.kind)
  586. {
  587. case FunctionBinding::Param::KIND_POINTER:
  588. o << "void* returnPtr = (void*)";
  589. break;
  590. case FunctionBinding::Param::KIND_VALUE:
  591. o << "void* returnPtr = (void*)new " << b.returnParam << "(";
  592. break;
  593. case FunctionBinding::Param::KIND_REFERENCE:
  594. o << "void* returnPtr = (void*)&(";
  595. break;
  596. default:
  597. GP_ERROR("Invalid return value kind '%d'.", b.returnParam.kind);
  598. break;
  599. }
  600. }
  601. if (b.type == FunctionBinding::STATIC_FUNCTION)
  602. {
  603. if (b.returnParam.type == FunctionBinding::Param::TYPE_VOID)
  604. indent(o, indentLevel);
  605. o << b.classname << "::" << b.name << "(";
  606. }
  607. else if (b.type == FunctionBinding::GLOBAL_FUNCTION)
  608. {
  609. if (b.returnParam.type == FunctionBinding::Param::TYPE_VOID)
  610. indent(o, indentLevel);
  611. o << b.name << "(";
  612. }
  613. else if (b.type == FunctionBinding::MEMBER_FUNCTION)
  614. {
  615. if (b.returnParam.type == FunctionBinding::Param::TYPE_CONSTRUCTOR)
  616. {
  617. o << "new " << Generator::getInstance()->getIdentifier(b.returnParam.info) << "(";
  618. }
  619. else
  620. {
  621. if (b.returnParam.type == FunctionBinding::Param::TYPE_VOID)
  622. indent(o, indentLevel);
  623. o << "instance->" << b.name << "(";
  624. }
  625. }
  626. // Pass the arguments.
  627. for (unsigned int i = 0, count = paramCount - ((isNonStatic) ? 1 : 0); i < count; i++)
  628. {
  629. if (b.paramTypes[i].type == FunctionBinding::Param::TYPE_OBJECT && b.paramTypes[i].kind != FunctionBinding::Param::KIND_POINTER)
  630. o << "*";
  631. o << "param" << i + 1;
  632. if (i != count - 1)
  633. o << ", ";
  634. }
  635. // Output the matching parenthesis for the case where a non-pointer object is being returned.
  636. if (b.returnParam.type == FunctionBinding::Param::TYPE_OBJECT && b.returnParam.kind != FunctionBinding::Param::KIND_POINTER)
  637. o << ")";
  638. o << ");\n";
  639. }
  640. outputReturnValue(o, b, indentLevel);
  641. }
  642. void writeObjectTemplateType(ostream& o, const FunctionBinding::Param& p)
  643. {
  644. o << getTypeName(p);
  645. for (int i = 0; i < p.levelsOfIndirection-1; ++i)
  646. o << "*";
  647. }
  648. void writePointerParameter(ostream& o, const char* primitiveType, const FunctionBinding::Param& p, int paramNum, int luaParamIndex, int indentLevel)
  649. {
  650. o << "ScriptUtil::LuaArray<";
  651. writeObjectTemplateType(o, p);
  652. //o << "> param" << paramNum << "Pointer = ScriptUtil::get" << primitiveType << "Pointer(" << luaParamIndex << ");\n";
  653. o << "> param" << paramNum << " = ScriptUtil::get" << primitiveType << "Pointer(" << luaParamIndex << ");\n";
  654. //indent(o, indentLevel);
  655. //o << p << " param" << paramNum << " = (" << p << ")param" << paramNum << "Pointer;\n";
  656. }
  657. static inline void outputGetParam(ostream& o, const FunctionBinding::Param& p, int i, int indentLevel, bool offsetIndex, int numBindings)
  658. {
  659. indent(o, indentLevel);
  660. o << "// Get parameter " << i + 1 << " off the stack.\n";
  661. int paramIndex = (offsetIndex) ? i + 2 : i + 1;
  662. switch (p.type)
  663. {
  664. case FunctionBinding::Param::TYPE_BOOL:
  665. indent(o, indentLevel);
  666. if (p.kind == FunctionBinding::Param::KIND_POINTER)
  667. writePointerParameter(o, "Bool", p, i+1, paramIndex, indentLevel);
  668. else
  669. o << p << " param" << i+1 << " = ScriptUtil::luaCheckBool(state, " << paramIndex << ");\n";
  670. break;
  671. case FunctionBinding::Param::TYPE_CHAR:
  672. indent(o, indentLevel);
  673. o << p << " param" << i+1 << " = (char)luaL_checkint(state, " << paramIndex << ");\n";
  674. break;
  675. case FunctionBinding::Param::TYPE_SHORT:
  676. indent(o, indentLevel);
  677. if (p.kind == FunctionBinding::Param::KIND_POINTER)
  678. writePointerParameter(o, "Short", p, i+1, paramIndex, indentLevel);
  679. else
  680. o << p << " param" << i+1 << " = (short)luaL_checkint(state, " << paramIndex << ");\n";
  681. break;
  682. case FunctionBinding::Param::TYPE_INT:
  683. indent(o, indentLevel);
  684. if (p.kind == FunctionBinding::Param::KIND_POINTER)
  685. writePointerParameter(o, "Int", p, i+1, paramIndex, indentLevel);
  686. else
  687. o << p << " param" << i+1 << " = (int)luaL_checkint(state, " << paramIndex << ");\n";
  688. break;
  689. case FunctionBinding::Param::TYPE_LONG:
  690. indent(o, indentLevel);
  691. if (p.kind == FunctionBinding::Param::KIND_POINTER)
  692. writePointerParameter(o, "Long", p, i+1, paramIndex, indentLevel);
  693. else
  694. o << p << " param" << i+1 << " = (long)luaL_checklong(state, " << paramIndex << ");\n";
  695. break;
  696. case FunctionBinding::Param::TYPE_UCHAR:
  697. indent(o, indentLevel);
  698. if (p.kind == FunctionBinding::Param::KIND_POINTER)
  699. writePointerParameter(o, "UnsignedChar", p, i+1, paramIndex, indentLevel);
  700. else
  701. o << p << " param" << i+1 << " = (unsigned char)luaL_checkunsigned(state, " << paramIndex << ");\n";
  702. break;
  703. case FunctionBinding::Param::TYPE_USHORT:
  704. indent(o, indentLevel);
  705. if (p.kind == FunctionBinding::Param::KIND_POINTER)
  706. writePointerParameter(o, "UnsignedShort", p, i+1, paramIndex, indentLevel);
  707. else
  708. o << p << " param" << i+1 << " = (unsigned short)luaL_checkunsigned(state, " << paramIndex << ");\n";
  709. break;
  710. case FunctionBinding::Param::TYPE_UINT:
  711. indent(o, indentLevel);
  712. if (p.kind == FunctionBinding::Param::KIND_POINTER)
  713. writePointerParameter(o, "UnsignedInt", p, i+1, paramIndex, indentLevel);
  714. else
  715. o << p << " param" << i+1 << " = (unsigned int)luaL_checkunsigned(state, " << paramIndex << ");\n";
  716. break;
  717. case FunctionBinding::Param::TYPE_ULONG:
  718. indent(o, indentLevel);
  719. if (p.kind == FunctionBinding::Param::KIND_POINTER)
  720. writePointerParameter(o, "UnsignedLong", p, i+1, paramIndex, indentLevel);
  721. else
  722. o << p << " param" << i+1 << " = (unsigned long)luaL_checkunsigned(state, " << paramIndex << ");\n";
  723. break;
  724. case FunctionBinding::Param::TYPE_FLOAT:
  725. indent(o, indentLevel);
  726. if (p.kind == FunctionBinding::Param::KIND_POINTER)
  727. writePointerParameter(o, "Float", p, i+1, paramIndex, indentLevel);
  728. else
  729. o << p << " param" << i+1 << " = (float)luaL_checknumber(state, " << paramIndex << ");\n";
  730. break;
  731. case FunctionBinding::Param::TYPE_DOUBLE:
  732. indent(o, indentLevel);
  733. if (p.kind == FunctionBinding::Param::KIND_POINTER)
  734. writePointerParameter(o, "Double", p, i+1, paramIndex, indentLevel);
  735. else
  736. o << p << " param" << i+1 << " = (double)luaL_checknumber(state, " << paramIndex << ");\n";
  737. break;
  738. case FunctionBinding::Param::TYPE_STRING:
  739. indent(o, indentLevel);
  740. o << p << " param" << i+1 << " = ScriptUtil::getString(" << paramIndex << ", " << ((p.info == "string") ? "true" : "false") << ");\n";
  741. break;
  742. case FunctionBinding::Param::TYPE_ENUM:
  743. indent(o, indentLevel);
  744. o << p << " param" << i+1 << " = (" << p << ")lua_enumFromString_" << Generator::getInstance()->getUniqueNameFromRef(p.info) << "(luaL_checkstring(state, " << paramIndex << "));\n";
  745. break;
  746. case FunctionBinding::Param::TYPE_UNRECOGNIZED:
  747. // Attempt to retrieve the unrecognized type as an unsigned integer.
  748. indent(o, indentLevel);
  749. o << "GP_WARN(\"Attempting to get parameter " << i + 1 << " with unrecognized type " << p.info << " as an unsigned integer.\");\n";
  750. indent(o, indentLevel);
  751. o << p << " param" << i+1 << " = (" << p.info << ")luaL_checkunsigned(state, " << paramIndex << ");\n";
  752. break;
  753. case FunctionBinding::Param::TYPE_OBJECT:
  754. {
  755. indent(o, indentLevel);
  756. o << "bool param" << i + 1 << "Valid;\n";
  757. indent(o, indentLevel);
  758. o << "ScriptUtil::LuaArray<";
  759. writeObjectTemplateType(o, p);
  760. //o << "> param" << i+1 << "Pointer = ScriptUtil::getObjectPointer<";
  761. o << "> param" << i+1 << " = ScriptUtil::getObjectPointer<";
  762. writeObjectTemplateType(o, p);
  763. o << ">(" << paramIndex;
  764. o << ", \"" << Generator::getInstance()->getUniqueNameFromRef(p.info) << "\", ";
  765. o << ((p.kind != FunctionBinding::Param::KIND_POINTER) ? "true" : "false") << ", &param" << i + 1 << "Valid);\n";
  766. indent(o, indentLevel);
  767. //writeObjectTemplateType(o, p);
  768. //o << "* param" << i+1 << " = (";
  769. //writeObjectTemplateType(o, p);
  770. //o << "*)param" << i+1 << "Pointer;\n";
  771. //indent(o, indentLevel);
  772. o << "if (!param" << i + 1 << "Valid)\n";
  773. if (numBindings > 1)
  774. {
  775. indent(o, indentLevel + 1);
  776. o << "break;\n";
  777. }
  778. else
  779. {
  780. indent(o, indentLevel);
  781. o << "{\n";
  782. indent(o, indentLevel + 1);
  783. o << "lua_pushstring(state, \"Failed to convert parameter " << i + 1 << " to type '" << getTypeName(p) << "'.\");\n";
  784. indent(o, indentLevel + 1);
  785. o << "lua_error(state);\n";
  786. indent(o, indentLevel);
  787. o << "}\n";
  788. }
  789. }
  790. break;
  791. case FunctionBinding::Param::TYPE_CONSTRUCTOR:
  792. case FunctionBinding::Param::TYPE_DESTRUCTOR:
  793. case FunctionBinding::Param::TYPE_VOID:
  794. default:
  795. // Ignore these cases.
  796. break;
  797. }
  798. o << "\n";
  799. }
  800. static inline void outputMatchedBinding(ostream& o, const FunctionBinding& b, unsigned int paramCount, unsigned int indentLevel, int numBindings)
  801. {
  802. bool isNonStatic = (b.type == FunctionBinding::MEMBER_FUNCTION && b.returnParam.type != FunctionBinding::Param::TYPE_CONSTRUCTOR);
  803. // If the current invocation of the function takes zero parameters, then invoke the binding.
  804. if (paramCount == 0)
  805. {
  806. outputBindingInvocation(o, b, paramCount, indentLevel, numBindings);
  807. }
  808. else
  809. {
  810. // NOTE: The way this currently works may cause some issues since Lua
  811. // has a smaller set of types than C++. There may be cases where functions
  812. // that take types with less precision (i.e. int vs. float) are called
  813. // when the user in fact wanted to call the version with more precision.
  814. // (this will only happen for overloaded functions).
  815. if (numBindings > 1)
  816. {
  817. o << "do\n";
  818. indent(o, indentLevel);
  819. o << "{\n";
  820. indent(o, ++indentLevel);
  821. }
  822. o << "if (";
  823. for (unsigned int i = 0, count = paramCount; i < count; i++)
  824. {
  825. if (isNonStatic && i == 0)
  826. {
  827. // This is always the "this / self" pointer for a member function
  828. outputLuaTypeCheckInstance(o);
  829. }
  830. else
  831. {
  832. // Function parameter
  833. outputLuaTypeCheck(o, i + 1, b.paramTypes[(isNonStatic ? i - 1 : i)]);
  834. }
  835. if (i == count - 1)
  836. o << ")\n";
  837. else
  838. {
  839. o << " &&\n";
  840. indent(o, indentLevel + 1);
  841. }
  842. }
  843. indent(o, indentLevel);
  844. o << "{\n";
  845. outputBindingInvocation(o, b, paramCount, indentLevel + 1, numBindings);
  846. indent(o, indentLevel);
  847. o << "}\n";
  848. if (numBindings > 1)
  849. {
  850. indent(o, --indentLevel);
  851. o << "} while (0);\n";
  852. }
  853. o << "\n";
  854. }
  855. }
  856. static inline void outputReturnValue(ostream& o, const FunctionBinding& b, int indentLevel)
  857. {
  858. // Pass the return value back to Lua.
  859. if (!(b.returnParam.type == FunctionBinding::Param::TYPE_CONSTRUCTOR ||
  860. b.returnParam.type == FunctionBinding::Param::TYPE_DESTRUCTOR ||
  861. b.returnParam.type == FunctionBinding::Param::TYPE_VOID ||
  862. b.returnParam.type == FunctionBinding::Param::TYPE_OBJECT))
  863. {
  864. o << "\n";
  865. indent(o, indentLevel);
  866. o << "// Push the return value onto the stack.\n";
  867. // If the return type is a basic type pointer, return it as light user data.
  868. if (b.returnParam.type != FunctionBinding::Param::TYPE_ENUM &&
  869. b.returnParam.type != FunctionBinding::Param::TYPE_STRING &&
  870. b.returnParam.kind == FunctionBinding::Param::KIND_POINTER)
  871. {
  872. indent(o, indentLevel);
  873. o << "lua_pushlightuserdata(state, result);\n";
  874. indent(o, indentLevel);
  875. o << "return 1;\n";
  876. return;
  877. }
  878. }
  879. indent(o, indentLevel);
  880. switch (b.returnParam.type)
  881. {
  882. case FunctionBinding::Param::TYPE_BOOL:
  883. o << "lua_pushboolean(state, result);\n";
  884. break;
  885. case FunctionBinding::Param::TYPE_CHAR:
  886. case FunctionBinding::Param::TYPE_SHORT:
  887. case FunctionBinding::Param::TYPE_INT:
  888. case FunctionBinding::Param::TYPE_LONG:
  889. o << "lua_pushinteger(state, result);\n";
  890. break;
  891. case FunctionBinding::Param::TYPE_UNRECOGNIZED:
  892. o << "GP_WARN(\"Attempting to return value with unrecognized type " << b.returnParam.info << " as an unsigned integer.\");\n";
  893. indent(o, indentLevel);
  894. case FunctionBinding::Param::TYPE_UCHAR:
  895. case FunctionBinding::Param::TYPE_USHORT:
  896. case FunctionBinding::Param::TYPE_UINT:
  897. case FunctionBinding::Param::TYPE_ULONG:
  898. o << "lua_pushunsigned(state, result);\n";
  899. break;
  900. case FunctionBinding::Param::TYPE_FLOAT:
  901. case FunctionBinding::Param::TYPE_DOUBLE:
  902. o << "lua_pushnumber(state, result);\n";
  903. break;
  904. case FunctionBinding::Param::TYPE_ENUM:
  905. o << "lua_pushstring(state, lua_stringFromEnum_" << Generator::getInstance()->getUniqueNameFromRef(b.returnParam.info) << "(result));\n";
  906. break;
  907. case FunctionBinding::Param::TYPE_STRING:
  908. if (b.returnParam.info == "string")
  909. o << "lua_pushstring(state, result.c_str());\n";
  910. else
  911. o << "lua_pushstring(state, result);\n";
  912. break;
  913. case FunctionBinding::Param::TYPE_OBJECT:
  914. case FunctionBinding::Param::TYPE_CONSTRUCTOR:
  915. o << "if (returnPtr)\n";
  916. indent(o, indentLevel);
  917. o << "{\n";
  918. indent(o, indentLevel + 1);
  919. o << LUA_OBJECT << "* object = (" << LUA_OBJECT << "*)lua_newuserdata(state, sizeof(" << LUA_OBJECT << "));\n";
  920. indent(o, indentLevel + 1);
  921. o << "object->instance = returnPtr;\n";
  922. indent(o, indentLevel + 1);
  923. o << "object->owns = ";
  924. if (b.own || (b.returnParam.type == FunctionBinding::Param::TYPE_OBJECT && b.returnParam.kind == FunctionBinding::Param::KIND_VALUE))
  925. o << "true";
  926. else
  927. o << "false";
  928. o << ";\n";
  929. indent(o, indentLevel + 1);
  930. o << "luaL_getmetatable(state, \"" << Generator::getInstance()->getUniqueNameFromRef(b.returnParam.info) << "\");\n";
  931. indent(o, indentLevel + 1);
  932. o << "lua_setmetatable(state, -2);\n";
  933. indent(o, indentLevel);
  934. o << "}\n";
  935. indent(o, indentLevel);
  936. o << "else\n";
  937. indent(o, indentLevel);
  938. o << "{\n";
  939. indent(o, indentLevel + 1);
  940. o << "lua_pushnil(state);\n";
  941. indent(o, indentLevel);
  942. o << "}\n";
  943. break;
  944. case FunctionBinding::Param::TYPE_DESTRUCTOR:
  945. case FunctionBinding::Param::TYPE_VOID:
  946. default:
  947. o << "\n";
  948. indent(o, indentLevel);
  949. o << "return 0;\n";
  950. return;
  951. }
  952. o << "\n";
  953. indent(o, indentLevel);
  954. o << "return 1;\n";
  955. }