func.c 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  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);
  38. }
  39. /*
  40. ** Garbage collection function.
  41. ** This function traverse the function list freeing unindexed functions
  42. */
  43. Long luaI_funccollector (void)
  44. {
  45. TFunc *curr = function_root;
  46. TFunc *prev = NULL;
  47. Long counter = 0;
  48. while (curr)
  49. {
  50. TFunc *next = curr->next;
  51. if (!curr->marked)
  52. {
  53. if (prev == NULL)
  54. function_root = next;
  55. else
  56. prev->next = next;
  57. freefunc (curr);
  58. ++counter;
  59. }
  60. else
  61. {
  62. curr->marked = 0;
  63. prev = curr;
  64. }
  65. curr = next;
  66. }
  67. return counter;
  68. }
  69. void lua_funcinfo (lua_Object func, char **filename, int *linedefined)
  70. {
  71. Object *f = luaI_Address(func);
  72. if (f->tag == LUA_T_MARK || f->tag == LUA_T_FUNCTION)
  73. {
  74. *filename = f->value.tf->fileName;
  75. *linedefined = f->value.tf->lineDefined;
  76. }
  77. else if (f->tag == LUA_T_CMARK || f->tag == LUA_T_CFUNCTION)
  78. {
  79. *filename = "(C)";
  80. *linedefined = -1;
  81. }
  82. }
  83. /*
  84. ** Stores information to know that variable has been declared in given line
  85. */
  86. void luaI_registerlocalvar (TreeNode *varname, int line)
  87. {
  88. if (numcurrvars >= maxcurrvars)
  89. if (currvars == NULL)
  90. {
  91. maxcurrvars = LOCALVARINITSIZE;
  92. currvars = newvector (maxcurrvars, LocVar);
  93. }
  94. else
  95. {
  96. maxcurrvars *= 2;
  97. currvars = growvector (currvars, maxcurrvars, LocVar);
  98. }
  99. currvars[numcurrvars].varname = varname;
  100. currvars[numcurrvars].line = line;
  101. numcurrvars++;
  102. }
  103. /*
  104. ** Stores information to know that variable has been out of scope in given line
  105. */
  106. void luaI_unregisterlocalvar (int line)
  107. {
  108. luaI_registerlocalvar(NULL, line);
  109. }
  110. /*
  111. ** Copies "currvars" into a new area and store it in function header.
  112. ** The values (varname = NULL, line = -1) signal the end of vector.
  113. */
  114. void luaI_closelocalvars (TFunc *func)
  115. {
  116. func->locvars = newvector (numcurrvars+1, LocVar);
  117. memcpy (func->locvars, currvars, numcurrvars*sizeof(LocVar));
  118. func->locvars[numcurrvars].varname = NULL;
  119. func->locvars[numcurrvars].line = -1;
  120. numcurrvars = 0; /* prepares for next function */
  121. }
  122. /*
  123. ** Look for n-esim local variable at line "line" in function "func".
  124. ** Returns NULL if not found.
  125. */
  126. char *luaI_getlocalname (TFunc *func, int local_number, int line)
  127. {
  128. int count = 0;
  129. char *varname = NULL;
  130. LocVar *lv = func->locvars;
  131. if (lv == NULL)
  132. return NULL;
  133. for (; lv->line != -1 && lv->line < line; lv++)
  134. {
  135. if (lv->varname) /* register */
  136. {
  137. if (++count == local_number)
  138. varname = lv->varname->ts.str;
  139. }
  140. else /* unregister */
  141. if (--count < local_number)
  142. varname = NULL;
  143. }
  144. return varname;
  145. }