stdlib.c 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. // clang --target=wasm32 -c -emit-llvm -O3 -ffreestanding -fno-builtin -Wall stdlib.c
  2. #include <stdint.h>
  3. #include <stddef.h>
  4. #include <stdbool.h>
  5. #include "stdlib.h"
  6. /*
  7. */
  8. void __memset8(void *_dest, uint64_t val, uint32_t length)
  9. {
  10. uint64_t *dest = _dest;
  11. do
  12. {
  13. *dest++ = val;
  14. } while (--length);
  15. }
  16. void __memset(void *_dest, uint8_t val, size_t length)
  17. {
  18. uint8_t *dest = _dest;
  19. do
  20. {
  21. *dest++ = val;
  22. } while (--length);
  23. }
  24. /*
  25. * Our memcpy can only deal with multiples of 8 bytes. This is enough for
  26. * simple allocator below.
  27. */
  28. void __memcpy8(void *_dest, void *_src, uint32_t length)
  29. {
  30. uint64_t *dest = _dest;
  31. uint64_t *src = _src;
  32. do
  33. {
  34. *dest++ = *src++;
  35. } while (--length);
  36. }
  37. void __memcpy(void *_dest, const void *_src, uint32_t length)
  38. {
  39. uint8_t *dest = _dest;
  40. const uint8_t *src = _src;
  41. while (length--)
  42. {
  43. *dest++ = *src++;
  44. }
  45. }
  46. /*
  47. * Fast-ish clear, 8 bytes at a time.
  48. */
  49. void __bzero8(void *_dest, uint32_t length)
  50. {
  51. uint64_t *dest = _dest;
  52. while (length--)
  53. {
  54. *dest++ = 0;
  55. }
  56. }
  57. int __memcmp_ord(uint8_t *a, uint8_t *b, uint32_t len)
  58. {
  59. do
  60. {
  61. int diff = (int)(*a++) - (int)(*b++);
  62. if (diff)
  63. return diff;
  64. } while (--len);
  65. return 0;
  66. }
  67. // This function is used for abi decoding integers.
  68. // ABI encoding is big endian, and can have integers of 8 to 256 bits
  69. // (1 to 32 bytes). This function copies length bytes and reverses the
  70. // order since wasm is little endian.
  71. void __be32toleN(uint8_t *from, uint8_t *to, uint32_t length)
  72. {
  73. from += 31;
  74. do
  75. {
  76. *to++ = *from--;
  77. } while (--length);
  78. }
  79. void __beNtoleN(uint8_t *from, uint8_t *to, uint32_t length)
  80. {
  81. from += length;
  82. do
  83. {
  84. *to++ = *--from;
  85. } while (--length);
  86. }
  87. // This function is for used for abi encoding integers
  88. // ABI encoding is big endian.
  89. void __leNtobe32(uint8_t *from, uint8_t *to, uint32_t length)
  90. {
  91. to += 31;
  92. do
  93. {
  94. *to-- = *from++;
  95. } while (--length);
  96. }
  97. void __leNtobeN(uint8_t *from, uint8_t *to, uint32_t length)
  98. {
  99. to += length;
  100. do
  101. {
  102. *--to = *from++;
  103. } while (--length);
  104. }
  105. // Create a new vector. If initial is -1 then clear the data. This is done since a null pointer valid in wasm
  106. struct vector *vector_new(uint32_t members, uint32_t size, uint8_t *initial)
  107. {
  108. struct vector *v;
  109. size_t size_array = members * size;
  110. v = __malloc(sizeof(*v) + size_array);
  111. v->len = members;
  112. v->size = members;
  113. uint8_t *data = v->data;
  114. if ((int)initial != -1)
  115. {
  116. while (size_array--)
  117. {
  118. *data++ = *initial++;
  119. }
  120. }
  121. else
  122. {
  123. while (size_array--)
  124. {
  125. *data++ = 0;
  126. }
  127. }
  128. return v;
  129. }
  130. uint64_t vector_hash(struct vector *v)
  131. {
  132. uint64_t hash = 0;
  133. uint8_t *data = v->data;
  134. uint32_t len = v->len;
  135. while (len--)
  136. {
  137. hash += *data;
  138. }
  139. return hash;
  140. }
  141. bool __memcmp(uint8_t *left, uint32_t left_len, uint8_t *right, uint32_t right_len)
  142. {
  143. if (left_len != right_len)
  144. return false;
  145. while (left_len--)
  146. {
  147. if (*left++ != *right++)
  148. return false;
  149. }
  150. return true;
  151. }
  152. struct vector *concat(uint8_t *left, uint32_t left_len, uint8_t *right, uint32_t right_len)
  153. {
  154. size_t size_array = left_len + right_len;
  155. struct vector *v = __malloc(sizeof(*v) + size_array);
  156. v->len = size_array;
  157. v->size = size_array;
  158. uint8_t *data = v->data;
  159. while (left_len--)
  160. {
  161. *data++ = *left++;
  162. }
  163. while (right_len--)
  164. {
  165. *data++ = *right++;
  166. }
  167. return v;
  168. }