func.c 3.3 KB

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