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.

loader.c 2.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. #include "loader.h"
  2. #include <stdint.h>
  3. int l2_bc_serialize(FILE *outf, l2_word *data, size_t len) {
  4. char header[4] = { 0x1b, 0x6c, 0x32, 0x63 };
  5. if (fwrite(header, 1, 4, outf) < 4) {
  6. fprintf(stderr, "Write error\n");
  7. return -1;
  8. }
  9. uint32_t version = l2_bytecode_version;
  10. unsigned char version_buf[4] = {
  11. (version & 0xff000000ull) >> 24,
  12. (version & 0x00ff0000ull) >> 16,
  13. (version & 0x0000ff00ull) >> 8,
  14. (version & 0x000000ffull) >> 0,
  15. };
  16. if (fwrite(version_buf, 1, 4, outf) < 4) {
  17. fprintf(stderr, "Write error\n");
  18. return -1;
  19. }
  20. struct l2_io_file_writer w = {
  21. .f = outf,
  22. };
  23. struct l2_bufio_writer writer;
  24. l2_bufio_writer_init(&writer, &w.w);
  25. unsigned char word_buf[4];
  26. for (size_t i = 0; i < len; ++i) {
  27. uint32_t word = data[i];
  28. word_buf[0] = (word & 0xff000000ull) >> 24;
  29. word_buf[1] = (word & 0x00ff0000ull) >> 16;
  30. word_buf[2] = (word & 0x0000ff00ull) >> 8;
  31. word_buf[3] = (word & 0x000000ffull) >> 0;
  32. l2_bufio_put_n(&writer, word_buf, 4);
  33. }
  34. l2_bufio_flush(&writer);
  35. return 0;
  36. }
  37. int l2_bc_load(FILE *inf, struct l2_io_writer *w) {
  38. // Header is already read by main
  39. unsigned char version_buf[4];
  40. if (fread(version_buf, 1, 4, inf) < 4) {
  41. fprintf(stderr, "Read error\n");
  42. return -1;
  43. }
  44. uint32_t version = 0 |
  45. ((uint32_t)version_buf[0]) << 24 |
  46. ((uint32_t)version_buf[1]) << 16 |
  47. ((uint32_t)version_buf[2]) << 8 |
  48. ((uint32_t)version_buf[3]) << 0;
  49. if (version != l2_bytecode_version) {
  50. fprintf(
  51. stderr, "Version mismatch! Bytecode file uses bytecode version %i"
  52. ", but your build of lang2 uses bytecode version %i\n",
  53. version, l2_bytecode_version);
  54. return -1;
  55. }
  56. struct l2_bufio_writer writer;
  57. l2_bufio_writer_init(&writer, w);
  58. // Must be divisible by 4
  59. unsigned char buffer[4096];
  60. while (1) {
  61. size_t n = fread(buffer, 1, sizeof(buffer), inf);
  62. if (n < 4) {
  63. l2_bufio_flush(&writer);
  64. return 0;
  65. }
  66. for (size_t i = 0; i < n; i += 4) {
  67. l2_word word = 0 |
  68. ((uint32_t)buffer[i + 0]) << 24 |
  69. ((uint32_t)buffer[i + 1]) << 16 |
  70. ((uint32_t)buffer[i + 2]) << 8 |
  71. ((uint32_t)buffer[i + 3]) << 0;
  72. l2_bufio_put_n(&writer, &word, 4);
  73. }
  74. }
  75. }