diff --git a/src/lib/dbg.rs b/src/lib/dbg.rs index 5b475e59e4a..77587bd058c 100644 --- a/src/lib/dbg.rs +++ b/src/lib/dbg.rs @@ -19,7 +19,6 @@ native "rust" mod rustrt { fn debug_obj(x: &T, nmethods: uint, nbytes: uint); fn debug_fn(x: &T); fn debug_ptrcast(x: @T) -> @U; - fn debug_trap(msg: str); } fn debug_tydesc() { rustrt::debug_tydesc::(); } @@ -48,8 +47,6 @@ fn debug_fn(x: &T) { rustrt::debug_fn::(x); } fn ptr_cast(x: @T) -> @U { ret rustrt::debug_ptrcast::(x); } -fn trap(s: str) { rustrt::debug_trap(s); } - fn refcount(a: &@T) -> uint { let p: *uint = unsafe::reinterpret_cast(a); ret *p; diff --git a/src/lib/posix_fs.rs b/src/lib/posix_fs.rs index 2aebc49619b..b31f9ca8637 100644 --- a/src/lib/posix_fs.rs +++ b/src/lib/posix_fs.rs @@ -1,7 +1,6 @@ native "rust" mod rustrt { fn rust_list_files(path: &istr) -> [istr]; - fn rust_dirent_filename(ent: os::libc::dirent) -> str; } fn list_dir(path: &istr) -> [istr] { diff --git a/src/rt/rust.cpp b/src/rt/rust.cpp index c20f93102c0..86a099c0cc2 100644 --- a/src/rt/rust.cpp +++ b/src/rt/rust.cpp @@ -7,11 +7,9 @@ command_line_args : public kernel_owned rust_task *task; int argc; char **argv; - rust_str **strs; // [str] passed to rust_task::start. rust_vec *args; - rust_vec *args_istr; command_line_args(rust_task *task, int sys_argc, @@ -40,52 +38,24 @@ command_line_args : public kernel_owned LocalFree(wargv); #endif - // Allocate a vector of estrs - size_t vec_fill = sizeof(rust_str *) * argc; - size_t vec_alloc = next_power_of_two(vec_fill); - void *mem = kernel->malloc(vec_alloc, "command line"); - strs = (rust_str**) mem; - for (int i = 0; i < argc; ++i) { - size_t str_fill = strlen(argv[i]) + 1; - size_t str_alloc = next_power_of_two(sizeof(rust_str) + str_fill); - mem = kernel->malloc(str_alloc, "command line arg"); - strs[i] = new (mem) rust_str(str_alloc, str_fill, - (uint8_t const *)argv[i]); - strs[i]->ref_count++; - } - args = (rust_vec *) - kernel->malloc(vec_size(argc), - "command line arg interior"); - args->fill = args->alloc = sizeof(rust_str *) * argc; - memcpy(&args->data[0], strs, args->fill); - - // Allocate a vector of istrs - args_istr = (rust_vec *) kernel->malloc(vec_size(argc), "command line arg interior"); - args_istr->fill = args_istr->alloc = sizeof(rust_vec*) * argc; + args->fill = args->alloc = sizeof(rust_vec*) * argc; for (int i = 0; i < argc; ++i) { rust_vec *str = make_istr(kernel, argv[i], strlen(argv[i]), "command line arg"); - ((rust_vec**)&args_istr->data)[i] = str; + ((rust_vec**)&args->data)[i] = str; } } ~command_line_args() { - // Free the estr args - kernel->free(args); - for (int i = 0; i < argc; ++i) - kernel->free(strs[i]); - kernel->free(strs); - - // Free the istr args for (int i = 0; i < argc; ++i) { - rust_vec *s = ((rust_vec**)&args_istr->data)[i]; + rust_vec *s = ((rust_vec**)&args->data)[i]; kernel->free(s); } - kernel->free(args_istr); + kernel->free(args); #ifdef __WIN32__ for (int i = 0; i < argc; ++i) { @@ -97,11 +67,9 @@ command_line_args : public kernel_owned }; -bool main_takes_istr = true; - +// FIXME: Transitional. Please remove. extern "C" CDECL void set_main_takes_istr(uintptr_t flag) { - main_takes_istr = flag != 0; } /** @@ -136,11 +104,7 @@ rust_start(uintptr_t main_fn, int argc, char **argv, DLOG(sched, dom, "startup: arg[%d] = '%s'", i, args->argv[i]); } - if (main_takes_istr) { - root_task->start(main_fn, (uintptr_t)args->args_istr); - } else { - root_task->start(main_fn, (uintptr_t)args->args); - } + root_task->start(main_fn, (uintptr_t)args->args); root_task->deref(); root_task = NULL; diff --git a/src/rt/rust_builtin.cpp b/src/rt/rust_builtin.cpp index b864ade6911..814822e8f1e 100644 --- a/src/rt/rust_builtin.cpp +++ b/src/rt/rust_builtin.cpp @@ -7,7 +7,7 @@ /* Native builtins. */ -extern "C" CDECL rust_str* +extern "C" CDECL rust_vec* last_os_error(rust_task *task) { LOG(task, task, "last_os_error()"); @@ -39,16 +39,9 @@ last_os_error(rust_task *task) { return NULL; } #endif - size_t fill = strlen(buf) + 1; - size_t alloc = next_power_of_two(sizeof(rust_str) + fill); - void *mem = task->malloc(alloc, "rust_str(last_os_error)"); - if (!mem) { - task->fail(); - return NULL; - } - rust_str *st = new (mem) rust_str(alloc, fill, - (const uint8_t *)buf); + rust_vec * st = make_istr(task->kernel, buf, strlen(buf), + "last_os_error"); #ifdef __WIN32__ LocalFree((HLOCAL)buf); #endif @@ -115,43 +108,6 @@ unsupervise(rust_task *task) { task->unsupervise(); } -/* Helper for str_alloc and str_from_vec. Returns NULL as failure. */ -static rust_evec* -vec_alloc_with_data(rust_task *task, - size_t n_elts, - size_t fill, - size_t elt_size, - void *d) -{ - size_t alloc = next_power_of_two(sizeof(rust_evec) + (n_elts * elt_size)); - void *mem = task->malloc(alloc, "rust_evec (with data)"); - if (!mem) return NULL; - return new (mem) rust_evec(alloc, fill * elt_size, (uint8_t*)d); -} - -extern "C" CDECL char const * -str_buf(rust_task *task, rust_str *s) -{ - return (char const *)&s->data[0]; -} - -extern "C" CDECL rust_str * -str_from_vec(rust_task *task, rust_vec **vp) -{ - rust_vec* v = *vp; - rust_str *st = vec_alloc_with_data(task, - v->fill + 1, // +1 for \0 - v->fill, - 1, - &v->data[0]); - if (!st) { - task->fail(); - return NULL; - } - st->data[st->fill++] = '\0'; - return st; -} - extern "C" CDECL void vec_reserve_shared(rust_task* task, type_desc* ty, rust_vec** vp, size_t n_elts) { @@ -370,19 +326,6 @@ debug_ptrcast(rust_task *task, return ptr; } -extern "C" CDECL void -debug_trap(rust_task *task, rust_str *s) -{ - LOG(task, stdlib, "trapping: %s", s->data); - // FIXME: x86-ism. - __asm__("int3"); -} - -rust_str* c_str_to_rust(rust_task *task, char const *str) { - size_t len = strlen(str) + 1; - return vec_alloc_with_data(task, len, len, 1, (void*)str); -} - extern "C" CDECL rust_vec* rust_list_files(rust_task *task, rust_vec **path) { array_list strings; @@ -421,18 +364,6 @@ rust_list_files(rust_task *task, rust_vec **path) { return vec; } -#if defined(__WIN32__) -extern "C" CDECL rust_str * -rust_dirent_filename(rust_task *task, void* ent) { - return NULL; -} -#else -extern "C" CDECL rust_str * -rust_dirent_filename(rust_task *task, dirent* ent) { - return c_str_to_rust(task, ent->d_name); -} -#endif - extern "C" CDECL int rust_file_is_dir(rust_task *task, char *path) { struct stat buf; diff --git a/src/rt/rust_upcall.cpp b/src/rt/rust_upcall.cpp index 98dd9136d9d..504338da862 100644 --- a/src/rt/rust_upcall.cpp +++ b/src/rt/rust_upcall.cpp @@ -4,8 +4,9 @@ // Upcalls. +// FIXME: Transitional. Please remove extern "C" CDECL char const * -str_buf(rust_task *task, rust_str *s); +str_buf(rust_task *task, void *s) { return NULL; } #ifdef __i386__ void @@ -52,15 +53,6 @@ void upcall_log_double(rust_task *task, uint32_t level, double *f) { task->sched->log(task, level, "rust: %12.12f", *f); } -extern "C" CDECL void -upcall_log_str(rust_task *task, uint32_t level, rust_str *str) { - LOG_UPCALL_ENTRY(task); - if (task->sched->log_lvl >= level) { - const char *c = str_buf(task, str); - task->sched->log(task, level, "rust: %s", c); - } -} - extern "C" CDECL void upcall_yield(rust_task *task) { LOG_UPCALL_ENTRY(task); @@ -68,6 +60,26 @@ upcall_yield(rust_task *task) { task->yield(1); } +// Copy elements from one vector to another, +// dealing with reference counts +static inline void +copy_elements(rust_task *task, type_desc *elem_t, + void *pdst, void *psrc, size_t n) +{ + char *dst = (char *)pdst, *src = (char *)psrc; + memmove(dst, src, n); + + // increment the refcount of each element of the vector + if (elem_t->take_glue) { + glue_fn *take_glue = elem_t->take_glue; + size_t elem_size = elem_t->size; + const type_desc **tydescs = elem_t->first_param; + for (char *p = dst; p < dst+n; p += elem_size) { + take_glue(NULL, task, NULL, tydescs, p); + } + } +} + extern "C" CDECL void upcall_sleep(rust_task *task, size_t time_in_us) { LOG_UPCALL_ENTRY(task); @@ -179,150 +191,6 @@ upcall_shared_free(rust_task *task, void* ptr) { task->kernel->free(ptr); } -rust_str *make_str(rust_task *task, char const *s, size_t fill) { - size_t alloc = next_power_of_two(sizeof(rust_str) + fill); - void *mem = task->malloc(alloc, "rust_str (make_str)"); - if (!mem) { - task->fail(); - return NULL; - } - rust_str *st = new (mem) rust_str(alloc, fill, - (uint8_t const *) s); - LOG(task, mem, - "upcall new_str('%s', %" PRIdPTR ") = 0x%" PRIxPTR, - s, fill, st); - return st; -} - -extern "C" CDECL rust_str * -upcall_new_str(rust_task *task, char const *s, size_t fill) { - LOG_UPCALL_ENTRY(task); - return make_str(task, s, fill); -} - -static rust_evec * -vec_grow(rust_task *task, - rust_evec *v, - size_t n_bytes, - uintptr_t *need_copy, - type_desc *td) -{ - rust_scheduler *sched = task->sched; - LOG(task, mem, - "vec_grow(0x%" PRIxPTR ", %" PRIdPTR - "), rc=%" PRIdPTR " alloc=%" PRIdPTR ", fill=%" PRIdPTR - ", need_copy=0x%" PRIxPTR, - v, n_bytes, v->ref_count, v->alloc, v->fill, need_copy); - - *need_copy = 0; - size_t alloc = next_power_of_two(sizeof(rust_evec) + v->fill + n_bytes); - - if (v->ref_count == 1) { - - // Fastest path: already large enough. - if (v->alloc >= alloc) { - LOG(task, mem, "no-growth path"); - return v; - } - - // Second-fastest path: can at least realloc. - LOG(task, mem, "realloc path"); - v = (rust_evec*) task->realloc(v, alloc, td->is_stateful); - if (!v) { - task->fail(); - return NULL; - } - v->alloc = alloc; - - } else { - /** - * Slowest path: make a new vec. - * - * 1. Allocate a new rust_evec with desired additional space. - * 2. Down-ref the shared rust_evec, point to the new one instead. - * 3. Copy existing elements into the new rust_evec. - * - * Step 3 is a bit tricky. We don't know how to properly copy the - * elements in the runtime (all we have are bits in a buffer; no - * type information and no copy glue). What we do instead is set the - * need_copy outparam flag to indicate to our caller (vec-copy glue) - * that we need the copies performed for us. - */ - LOG(task, mem, "new vec path"); - void *mem = task->malloc(alloc, "rust_evec (vec_grow)", td); - if (!mem) { - task->fail(); - return NULL; - } - - if (v->ref_count != CONST_REFCOUNT) - v->deref(); - - v = new (mem) rust_evec(alloc, 0, NULL); - *need_copy = 1; - } - I(sched, sizeof(rust_evec) + v->fill <= v->alloc); - return v; -} - -// Copy elements from one vector to another, -// dealing with reference counts -static inline void -copy_elements(rust_task *task, type_desc *elem_t, - void *pdst, void *psrc, size_t n) -{ - char *dst = (char *)pdst, *src = (char *)psrc; - memmove(dst, src, n); - - // increment the refcount of each element of the vector - if (elem_t->take_glue) { - glue_fn *take_glue = elem_t->take_glue; - size_t elem_size = elem_t->size; - const type_desc **tydescs = elem_t->first_param; - for (char *p = dst; p < dst+n; p += elem_size) { - take_glue(NULL, task, NULL, tydescs, p); - } - } -} - -extern "C" CDECL void -upcall_evec_append(rust_task *task, type_desc *t, type_desc *elem_t, - rust_evec **dst_ptr, rust_evec *src, bool skip_null) -{ - LOG_UPCALL_ENTRY(task); - rust_evec *dst = *dst_ptr; - uintptr_t need_copy; - size_t n_src_bytes = skip_null ? src->fill - 1 : src->fill; - size_t n_dst_bytes = skip_null ? dst->fill - 1 : dst->fill; - rust_evec *new_vec = vec_grow(task, dst, n_src_bytes, &need_copy, t); - - // If src and dst are the same (due to "v += v"), then dst getting - // resized causes src to move as well. - if (dst == src && !need_copy) { - src = new_vec; - } - - if (need_copy) { - // Copy any dst elements in, omitting null if doing str. - copy_elements(task, elem_t, &new_vec->data, &dst->data, n_dst_bytes); - } - - // Copy any src elements in, carrying along null if doing str. - void *new_end = (void *)((char *)new_vec->data + n_dst_bytes); - copy_elements(task, elem_t, new_end, &src->data, src->fill); - new_vec->fill = n_dst_bytes + src->fill; - - // Write new_vec back through the alias we were given. - *dst_ptr = new_vec; -} - -// FIXME: Transitional. Please remove. -extern "C" CDECL void -upcall_vec_append(rust_task *task, type_desc *t, type_desc *elem_t, - rust_evec **dst_ptr, rust_evec *src, bool skip_null) { - upcall_evec_append(task, t, elem_t, dst_ptr, src, skip_null); -} - extern "C" CDECL type_desc * upcall_get_type_desc(rust_task *task, void *curr_crate, // ignored, legacy compat. diff --git a/src/rt/rust_util.h b/src/rt/rust_util.h index 1137a63c0e1..dc8eea20f72 100644 --- a/src/rt/rust_util.h +++ b/src/rt/rust_util.h @@ -164,36 +164,6 @@ isaac_init(sched_or_kernel *sched, randctx *rctx) randinit(rctx, 1); } -// Vectors (rust-user-code level). - -struct -rust_evec -{ - RUST_REFCOUNTED(rust_evec) - - size_t alloc; - size_t fill; - size_t pad; // Pad to align data[0] to 16 bytes. - uint8_t data[]; - rust_evec(size_t alloc, size_t fill, - uint8_t const *d) - : ref_count(1), - alloc(alloc), - fill(fill) - { - if (d) - memcpy(&data[0], d, fill); - } - ~rust_evec() {} - - inline void *operator new(size_t size, void *mem) { - return mem; - } -}; - -// Strings are just exterior vecs -typedef rust_evec rust_str; - // Interior vectors (rust-user-code level). struct diff --git a/src/rt/rustrt.def.in b/src/rt/rustrt.def.in index 1b623da6c2b..550155a8345 100644 --- a/src/rt/rustrt.def.in +++ b/src/rt/rustrt.def.in @@ -19,7 +19,6 @@ debug_opaque del_port debug_ptrcast debug_tag -debug_trap debug_tydesc do_gc drop_port @@ -44,7 +43,6 @@ rand_free rand_new rand_next refcount -rust_dirent_filename rust_file_is_dir rust_get_stdin rust_get_stdout @@ -63,7 +61,6 @@ size_of squareroot start_task str_buf -str_from_vec vec_reserve_shared vec_from_buf_shared task_sleep @@ -86,14 +83,9 @@ upcall_kill upcall_log_double upcall_log_float upcall_log_int -upcall_log_str -upcall_log_str upcall_log_type upcall_malloc -upcall_new_str upcall_shared_malloc upcall_shared_free upcall_sleep -upcall_evec_append -upcall_vec_append upcall_yield diff --git a/src/test/stdtest/stdtest.rc b/src/test/stdtest/stdtest.rc index ce087b2e0ba..b94f18f77f4 100644 --- a/src/test/stdtest/stdtest.rc +++ b/src/test/stdtest/stdtest.rc @@ -25,6 +25,7 @@ mod run; mod sha1; mod sort; mod str; +mod sys; mod task; mod test; mod uint; diff --git a/src/test/stdtest/sys.rs b/src/test/stdtest/sys.rs new file mode 100644 index 00000000000..006aaaa8f5e --- /dev/null +++ b/src/test/stdtest/sys.rs @@ -0,0 +1,6 @@ +import std::sys; + +#[test] +fn last_os_error() { + log sys::rustrt::last_os_error(); +} \ No newline at end of file