You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

print.c 7.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321
  1. #include "vm/print.h"
  2. #include <stdio.h>
  3. #include <string.h>
  4. #include <stdint.h>
  5. static l2_word read_u4le(unsigned char *ops, size_t *ptr) {
  6. unsigned char *data = &ops[*ptr];
  7. l2_word ret =
  8. (l2_word)data[0] |
  9. (l2_word)data[1] << 8 |
  10. (l2_word)data[2] << 16 |
  11. (l2_word)data[3] << 24;
  12. *ptr += 4;
  13. return ret;
  14. }
  15. static l2_word read_u1le(unsigned char *ops, size_t *ptr) {
  16. return ops[(*ptr)++];
  17. }
  18. static double read_d8le(unsigned char *ops, size_t *ptr) {
  19. unsigned char *data = &ops[*ptr];
  20. uint64_t integer = 0 |
  21. (uint64_t)data[0] |
  22. (uint64_t)data[1] << 8 |
  23. (uint64_t)data[2] << 16 |
  24. (uint64_t)data[3] << 24 |
  25. (uint64_t)data[4] << 32 |
  26. (uint64_t)data[5] << 40 |
  27. (uint64_t)data[6] << 48 |
  28. (uint64_t)data[7] << 56;
  29. double num;
  30. memcpy(&num, &integer, 8);
  31. *ptr += 8;
  32. return num;
  33. }
  34. void l2_vm_print_val(struct l2_vm_value *val) {
  35. switch (l2_vm_value_type(val)) {
  36. case L2_VAL_TYPE_NONE:
  37. printf("NONE\n");
  38. break;
  39. case L2_VAL_TYPE_ATOM:
  40. printf("ATOM %u\n", val->atom);
  41. break;
  42. case L2_VAL_TYPE_REAL:
  43. printf("REAL %f\n", val->real);
  44. break;
  45. case L2_VAL_TYPE_ARRAY:
  46. {
  47. if (val->array == NULL) {
  48. printf("ARRAY, empty\n");
  49. return;
  50. }
  51. printf("ARRAY, len %zu\n", val->array->len);
  52. for (size_t i = 0; i < val->array->len; ++i) {
  53. printf(" %zu: %u\n", i, val->array->data[i]);
  54. }
  55. }
  56. break;
  57. case L2_VAL_TYPE_BUFFER:
  58. {
  59. if (val->buffer == NULL) {
  60. printf("BUFFER, empty\n");
  61. return;
  62. }
  63. printf("BUFFER, len %zu\n", val->buffer->len);
  64. for (size_t i = 0; i < val->buffer->len; ++i) {
  65. printf(" %zu: %c\n", i, val->buffer->data[i]);
  66. }
  67. }
  68. break;
  69. case L2_VAL_TYPE_NAMESPACE:
  70. {
  71. if (val->ns == NULL) {
  72. printf("NAMESPACE, empty, parent %u\n", val->extra.ns_parent);
  73. return;
  74. }
  75. printf("NAMESPACE, len %zu, parent %u\n", val->ns->len, val->extra.ns_parent);
  76. for (size_t i = 0; i < val->ns->size; ++i) {
  77. l2_word key = val->ns->data[i];
  78. l2_word v = val->ns->data[val->ns->size + i];
  79. if (key == 0 || key == ~(l2_word)0) continue;
  80. printf(" %u: %u\n", key, v);
  81. }
  82. }
  83. break;
  84. case L2_VAL_TYPE_FUNCTION:
  85. printf("FUNCTION, pos %u, ns %u\n", val->func.pos, val->func.ns);
  86. break;
  87. case L2_VAL_TYPE_CFUNCTION:
  88. // ISO C doesn't let you cast a function pointer to void*.
  89. printf("C FUNCTION, %jx\n", (uintmax_t)val->cfunc);
  90. break;
  91. case L2_VAL_TYPE_ERROR:
  92. printf("ERROR, %s\n", val->error);
  93. break;
  94. case L2_VAL_TYPE_CONTINUATION:
  95. printf("CONTINUATION, call %u, arg %u\n", val->cont.call, val->cont.arg);
  96. break;
  97. }
  98. }
  99. void l2_vm_print_state(struct l2_vm *vm) {
  100. printf("Stack:\n");
  101. l2_vm_print_stack(vm);
  102. printf("Heap:\n");
  103. l2_vm_print_heap(vm);
  104. printf("Frame Stack:\n");
  105. l2_vm_print_fstack(vm);
  106. }
  107. void l2_vm_print_heap(struct l2_vm *vm) {
  108. for (l2_word i = 0; i < vm->valuessize; ++i) {
  109. if (l2_bitset_get(&vm->valueset, i)) {
  110. printf(" %u: ", i);
  111. l2_vm_print_val(&vm->values[i]);
  112. }
  113. }
  114. }
  115. void l2_vm_print_stack(struct l2_vm *vm) {
  116. for (l2_word i = 0; i < vm->sptr; ++i) {
  117. printf(" %i: %i\n", i, vm->stack[i]);
  118. }
  119. }
  120. void l2_vm_print_fstack(struct l2_vm *vm) {
  121. for (l2_word i = 0; i < vm->fsptr; ++i) {
  122. printf(" %i: %i, ret %i, stack base %i\n",
  123. i, vm->fstack[i].ns, vm->fstack[i].retptr, vm->fstack[i].sptr);
  124. }
  125. }
  126. void l2_vm_print_op(unsigned char *ops, size_t opcount, size_t *ptr) {
  127. enum l2_opcode opcode = (enum l2_opcode)ops[(*ptr)++];
  128. switch (opcode) {
  129. case L2_OP_NOP:
  130. printf("NOP\n");
  131. return;
  132. case L2_OP_DISCARD:
  133. printf("DISCARD\n");
  134. return;
  135. case L2_OP_SWAP_DISCARD:
  136. printf("SWAP_DISCARD\n");
  137. return;
  138. case L2_OP_DUP:
  139. printf("DUP\n");
  140. return;
  141. case L2_OP_ADD:
  142. printf("ADD\n");
  143. return;
  144. case L2_OP_FUNC_CALL_U4:
  145. printf("FUNC_CALL %08x\n", read_u4le(ops, ptr));
  146. return;
  147. case L2_OP_FUNC_CALL_U1:
  148. printf("FUNC_CALL %02x\n", read_u1le(ops, ptr));
  149. return;
  150. case L2_OP_FUNC_CALL_INFIX:
  151. printf("FUNC_CALL_INFIX\n");
  152. return;
  153. case L2_OP_RJMP_U4:
  154. printf("RJMP %08x\n", read_u4le(ops, ptr));
  155. return;
  156. case L2_OP_RJMP_U1:
  157. printf("RJMP %02x\n", read_u1le(ops, ptr));
  158. return;
  159. case L2_OP_STACK_FRAME_LOOKUP_U4:
  160. printf("STACK_FRAME_LOOKUP %08x\n", read_u4le(ops, ptr));
  161. return;
  162. case L2_OP_STACK_FRAME_LOOKUP_U1:
  163. printf("STACK_FRAME_LOOKUP %02x\n", read_u1le(ops, ptr));
  164. return;
  165. case L2_OP_STACK_FRAME_SET_U4:
  166. printf("STACK_FRAME_SET %08x\n", read_u4le(ops, ptr));
  167. return;
  168. case L2_OP_STACK_FRAME_SET_U1:
  169. printf("STACK_FRAME_SET %02x\n", read_u1le(ops, ptr));
  170. return;
  171. case L2_OP_STACK_FRAME_REPLACE_U4:
  172. printf("STACK_FRAME_REPLACE %08x\n", read_u4le(ops, ptr));
  173. return;
  174. case L2_OP_STACK_FRAME_REPLACE_U1:
  175. printf("STACK_FRAME_REPLACE %02x\n", read_u1le(ops, ptr));
  176. return;
  177. case L2_OP_RET:
  178. printf("RET\n");
  179. return;
  180. case L2_OP_ALLOC_NONE:
  181. printf("ALLOC_NONE\n");
  182. return;
  183. case L2_OP_ALLOC_ATOM_U4:
  184. printf("ALLOC_ATOM %08x\n", read_u4le(ops, ptr));
  185. return;
  186. case L2_OP_ALLOC_ATOM_U1:
  187. printf("ALLOC_ATOM %02x\n", read_u1le(ops, ptr));
  188. return;
  189. case L2_OP_ALLOC_REAL_D8:
  190. printf("ALLOC_REAL %f\n", read_d8le(ops, ptr));
  191. return;
  192. case L2_OP_ALLOC_BUFFER_STATIC_U4:
  193. {
  194. l2_word w1 = read_u4le(ops, ptr);
  195. l2_word w2 = read_u4le(ops, ptr);;
  196. printf("ALLOC_BUFFER_STATIC %08x %08x\n", w1, w2);
  197. }
  198. return;
  199. case L2_OP_ALLOC_BUFFER_STATIC_U1:
  200. {
  201. l2_word w1 = read_u1le(ops, ptr);
  202. l2_word w2 = read_u1le(ops, ptr);;
  203. printf("ALLOC_BUFFER_STATIC %02x %02x\n", w1, w2);
  204. }
  205. return;
  206. case L2_OP_ALLOC_ARRAY_U4:
  207. printf("ALLOC_ARRAY %08x\n", read_u4le(ops, ptr));
  208. return;
  209. case L2_OP_ALLOC_ARRAY_U1:
  210. printf("ALLOC_ARRAY %02x\n", read_u1le(ops, ptr));
  211. return;
  212. case L2_OP_ALLOC_NAMESPACE:
  213. printf("ALLOC_NAMESPACE\n");
  214. return;
  215. case L2_OP_ALLOC_FUNCTION_U4:
  216. printf("ALLOC_FUNCTION %08x\n", read_u4le(ops, ptr));
  217. return;
  218. case L2_OP_ALLOC_FUNCTION_U1:
  219. printf("ALLOC_FUNCTION %02x\n", read_u1le(ops, ptr));
  220. return;
  221. case L2_OP_NAMESPACE_SET_U4:
  222. printf("NAMESPACE_SET %08x\n", read_u4le(ops, ptr));
  223. return;
  224. case L2_OP_NAMESPACE_SET_U1:
  225. printf("NAMESPACE_SET %02x\n", read_u1le(ops, ptr));
  226. return;
  227. case L2_OP_NAMESPACE_LOOKUP_U4:
  228. printf("NAMESPACE_LOOKUP %08x\n", read_u4le(ops, ptr));
  229. return;
  230. case L2_OP_NAMESPACE_LOOKUP_U1:
  231. printf("NAMESPACE_LOOKUP %02x\n", read_u1le(ops, ptr));
  232. return;
  233. case L2_OP_ARRAY_LOOKUP_U4:
  234. printf("ARRAY_LOOKUP %08x\n", read_u4le(ops, ptr));
  235. return;
  236. case L2_OP_ARRAY_LOOKUP_U1:
  237. printf("ARRAY_LOOKUP %02x\n", read_u1le(ops, ptr));
  238. return;
  239. case L2_OP_ARRAY_SET_U4:
  240. printf("ARRAY_SET %08x\n", read_u4le(ops, ptr));
  241. return;
  242. case L2_OP_ARRAY_SET_U1:
  243. printf("ARRAY_SET %02x\n", read_u1le(ops, ptr));
  244. return;
  245. case L2_OP_DYNAMIC_LOOKUP:
  246. printf("DYNAMIC_LOOKUP\n");
  247. return;
  248. case L2_OP_DYNAMIC_SET:
  249. printf("DYNAMIC_SET\n");
  250. return;
  251. case L2_OP_HALT:
  252. printf("HALT\n");
  253. return;
  254. }
  255. l2_word word = (l2_word)opcode;
  256. char bytes[sizeof(word)];
  257. memcpy(&bytes, &word, sizeof(word));
  258. printf("?");
  259. for (size_t i = 0; i < sizeof(bytes); ++i) {
  260. printf(" %02x", bytes[i]);
  261. }
  262. printf("\n");
  263. }
  264. void l2_vm_print_bytecode(unsigned char *ops, size_t opcount) {
  265. size_t ptr = 0;
  266. while (ptr < opcount) {
  267. printf("%04zu ", ptr);
  268. l2_vm_print_op(ops, opcount, &ptr);
  269. }
  270. }