debug.c 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. //
  2. // Created by 李晓明 on 2023/8/16.
  3. //
  4. #include "debug.h"
  5. #include "object.h"
  6. #include "value.h"
  7. #include <stdio.h>
  8. static int constantInstruction(const char *, Chunk *, int);
  9. static int simpleInstruction(const char *name, int offset);
  10. static int byteInstruction(const char *name, Chunk *chunk, int offset);
  11. void disassembleChunk(Chunk *chunk, const char *name) {
  12. printf("== %s STARTING ==\n", name);
  13. for (int offset = 0; offset < chunk->count;) {
  14. offset = disassembleInstruction(chunk, offset);
  15. }
  16. printf("== %s END ==\n", name);
  17. }
  18. static int jumpInstruction(const char *name, int sign, Chunk *chunk, int offset) {
  19. uint16_t jump = (uint16_t) (chunk->code[offset + 1] << 8);
  20. jump |= chunk->code[offset + 2];
  21. printf("%-16s %4d -> %d\n", name, offset, offset + 3 + sign * jump);
  22. return offset + 3;
  23. }
  24. static int invokeInstruction(const char *name, Chunk *chunk, int offset) {
  25. uint8_t constant = chunk->code[offset + 1];
  26. uint8_t argCount = chunk->code[offset + 2];
  27. printf("%-16s (%d args) %4d '", name, argCount, constant);
  28. printValue(chunk->constants.values[constant]);
  29. printf("\n");
  30. return offset + 3;
  31. }
  32. int disassembleInstruction(Chunk *chunk, int offset) {
  33. printf("%04d ", offset);
  34. if (offset > 0 && chunk->lines[offset] == chunk->lines[offset - 1]) {
  35. printf(" | ");
  36. } else {
  37. printf("%4d ", chunk->lines[offset]);
  38. }
  39. uint8_t instruction = chunk->code[offset];
  40. switch (instruction) {
  41. case OP_CONSTANT: return constantInstruction("OP_CONSTANT", chunk, offset);
  42. case OP_NIL: return simpleInstruction("OP_NIL", offset);
  43. case OP_TRUE: return simpleInstruction("OP_TRUE", offset);
  44. case OP_FALSE: return simpleInstruction("OP_FALSE", offset);
  45. case OP_POP: return simpleInstruction("OP_POP", offset);
  46. case OP_DEFINE_GLOBAL: return constantInstruction("OP_DEFINE_GLOBAL", chunk, offset);
  47. case OP_GET_GLOBAL: return constantInstruction("OP_GET_GLOBAL", chunk, offset);
  48. case OP_SET_GLOBAL: return constantInstruction("OP_SET_GLOBAL", chunk, offset);
  49. case OP_GET_LOCAL: return byteInstruction("OP_GET_LOCAL", chunk, offset);
  50. case OP_SET_LOCAL: return byteInstruction("OP_SET_LOCAL", chunk, offset);
  51. case OP_ADD: return simpleInstruction("OP_ADD", offset);
  52. case OP_SUBTRACT: return simpleInstruction("OP_SUBTRACT", offset);
  53. case OP_MULTIPLY: return simpleInstruction("OP_MULTIPLY", offset);
  54. case OP_DIVIDE: return simpleInstruction("OP_DIVIDE", offset);
  55. case OP_NOT: return simpleInstruction("OP_NOT", offset);
  56. case OP_NEGATE: return simpleInstruction("OP_NEGATE", offset);
  57. case OP_EQUAL: return simpleInstruction("OP_EQUAL", offset);
  58. case OP_GREATER: return simpleInstruction("OP_GREATER", offset);
  59. case OP_LESS: return simpleInstruction("OP_LESS", offset);
  60. case OP_PRINT: return simpleInstruction("OP_PRINT", offset);
  61. case OP_JUMP: return jumpInstruction("OP_JUMP", 1, chunk, offset);
  62. case OP_LOOP: return jumpInstruction("OP_LOOP", -1, chunk, offset);
  63. case OP_CALL: return byteInstruction("OP_CALL", chunk, offset);
  64. case OP_JUMP_IF_FALSE: return jumpInstruction("OP_JUMP_IF_FALSE", 1, chunk, offset);
  65. case OP_CLOSURE: {
  66. offset++;
  67. uint8_t constant = chunk->code[offset++];
  68. printf("%-16s %4d ", "OP_CLOSURE", constant);
  69. printValue(chunk->constants.values[constant]);
  70. printf("\n");
  71. ObjFunction *function = AS_FUNCTION(chunk->constants.values[constant]);
  72. for (int j = 0; j < function->upvalueCount; j++) {
  73. int isLocal = chunk->code[offset++];
  74. int index = chunk->code[offset++];
  75. printf("%04d | %s %d\n", offset - 2, isLocal ? "local" : "upvalue", index);
  76. }
  77. return offset;
  78. }
  79. case OP_GET_UPVALUE: return byteInstruction("OP_GET_UPVALUE", chunk, offset);
  80. case OP_SET_UPVALUE: return byteInstruction("OP_SET_UPVALUE", chunk, offset);
  81. case OP_CLOSE_UPVALUE: return simpleInstruction("OP_CLOSE_UPVALUE", offset);
  82. case OP_CLASS: return constantInstruction("OP_CLASS", chunk, offset);
  83. case OP_METHOD: return constantInstruction("OP_METHOD", chunk, offset);
  84. case OP_GET_PROPERTY: return constantInstruction("OP_GET_PROPERTY", chunk, offset);
  85. case OP_SET_PROPERTY: return constantInstruction("OP_SET_PROPERTY", chunk, offset);
  86. case OP_INVOKE: return invokeInstruction("OP_INVOKE", chunk, offset);
  87. case OP_INHERIT: return simpleInstruction("OP_INHERIT", offset);
  88. case OP_GET_SUPER: return constantInstruction("OP_GET_SUPER", chunk, offset);
  89. case OP_SUPER_INVOKE: return invokeInstruction("OP_SUPER_INVOKE", chunk, offset);
  90. case OP_RETURN: return simpleInstruction("OP_RETURN", offset);
  91. default:
  92. printf("Unknown opcode %d\n", instruction);
  93. return offset + 1;
  94. }
  95. }
  96. /**
  97. * @brief 打印常量指令
  98. * @param name
  99. * @param chunk
  100. * @param offset
  101. * @return
  102. */
  103. static int constantInstruction(const char *name, Chunk *chunk, int offset) {
  104. uint8_t constant = chunk->code[offset + 1];
  105. printf("%-16s %4d '", name, constant);
  106. printValue(chunk->constants.values[constant]);
  107. printf("'\n");
  108. return offset + 2;
  109. }
  110. /**
  111. * @brief 打印指令
  112. * @param name 名称
  113. * @param offset 偏移
  114. * @return
  115. */
  116. static int simpleInstruction(const char *name, int offset) {
  117. printf("%s\n", name);
  118. return offset + 1;
  119. }
  120. static int byteInstruction(const char *name, Chunk *chunk, int offset) {
  121. uint8_t slot = chunk->code[offset + 1];
  122. printf("%-16s %4d\n", name, slot);
  123. return offset + 2;
  124. }