From 4b1f9914f7d85890a041c5b4be067c7240e3bdaf Mon Sep 17 00:00:00 2001 From: Sean McBride Date: Fri, 10 Dec 2021 13:52:37 +0000 Subject: [PATCH] refactor: flatten http buffers --- .../include/current_sandbox_send_response.h | 2 +- runtime/include/sandbox_functions.h | 8 +- runtime/include/sandbox_receive_request.h | 2 +- runtime/include/sandbox_types.h | 4 +- runtime/include/vec_u8.h | 90 +++++++++++++++++-- runtime/src/libc/syscall.c | 11 +-- runtime/src/sandbox.c | 11 +-- 7 files changed, 100 insertions(+), 28 deletions(-) diff --git a/runtime/include/current_sandbox_send_response.h b/runtime/include/current_sandbox_send_response.h index ddccc8f..38f586c 100644 --- a/runtime/include/current_sandbox_send_response.h +++ b/runtime/include/current_sandbox_send_response.h @@ -25,7 +25,7 @@ current_sandbox_send_response() { struct sandbox *sandbox = current_sandbox_get(); assert(sandbox != NULL); - struct vec_u8 *response = sandbox->response; + struct vec_u8 *response = &sandbox->response; assert(response != NULL); int rc; diff --git a/runtime/include/sandbox_functions.h b/runtime/include/sandbox_functions.h index 9ad0731..45492d3 100644 --- a/runtime/include/sandbox_functions.h +++ b/runtime/include/sandbox_functions.h @@ -48,12 +48,8 @@ static inline void sandbox_free_http_buffers(struct sandbox *sandbox) { assert(sandbox); - assert(sandbox->request); - assert(sandbox->response); - vec_u8_free(sandbox->request); - vec_u8_free(sandbox->response); - sandbox->request = NULL; - sandbox->response = NULL; + vec_u8_deinit(&sandbox->request); + vec_u8_deinit(&sandbox->response); } /** diff --git a/runtime/include/sandbox_receive_request.h b/runtime/include/sandbox_receive_request.h index 03a0277..507110e 100644 --- a/runtime/include/sandbox_receive_request.h +++ b/runtime/include/sandbox_receive_request.h @@ -27,7 +27,7 @@ sandbox_receive_request(struct sandbox *sandbox) int rc = 0; - struct vec_u8 *request = sandbox->request; + struct vec_u8 *request = &sandbox->request; assert(request->length == 0); assert(request->capacity > 0); diff --git a/runtime/include/sandbox_types.h b/runtime/include/sandbox_types.h index 6267e8f..7495494 100644 --- a/runtime/include/sandbox_types.h +++ b/runtime/include/sandbox_types.h @@ -50,8 +50,8 @@ struct sandbox { int client_socket_descriptor; http_parser http_parser; struct http_request http_request; - struct vec_u8 * request; - struct vec_u8 * response; + struct vec_u8 request; + struct vec_u8 response; /* WebAssembly Module State */ struct module *module; /* the module this is an instance of */ diff --git a/runtime/include/vec_u8.h b/runtime/include/vec_u8.h index 8ac47df..2a43e9e 100644 --- a/runtime/include/vec_u8.h +++ b/runtime/include/vec_u8.h @@ -4,34 +4,108 @@ #include struct vec_u8 { - size_t length; - size_t capacity; - uint8_t buffer[]; + size_t length; + size_t capacity; + uint8_t *buffer; }; +static inline struct vec_u8 *vec_u8_alloc(void); +static inline int vec_u8_init(struct vec_u8 *self, size_t capacity); +static inline struct vec_u8 *vec_u8_new(size_t capacity); +static inline void vec_u8_deinit(struct vec_u8 *self); +static inline void vec_u8_free(struct vec_u8 *self); +static inline void vec_u8_delete(struct vec_u8 *self); + +/** + * Allocates an uninitialized vec on the heap' + * @returns a pointer to an uninitialized vec on the heap + */ static inline struct vec_u8 * -vec_u8_alloc(size_t capacity) +vec_u8_alloc(void) { - return (struct vec_u8 *)calloc(1, sizeof(struct vec_u8) + capacity * sizeof(uint8_t)); + return (struct vec_u8 *)calloc(1, sizeof(struct vec_u8)); } -static inline void +/** + * Initializes a vec, allocating a backing buffer for the provided capcity + * @param self pointer to an uninitialized vec + * @param capacity + * @returns 0 on success, -1 on failure + */ +static inline int vec_u8_init(struct vec_u8 *self, size_t capacity) { + if (capacity == 0) { + self->buffer = NULL; + } else { + self->buffer = calloc(capacity, sizeof(uint8_t)); + if (self->buffer == NULL) return -1; + } + self->length = 0; self->capacity = capacity; + + return 0; } +/** + * Allocate and initialize a vec with a backing buffer + * @param capacity + * @returns a pointer to an initialized vec on the heap, ready for use + */ static inline struct vec_u8 * vec_u8_new(size_t capacity) { - struct vec_u8 *self = vec_u8_alloc(capacity); - vec_u8_init(self, capacity); + struct vec_u8 *self = vec_u8_alloc(); + if (self == NULL) return self; + + int rc = vec_u8_init(self, capacity); + if (rc < 0) { + vec_u8_free(self); + return NULL; + } + return self; } +/** + * Deinitialize a vec, clearing out members and releasing the backing buffer + * @param self + */ +static inline void +vec_u8_deinit(struct vec_u8 *self) +{ + if (self->capacity == 0) { + assert(self->buffer == NULL); + assert(self->length == 0); + } + + free(self->buffer); + self->buffer = NULL; + self->length = 0; + self->capacity = 0; +} + +/** + * Frees a vec struct allocated on the heap + * Assumes that the vec has already been deinitialized + */ static inline void vec_u8_free(struct vec_u8 *self) { + assert(self->buffer == NULL); + assert(self->length == 0); + assert(self->capacity == 0); free(self); } + +/** + * Deinitializes and frees a vec allocated to the heap + * @param self + */ +static inline void +vec_u8_delete(struct vec_u8 *self) +{ + vec_u8_deinit(self); + vec_u8_free(self); +} diff --git a/runtime/src/libc/syscall.c b/runtime/src/libc/syscall.c index 8e71b1b..ba657f8 100644 --- a/runtime/src/libc/syscall.c +++ b/runtime/src/libc/syscall.c @@ -135,18 +135,19 @@ err: int32_t wasm_write(int32_t fd, int32_t buf_offset, int32_t buf_size) { - struct sandbox *s = current_sandbox_get(); - char * buffer = current_sandbox_get_ptr_void(buf_offset, buf_size); + struct sandbox *s = current_sandbox_get(); + char * buffer = current_sandbox_get_ptr_void(buf_offset, buf_size); + struct vec_u8 * response = &s->response; if (fd == STDERR_FILENO) { write(STDERR_FILENO, buffer, buf_size); } if (fd == STDOUT_FILENO) { - int buffer_remaining = s->response->capacity - s->response->length; + int buffer_remaining = response->capacity - response->length; int to_write = buffer_remaining > buf_size ? buf_size : buffer_remaining; if (to_write == 0) return 0; - memcpy(&s->response->buffer[s->response->length], buffer, to_write); - s->response->length += to_write; + memcpy(&response->buffer[response->length], buffer, to_write); + response->length += to_write; return to_write; } diff --git a/runtime/src/sandbox.c b/runtime/src/sandbox.c index e6e7118..eff6c90 100644 --- a/runtime/src/sandbox.c +++ b/runtime/src/sandbox.c @@ -74,12 +74,13 @@ sandbox_free_stack(struct sandbox *sandbox) static inline int sandbox_allocate_http_buffers(struct sandbox *self) { - self->request = vec_u8_new(self->module->max_request_size); - if (self->request == NULL) return -1; + int rc; + rc = vec_u8_init(&self->request, self->module->max_request_size); + if (rc < 0) return -1; - self->response = vec_u8_new(self->module->max_response_size); - if (self->response == NULL) { - vec_u8_free(self->request); + rc = vec_u8_init(&self->response, self->module->max_response_size); + if (rc < 0) { + vec_u8_deinit(&self->request); return -1; }