diff options
| author | Graydon Hoare <[email protected]> | 2010-06-23 21:03:09 -0700 |
|---|---|---|
| committer | Graydon Hoare <[email protected]> | 2010-06-23 21:03:09 -0700 |
| commit | d6b7c96c3eb29b9244ece0c046d3f372ff432d04 (patch) | |
| tree | b425187e232966063ffc2f0d14c04a55d8f004ef /src/rt/rust_builtin.cpp | |
| parent | Initial git commit. (diff) | |
| download | rust-d6b7c96c3eb29b9244ece0c046d3f372ff432d04.tar.xz rust-d6b7c96c3eb29b9244ece0c046d3f372ff432d04.zip | |
Populate tree.
Diffstat (limited to 'src/rt/rust_builtin.cpp')
| -rw-r--r-- | src/rt/rust_builtin.cpp | 129 |
1 files changed, 129 insertions, 0 deletions
diff --git a/src/rt/rust_builtin.cpp b/src/rt/rust_builtin.cpp new file mode 100644 index 00000000..71aa644b --- /dev/null +++ b/src/rt/rust_builtin.cpp @@ -0,0 +1,129 @@ + +#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) { + rust_dom *dom = task->dom; + dom->log(rust_log::TASK, "last_os_error()"); + +#if defined(__WIN32__) + LPTSTR buf; + DWORD err = GetLastError(); + DWORD res = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, err, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + (LPTSTR) &buf, 0, NULL); + if (!res) { + task->fail(1); + return NULL; + } +#elif defined(_GNU_SOURCE) + char cbuf[1024]; + char *buf = strerror_r(errno, cbuf, sizeof(cbuf)); + if (!buf) { + task->fail(1); + return NULL; + } +#else + char buf[1024]; + int err = strerror_r(errno, buf, sizeof(buf)); + if (err) { + task->fail(1); + return NULL; + } +#endif + size_t fill = strlen(buf) + 1; + size_t alloc = next_power_of_two(sizeof(rust_str) + fill); + void *mem = dom->malloc(alloc); + if (!mem) { + task->fail(1); + return NULL; + } + rust_str *st = new (mem) rust_str(dom, alloc, fill, (const uint8_t *)buf); + +#ifdef __WIN32__ + LocalFree((HLOCAL)buf); +#endif + return st; +} + +extern "C" CDECL size_t +size_of(rust_task *task, type_desc *t) { + return t->size; +} + +extern "C" CDECL size_t +align_of(rust_task *task, type_desc *t) { + return t->align; +} + +extern "C" CDECL size_t +refcount(rust_task *task, type_desc *t, size_t *v) { + // Passed-in value has refcount 1 too high + // because it was ref'ed while making the call. + return (*v) - 1; +} + +extern "C" CDECL rust_vec* +vec_alloc(rust_task *task, type_desc *t, size_t n_elts) +{ + rust_dom *dom = task->dom; + dom->log(rust_log::MEM, + "vec_alloc %" PRIdPTR " elements of size %" PRIdPTR, + n_elts, t->size); + size_t fill = n_elts * t->size; + size_t alloc = next_power_of_two(sizeof(rust_vec) + fill); + void *mem = dom->malloc(alloc); + if (!mem) { + task->fail(3); + return NULL; + } + rust_vec *vec = new (mem) rust_vec(dom, alloc, 0, NULL); + return vec; +} + +extern "C" CDECL char const * +str_buf(rust_task *task, rust_str *s) +{ + return (char const *)&s->data[0]; +} + +extern "C" CDECL void * +vec_buf(rust_task *task, type_desc *ty, rust_vec *v) +{ + return (void *)&v->data[0]; +} + +extern "C" CDECL size_t +vec_len(rust_task *task, type_desc *ty, rust_vec *v) +{ + return v->fill; +} + +// +// Local Variables: +// mode: C++ +// fill-column: 78; +// indent-tabs-mode: nil +// c-basic-offset: 4 +// buffer-file-coding-system: utf-8-unix +// compile-command: "make -k -C .. 2>&1 | sed -e 's/\\/x\\//x:\\//g'"; +// End: +// |