about summary refs log tree commit diff
path: root/src/rt/rust_builtin.cpp
diff options
context:
space:
mode:
authorGraydon Hoare <graydon@mozilla.com>2010-06-23 21:03:09 -0700
committerGraydon Hoare <graydon@mozilla.com>2010-06-23 21:03:09 -0700
commitd6b7c96c3eb29b9244ece0c046d3f372ff432d04 (patch)
treeb425187e232966063ffc2f0d14c04a55d8f004ef /src/rt/rust_builtin.cpp
parentc01efc669f09508b55eced32d3c88702578a7c3e (diff)
downloadrust-d6b7c96c3eb29b9244ece0c046d3f372ff432d04.tar.gz
rust-d6b7c96c3eb29b9244ece0c046d3f372ff432d04.zip
Populate tree.
Diffstat (limited to 'src/rt/rust_builtin.cpp')
-rw-r--r--src/rt/rust_builtin.cpp129
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 00000000000..71aa644b144
--- /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:
+//