rust/src/rt/intrinsics/intrinsics.cpp
2011-11-18 15:37:14 -08:00

87 lines
2.2 KiB
C++

// Rust intrinsics. These are built into each compilation unit and are
// run on the Rust stack. They should not call C methods because that
// will very likely result in running off the end of the stack.
// Build with the script in src/etc/gen-intrinsics
#include "../rust_internal.h"
#include "../rust_scheduler.h"
#include <cstdlib>
#include <cstring>
extern "C" CDECL void
rust_task_sleep(rust_task *task, size_t time_in_us, bool *killed);
extern "C" void
rust_intrinsic_vec_len(size_t *retptr,
void *env,
type_desc *ty,
rust_vec **vp)
{
*retptr = (*vp)->fill / ty->size;
}
extern "C" void
rust_intrinsic_ptr_offset(void **retptr,
void *env,
type_desc *ty,
void *ptr,
uintptr_t count)
{
*retptr = &((uint8_t *)ptr)[ty->size * count];
}
extern "C" void
rust_intrinsic_cast(void *retptr,
void *env,
type_desc *t1,
type_desc *t2,
void *src)
{
// assert t1->size == t2->size
// FIXME: This should be easily expressible in rust
memmove(retptr, src, t1->size);
}
extern "C" void
rust_intrinsic_addr_of(void **retptr,
void *env,
type_desc *ty,
void *valptr) {
*retptr = valptr;
}
struct rust_fn {
uintptr_t *fn;
rust_box *env;
};
typedef void (*retptr_fn)(void **retptr,
void *env,
void **dptr);
// FIXME (1185): This exists just to get access to the return pointer
extern "C" void
rust_intrinsic_call_with_retptr(void **retptr,
void *env,
type_desc *ty,
rust_fn *recvfn) {
retptr_fn fn = ((retptr_fn)(recvfn->fn));
((retptr_fn)(*fn))(NULL, recvfn->env, retptr);
}
extern "C" void
rust_intrinsic_get_type_desc(void **retptr,
void *env,
type_desc* ty) {
*(type_desc**)retptr = ty;
}
extern "C" void
rust_intrinsic_task_sleep(void **retptr,
void *env,
rust_task *task,
size_t time_in_us,
bool *killed) {
rust_task_sleep(task, time_in_us, killed);
}