func.c 3.3 KB

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