func.c 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. #include <stdio.h>
  2. #include "luadebug.h"
  3. #include "table.h"
  4. #include "mem.h"
  5. #include "func.h"
  6. #include "opcode.h"
  7. #define LOCALVARINITSIZE 10
  8. static TFunc *function_root = NULL;
  9. static LocVar *currvars = NULL;
  10. static int numcurrvars = 0;
  11. static int maxcurrvars = 0;
  12. /*
  13. ** Initialize TFunc struct
  14. */
  15. void luaI_initTFunc (TFunc *f)
  16. {
  17. f->code = NULL;
  18. f->lineDefined = 0;
  19. f->locvars = NULL;
  20. }
  21. /*
  22. ** Insert function in list for GC
  23. */
  24. void luaI_insertfunction (TFunc *f)
  25. {
  26. lua_pack();
  27. f->next = function_root;
  28. function_root = f;
  29. f->marked = 0;
  30. }
  31. /*
  32. ** Free function
  33. */
  34. static void freefunc (TFunc *f)
  35. {
  36. luaI_free (f->code);
  37. luaI_free (f->locvars);
  38. luaI_free (f);
  39. }
  40. /*
  41. ** Garbage collection function.
  42. ** This function traverse the function list freeing unindexed functions
  43. */
  44. Long luaI_funccollector (void)
  45. {
  46. TFunc *curr = function_root;
  47. TFunc *prev = NULL;
  48. Long counter = 0;
  49. while (curr)
  50. {
  51. TFunc *next = curr->next;
  52. if (!curr->marked)
  53. {
  54. if (prev == NULL)
  55. function_root = next;
  56. else
  57. prev->next = next;
  58. freefunc (curr);
  59. ++counter;
  60. }
  61. else
  62. {
  63. curr->marked = 0;
  64. prev = curr;
  65. }
  66. curr = next;
  67. }
  68. return counter;
  69. }
  70. void lua_funcinfo (lua_Object func, char **filename, int *linedefined)
  71. {
  72. Object *f = luaI_Address(func);
  73. if (f->tag == LUA_T_MARK || f->tag == LUA_T_FUNCTION)
  74. {
  75. *filename = f->value.tf->fileName;
  76. *linedefined = f->value.tf->lineDefined;
  77. }
  78. else if (f->tag == LUA_T_CMARK || f->tag == LUA_T_CFUNCTION)
  79. {
  80. *filename = "(C)";
  81. *linedefined = -1;
  82. }
  83. }
  84. /*
  85. ** Stores information to know that variable has been declared in given line
  86. */
  87. void luaI_registerlocalvar (TaggedString *varname, int line)
  88. {
  89. if (numcurrvars >= maxcurrvars)
  90. {
  91. maxcurrvars = (maxcurrvars == 0) ? LOCALVARINITSIZE : maxcurrvars*2;
  92. currvars = growvector(currvars, maxcurrvars, LocVar);
  93. }
  94. currvars[numcurrvars].varname = varname;
  95. currvars[numcurrvars].line = line;
  96. numcurrvars++;
  97. }
  98. /*
  99. ** Stores information to know that variable has been out of scope in given line
  100. */
  101. void luaI_unregisterlocalvar (int line)
  102. {
  103. luaI_registerlocalvar(NULL, line);
  104. }
  105. /*
  106. ** Copies "currvars" into a new area and store it in function header.
  107. ** The values (varname = NULL, line = -1) signal the end of vector.
  108. */
  109. void luaI_closelocalvars (TFunc *func)
  110. {
  111. func->locvars = newvector (numcurrvars+1, LocVar);
  112. memcpy (func->locvars, currvars, numcurrvars*sizeof(LocVar));
  113. func->locvars[numcurrvars].varname = NULL;
  114. func->locvars[numcurrvars].line = -1;
  115. numcurrvars = 0; /* prepares for next function */
  116. }
  117. /*
  118. ** Look for n-esim local variable at line "line" in function "func".
  119. ** Returns NULL if not found.
  120. */
  121. char *luaI_getlocalname (TFunc *func, int local_number, int line)
  122. {
  123. int count = 0;
  124. char *varname = NULL;
  125. LocVar *lv = func->locvars;
  126. if (lv == NULL)
  127. return NULL;
  128. for (; lv->line != -1 && lv->line < line; lv++)
  129. {
  130. if (lv->varname) /* register */
  131. {
  132. if (++count == local_number)
  133. varname = lv->varname->str;
  134. }
  135. else /* unregister */
  136. if (--count < local_number)
  137. varname = NULL;
  138. }
  139. return varname;
  140. }