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.

vm.h 2.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  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, struct l2_vm_array *args);
  10. enum l2_value_type {
  11. L2_VAL_TYPE_NONE,
  12. L2_VAL_TYPE_ATOM,
  13. L2_VAL_TYPE_REAL,
  14. L2_VAL_TYPE_BUFFER,
  15. L2_VAL_TYPE_ARRAY,
  16. L2_VAL_TYPE_NAMESPACE,
  17. L2_VAL_TYPE_FUNCTION,
  18. L2_VAL_TYPE_CFUNCTION,
  19. };
  20. enum l2_value_flags {
  21. L2_VAL_MARKED = 1 << 6,
  22. L2_VAL_CONST = 1 << 7,
  23. };
  24. // The smallest size an l2_vm_value can be is 16 bytes on common platforms.
  25. // Pointers are 8 bytes, and since we need to store _at least_ 1 pointer +
  26. // 1 byte for flags, it's going to be padded up to 16 bytes anyways.
  27. // Might as well store some useful extra info in here.
  28. struct l2_vm_value {
  29. // Byte 0: 4 bytes
  30. union {
  31. l2_word ns_parent;
  32. } extra;
  33. // Byte 4: 1 byte, 3 bytes padding
  34. uint8_t flags;
  35. // Byte 8: 8 bytes
  36. union {
  37. l2_word atom;
  38. double real;
  39. struct l2_vm_buffer *buffer;
  40. struct l2_vm_array *array;
  41. struct l2_vm_namespace *ns;
  42. struct {
  43. l2_word pos;
  44. l2_word ns;
  45. } func;
  46. l2_vm_cfunction cfunc;
  47. };
  48. };
  49. #define l2_vm_value_type(val) ((enum l2_value_type)((val)->flags & 0x0f))
  50. struct l2_vm_buffer {
  51. size_t len;
  52. char data[];
  53. };
  54. struct l2_vm_array {
  55. size_t len;
  56. size_t size;
  57. l2_word data[];
  58. };
  59. struct l2_vm_namespace {
  60. size_t len;
  61. size_t size;
  62. l2_word mask;
  63. l2_word data[];
  64. };
  65. struct l2_vm_stack_frame {
  66. l2_word ns;
  67. l2_word retptr;
  68. };
  69. l2_word l2_vm_namespace_get(struct l2_vm *vm, struct l2_vm_value *ns, l2_word key);
  70. void l2_vm_namespace_set(struct l2_vm_value *ns, l2_word key, l2_word val);
  71. int l2_vm_namespace_replace(struct l2_vm *vm, struct l2_vm_value *ns, l2_word key, l2_word val);
  72. struct l2_vm {
  73. l2_word *ops;
  74. size_t opcount;
  75. l2_word iptr;
  76. struct l2_io_writer *std_output;
  77. struct l2_io_writer *std_error;
  78. struct l2_vm_value *values;
  79. size_t valuessize;
  80. struct l2_bitset valueset;
  81. l2_word stack[1024];
  82. l2_word sptr;
  83. struct l2_vm_stack_frame fstack[1024];
  84. l2_word fsptr;
  85. };
  86. void l2_vm_init(struct l2_vm *vm, l2_word *ops, size_t opcount);
  87. l2_word l2_vm_alloc(struct l2_vm *vm, enum l2_value_type typ, enum l2_value_flags flags);
  88. void l2_vm_free(struct l2_vm *vm);
  89. void l2_vm_step(struct l2_vm *vm);
  90. void l2_vm_run(struct l2_vm *vm);
  91. size_t l2_vm_gc(struct l2_vm *vm);
  92. #endif