lnodemcu.c 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. /*
  2. ** $Id: ltm.c,v 2.8.1.1 2007/12/27 13:02:25 roberto Exp $
  3. ** Tag methods
  4. ** See Copyright Notice in lua.h
  5. */
  6. #define lnodemcu_c
  7. #define LUA_CORE
  8. #include "lua.h"
  9. #include <string.h>
  10. #include "lobject.h"
  11. #include "lstate.h"
  12. #include "lauxlib.h"
  13. #include "lgc.h"
  14. #include "lstring.h"
  15. #include "ltable.h"
  16. #include "ltm.h"
  17. #include "lrotable.h"
  18. #include "platform.h"
  19. extern int debug_errorfb (lua_State *L);
  20. #if 0
  21. extern int pipe_create(lua_State *L);
  22. extern int pipe_read(lua_State *L);
  23. extern int pipe_unread(lua_State *L);
  24. extern int pipe_write(lua_State *L);
  25. #endif
  26. /*
  27. ** Error Reporting Task. We can't pass a string parameter to the error reporter
  28. ** directly through the task interface the call is wrapped in a C closure with
  29. ** the error string as an Upval and this is posted to call the Lua reporter.
  30. */
  31. static int report_traceback (lua_State *L) {
  32. // **Temp** lua_rawgeti(L, LUA_REGISTRYINDEX, G(L)->error_reporter);
  33. lua_getglobal(L, "print");
  34. lua_pushvalue(L, lua_upvalueindex(1));
  35. lua_call(L, 1, 0); /* Using an error handler would cause an infinite loop! */
  36. return 0;
  37. }
  38. /*
  39. ** Catch all error handler for CB calls. This uses debug.traceback() to
  40. ** generate a full Lua traceback.
  41. */
  42. int luaN_traceback (lua_State *L) {
  43. if (lua_isstring(L, 1)) {
  44. lua_pushlightfunction(L, &debug_errorfb);
  45. lua_pushvalue(L, 1); /* pass error message */
  46. lua_pushinteger(L, 2); /* skip this function and traceback */
  47. lua_call(L, 2, 1); /* call debug.traceback and return it as a string */
  48. lua_pushcclosure(L, report_traceback, 1); /* report with str as upval */
  49. luaN_posttask(L, LUA_TASK_HIGH);
  50. }
  51. return 0;
  52. }
  53. /*
  54. ** Use in CBs and other C functions to call a Lua function. This includes
  55. ** an error handler which will catch any error and then post this to the
  56. ** registered reporter function as a separate follow-on task.
  57. */
  58. int luaN_call (lua_State *L, int narg, int res, int doGC) { // [-narg, +0, v]
  59. int status;
  60. int base = lua_gettop(L) - narg;
  61. lua_pushcfunction(L, luaN_traceback);
  62. lua_insert(L, base); /* put under args */
  63. status = lua_pcall(L, narg, (res < 0 ? LUA_MULTRET : res), base);
  64. lua_remove(L, base); /* remove traceback function */
  65. /* force a complete garbage collection if requested */
  66. if (doGC)
  67. lua_gc(L, LUA_GCCOLLECT, 0);
  68. return status;
  69. }
  70. static platform_task_handle_t task_handle = 0;
  71. /*
  72. ** Task callback handler. Uses luaN_call to do a protected call with full traceback
  73. */
  74. static void do_task (platform_task_param_t task_fn_ref, uint8_t prio) {
  75. lua_State* L = lua_getstate();
  76. if (prio < 0|| prio > 2)
  77. luaL_error(L, "invalid posk task");
  78. /* Pop the CB func from the Reg */
  79. //dbg_printf("calling Reg[%u]\n", task_fn_ref);
  80. lua_rawgeti(L, LUA_REGISTRYINDEX, (int) task_fn_ref);
  81. luaL_checkanyfunction(L, -1);
  82. luaL_unref(L, LUA_REGISTRYINDEX, (int) task_fn_ref);
  83. lua_pushinteger(L, prio);
  84. luaN_call (L, 1, 0, 1);
  85. }
  86. /*
  87. ** Schedule a Lua function for task execution
  88. */
  89. #include "lstate.h" /*DEBUG*/
  90. LUA_API int luaN_posttask( lua_State* L, int prio ) { // [-1, +0, -]
  91. if (!task_handle)
  92. task_handle = platform_task_get_id(do_task);
  93. if (!lua_isanyfunction(L, -1) || prio < LUA_TASK_LOW|| prio > LUA_TASK_HIGH)
  94. luaL_error(L, "invalid posk task");
  95. //void *cl = clvalue(L->top-1);
  96. int task_fn_ref = luaL_ref(L, LUA_REGISTRYINDEX);
  97. //dbg_printf("posting Reg[%u]=%p\n",task_fn_ref,cl);
  98. if(!platform_post(prio, task_handle, (platform_task_param_t)task_fn_ref)) {
  99. luaL_unref(L, LUA_REGISTRYINDEX, task_fn_ref);
  100. luaL_error(L, "Task queue overflow. Task not posted");
  101. }
  102. return task_fn_ref;
  103. }