codeobject.h 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. #pragma once
  2. #include "obj.h"
  3. #include "pointer.h"
  4. enum Opcode {
  5. #define OPCODE(name) OP_##name,
  6. #include "opcodes.h"
  7. #undef OPCODE
  8. };
  9. static const char* OP_NAMES[] = {
  10. #define OPCODE(name) #name,
  11. #include "opcodes.h"
  12. #undef OPCODE
  13. };
  14. struct ByteCode{
  15. uint8_t op;
  16. int arg;
  17. uint16_t line;
  18. };
  19. _Str pad(const _Str& s, const int n){
  20. return s + _Str(n - s.size(), ' ');
  21. }
  22. enum CompileMode {
  23. EXEC_MODE,
  24. EVAL_MODE,
  25. SINGLE_MODE
  26. };
  27. struct CodeObject {
  28. CompileMode mode = EXEC_MODE;
  29. std::vector<ByteCode> co_code;
  30. _Str co_filename;
  31. _Str co_name;
  32. PyVarList co_consts;
  33. std::vector<std::shared_ptr<NamePointer>> co_names;
  34. int addName(const _Str& name, NameScope scope){
  35. auto p = std::make_shared<NamePointer>(name, scope);
  36. for(int i=0; i<co_names.size(); i++){
  37. if(*co_names[i] == *p) return i;
  38. }
  39. co_names.push_back(p);
  40. return co_names.size() - 1;
  41. }
  42. int addConst(PyVar v){
  43. co_consts.push_back(v);
  44. return co_consts.size() - 1;
  45. }
  46. void __copyToEnd(int start, int end){
  47. auto _start = co_code.begin() + start;
  48. auto _end = co_code.begin() + end;
  49. co_code.insert(co_code.end(), _start, _end);
  50. }
  51. _Str toString(){
  52. _StrStream ss;
  53. int prev_line = -1;
  54. for(int i=0; i<co_code.size(); i++){
  55. const ByteCode& byte = co_code[i];
  56. _Str line = std::to_string(byte.line);
  57. if(byte.line == prev_line) line = "";
  58. else{
  59. if(prev_line != -1) ss << "\n";
  60. prev_line = byte.line;
  61. }
  62. ss << pad(line, 12) << " " << pad(std::to_string(i), 3);
  63. ss << " " << pad(OP_NAMES[byte.op], 20) << " ";
  64. ss << (byte.arg == -1 ? "" : std::to_string(byte.arg));
  65. if(i != co_code.size() - 1) ss << '\n';
  66. }
  67. _StrStream consts;
  68. consts << "co_consts: ";
  69. for(int i=0; i<co_consts.size(); i++){
  70. consts << co_consts[i]->getTypeName();
  71. if(i != co_consts.size() - 1) consts << ", ";
  72. }
  73. _StrStream names;
  74. names << "co_names: ";
  75. for(int i=0; i<co_names.size(); i++){
  76. names << co_names[i]->name;
  77. if(i != co_names.size() - 1) names << ", ";
  78. }
  79. ss << '\n' << consts.str() << '\n' << names.str() << '\n';
  80. for(int i=0; i<co_consts.size(); i++){
  81. auto fn = std::get_if<_Func>(&co_consts[i]->_native);
  82. if(fn) ss << '\n' << fn->code->co_name << ":\n" << fn->code->toString();
  83. }
  84. return _Str(ss);
  85. }
  86. };
  87. class Frame {
  88. private:
  89. std::vector<PyVar> s_data;
  90. int ip = 0;
  91. public:
  92. StlDict* f_globals;
  93. StlDict f_locals;
  94. const CodeObject* code;
  95. Frame(const CodeObject* code, StlDict locals, StlDict* globals)
  96. : code(code), f_locals(locals), f_globals(globals) {}
  97. inline const ByteCode& readCode() {
  98. return code->co_code[ip++];
  99. }
  100. int currentLine(){
  101. if(isEnd()) return -1;
  102. return code->co_code[ip].line;
  103. }
  104. int stackSize() const {
  105. return s_data.size();
  106. }
  107. inline bool isEnd() const {
  108. return ip >= code->co_code.size();
  109. }
  110. inline PyVar __pop(){
  111. PyVar v = s_data.back();
  112. s_data.pop_back();
  113. return v;
  114. }
  115. inline PyVar __deref_pointer(VM*, PyVar);
  116. inline PyVar popValue(VM* vm){
  117. return __deref_pointer(vm, __pop());
  118. }
  119. inline PyVar topValue(VM* vm){
  120. return __deref_pointer(vm, s_data.back());
  121. }
  122. inline PyVar topNValue(VM* vm, int n=-1){
  123. return __deref_pointer(vm, s_data[s_data.size() + n]);
  124. }
  125. inline void push(PyVar v){
  126. s_data.push_back(v);
  127. }
  128. inline void jumpTo(int i){
  129. this->ip = i;
  130. }
  131. PyVarList popNValuesReversed(VM* vm, int n){
  132. PyVarList v(n);
  133. for(int i=n-1; i>=0; i--) v[i] = popValue(vm);
  134. return v;
  135. }
  136. PyVarList __popNReversed(int n){
  137. PyVarList v(n);
  138. for(int i=n-1; i>=0; i--) v[i] = __pop();
  139. return v;
  140. }
  141. };