lref.c 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. /*
  2. ** $Id: $
  3. ** REF mechanism
  4. ** See Copyright Notice in lua.h
  5. */
  6. #include "lmem.h"
  7. #include "lref.h"
  8. #include "lstate.h"
  9. #include "lua.h"
  10. int luaR_ref (const TObject *o, int lock) {
  11. int ref;
  12. if (ttype(o) == LUA_T_NIL)
  13. ref = LUA_REFNIL;
  14. else {
  15. for (ref=0; ref<L->refSize; ref++)
  16. if (L->refArray[ref].status == FREE)
  17. break;
  18. if (ref == L->refSize) { /* no more empty spaces? */
  19. luaM_growvector(L->refArray, L->refSize, 1, struct ref, refEM, MAX_INT);
  20. L->refSize++;
  21. }
  22. L->refArray[ref].o = *o;
  23. L->refArray[ref].status = lock ? LOCK : HOLD;
  24. }
  25. return ref;
  26. }
  27. void lua_unref (int ref) {
  28. if (ref >= 0 && ref < L->refSize)
  29. L->refArray[ref].status = FREE;
  30. }
  31. const TObject *luaR_getref (int ref) {
  32. if (ref == LUA_REFNIL)
  33. return &luaO_nilobject;
  34. if (ref >= 0 && ref < L->refSize &&
  35. (L->refArray[ref].status == LOCK || L->refArray[ref].status == HOLD))
  36. return &L->refArray[ref].o;
  37. else
  38. return NULL;
  39. }
  40. static int ismarked (const TObject *o) {
  41. /* valid only for locked objects */
  42. switch (o->ttype) {
  43. case LUA_T_STRING: case LUA_T_USERDATA:
  44. return o->value.ts->marked;
  45. case LUA_T_ARRAY:
  46. return o->value.a->marked;
  47. case LUA_T_CLOSURE:
  48. return o->value.cl->marked;
  49. case LUA_T_PROTO:
  50. return o->value.tf->marked;
  51. #ifdef DEBUG
  52. case LUA_T_LINE: case LUA_T_CLMARK:
  53. case LUA_T_CMARK: case LUA_T_PMARK:
  54. LUA_INTERNALERROR("invalid type");
  55. #endif
  56. default: /* nil, number or cproto */
  57. return 1;
  58. }
  59. }
  60. void luaR_invalidaterefs (void) {
  61. int i;
  62. for (i=0; i<L->refSize; i++)
  63. if (L->refArray[i].status == HOLD && !ismarked(&L->refArray[i].o))
  64. L->refArray[i].status = COLLECTED;
  65. }