inter.cpp 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229
  1. #include "inter.h"
  2. #include "core-activation.h"
  3. #include "core-init.h"
  4. #include "msg.h"
  5. #include "core-exception.h"
  6. namespace aFuncore {
  7. Inter::Inter(Environment &env_)
  8. : status{inter_init}, env{env_}, activation{nullptr}, out{}, in{} {
  9. env++;
  10. }
  11. Inter::Inter(const Inter &base_inter)
  12. : status{inter_init}, env{base_inter.env}, activation{nullptr}, out{}, in{}{
  13. for (auto &i: base_inter.literal)
  14. literal.push_back(i);
  15. env++;
  16. }
  17. Inter::~Inter(){
  18. env--;
  19. }
  20. /**
  21. * 使能 (激活解释器)
  22. */
  23. void Inter::enable(){
  24. if (status == inter_init) {
  25. env.protect->setProtect(true);
  26. status = inter_normal;
  27. }
  28. }
  29. /**
  30. * 运行代码(直接运行activation)
  31. * @return
  32. */
  33. bool Inter::runCode(){
  34. if (status == inter_stop)
  35. status = inter_normal;
  36. while (activation != nullptr) {
  37. if (isInterStop()) {
  38. while (activation != nullptr)
  39. delete popActivation();
  40. return false;
  41. }
  42. const Code::ByteCode *code = nullptr;
  43. Activation::ActivationStatus as = activation->getCode(code);
  44. switch (as) {
  45. case Activation::as_end: {
  46. delete popActivation();
  47. break;
  48. }
  49. case Activation::as_run:
  50. activation->runCode(code);
  51. break;
  52. case Activation::as_end_run:
  53. activation->endRun();
  54. break;
  55. default:
  56. errorLog(aFunCoreLogger, "Error activation status.");
  57. activation->getDownStream().pushMessage("ERROR",
  58. new ErrorMessage("RuntimeError", "Error activation status.", activation));
  59. break;
  60. }
  61. }
  62. return true;
  63. }
  64. /**
  65. * 运行代码
  66. * @param code 代码
  67. * @return
  68. */
  69. bool Inter::runCode(const Code &code){
  70. if (activation != nullptr) {
  71. errorLog(aFunCoreLogger, "Run code with activation");
  72. return false;
  73. }
  74. new TopActivation(code, *this);
  75. return runCode();
  76. }
  77. /**
  78. * 函数调用
  79. * @param code 代码
  80. * @return
  81. */
  82. bool Inter::runCode(Object *func){
  83. if (activation != nullptr) {
  84. errorLog(aFunCoreLogger, "Run function with activation");
  85. return false;
  86. }
  87. auto func_obj = dynamic_cast<Function *>(func);
  88. if (func_obj == nullptr) {
  89. errorLog(aFunCoreLogger, "Run without function");
  90. return false;
  91. }
  92. new FuncActivation(func_obj, *this);
  93. return runCode();
  94. }
  95. /**
  96. * 检查字面量是否匹配
  97. * @param element 字面量
  98. * @return
  99. */
  100. bool Inter::checkLiteral(const std::string &element) const{
  101. if (literal.empty())
  102. return false;
  103. for (auto &i: literal) {
  104. try {
  105. if (i.rg.match(element) != 1)
  106. continue;
  107. return true;
  108. } catch (aFuntool::RegexException &e) {
  109. continue;
  110. }
  111. }
  112. return false;
  113. }
  114. /**
  115. * 检查字面量正则匹配
  116. * @param element 字面量
  117. * @param literaler 函数
  118. * @param in_protect 是否保护空间
  119. * @return
  120. */
  121. bool Inter::checkLiteral(const std::string &element, std::string &literaler, bool &in_protect) const{
  122. if (literal.empty())
  123. return false;
  124. for (auto &i: literal) {
  125. try {
  126. if (i.rg.match(element) != 1)
  127. continue;
  128. literaler = i.literaler;
  129. in_protect = i.in_protect;
  130. return true;
  131. } catch (aFuntool::RegexException &e) {
  132. continue;
  133. }
  134. }
  135. return false;
  136. }
  137. bool Inter::pushLiteral(const std::string &pattern, const std::string &literaler, bool in_protect){
  138. try {
  139. literal.push_front({aFuntool::Regex(pattern), pattern, literaler, in_protect});
  140. } catch (aFuntool::RegexException &e) {
  141. return false;
  142. }
  143. return true;
  144. }
  145. void Environment::gcThread() {
  146. while(true) {
  147. std::queue<Object *> del;
  148. std::queue<Object *> des;
  149. {
  150. std::unique_lock<std::mutex> mutex{lock};
  151. if (destruct)
  152. break;
  153. Object::checkReachable(gc);
  154. Object::setReachable(gc, des, del);
  155. }
  156. Object::deleteUnreachable(del);
  157. Object::destructUnreachable(des, gc_inter);
  158. aFuntool::safeSleep(1);
  159. }
  160. Object::destructAll(gc, gc_inter); /* 不需要mutex锁 */
  161. }
  162. Environment::Environment(int argc, char **argv)
  163. : reference{0}, destruct{false}, gc_inter{*(new Inter(*this))}, protect{new ProtectVarSpace(*this)} {
  164. /* 生成 gc_inter 后, reference == 1 */
  165. envvar.setNumber("sys:gc-runtime", 2);
  166. envvar.setString("sys:prefix", "''"); // 引用,顺序执行
  167. envvar.setNumber("sys:exit-code", 0);
  168. envvar.setNumber("sys:argc", argc);
  169. envvar.setNumber("sys:error_std", 0);
  170. for (int i = 0; i < argc; i++) {
  171. char buf[20];
  172. snprintf(buf, 10, "sys:arg%d", i);
  173. envvar.setString(buf, argv[i]);
  174. }
  175. gc_thread = std::thread([this](){this->gcThread();});
  176. { // 导入函数
  177. auto import = new ImportFunction(*this);
  178. protect->defineVar("import", import);
  179. import->delReference();
  180. }
  181. }
  182. Environment::~Environment() noexcept(false) {
  183. { /* 使用互斥锁, 防止与gc线程出现不同步的情况 */
  184. std::unique_lock<std::mutex> mutex{lock};
  185. if (reference != 1) // gc_inter 有一个引用
  186. throw EnvironmentDestructException();
  187. if (destruct)
  188. return;
  189. destruct = true;
  190. }
  191. gc_thread.join();
  192. delete &gc_inter;
  193. protect->delReference();
  194. Object::deleteAll(gc); /* 不需要mutex锁 */
  195. if (reference != 0)
  196. throw EnvironmentDestructException();
  197. }
  198. }