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.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. #ifndef L2_VM_H
  2. #define L2_VM_H
  3. #include <stdlib.h>
  4. #include "../bytecode.h"
  5. #include "../bitset.h"
  6. #include "../io.h"
  7. struct l2_vm;
  8. struct l2_vm_array;
  9. typedef l2_word (*l2_vm_cfunction)(struct l2_vm *vm, l2_word argc, l2_word *argv);
  10. typedef l2_word (*l2_vm_contcallback)(struct l2_vm *vm, l2_word retval, l2_word cont);
  11. typedef void (*l2_vm_gcmarker)(
  12. struct l2_vm *vm, void *data, void (*mark)(struct l2_vm *vm, l2_word id));
  13. enum l2_value_type {
  14. L2_VAL_TYPE_NONE,
  15. L2_VAL_TYPE_ATOM,
  16. L2_VAL_TYPE_REAL,
  17. L2_VAL_TYPE_BUFFER,
  18. L2_VAL_TYPE_ARRAY,
  19. L2_VAL_TYPE_NAMESPACE,
  20. L2_VAL_TYPE_FUNCTION,
  21. L2_VAL_TYPE_CFUNCTION,
  22. L2_VAL_TYPE_CONTINUATION,
  23. L2_VAL_TYPE_RETURN,
  24. L2_VAL_TYPE_ERROR,
  25. };
  26. const char *l2_value_type_name(enum l2_value_type typ);
  27. enum l2_value_flags {
  28. L2_VAL_MARKED = 1 << 7,
  29. L2_VAL_CONST = 1 << 6,
  30. L2_VAL_SBO = 1 << 5,
  31. };
  32. struct l2_vm_contcontext {
  33. l2_vm_contcallback callback;
  34. l2_vm_gcmarker marker;
  35. l2_word args;
  36. };
  37. // The smallest size an l2_vm_value can be is 16 bytes on common platforms.
  38. // Pointers are 8 bytes, and since we need to store _at least_ 1 pointer +
  39. // 1 byte for flags, it's going to be padded up to 16 bytes anyways.
  40. // Might as well store some useful extra info in here.
  41. struct l2_vm_value {
  42. // Byte 0: 4 bytes
  43. union {
  44. l2_word ns_parent;
  45. l2_word cont_call;
  46. l2_word buf_length;
  47. l2_word arr_length;
  48. } extra;
  49. // Byte 4: 1 byte, 3 bytes padding
  50. uint8_t flags;
  51. // Byte 8: 8 bytes
  52. union {
  53. l2_word atom;
  54. double real;
  55. char *buffer;
  56. struct l2_vm_array *array;
  57. l2_word shortarray[2];
  58. struct l2_vm_namespace *ns;
  59. struct {
  60. l2_word pos;
  61. l2_word ns;
  62. } func;
  63. l2_vm_cfunction cfunc;
  64. struct l2_vm_contcontext *cont;
  65. l2_word ret;
  66. char *error;
  67. };
  68. };
  69. #define l2_value_get_type(val) ((enum l2_value_type)((val)->flags & 0x0f))
  70. l2_word *l2_value_arr_data(struct l2_vm *vm, struct l2_vm_value *val);
  71. l2_word l2_value_arr_get(struct l2_vm *vm, struct l2_vm_value *val, l2_word k);
  72. l2_word l2_value_arr_set(struct l2_vm *vm, struct l2_vm_value *val, l2_word k, l2_word v);
  73. struct l2_vm_array {
  74. size_t size;
  75. l2_word data[];
  76. };
  77. struct l2_vm_namespace {
  78. size_t len;
  79. size_t size;
  80. l2_word mask;
  81. l2_word data[];
  82. };
  83. l2_word l2_vm_namespace_get(struct l2_vm *vm, struct l2_vm_value *ns, l2_word key);
  84. void l2_vm_namespace_set(struct l2_vm_value *ns, l2_word key, l2_word val);
  85. int l2_vm_namespace_replace(struct l2_vm *vm, struct l2_vm_value *ns, l2_word key, l2_word val);
  86. struct l2_vm_stack_frame {
  87. l2_word ns;
  88. l2_word sptr;
  89. l2_word retptr;
  90. l2_word args;
  91. };
  92. struct l2_vm {
  93. int halted;
  94. int need_gc;
  95. int need_check_retval;
  96. unsigned char *ops;
  97. size_t opslen;
  98. l2_word iptr;
  99. struct l2_io_writer *std_output;
  100. struct l2_io_writer *std_error;
  101. struct l2_vm_value *values;
  102. size_t valuessize;
  103. struct l2_bitset valueset;
  104. l2_word stack[1024];
  105. l2_word sptr;
  106. struct l2_vm_stack_frame fstack[1024];
  107. l2_word fsptr;
  108. l2_word knone, ktrue, kfalse, kstop;
  109. l2_word gc_start;
  110. };
  111. void l2_vm_init(struct l2_vm *vm, unsigned char *ops, size_t opslen);
  112. l2_word l2_vm_alloc(struct l2_vm *vm, enum l2_value_type typ, enum l2_value_flags flags);
  113. l2_word l2_vm_error(struct l2_vm *vm, const char *fmt, ...);
  114. l2_word l2_vm_type_error(struct l2_vm *vm, struct l2_vm_value *val);
  115. void l2_vm_free(struct l2_vm *vm);
  116. void l2_vm_step(struct l2_vm *vm);
  117. void l2_vm_run(struct l2_vm *vm);
  118. size_t l2_vm_gc(struct l2_vm *vm);
  119. int l2_vm_val_is_true(struct l2_vm *vm, struct l2_vm_value *val);
  120. #endif