aboutsummaryrefslogtreecommitdiff
path: root/src/rt/rust_builtin.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/rt/rust_builtin.cpp')
-rw-r--r--src/rt/rust_builtin.cpp125
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++