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.2KB

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