diff options
Diffstat (limited to 'src/rt/rust_builtin.cpp')
| -rw-r--r-- | src/rt/rust_builtin.cpp | 125 |
1 files changed, 101 insertions, 24 deletions
diff --git a/src/rt/rust_builtin.cpp b/src/rt/rust_builtin.cpp index d8d9b8d6..d2bad054 100644 --- a/src/rt/rust_builtin.cpp +++ b/src/rt/rust_builtin.cpp @@ -2,19 +2,6 @@ #include "rust_internal.h" /* Native builtins. */ -extern "C" CDECL rust_str* -str_alloc(rust_task *task, size_t n_bytes) -{ - rust_dom *dom = task->dom; - size_t alloc = next_power_of_two(sizeof(rust_str) + n_bytes); - void *mem = dom->malloc(alloc); - if (!mem) { - task->fail(2); - return NULL; - } - rust_str *st = new (mem) rust_str(dom, alloc, 1, (uint8_t const *)""); - return st; -} extern "C" CDECL rust_str* last_os_error(rust_task *task) { @@ -51,7 +38,7 @@ last_os_error(rust_task *task) { #endif size_t fill = strlen(buf) + 1; size_t alloc = next_power_of_two(sizeof(rust_str) + fill); - void *mem = dom->malloc(alloc); + void *mem = dom->malloc(alloc, memory_region::LOCAL); if (!mem) { task->fail(1); return NULL; @@ -95,7 +82,7 @@ extern "C" CDECL rust_vec* vec_alloc(rust_task *task, type_desc *t, type_desc *elem_t, size_t n_elts) { rust_dom *dom = task->dom; - task->log(rust_log::MEM, + task->log(rust_log::MEM | rust_log::STDLIB, "vec_alloc %" PRIdPTR " elements of size %" PRIdPTR, n_elts, elem_t->size); size_t fill = n_elts * elem_t->size; @@ -109,6 +96,85 @@ vec_alloc(rust_task *task, type_desc *t, type_desc *elem_t, size_t n_elts) return vec; } +extern "C" CDECL void * +vec_buf(rust_task *task, type_desc *ty, rust_vec *v, size_t offset) +{ + return (void *)&v->data[ty->size * offset]; +} + +extern "C" CDECL size_t +vec_len(rust_task *task, type_desc *ty, rust_vec *v) +{ + return v->fill / ty->size; +} + +extern "C" CDECL void +vec_len_set(rust_task *task, type_desc *ty, rust_vec *v, size_t len) +{ + task->log(rust_log::STDLIB, + "vec_len_set(0x%" PRIxPTR ", %" PRIdPTR ") on vec with " + "alloc = %" PRIdPTR + ", fill = %" PRIdPTR + ", len = %" PRIdPTR + ". New fill is %" PRIdPTR, + v, len, v->alloc, v->fill, v->fill / ty->size, len * ty->size); + v->fill = len * ty->size; +} + +extern "C" CDECL void +vec_print_debug_info(rust_task *task, type_desc *ty, rust_vec *v) +{ + task->log(rust_log::STDLIB, + "vec_print_debug_info(0x%" PRIxPTR ")" + " with tydesc 0x%" PRIxPTR + " (size = %" PRIdPTR ", align = %" PRIdPTR ")" + " alloc = %" PRIdPTR ", fill = %" PRIdPTR ", len = %" PRIdPTR + " , data = ...", + v, + ty, + ty->size, + ty->align, + v->alloc, + v->fill, + v->fill / ty->size); + + for (size_t i = 0; i < v->fill; ++i) { + task->log(rust_log::STDLIB, + " %" PRIdPTR ": 0x%" PRIxPTR, + i, v->data[i]); + } +} + +/* Helper for str_alloc and str_from_vec. Returns NULL as failure. */ +static rust_str * +str_alloc_with_data(rust_task *task, + size_t n_bytes, + size_t fill, + uint8_t const *d) +{ + rust_dom *dom = task->dom; + size_t alloc = next_power_of_two(sizeof(rust_str) + n_bytes); + void *mem = dom->malloc(alloc, memory_region::LOCAL); + if (!mem) + return NULL; + rust_str *st = new (mem) rust_str(dom, alloc, fill, d); + return st; +} + +extern "C" CDECL rust_str* +str_alloc(rust_task *task, size_t n_bytes) +{ + rust_str *st = str_alloc_with_data(task, + n_bytes + 1, // +1 to fit at least "" + 1, + (uint8_t const *)""); + if (!st) { + task->fail(2); + return NULL; + } + return st; +} + extern "C" CDECL char const * str_buf(rust_task *task, rust_str *s) { @@ -121,16 +187,20 @@ str_byte_len(rust_task *task, rust_str *s) return s->fill - 1; // -1 for the '\0' terminator. } -extern "C" CDECL void * -vec_buf(rust_task *task, type_desc *ty, rust_vec *v, size_t offset) -{ - return (void *)&v->data[ty->size * offset]; -} - -extern "C" CDECL size_t -vec_len(rust_task *task, type_desc *ty, rust_vec *v) +extern "C" CDECL rust_str * +str_from_vec(rust_task *task, rust_vec *v) { - return v->fill / ty->size; + rust_str *st = + str_alloc_with_data(task, + v->fill + 1, // +1 to fit at least '\0' + v->fill, + v->fill ? (uint8_t const *)v->data : NULL); + if (!st) { + task->fail(2); + return NULL; + } + st->data[st->fill++] = '\0'; + return st; } extern "C" CDECL void * @@ -158,6 +228,13 @@ rand_free(rust_task *task, randctx *rctx) task->free(rctx); } +extern "C" CDECL void upcall_sleep(rust_task *task, size_t time_in_us); + +extern "C" CDECL void +task_sleep(rust_task *task, size_t time_in_us) { + upcall_sleep(task, time_in_us); +} + // // Local Variables: // mode: C++ |