runcall.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411
  1. #include "__run.h"
  2. ResultType setClass(FUNC) {
  3. Argument *call = NULL;
  4. LinkValue *tmp = NULL;
  5. Inherit *class_inherit = NULL;
  6. setResultCore(result);
  7. call = getArgument(st->u.set_class.father, false, CNEXT_NT);
  8. if (!CHECK_RESULT(result))
  9. goto error_return;
  10. class_inherit = setFather(call);
  11. freeArgument(call, false);
  12. tmp = makeLinkValue(makeClassValue(var_list, inter, class_inherit), belong, inter);
  13. gc_addTmpLink(&tmp->gc_status);
  14. freeResult(result);
  15. {
  16. enum FunctionPtType pt_type_bak = inter->data.default_pt_type;
  17. VarList *var_backup = tmp->value->object.var->next;
  18. inter->data.default_pt_type = object_free_;
  19. tmp->value->object.var->next = var_list;
  20. gc_freeze(inter, var_backup, NULL, true);
  21. // 运行类定义的时候需要调整belong
  22. functionSafeInterStatement(CFUNC(st->u.set_class.st, tmp->value->object.var, result, tmp));
  23. gc_freeze(inter, var_backup, NULL, false);
  24. tmp->value->object.var->next = var_backup;
  25. inter->data.default_pt_type = pt_type_bak;
  26. if (result->type != R_yield && !CHECK_RESULT(result))
  27. goto error_;
  28. freeResult(result);
  29. }
  30. if (st->u.set_class.decoration != NULL){
  31. setDecoration(st->u.set_class.decoration, tmp, CNEXT_NT);
  32. if (!CHECK_RESULT(result))
  33. goto error_;
  34. gc_freeTmpLink(&tmp->gc_status);
  35. tmp = result->value;
  36. result->value = NULL;
  37. freeResult(result);
  38. }
  39. assCore(st->u.set_class.name, tmp, false, true, CNEXT_NT);
  40. if (CHECK_RESULT(result))
  41. setResult(result, inter);
  42. gc_freeTmpLink(&tmp->gc_status);
  43. return result->type;
  44. error_:
  45. gc_freeTmpLink(&tmp->gc_status);
  46. error_return:
  47. setResultErrorSt(E_BaseException, NULL, false, st, CNEXT_NT);
  48. return result->type;
  49. }
  50. ResultType setFunction(FUNC) {
  51. LinkValue *func = NULL;
  52. setResultCore(result);
  53. makeVMFunctionValue(st->u.set_function.function, st->u.set_function.parameter, CNEXT_NT);
  54. if (!CHECK_RESULT(result))
  55. return result->type;
  56. func = result->value;
  57. result->value = NULL;
  58. freeResult(result);
  59. {
  60. enum FunctionPtType pt_type_bak = inter->data.default_pt_type;
  61. VarList *var_backup = func->value->object.var->next;
  62. inter->data.default_pt_type = object_free_;
  63. func->value->object.var->next = var_list;
  64. // 运行函数初始化模块的时候需要调整belong
  65. functionSafeInterStatement(CFUNC(st->u.set_function.first_do, func->value->object.var, result, func));
  66. func->value->object.var->next = var_backup;
  67. inter->data.default_pt_type = pt_type_bak;
  68. if (result->type != R_yield && !CHECK_RESULT(result))
  69. goto error_;
  70. freeResult(result);
  71. }
  72. if (st->u.set_function.decoration != NULL){
  73. setDecoration(st->u.set_function.decoration, func, CNEXT_NT);
  74. if (!CHECK_RESULT(result))
  75. goto error_;
  76. gc_freeTmpLink(&func->gc_status);
  77. func = result->value;
  78. result->value = NULL;
  79. freeResult(result);
  80. }
  81. assCore(st->u.set_function.name, func, false, true, CNEXT_NT);
  82. if (CHECK_RESULT(result)) // 若没有出现错误则设定none
  83. setResult(result, inter);
  84. error_:
  85. gc_freeTmpLink(&func->gc_status);
  86. return result->type;
  87. }
  88. ResultType setLambda(FUNC) {
  89. Statement *resunt_st = NULL;
  90. setResultCore(result);
  91. resunt_st = makeReturnStatement(st->u.base_lambda.function, st->line, st->code_file);
  92. makeVMFunctionValue(resunt_st, st->u.base_lambda.parameter, CNEXT_NT);
  93. resunt_st->u.return_code.value = NULL;
  94. freeStatement(resunt_st);
  95. return result->type;
  96. }
  97. ResultType elementSlice(FUNC) {
  98. LinkValue *element = NULL;
  99. LinkValue *_func_ = NULL;
  100. wchar_t *func_name = NULL;
  101. setResultCore(result);
  102. if (operationSafeInterStatement(CFUNC(st->u.slice_.element, var_list, result, belong)))
  103. return result->type;
  104. element = result->value;
  105. result->value = NULL;
  106. freeResult(result);
  107. func_name = st->u.slice_.type == SliceType_down_ ? inter->data.object_down : inter->data.object_slice;
  108. _func_ = findAttributes(func_name, false, LINEFILE, true, CFUNC_NT(var_list, result, element));
  109. if (!CHECK_RESULT(result))
  110. goto return_;
  111. freeResult(result);
  112. if (_func_ != NULL){
  113. gc_addTmpLink(&_func_->gc_status);
  114. callBackCorePt(_func_, st->u.slice_.index, st->line, st->code_file, CNEXT_NT);
  115. gc_freeTmpLink(&_func_->gc_status);
  116. }
  117. else
  118. setResultErrorSt(E_TypeException, OBJ_NOTSUPPORT(__down__/__slice__), true, st, CNEXT_NT);
  119. return_:
  120. gc_freeTmpLink(&element->gc_status);
  121. return result->type;
  122. }
  123. ResultType callBack(FUNC) {
  124. LinkValue *function_value = NULL;
  125. setResultCore(result);
  126. if (operationSafeInterStatement(CFUNC(st->u.call_function.function, var_list, result, belong)))
  127. return result->type;
  128. function_value = result->value;
  129. result->value = NULL;
  130. freeResult(result);
  131. callBackCorePt(function_value, st->u.call_function.parameter, st->line, st->code_file, CNEXT_NT);
  132. gc_freeTmpLink(&function_value->gc_status);
  133. return result->type;
  134. }
  135. ResultType callBackCorePt(LinkValue *function_value, Parameter *pt, long line, char *file, FUNC_NT) {
  136. Argument *arg = NULL;
  137. int pt_sep =1;
  138. bool sep = false;
  139. setResultCore(result);
  140. gc_addTmpLink(&function_value->gc_status);
  141. arg = getArgument(pt, false, CNEXT_NT);
  142. if (!CHECK_RESULT(result))
  143. goto return_;
  144. for (Parameter *tmp = pt; tmp != NULL; tmp = tmp->next, pt_sep++) {
  145. if (tmp->data.is_sep) {
  146. sep = true;
  147. break;
  148. }
  149. }
  150. freeResult(result);
  151. callBackCore(function_value, arg, line, file, sep ? pt_sep : 0, CNEXT_NT);
  152. return_:
  153. gc_freeTmpLink(&function_value->gc_status);
  154. freeArgument(arg, false);
  155. return result->type;
  156. }
  157. static ResultType callClass(LinkValue *class_value, Argument *arg, fline line, char *file, int pt_sep, FUNC_NT) {
  158. LinkValue *_new_;
  159. setResultCore(result);
  160. gc_addTmpLink(&class_value->gc_status);
  161. _new_ = findAttributes(inter->data.object_new, false, LINEFILE, true, CFUNC_NT(var_list, result, class_value));
  162. if (!CHECK_RESULT(result))
  163. goto return_;
  164. freeResult(result);
  165. if (_new_ != NULL){
  166. gc_addTmpLink(&_new_->gc_status);
  167. callBackCore(_new_, arg, line, file, pt_sep, CNEXT_NT);
  168. gc_freeTmpLink(&_new_->gc_status);
  169. }
  170. else
  171. setResultError(E_TypeException, OBJ_NOTSUPPORT(new(__new__)), line, file, true, CNEXT_NT);
  172. return_:
  173. gc_freeTmpLink(&class_value->gc_status);
  174. return result->type;
  175. }
  176. static ResultType callObject(LinkValue *object_value, Argument *arg, fline line, char *file, int pt_sep, FUNC_NT) {
  177. LinkValue *_call_;
  178. setResultCore(result);
  179. gc_addTmpLink(&object_value->gc_status);
  180. _call_ = findAttributes(inter->data.object_call, false, LINEFILE, true, CFUNC_NT(var_list, result, object_value));
  181. if (!CHECK_RESULT(result))
  182. goto return_;
  183. freeResult(result);
  184. if (_call_ != NULL){
  185. gc_addTmpLink(&_call_->gc_status);
  186. callBackCore(_call_, arg, line, file, pt_sep, CNEXT_NT);
  187. gc_freeTmpLink(&_call_->gc_status);
  188. }
  189. else
  190. setResultError(E_TypeException, OBJ_NOTSUPPORT(call(__call__)), line, file, true, CNEXT_NT);
  191. return_:
  192. gc_freeTmpLink(&object_value->gc_status);
  193. return result->type;
  194. }
  195. static ResultType callCFunction(LinkValue *function_value, Argument *arg, long int line, char *file, int pt_sep, FUNC_NT){
  196. VarList *function_var = NULL;
  197. OfficialFunction of = NULL;
  198. Argument *bak;
  199. setResultCore(result);
  200. gc_addTmpLink(&function_value->gc_status);
  201. setFunctionArgument(&arg, &bak, function_value, line, file, pt_sep, CNEXT_NT);
  202. if (!CHECK_RESULT(result))
  203. goto return_;
  204. of = function_value->value->data.function.of;
  205. function_var = pushVarList(function_value->value->object.out_var != NULL ? function_value->value->object.out_var : var_list, inter);
  206. gc_freeze(inter, var_list, function_var, true);
  207. freeResult(result);
  208. of(CO_FUNC(arg, function_var, result, function_value));
  209. if (result->type == R_func)
  210. result->type = R_opt;
  211. else if (result->type != R_opt && result->type != R_error)
  212. setResult(result, inter);
  213. gc_freeze(inter, var_list, function_var, false);
  214. popVarList(function_var);
  215. freeFunctionArgument(arg, bak);
  216. return_: gc_freeTmpLink(&function_value->gc_status);
  217. return result->type;
  218. }
  219. static ResultType callFFunction(LinkValue *function_value, Argument *arg, long int line, char *file, int pt_sep, FUNC_NT){
  220. ffi_cif cif;
  221. setResultCore(result);
  222. gc_addTmpLink(&function_value->gc_status);
  223. ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 0, &ffi_type_void, NULL);
  224. ffi_call(&cif, function_value->value->data.function.ffunc, NULL, NULL);
  225. setResult(result, inter);
  226. gc_freeTmpLink(&function_value->gc_status);
  227. return result->type;
  228. }
  229. static void updateFunctionYield(Statement *func_st, Statement *node){
  230. func_st->info.node = node->type == yield_code ? node->next : node;
  231. func_st->info.have_info = true;
  232. }
  233. static void newFunctionYield(Statement *func_st, Statement *node, VarList *new_var, Inter *inter){
  234. new_var->next = NULL;
  235. gc_freeze(inter, new_var, NULL, true);
  236. func_st->info.var_list = new_var;
  237. func_st->info.node = node->type == yield_code ? node->next : node;
  238. func_st->info.have_info = true;
  239. }
  240. static void setFunctionResult(LinkValue *func_value, bool yield_run, Result *result, FUNC_CORE) {
  241. Statement *st_func = func_value->value->data.function.function;
  242. if (yield_run) {
  243. if (result->type == R_yield) {
  244. updateFunctionYield(st_func, result->node);
  245. result->type = R_opt;
  246. result->is_yield = true;
  247. } else
  248. freeRunInfo(st_func);
  249. } else {
  250. if (result->type == R_yield) {
  251. newFunctionYield(st_func, result->node, var_list, inter);
  252. result->type = R_opt;
  253. result->is_yield = true;
  254. } else
  255. popVarList(var_list);
  256. }
  257. }
  258. static ResultType callVMFunction(LinkValue *func_value, Argument *arg, long int line, char *file, int pt_sep, FUNC_NT) {
  259. Argument *bak;
  260. VarList *var_func = NULL;
  261. Statement *st_func = NULL;
  262. Parameter *pt_func = func_value->value->data.function.pt;
  263. bool yield_run = false;
  264. setResultCore(result);
  265. st_func = func_value->value->data.function.function;
  266. if (st_func == NULL) {
  267. setResult(result, inter);
  268. return result->type;
  269. }
  270. gc_addTmpLink(&func_value->gc_status);
  271. {
  272. VarList *out_var;
  273. if (func_value->value->object.out_var == NULL)
  274. out_var = var_list; // 当out_var等于空的时候为内联函数
  275. else
  276. out_var = func_value->value->object.out_var;
  277. yield_run = popYieldVarList(st_func, &var_func, out_var, inter);
  278. }
  279. if (yield_run)
  280. st_func = st_func->info.node;
  281. gc_freeze(inter, var_list, var_func, true);
  282. setFunctionArgument(&arg, &bak, func_value, line, file, pt_sep, CNEXT_NT);
  283. if (!CHECK_RESULT(result))
  284. goto return_;
  285. freeResult(result);
  286. gc_addTmpLink(&var_func->hashtable->gc_status);
  287. setParameterCore(line, file, arg, pt_func, var_func, CFUNC_NT(var_list, result, func_value));
  288. freeFunctionArgument(arg, bak);
  289. gc_freeTmpLink(&var_func->hashtable->gc_status);
  290. if (!CHECK_RESULT(result))
  291. goto return_;
  292. freeResult(result);
  293. functionSafeInterStatement(CFUNC(st_func, var_func, result, func_value)); // 运行函数的时候, belong调整为函数本身
  294. return_:
  295. gc_freeze(inter, var_list, var_func, false);
  296. setFunctionResult(func_value, yield_run, result, CFUNC_CORE(var_func));
  297. gc_freeTmpLink(&func_value->gc_status);
  298. return result->type;
  299. }
  300. ResultType callBackCore(LinkValue *function_value, Argument *arg, fline line, char *file, int pt_sep, FUNC_NT) {
  301. setResultCore(result);
  302. gc_addTmpLink(&function_value->gc_status);
  303. if (function_value->value->type == V_func) {
  304. switch (function_value->value->data.function.type) {
  305. case vm_func:
  306. callVMFunction(function_value, arg, line, file, pt_sep, CNEXT_NT);
  307. break;
  308. case c_func:
  309. callCFunction(function_value, arg, line, file, pt_sep, CNEXT_NT);
  310. break;
  311. case f_func:
  312. callFFunction(function_value, arg, line, file, pt_sep, CNEXT_NT);
  313. break;
  314. default:
  315. setResultError(E_SystemException, L"function type error", line, file, true, CNEXT_NT);
  316. goto return_;
  317. }
  318. } else if (function_value->value->type == V_class)
  319. callClass(function_value, arg, line, file, pt_sep, CNEXT_NT);
  320. else
  321. callObject(function_value, arg, line, file, pt_sep, CNEXT_NT);
  322. setResultError(E_BaseException, NULL, line, file, false, CNEXT_NT);
  323. return_:
  324. gc_freeTmpLink(&function_value->gc_status);
  325. return result->type;
  326. }
  327. ResultType setDecoration(DecorationStatement *ds, LinkValue *value, FUNC_NT) {
  328. LinkValue *decall = NULL;
  329. Parameter *pt = NULL;
  330. setResultCore(result);
  331. gc_addTmpLink(&value->gc_status);
  332. for (PASS; ds != NULL; ds = ds->next){
  333. freeResult(result);
  334. if (operationSafeInterStatement(CFUNC(ds->decoration, var_list, result, belong)))
  335. break;
  336. pt = makeValueParameter(makeBaseLinkValueStatement(value, ds->decoration->line, ds->decoration->code_file));
  337. decall = result->value;
  338. result->value = NULL;
  339. freeResult(result);
  340. callBackCorePt(decall, pt, ds->decoration->line, ds->decoration->code_file, CNEXT_NT);
  341. gc_freeTmpLink(&decall->gc_status);
  342. freeParameter(pt, true);
  343. if (!CHECK_RESULT(result))
  344. break;
  345. gc_freeTmpLink(&value->gc_status);
  346. value = result->value;
  347. gc_addTmpLink(&value->gc_status);
  348. }
  349. gc_freeTmpLink(&value->gc_status);
  350. return result->type;
  351. }