internal.c 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331
  1. #include "pocketpy/objects/codeobject.h"
  2. #include "pocketpy/objects/sourcedata.h"
  3. #include "pocketpy/pocketpy.h"
  4. #include "pocketpy/common/utils.h"
  5. #include "pocketpy/common/sstream.h"
  6. #include "pocketpy/objects/object.h"
  7. #include "pocketpy/interpreter/vm.h"
  8. #include "pocketpy/compiler/compiler.h"
  9. #include <stdint.h>
  10. VM* pk_current_vm;
  11. py_GlobalRef py_True;
  12. py_GlobalRef py_False;
  13. py_GlobalRef py_None;
  14. py_GlobalRef py_NIL;
  15. static VM pk_default_vm;
  16. static VM* pk_all_vm[16];
  17. void py_initialize() {
  18. MemoryPools__initialize();
  19. py_Name__initialize();
  20. pk_current_vm = pk_all_vm[0] = &pk_default_vm;
  21. // initialize some convenient references
  22. static py_TValue _True, _False, _None, _NIL;
  23. py_newbool(&_True, true);
  24. py_newbool(&_False, false);
  25. py_newnone(&_None);
  26. py_newnil(&_NIL);
  27. py_True = &_True;
  28. py_False = &_False;
  29. py_None = &_None;
  30. py_NIL = &_NIL;
  31. VM__ctor(&pk_default_vm);
  32. }
  33. void py_finalize() {
  34. for(int i = 1; i < 16; i++) {
  35. VM* vm = pk_all_vm[i];
  36. if(vm) {
  37. VM__dtor(vm);
  38. free(vm);
  39. }
  40. }
  41. VM__dtor(&pk_default_vm);
  42. pk_current_vm = NULL;
  43. py_Name__finalize();
  44. MemoryPools__finalize();
  45. }
  46. void py_switchvm(int index) {
  47. if(index < 0 || index >= 16) c11__abort("invalid vm index");
  48. if(!pk_all_vm[index]) {
  49. pk_all_vm[index] = malloc(sizeof(VM));
  50. VM__ctor(pk_all_vm[index]);
  51. }
  52. pk_current_vm = pk_all_vm[index];
  53. }
  54. int py_currentvm() {
  55. for(int i = 0; i < 16; i++) {
  56. if(pk_all_vm[i] == pk_current_vm) return i;
  57. }
  58. return -1;
  59. }
  60. const char* pk_opname(Opcode op) {
  61. const static char* OP_NAMES[] = {
  62. #define OPCODE(name) #name,
  63. #include "pocketpy/xmacros/opcodes.h"
  64. #undef OPCODE
  65. };
  66. return OP_NAMES[op];
  67. }
  68. static void disassemble(CodeObject* co) {
  69. c11_vector /*T=int*/ jumpTargets;
  70. c11_vector__ctor(&jumpTargets, sizeof(int));
  71. for(int i = 0; i < co->codes.count; i++) {
  72. Bytecode* bc = c11__at(Bytecode, &co->codes, i);
  73. if(Bytecode__is_forward_jump(bc)) {
  74. int target = (int16_t)bc->arg + i;
  75. c11_vector__push(int, &jumpTargets, target);
  76. }
  77. }
  78. c11_sbuf ss;
  79. c11_sbuf__ctor(&ss);
  80. int prev_line = -1;
  81. for(int i = 0; i < co->codes.count; i++) {
  82. Bytecode byte = c11__getitem(Bytecode, &co->codes, i);
  83. BytecodeEx ex = c11__getitem(BytecodeEx, &co->codes_ex, i);
  84. char line[8] = "";
  85. if(ex.lineno == prev_line) {
  86. // do nothing
  87. } else {
  88. snprintf(line, sizeof(line), "%d", ex.lineno);
  89. if(prev_line != -1) c11_sbuf__write_char(&ss, '\n');
  90. prev_line = ex.lineno;
  91. }
  92. char pointer[4] = "";
  93. c11__foreach(int, &jumpTargets, it) {
  94. if(*it == i) {
  95. snprintf(pointer, sizeof(pointer), "->");
  96. break;
  97. }
  98. }
  99. char buf[32];
  100. snprintf(buf, sizeof(buf), "%-8s%-3s%-3d ", line, pointer, i);
  101. c11_sbuf__write_cstr(&ss, buf);
  102. c11_sbuf__write_cstr(&ss, pk_opname(byte.op));
  103. c11_sbuf__write_char(&ss, ex.is_virtual ? '*' : ' ');
  104. int padding = 24 - strlen(pk_opname(byte.op));
  105. for(int j = 0; j < padding; j++)
  106. c11_sbuf__write_char(&ss, ' ');
  107. do {
  108. if(Bytecode__is_forward_jump(&byte)) {
  109. pk_sprintf(&ss, "%d (to %d)", (int16_t)byte.arg, (int16_t)byte.arg + i);
  110. break;
  111. }
  112. c11_sbuf__write_int(&ss, byte.arg);
  113. switch(byte.op) {
  114. case OP_LOAD_CONST:
  115. case OP_FORMAT_STRING:
  116. case OP_IMPORT_PATH: {
  117. py_Ref path = c11__at(py_TValue, &co->consts, byte.arg);
  118. pk_sprintf(&ss, " (%q)", py_tosv(path));
  119. break;
  120. }
  121. case OP_LOAD_NAME:
  122. case OP_LOAD_GLOBAL:
  123. case OP_LOAD_NONLOCAL:
  124. case OP_STORE_GLOBAL:
  125. case OP_LOAD_ATTR:
  126. case OP_LOAD_METHOD:
  127. case OP_STORE_ATTR:
  128. case OP_DELETE_ATTR:
  129. case OP_BEGIN_CLASS:
  130. case OP_GOTO:
  131. case OP_DELETE_GLOBAL:
  132. case OP_STORE_CLASS_ATTR: {
  133. pk_sprintf(&ss, " (%n)", byte.arg);
  134. break;
  135. }
  136. case OP_LOAD_FAST:
  137. case OP_STORE_FAST:
  138. case OP_DELETE_FAST: {
  139. py_Name name = c11__getitem(py_Name, &co->varnames, byte.arg);
  140. pk_sprintf(&ss, " (%n)", name);
  141. break;
  142. }
  143. case OP_LOAD_FUNCTION: {
  144. const FuncDecl* decl = c11__getitem(FuncDecl*, &co->func_decls, byte.arg);
  145. pk_sprintf(&ss, " (%s)", decl->code.name->data);
  146. break;
  147. }
  148. case OP_BINARY_OP: {
  149. py_Name name = byte.arg & 0xFF;
  150. pk_sprintf(&ss, " (%n)", name);
  151. break;
  152. }
  153. }
  154. } while(0);
  155. if(i != co->codes.count - 1) c11_sbuf__write_char(&ss, '\n');
  156. }
  157. c11_string* output = c11_sbuf__submit(&ss);
  158. pk_current_vm->print(output->data);
  159. pk_current_vm->print("\n");
  160. c11_string__delete(output);
  161. c11_vector__dtor(&jumpTargets);
  162. }
  163. bool py_exec(const char* source, const char* filename, enum py_CompileMode mode, py_Ref module) {
  164. VM* vm = pk_current_vm;
  165. CodeObject co;
  166. SourceData_ src = SourceData__rcnew(source, filename, mode, false);
  167. Error* err = pk_compile(src, &co);
  168. if(err) {
  169. py_exception("SyntaxError", err->msg);
  170. py_BaseException__stpush(&vm->curr_exception, src, err->lineno, NULL);
  171. PK_DECREF(src);
  172. free(err);
  173. return false;
  174. }
  175. // disassemble(&co);
  176. if(!module) module = &vm->main;
  177. Frame* frame = Frame__new(&co, module, NULL, vm->stack.sp, vm->stack.sp, &co);
  178. VM__push_frame(vm, frame);
  179. FrameResult res = VM__run_top_frame(vm);
  180. CodeObject__dtor(&co);
  181. PK_DECREF(src);
  182. if(res == RES_ERROR) return false;
  183. if(res == RES_RETURN) return true;
  184. c11__unreachedable();
  185. }
  186. bool py_call(py_Ref f, int argc, py_Ref argv) {
  187. if(f->type == tp_nativefunc) {
  188. return f->_cfunc(argc, argv);
  189. } else {
  190. py_push(f);
  191. py_pushnil();
  192. for(int i = 0; i < argc; i++)
  193. py_push(py_offset(argv, i));
  194. return py_vectorcall(argc, 0);
  195. }
  196. }
  197. bool py_callmethod(py_Ref self, py_Name name, int argc, py_Ref argv) { return -1; }
  198. bool py_vectorcall(uint16_t argc, uint16_t kwargc) {
  199. VM* vm = pk_current_vm;
  200. return VM__vectorcall(vm, argc, kwargc, false) != RES_ERROR;
  201. }
  202. py_Ref py_retval() { return &pk_current_vm->last_retval; }
  203. bool py_pushmethod(py_Name name) { return pk_pushmethod(py_peek(-1), name); }
  204. bool pk_pushmethod(py_StackRef self, py_Name name) {
  205. // NOTE: `out` and `out_self` may overlap with `self`
  206. py_Type type;
  207. // handle super() proxy
  208. if(py_istype(self, tp_super)) {
  209. type = *(py_Type*)py_touserdata(self);
  210. *self = *py_getslot(self, 0);
  211. } else {
  212. type = self->type;
  213. }
  214. py_Ref cls_var = py_tpfindname(type, name);
  215. if(cls_var != NULL) {
  216. pk_current_vm->stack.sp++;
  217. switch(cls_var->type) {
  218. case tp_function:
  219. case tp_nativefunc: {
  220. py_TValue self_bak = *self;
  221. // `out` may overlap with `self`. If we assign `out`, `self` may be corrupted.
  222. self[0] = *cls_var;
  223. self[1] = self_bak;
  224. break;
  225. }
  226. case tp_staticmethod:
  227. self[0] = *py_getslot(cls_var, 0);
  228. self[1] = *py_NIL;
  229. break;
  230. case tp_classmethod:
  231. self[0] = *py_getslot(cls_var, 0);
  232. self[1] = c11__getitem(py_TypeInfo, &pk_current_vm->types, type).self;
  233. break;
  234. default: c11__unreachedable();
  235. }
  236. return true;
  237. }
  238. return false;
  239. }
  240. py_Ref py_tpfindmagic(py_Type t, py_Name name) {
  241. assert(py_ismagicname(name));
  242. py_TypeInfo* types = (py_TypeInfo*)pk_current_vm->types.data;
  243. do {
  244. py_Ref f = &types[t].magic[name];
  245. if(!py_isnil(f)) return f;
  246. t = types[t].base;
  247. } while(t);
  248. return NULL;
  249. }
  250. py_Ref py_tpfindname(py_Type t, py_Name name) {
  251. py_TypeInfo* types = (py_TypeInfo*)pk_current_vm->types.data;
  252. do {
  253. py_Ref res = py_getdict(&types[t].self, name);
  254. if(res) return res;
  255. t = types[t].base;
  256. } while(t);
  257. return NULL;
  258. }
  259. py_Ref py_tpmagic(py_Type type, py_Name name) {
  260. assert(py_ismagicname(name));
  261. VM* vm = pk_current_vm;
  262. return &c11__at(py_TypeInfo, &vm->types, type)->magic[name];
  263. }
  264. py_Ref py_tpobject(py_Type type) {
  265. assert(type);
  266. VM* vm = pk_current_vm;
  267. return &c11__at(py_TypeInfo, &vm->types, type)->self;
  268. }
  269. const char* py_tpname(py_Type type) {
  270. if(!type) return "nil";
  271. VM* vm = pk_current_vm;
  272. py_Name name = c11__at(py_TypeInfo, &vm->types, type)->name;
  273. return py_name2str(name);
  274. }
  275. bool py_tpcall(py_Type type, int argc, py_Ref argv) {
  276. return py_call(py_tpobject(type), argc, argv);
  277. }
  278. bool pk_callmagic(py_Name name, int argc, py_Ref argv) {
  279. assert(argc >= 1);
  280. assert(py_ismagicname(name));
  281. py_Ref tmp = py_tpfindmagic(argv->type, name);
  282. if(!tmp) return AttributeError(argv, name);
  283. return py_call(tmp, argc, argv);
  284. }
  285. bool StopIteration() {
  286. VM* vm = pk_current_vm;
  287. assert(!vm->is_stopiteration); // flag is already set
  288. vm->is_stopiteration = true;
  289. return false;
  290. }