runcall.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362
  1. #include "__run.h"
  2. ResultType setClass(INTER_FUNCTIONSIG) {
  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, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
  8. if (!CHECK_RESULT(result))
  9. goto error_;
  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. functionSafeInterStatement(CALL_INTER_FUNCTIONSIG(st->u.set_class.st, tmp->value->object.var, result, tmp));
  22. gc_freeze(inter, var_backup, NULL, false);
  23. tmp->value->object.var->next = var_backup;
  24. inter->data.default_pt_type = pt_type_bak;
  25. if (result->type != R_yield && !CHECK_RESULT(result))
  26. goto error_;
  27. freeResult(result);
  28. }
  29. if (st->u.set_class.decoration != NULL){
  30. setDecoration(st->u.set_class.decoration, tmp, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
  31. if (!CHECK_RESULT(result))
  32. goto error_;
  33. gc_freeTmpLink(&tmp->gc_status);
  34. tmp = result->value;
  35. result->value = NULL;
  36. freeResult(result);
  37. }
  38. assCore(st->u.set_class.name, tmp, false, true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
  39. if (CHECK_RESULT(result))
  40. setResult(result, inter);
  41. gc_freeTmpLink(&tmp->gc_status);
  42. return result->type;
  43. error_:
  44. gc_freeTmpLink(&tmp->gc_status);
  45. setResultErrorSt(E_BaseException, NULL, false, st, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
  46. return result->type;
  47. }
  48. ResultType setFunction(INTER_FUNCTIONSIG) {
  49. LinkValue *func = NULL;
  50. setResultCore(result);
  51. makeVMFunctionValue(st->u.set_function.function, st->u.set_function.parameter, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
  52. if (!CHECK_RESULT(result))
  53. return result->type;
  54. func = result->value;
  55. result->value = NULL;
  56. freeResult(result);
  57. {
  58. enum FunctionPtType pt_type_bak = inter->data.default_pt_type;
  59. VarList *var_backup = func->value->object.var->next;
  60. inter->data.default_pt_type = object_free_;
  61. func->value->object.var->next = var_list;
  62. functionSafeInterStatement(CALL_INTER_FUNCTIONSIG(st->u.set_function.first_do, func->value->object.var, result, func));
  63. func->value->object.var->next = var_backup;
  64. inter->data.default_pt_type = pt_type_bak;
  65. if (result->type != R_yield && !CHECK_RESULT(result))
  66. goto error_;
  67. freeResult(result);
  68. }
  69. if (st->u.set_function.decoration != NULL){
  70. setDecoration(st->u.set_function.decoration, func, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
  71. if (!CHECK_RESULT(result))
  72. goto error_;
  73. gc_freeTmpLink(&func->gc_status);
  74. func = result->value;
  75. result->value = NULL;
  76. freeResult(result);
  77. }
  78. assCore(st->u.set_function.name, func, false, true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
  79. if (CHECK_RESULT(result))
  80. setResult(result, inter);
  81. error_:
  82. gc_freeTmpLink(&func->gc_status);
  83. return result->type;
  84. }
  85. ResultType setLambda(INTER_FUNCTIONSIG) {
  86. Statement *resunt_st = NULL;
  87. setResultCore(result);
  88. resunt_st = makeReturnStatement(st->u.base_lambda.function, st->line, st->code_file);
  89. makeVMFunctionValue(resunt_st, st->u.base_lambda.parameter, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
  90. resunt_st->u.return_code.value = NULL;
  91. freeStatement(resunt_st);
  92. return result->type;
  93. }
  94. ResultType elementSlice(INTER_FUNCTIONSIG) {
  95. LinkValue *element = NULL;
  96. LinkValue *_func_ = NULL;
  97. wchar_t *func_name = NULL;
  98. setResultCore(result);
  99. if (operationSafeInterStatement(CALL_INTER_FUNCTIONSIG(st->u.slice_.element, var_list, result, belong)))
  100. return result->type;
  101. element = result->value;
  102. result->value = NULL;
  103. freeResult(result);
  104. func_name = st->u.slice_.type == SliceType_down_ ? inter->data.object_down : inter->data.object_slice;
  105. _func_ = findAttributes(func_name, false, 0, "sys", true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, element));
  106. if (_func_ != NULL){
  107. gc_addTmpLink(&_func_->gc_status);
  108. callBackCorePt(_func_, st->u.slice_.index, st->line, st->code_file, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
  109. gc_freeTmpLink(&_func_->gc_status);
  110. }
  111. else
  112. setResultErrorSt(E_TypeException, OBJ_NOTSUPPORT(__down__/__slice__), true, st, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
  113. gc_freeTmpLink(&element->gc_status);
  114. return result->type;
  115. }
  116. ResultType callBack(INTER_FUNCTIONSIG) {
  117. LinkValue *function_value = NULL;
  118. setResultCore(result);
  119. if (operationSafeInterStatement(CALL_INTER_FUNCTIONSIG(st->u.call_function.function, var_list, result, belong)))
  120. return result->type;
  121. function_value = result->value;
  122. result->value = NULL;
  123. freeResult(result);
  124. callBackCorePt(function_value, st->u.call_function.parameter, st->line, st->code_file, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
  125. gc_freeTmpLink(&function_value->gc_status);
  126. return result->type;
  127. }
  128. ResultType callBackCorePt(LinkValue *function_value, Parameter *pt, long line, char *file, INTER_FUNCTIONSIG_NOT_ST) {
  129. Argument *arg = NULL;
  130. int pt_sep =1;
  131. bool sep = false;
  132. setResultCore(result);
  133. gc_addTmpLink(&function_value->gc_status);
  134. arg = getArgument(pt, false, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
  135. if (!CHECK_RESULT(result))
  136. goto return_;
  137. for (Parameter *tmp = pt; tmp != NULL; tmp = tmp->next, pt_sep++) {
  138. if (tmp->data.is_sep) {
  139. sep = true;
  140. break;
  141. }
  142. }
  143. freeResult(result);
  144. callBackCore(function_value, arg, line, file, sep ? pt_sep : 0, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
  145. return_:
  146. gc_freeTmpLink(&function_value->gc_status);
  147. freeArgument(arg, false);
  148. return result->type;
  149. }
  150. static ResultType callClass(LinkValue *class_value, Argument *arg, fline line, char *file, int pt_sep, INTER_FUNCTIONSIG_NOT_ST) {
  151. LinkValue *_new_ = findAttributes(inter->data.object_new, false, 0, "sys", true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, class_value));
  152. setResultCore(result);
  153. if (_new_ != NULL){
  154. gc_addTmpLink(&_new_->gc_status);
  155. callBackCore(_new_, arg, line, file, pt_sep, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
  156. gc_freeTmpLink(&_new_->gc_status);
  157. }
  158. else
  159. setResultError(E_TypeException, OBJ_NOTSUPPORT(new(__new__)), line, file, true,
  160. CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
  161. return result->type;
  162. }
  163. static ResultType callObject(LinkValue *object_value, Argument *arg, fline line, char *file, int pt_sep, INTER_FUNCTIONSIG_NOT_ST) {
  164. LinkValue *_call_ = findAttributes(inter->data.object_call, false, 0, "sys", true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, object_value));
  165. setResultCore(result);
  166. if (_call_ != NULL){
  167. gc_addTmpLink(&_call_->gc_status);
  168. callBackCore(_call_, arg, line, file, pt_sep, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
  169. gc_freeTmpLink(&_call_->gc_status);
  170. }
  171. else
  172. setResultError(E_TypeException, OBJ_NOTSUPPORT(call(__call__)), line, file, true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
  173. return result->type;
  174. }
  175. static ResultType callCFunction(LinkValue *function_value, Argument *arg, long int line, char *file, int pt_sep, INTER_FUNCTIONSIG_NOT_ST){
  176. VarList *function_var = NULL;
  177. OfficialFunction of = NULL;
  178. Argument *bak;
  179. setResultCore(result);
  180. gc_addTmpLink(&function_value->gc_status);
  181. setFunctionArgument(&arg, &bak, function_value, line, file, pt_sep, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
  182. if (!CHECK_RESULT(result))
  183. goto return_;
  184. of = function_value->value->data.function.of;
  185. function_var = pushVarList(function_value->value->object.out_var != NULL ? function_value->value->object.out_var : var_list, inter);
  186. gc_freeze(inter, var_list, function_var, true);
  187. freeResult(result);
  188. of(CALL_OFFICAL_FUNCTION(arg, function_var, result, function_value->belong));
  189. if (result->type == R_func)
  190. result->type = R_opt;
  191. else if (result->type != R_opt && result->type != R_error)
  192. setResult(result, inter);
  193. gc_freeze(inter, var_list, function_var, false);
  194. popVarList(function_var);
  195. freeFunctionArgument(arg, bak);
  196. return_: gc_freeTmpLink(&function_value->gc_status);
  197. return result->type;
  198. }
  199. static void updateFunctionYield(Statement *func_st, Statement *node){
  200. func_st->info.node = node->type == yield_code ? node->next : node;
  201. func_st->info.have_info = true;
  202. }
  203. static void newFunctionYield(Statement *func_st, Statement *node, VarList *new_var, Inter *inter){
  204. new_var->next = NULL;
  205. gc_freeze(inter, new_var, NULL, true);
  206. func_st->info.var_list = new_var;
  207. func_st->info.node = node->type == yield_code ? node->next : node;
  208. func_st->info.have_info = true;
  209. }
  210. static void setFunctionResult(LinkValue *func_value, bool yield_run, Result *result, INTER_FUNCTIONSIG_CORE) {
  211. Statement *st_func = func_value->value->data.function.function;
  212. if (yield_run) {
  213. if (result->type == R_yield) {
  214. updateFunctionYield(st_func, result->node);
  215. result->type = R_opt;
  216. result->is_yield = true;
  217. } else
  218. freeRunInfo(st_func);
  219. } else {
  220. if (result->type == R_yield) {
  221. newFunctionYield(st_func, result->node, var_list, inter);
  222. result->type = R_opt;
  223. result->is_yield = true;
  224. } else
  225. popVarList(var_list);
  226. }
  227. }
  228. static ResultType callVMFunction(LinkValue *func_value, Argument *arg, long int line, char *file, int pt_sep, INTER_FUNCTIONSIG_NOT_ST) {
  229. Argument *bak;
  230. VarList *var_func = NULL;
  231. Statement *st_func = NULL;
  232. Parameter *pt_func = func_value->value->data.function.pt;
  233. bool yield_run = false;
  234. setResultCore(result);
  235. st_func = func_value->value->data.function.function;
  236. if (st_func == NULL) {
  237. setResult(result, inter);
  238. return result->type;
  239. }
  240. gc_addTmpLink(&func_value->gc_status);
  241. {
  242. VarList *out_var;
  243. if (func_value->value->object.out_var == NULL)
  244. out_var = var_list; // 当out_var等于空的时候为内联函数
  245. else
  246. out_var = func_value->value->object.out_var;
  247. yield_run = popYieldVarList(st_func, &var_func, out_var, inter);
  248. }
  249. if (yield_run)
  250. st_func = st_func->info.node;
  251. gc_freeze(inter, var_list, var_func, true);
  252. setFunctionArgument(&arg, &bak, func_value, line, file, pt_sep, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
  253. if (!CHECK_RESULT(result))
  254. goto return_;
  255. freeResult(result);
  256. gc_addTmpLink(&var_func->hashtable->gc_status);
  257. setParameterCore(line, file, arg, pt_func, var_func, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, func_value->belong));
  258. freeFunctionArgument(arg, bak);
  259. gc_freeTmpLink(&var_func->hashtable->gc_status);
  260. if (!CHECK_RESULT(result))
  261. goto return_;
  262. freeResult(result);
  263. functionSafeInterStatement(CALL_INTER_FUNCTIONSIG(st_func, var_func, result, func_value->belong));
  264. return_:
  265. gc_freeze(inter, var_list, var_func, false);
  266. setFunctionResult(func_value, yield_run, result, CALL_INTER_FUNCTIONSIG_CORE(var_func));
  267. gc_freeTmpLink(&func_value->gc_status);
  268. return result->type;
  269. }
  270. ResultType callBackCore(LinkValue *function_value, Argument *arg, fline line, char *file, int pt_sep, INTER_FUNCTIONSIG_NOT_ST) {
  271. setResultCore(result);
  272. gc_addTmpLink(&function_value->gc_status);
  273. if (function_value->value->type == V_func && function_value->value->data.function.type == vm_func)
  274. callVMFunction(function_value, arg, line, file, pt_sep, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
  275. else if (function_value->value->type == V_func && function_value->value->data.function.type == c_func)
  276. callCFunction(function_value, arg, line, file, pt_sep, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
  277. else if (function_value->value->type == V_class)
  278. callClass(function_value, arg, line, file, pt_sep, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
  279. else
  280. callObject(function_value, arg, line, file, pt_sep, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
  281. setResultError(E_BaseException, NULL, line, file, false, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
  282. gc_freeTmpLink(&function_value->gc_status);
  283. return result->type;
  284. }
  285. ResultType setDecoration(DecorationStatement *ds, LinkValue *value, INTER_FUNCTIONSIG_NOT_ST) {
  286. LinkValue *decall = NULL;
  287. Parameter *pt = NULL;
  288. setResultCore(result);
  289. gc_addTmpLink(&value->gc_status);
  290. for (PASS; ds != NULL; ds = ds->next){
  291. freeResult(result);
  292. if (operationSafeInterStatement(CALL_INTER_FUNCTIONSIG(ds->decoration, var_list, result, belong)))
  293. break;
  294. pt = makeValueParameter(makeBaseLinkValueStatement(value, ds->decoration->line, ds->decoration->code_file));
  295. decall = result->value;
  296. result->value = NULL;
  297. freeResult(result);
  298. callBackCorePt(decall, pt, ds->decoration->line, ds->decoration->code_file, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
  299. gc_freeTmpLink(&decall->gc_status);
  300. freeParameter(pt, true);
  301. if (!CHECK_RESULT(result))
  302. break;
  303. gc_freeTmpLink(&value->gc_status);
  304. value = result->value;
  305. gc_addTmpLink(&value->gc_status);
  306. }
  307. gc_freeTmpLink(&value->gc_status);
  308. return result->type;
  309. }