about summary refs log tree commit diff
path: root/src/rt/intrinsics/intrinsics.cpp
blob: 2e897bce797656d358bbdca2f62064d009ff59d9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
// 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);
}