vm.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388
  1. /**
  2. ******************************************************************************
  3. * @file : vm.c
  4. * @author : simon
  5. * @brief : Interpret the bytecode from chunk
  6. * @attention : None
  7. * @date : 2023/8/17
  8. ******************************************************************************
  9. */
  10. #include "vm.h"
  11. #include "common.h"
  12. #include "compiler.h"
  13. #include "debug.h"
  14. #include "memory.h"
  15. #include <stdarg.h>
  16. #include <time.h>
  17. VM vm;
  18. /// \brief 重置栈
  19. static void resetStack() {
  20. vm.stackTop = vm.stack;// 指针指向栈底
  21. vm.frameCount = 0;
  22. }
  23. static void runtimeError(const char *format, ...) {
  24. va_list args;
  25. va_start(args, format);
  26. vfprintf(stderr, format, args);
  27. va_end(args);
  28. fputs("\n", stderr);
  29. for (int i = vm.frameCount - 1; i >= 0; i--) {
  30. CallFrame *frame = &vm.frames[i];
  31. ObjFunction *function = frame->closure->function;
  32. size_t instruction = frame->ip - function->chunk.code - 1;
  33. int line = function->chunk.lines[instruction];
  34. fprintf(stderr, "[line %d] in ", line);
  35. if (function->name == NULL) {
  36. fprintf(stderr, "script\n");
  37. } else {
  38. fprintf(stderr, "%s()\n", function->name->chars);
  39. }
  40. }
  41. resetStack();
  42. }
  43. static void defineNative(const char *name, NativeFn function) {
  44. push(OBJ_VAL(copyString(name, (int) strlen(name))));
  45. push(OBJ_VAL(newNative(function)));
  46. tableSet(&vm.globals, AS_STRING(vm.stack[0]), vm.stack[1]);
  47. pop();
  48. pop();
  49. }
  50. static Value clockNative(int argCount, Value *args) {
  51. return NUMBER_VAL((double) clock() / CLOCKS_PER_SEC);
  52. }
  53. void initVM() {
  54. resetStack();
  55. vm.objects = NULL;
  56. initTable(&vm.globals);
  57. initTable(&vm.strings);
  58. /// Native Function define.
  59. defineNative("clock", clockNative);
  60. }
  61. static Value peek(int distance) {
  62. return vm.stackTop[-1 - distance];
  63. }
  64. static bool call(ObjClosure *closure, int argCount) {
  65. if (argCount != closure->function->arity) {
  66. runtimeError("Expected %d arguments but got %d", closure->function->arity, argCount);
  67. return false;
  68. }
  69. if (vm.frameCount == FRAMES_MAX) {
  70. runtimeError("Stack overflow.");
  71. return false;
  72. }
  73. CallFrame *frame = &vm.frames[vm.frameCount++];
  74. frame->closure = closure;
  75. frame->ip = closure->function->chunk.code;
  76. frame->slots = vm.stackTop - argCount - 1;
  77. return true;
  78. }
  79. static bool callValue(Value callee, int argCount) {
  80. if (IS_OBJ(callee)) {
  81. switch (OBJ_TYPE(callee)) {
  82. case OBJ_CLOSURE:
  83. return call(AS_CLOSURE(callee), argCount);
  84. case OBJ_NATIVE: {
  85. NativeFn fn = AS_NATIVE(callee);
  86. Value result = fn(argCount, vm.stackTop - argCount);
  87. vm.stackTop -= argCount + 1;
  88. push(result);
  89. return true;
  90. }
  91. default:
  92. break;// Non-callable object type.
  93. }
  94. }
  95. runtimeError("Can only call functions and classes.");
  96. return false;
  97. }
  98. static bool isFalse(Value value) {
  99. // the nil and false will return true
  100. return IS_NIL(value) || (IS_BOOL(value) && !AS_BOOL(value));
  101. }
  102. static void concatenate() {
  103. ObjString *b = AS_STRING(pop());
  104. ObjString *a = AS_STRING(pop());
  105. int length = a->length + b->length;
  106. char *chars = ALLOCATE(char, length + 1);
  107. memcpy(chars, a->chars, a->length);
  108. memcpy(chars + a->length, b->chars, b->length);
  109. chars[length] = '\0';
  110. ObjString *result = takeString(chars, length);
  111. push(OBJ_VAL(result));
  112. }
  113. static ObjUpvalue *captureUpvalue(Value *local) {
  114. ObjUpvalue *createdUpvalue = newUpvalue(local);
  115. return createdUpvalue;
  116. }
  117. /// VM run function - exec opcode
  118. /// \return
  119. static InterpretResult run() {
  120. CallFrame *frame = &vm.frames[vm.frameCount - 1];
  121. //! <macro> reads the byte currently pointed at by ip
  122. //! and then advances the instruction pointer
  123. #define READ_BYTE() (*frame->ip++)
  124. //! reads the next byte from the bytecode
  125. //! treats the resulting number as an index
  126. #define READ_CONSTANT() \
  127. (frame->closure->function->chunk.constants.values[READ_BYTE()])
  128. #define READ_SHORT() \
  129. (frame->ip += 2, (uint16_t) ((frame->ip[-2] << 8) | frame->ip[-1]))
  130. #define READ_STRING() AS_STRING(READ_CONSTANT())
  131. #define BINARY_OP(valueType, op) \
  132. do { \
  133. if (!IS_NUMBER(peek(0)) || !IS_NUMBER(peek(1))) { \
  134. runtimeError("Operands must be numbers."); \
  135. return INTERPRET_RUNTIME_ERROR; \
  136. } \
  137. double b = AS_NUMBER(pop()); \
  138. double a = AS_NUMBER(pop()); \
  139. push(valueType(a op b)); \
  140. } while (false)
  141. for (;;) {
  142. #ifdef DEBUG_TRACE_EXECUTION
  143. //! <Stack tracing> start
  144. printf("\n!!! <Stack tracing now>:\n");
  145. printf("------------------------\n|");
  146. for (Value *slot = vm.stack; slot < vm.stackTop; slot++) {
  147. printf("[ ");
  148. printValue(*slot);
  149. printf(" ]");
  150. }
  151. printf("\n------------------------");
  152. printf("\n");
  153. printf("\n");
  154. //! <Stack tracing> end
  155. printf("The Instruction: \n");
  156. disassembleInstruction(&frame->closure->function->chunk, (int) (frame->ip - frame->closure->function->chunk.code));
  157. #endif
  158. uint8_t opCode = READ_BYTE();
  159. switch (opCode) {
  160. case OP_CONSTANT: {
  161. Value constant = READ_CONSTANT();
  162. push(constant);
  163. break;
  164. }
  165. case OP_NIL:
  166. push(NIL_VAL);
  167. break;
  168. case OP_TRUE:
  169. push(BOOL_VAL(true));
  170. break;
  171. case OP_FALSE:
  172. push(BOOL_VAL(false));
  173. break;
  174. case OP_POP:
  175. pop();
  176. break;
  177. case OP_DEFINE_GLOBAL: {
  178. ObjString *name = READ_STRING();
  179. tableSet(&vm.globals, name, peek(0));
  180. pop();
  181. break;
  182. }
  183. case OP_GET_GLOBAL: {
  184. ObjString *name = READ_STRING();
  185. Value value;
  186. if (!tableGet(&vm.globals, name, &value)) {
  187. runtimeError("Undefined variable '%s'.", name->chars);
  188. return INTERPRET_RUNTIME_ERROR;
  189. }
  190. push(value);
  191. break;
  192. }
  193. case OP_SET_GLOBAL: {
  194. ObjString *name = READ_STRING();
  195. if (tableSet(&vm.globals, name, peek(0))) {
  196. tableDelete(&vm.globals, name);
  197. runtimeError("Undefined variable '%s'.", name->chars);
  198. return INTERPRET_RUNTIME_ERROR;
  199. }
  200. break;
  201. }
  202. case OP_GET_LOCAL: {
  203. uint8_t slot = READ_BYTE();
  204. push(frame->slots[slot]);
  205. break;
  206. }
  207. case OP_SET_LOCAL: {
  208. uint8_t slot = READ_BYTE();
  209. frame->slots[slot] = peek(0);
  210. break;
  211. }
  212. case OP_ADD: {
  213. if (IS_STRING(peek(0)) && IS_STRING(peek(1))) {
  214. // 字串拼接
  215. concatenate();
  216. } else if (IS_NUMBER(peek(0)) && IS_NUMBER(peek(1))) {
  217. double b = AS_NUMBER(pop());
  218. double a = AS_NUMBER(pop());
  219. push(NUMBER_VAL(a + b));
  220. } else {
  221. runtimeError("Operands must be two numbers or two strings.");
  222. return INTERPRET_RUNTIME_ERROR;
  223. }
  224. break;
  225. }
  226. case OP_SUBTRACT:
  227. BINARY_OP(NUMBER_VAL, -);
  228. break;
  229. case OP_MULTIPLY:
  230. BINARY_OP(NUMBER_VAL, *);
  231. break;
  232. case OP_DIVIDE:
  233. BINARY_OP(NUMBER_VAL, /);
  234. break;
  235. case OP_NOT:
  236. push(BOOL_VAL(isFalse(pop())));
  237. break;
  238. case OP_NEGATE:
  239. if (!IS_NUMBER(peek(0))) {
  240. runtimeError("Operand must be a number.");
  241. return INTERPRET_RUNTIME_ERROR;
  242. }
  243. push(NUMBER_VAL(-AS_NUMBER(pop())));
  244. break;
  245. case OP_EQUAL: {
  246. Value b = pop();
  247. Value a = pop();
  248. push(BOOL_VAL(valuesEqual(a, b)));
  249. break;
  250. }
  251. case OP_GREATER:
  252. BINARY_OP(BOOL_VAL, >);
  253. break;
  254. case OP_LESS:
  255. BINARY_OP(BOOL_VAL, <);
  256. break;
  257. case OP_PRINT: {
  258. printValue(pop());
  259. printf("\n");
  260. break;
  261. }
  262. case OP_JUMP_IF_FALSE: {
  263. uint16_t offset = READ_SHORT();
  264. if (isFalse(peek(0))) frame->ip += offset;
  265. break;
  266. }
  267. case OP_JUMP: {
  268. uint16_t offset = READ_SHORT();
  269. frame->ip += offset;
  270. break;
  271. }
  272. case OP_LOOP: {
  273. uint16_t offset = READ_SHORT();
  274. frame->ip -= offset;
  275. break;
  276. }
  277. case OP_CALL: {
  278. int argCount = READ_BYTE();
  279. if (!callValue(peek(argCount), argCount)) {
  280. return INTERPRET_RUNTIME_ERROR;
  281. }
  282. frame = &vm.frames[vm.frameCount - 1];
  283. break;
  284. }
  285. case OP_CLOSURE: {
  286. ObjFunction *function = AS_FUNCTION(READ_CONSTANT());
  287. ObjClosure *closure = newClosure(function);
  288. push(OBJ_VAL(closure));
  289. for (int i = 0; i < closure->upvalueCount; i++) {
  290. uint8_t isLocal = READ_BYTE();
  291. uint8_t index = READ_BYTE();
  292. if (isLocal) {
  293. closure->upvalues[i] = captureUpvalue(frame->slots + index);
  294. } else {
  295. closure->upvalues[i] = frame->closure->upvalues[index];
  296. }
  297. }
  298. break;
  299. }
  300. case OP_GET_UPVALUE: {
  301. uint8_t slot = READ_BYTE();
  302. push(*frame->closure->upvalues[slot]->location);
  303. break;
  304. }
  305. case OP_SET_UPVALUE: {
  306. uint8_t slot = READ_BYTE();
  307. *frame->closure->upvalues[slot]->location = peek(0);
  308. break;
  309. }
  310. case OP_RETURN: {
  311. Value result = pop();
  312. vm.frameCount--;
  313. if (vm.frameCount == 0) {
  314. pop();
  315. return INTERPRET_OK;
  316. }
  317. vm.stackTop = frame->slots;
  318. push(result);
  319. frame = &vm.frames[vm.frameCount - 1];
  320. break;
  321. }
  322. default:
  323. break;
  324. }
  325. }
  326. #undef READ_BYTE
  327. #undef READ_CONSTANT
  328. #undef READ_SHORT
  329. #undef READ_STRING
  330. #undef BINARY_OP
  331. }
  332. void freeVM() {
  333. freeTable(&vm.globals);
  334. freeTable(&vm.strings);
  335. freeObjects();
  336. }
  337. InterpretResult interpret(const char *source) {
  338. ObjFunction *function = compile(source);
  339. if (function == NULL) return INTERPRET_COMPILE_ERROR;
  340. push(OBJ_VAL(function));
  341. ObjClosure *closure = newClosure(function);
  342. pop();
  343. push(OBJ_VAL(closure));
  344. // CallFrame *frame = &vm.frames[vm.frameCount++];
  345. // frame->function = function;
  346. // frame->ip = function->chunk.code;
  347. // frame->slots = vm.stack;
  348. call(closure, 0);
  349. return run();
  350. }
  351. void push(Value value) {
  352. *vm.stackTop = value;
  353. vm.stackTop++;
  354. }
  355. Value pop() {
  356. vm.stackTop--;
  357. //! NOTE: 出栈后,里面的值没有清除
  358. return *vm.stackTop;
  359. }