wasm_vector.c 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. /*
  2. * Copyright (C) 2019 Intel Corporation. All rights reserved.
  3. * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  4. */
  5. #include "wasm_log.h"
  6. #include "wasm_vector.h"
  7. #include "wasm_memory.h"
  8. static uint8*
  9. alloc_vector_data(uint32 length, uint32 size_elem)
  10. {
  11. uint64 total_size = ((uint64)size_elem) * length;
  12. uint8 *data;
  13. if (total_size > UINT32_MAX) {
  14. return NULL;
  15. }
  16. if ((data = wasm_malloc((uint32)total_size))) {
  17. memset(data, 0, (uint32)total_size);
  18. }
  19. return data;
  20. }
  21. static bool
  22. extend_vector(Vector *vector, uint32 length)
  23. {
  24. uint8 *data;
  25. if (length <= vector->max_elements)
  26. return true;
  27. if (length < vector->size_elem * 3 / 2)
  28. length = vector->size_elem * 3 / 2;
  29. if (!(data = alloc_vector_data(length, vector->size_elem))) {
  30. return false;
  31. }
  32. memcpy(data, vector->data, vector->size_elem * vector->max_elements);
  33. wasm_free(vector->data);
  34. vector->data = data;
  35. vector->max_elements = length;
  36. return true;
  37. }
  38. bool
  39. wasm_vector_init(Vector *vector, uint32 init_length, uint32 size_elem)
  40. {
  41. if (!vector) {
  42. LOG_ERROR("Init vector failed: vector is NULL.\n");
  43. return false;
  44. }
  45. if (init_length == 0) {
  46. init_length = 4;
  47. }
  48. if (!(vector->data = alloc_vector_data(init_length, size_elem))) {
  49. LOG_ERROR("Init vector failed: alloc memory failed.\n");
  50. return false;
  51. }
  52. vector->size_elem = size_elem;
  53. vector->max_elements = init_length;
  54. vector->num_elements = 0;
  55. return true;
  56. }
  57. bool
  58. wasm_vector_set(Vector *vector, uint32 index, const void *elem_buf)
  59. {
  60. if (!vector || !elem_buf) {
  61. LOG_ERROR("Set vector elem failed: vector or elem buf is NULL.\n");
  62. return false;
  63. }
  64. if (index >= vector->num_elements) {
  65. LOG_ERROR("Set vector elem failed: invalid elem index.\n");
  66. return false;
  67. }
  68. memcpy(vector->data + vector->size_elem * index,
  69. elem_buf, vector->size_elem);
  70. return true;
  71. }
  72. bool wasm_vector_get(const Vector *vector, uint32 index, void *elem_buf)
  73. {
  74. if (!vector || !elem_buf) {
  75. LOG_ERROR("Get vector elem failed: vector or elem buf is NULL.\n");
  76. return false;
  77. }
  78. if (index >= vector->num_elements) {
  79. LOG_ERROR("Get vector elem failed: invalid elem index.\n");
  80. return false;
  81. }
  82. memcpy(elem_buf, vector->data + vector->size_elem * index,
  83. vector->size_elem);
  84. return true;
  85. }
  86. bool wasm_vector_insert(Vector *vector, uint32 index, const void *elem_buf)
  87. {
  88. uint32 i;
  89. uint8 *p;
  90. if (!vector || !elem_buf) {
  91. LOG_ERROR("Insert vector elem failed: vector or elem buf is NULL.\n");
  92. return false;
  93. }
  94. if (index >= vector->num_elements) {
  95. LOG_ERROR("Insert vector elem failed: invalid elem index.\n");
  96. return false;
  97. }
  98. if (!extend_vector(vector, vector->num_elements + 1)) {
  99. LOG_ERROR("Insert vector elem failed: extend vector failed.\n");
  100. return false;
  101. }
  102. p = vector->data + vector->size_elem * vector->num_elements;
  103. for (i = vector->num_elements - 1; i > index; i--) {
  104. memcpy(p, p - vector->size_elem, vector->size_elem);
  105. p -= vector->size_elem;
  106. }
  107. memcpy(p, elem_buf, vector->size_elem);
  108. vector->num_elements++;
  109. return true;
  110. }
  111. bool wasm_vector_append(Vector *vector, const void *elem_buf)
  112. {
  113. if (!vector || !elem_buf) {
  114. LOG_ERROR("Append vector elem failed: vector or elem buf is NULL.\n");
  115. return false;
  116. }
  117. if (!extend_vector(vector, vector->num_elements + 1)) {
  118. LOG_ERROR("Append ector elem failed: extend vector failed.\n");
  119. return false;
  120. }
  121. memcpy(vector->data + vector->size_elem * vector->num_elements,
  122. elem_buf, vector->size_elem);
  123. vector->num_elements++;
  124. return true;
  125. }
  126. bool
  127. wasm_vector_remove(Vector *vector, uint32 index, void *old_elem_buf)
  128. {
  129. uint32 i;
  130. uint8 *p;
  131. if (!vector) {
  132. LOG_ERROR("Remove vector elem failed: vector is NULL.\n");
  133. return false;
  134. }
  135. if (index >= vector->num_elements) {
  136. LOG_ERROR("Remove vector elem failed: invalid elem index.\n");
  137. return false;
  138. }
  139. p = vector->data + vector->size_elem * index;
  140. if (old_elem_buf) {
  141. memcpy(old_elem_buf, p, vector->size_elem);
  142. }
  143. for (i = index; i < vector->num_elements - 1; i++) {
  144. memcpy(p, p + vector->size_elem, vector->size_elem);
  145. p += vector->size_elem;
  146. }
  147. vector->num_elements--;
  148. return true;
  149. }
  150. uint32
  151. wasm_vector_size(const Vector *vector)
  152. {
  153. return vector ? vector->num_elements : 0;
  154. }
  155. bool
  156. wasm_vector_destroy(Vector *vector)
  157. {
  158. if (!vector) {
  159. LOG_ERROR("Destroy vector elem failed: vector is NULL.\n");
  160. return false;
  161. }
  162. if (vector->data)
  163. wasm_free(vector->data);
  164. memset(vector, 0, sizeof(Vector));
  165. return true;
  166. }