gc.c 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. #include "__virtualmath.h"
  2. void gc_iterLinkValue(LinkValue *value){
  3. if (value == NULL)
  4. return;
  5. gc_addLink(&value->gc_status);
  6. if (!gc_IterAlready(&value->gc_status)){
  7. gc_iterLinkValue(value->belong);
  8. gc_iterValue(value->value);
  9. }
  10. }
  11. void gc_fatherValue(Inherit *value){
  12. for (PASS; value != NULL; value = value->next)
  13. gc_iterLinkValue(value->value);
  14. }
  15. void gc_iterValue(Value *value){
  16. if (value == NULL)
  17. return;
  18. gc_addLink(&value->gc_status);
  19. if (gc_IterAlready(&value->gc_status))
  20. return;
  21. gc_varList(value->object.var);
  22. gc_varList(value->object.out_var);
  23. gc_fatherValue(value->object.inherit);
  24. gc_resetValue(value);
  25. switch (value->type) {
  26. case list:
  27. for (int i=0;i < value->data.list.size;i++)
  28. gc_iterLinkValue(value->data.list.list[i]);
  29. break;
  30. case dict:
  31. gc_iterHashTable(value->data.dict.dict);
  32. break;
  33. default:
  34. break;
  35. }
  36. }
  37. void gc_varList(VarList *vl){
  38. for (PASS; vl != NULL; vl = vl->next)
  39. gc_iterHashTable(vl->hashtable);
  40. }
  41. void gc_iterHashTable(HashTable *ht){
  42. if (ht == NULL)
  43. return;
  44. gc_addLink(&ht->gc_status);
  45. if (gc_IterAlready(&ht->gc_status))
  46. return;
  47. for (int i=0;i < MAX_SIZE;i++)
  48. gc_iterVar(ht->hashtable[i]);
  49. }
  50. void gc_iterVar(Var *var){
  51. if (var == NULL)
  52. return;
  53. if (gc_IterAlready(&var->gc_status))
  54. return;
  55. for (PASS; var != NULL; var = var->next){
  56. gc_addLink(&var->gc_status);
  57. gc_iterLinkValue(var->name_);
  58. gc_iterLinkValue(var->value);
  59. }
  60. }
  61. void gc_resetBase(Inter *inter){
  62. for (Value *value_base = inter->base; value_base != NULL; value_base = value_base->gc_next)
  63. resetGC(&value_base->gc_status);
  64. for (LinkValue *link_base = inter->link_base; link_base != NULL; link_base = link_base->gc_next)
  65. resetGC(&link_base->gc_status);
  66. for (HashTable *hash_base = inter->hash_base; hash_base != NULL; hash_base = hash_base->gc_next)
  67. resetGC(&hash_base->gc_status);
  68. for (Var *var_base = inter->base_var; var_base != NULL; var_base = var_base->gc_next)
  69. resetGC(&var_base->gc_status);
  70. }
  71. void gc_checkBase(Inter *inter){
  72. for (Value *value_base = inter->base; value_base != NULL; value_base = value_base->gc_next)
  73. if (!gc_needFree(&value_base->gc_status) && !value_base->gc_status.continue_)
  74. gc_iterValue(value_base);
  75. for (LinkValue *link_base = inter->link_base; link_base != NULL; link_base = link_base->gc_next)
  76. if (!gc_needFree(&link_base->gc_status) && !link_base->gc_status.continue_)
  77. gc_iterLinkValue(link_base);
  78. for (HashTable *hash_base = inter->hash_base; hash_base != NULL; hash_base = hash_base->gc_next)
  79. if (!gc_needFree(&hash_base->gc_status) && !hash_base->gc_status.continue_)
  80. gc_iterHashTable(hash_base);
  81. for (Var *var_base = inter->base_var; var_base != NULL; var_base = var_base->gc_next)
  82. if (!gc_needFree(&var_base->gc_status) && !var_base->gc_status.continue_)
  83. gc_iterVar(var_base);
  84. }
  85. void gc_checkDel(Inter *inter){
  86. for (Value *value = inter->base; value != NULL; value = value->gc_next)
  87. if (!gc_needFree(&value->gc_status))
  88. gc_resetValue(value);
  89. else if (value->gc_status.c_value == not_free){
  90. if (needDel(value, inter)){
  91. gc_iterValue(value);
  92. value->gc_status.c_value = run_del;
  93. }
  94. else
  95. value->gc_status.c_value = need_free;
  96. }
  97. }
  98. void gc_runDelAll(Inter *inter){
  99. Result result;
  100. setResultCore(&result);
  101. for (Value *value = inter->base; value != NULL; value = value->gc_next) {
  102. freeResult(&result);
  103. gc_addTmpLink(&value->gc_status);
  104. if (needDel(value, inter)) {
  105. callDel(value, &result, inter, inter->var_list);
  106. if (!RUN_TYPE(result.type))
  107. printError(&result, inter, true);
  108. }
  109. gc_freeTmpLink(&value->gc_status);
  110. }
  111. }
  112. void gc_runDel(Inter *inter, VarList *var_list){
  113. Result result;
  114. setResultCore(&result);
  115. for (Value *value = inter->base; value != NULL; value = value->gc_next) {
  116. freeResult(&result);
  117. if (value->gc_status.c_value == run_del) {
  118. gc_addTmpLink(&value->gc_status);
  119. callDel(value, &result, inter, var_list);
  120. if (!RUN_TYPE(result.type))
  121. printError(&result, inter, true);
  122. gc_freeTmpLink(&value->gc_status);
  123. value->gc_status.c_value = need_free;
  124. }
  125. }
  126. }
  127. void gc_freeBase(Inter *inter){
  128. #if START_GC
  129. for (Value **value_base = &inter->base; *value_base != NULL;)
  130. if (gc_needFreeValue(*value_base))
  131. freeValue(value_base);
  132. else
  133. value_base = &(*value_base)->gc_next;
  134. for (LinkValue **link_base = &inter->link_base; *link_base != NULL;)
  135. if (gc_needFree(&(*link_base)->gc_status))
  136. freeLinkValue(link_base);
  137. else
  138. link_base = &(*link_base)->gc_next;
  139. for (HashTable **hash_base = &inter->hash_base; *hash_base != NULL;)
  140. if (gc_needFree(&(*hash_base)->gc_status))
  141. freeHashTable(hash_base);
  142. else
  143. hash_base = &(*hash_base)->gc_next;
  144. for (Var **var_base = &inter->base_var; *var_base != NULL;)
  145. if (gc_needFree(&(*var_base)->gc_status))
  146. freeVar(var_base);
  147. else
  148. var_base = &(*var_base)->gc_next;
  149. #endif
  150. }
  151. void gc_run(Inter *inter, VarList *run_var, int var_list, int link_value, int value, ...){
  152. #if START_GC
  153. gc_resetBase(inter);
  154. va_list arg;
  155. va_start(arg, value);
  156. for (int i =0;i < var_list;i ++){
  157. VarList *tmp = va_arg(arg, VarList *);
  158. gc_varList(tmp);
  159. }
  160. for (int i =0;i < link_value;i ++){
  161. LinkValue *tmp = va_arg(arg, LinkValue *);
  162. gc_iterLinkValue(tmp);
  163. }
  164. for (int i =0;i < value;i ++){
  165. Value *tmp = va_arg(arg, Value *);
  166. gc_iterValue(tmp);
  167. }
  168. va_end(arg);
  169. gc_checkBase(inter);
  170. gc_checkDel(inter);
  171. gc_freeBase(inter);
  172. gc_runDel(inter, run_var);
  173. #endif
  174. }