rt: Add an upcall to allocate space on the C stack. This will be used for native calls on the C stack.
This commit is contained in:
parent
e8757ea01f
commit
1eaaae860f
|
@ -3,7 +3,17 @@
|
|||
#ifndef CONTEXT_H
|
||||
#define CONTEXT_H
|
||||
|
||||
#include <cstdlib>
|
||||
#include <inttypes.h>
|
||||
#include <stdint.h>
|
||||
|
||||
template<typename T>
|
||||
T align_down(T sp)
|
||||
{
|
||||
// There is no platform we care about that needs more than a
|
||||
// 16-byte alignment.
|
||||
return (T)((uint32_t)sp & ~(16 - 1));
|
||||
}
|
||||
|
||||
struct registers_t {
|
||||
// general purpose registers
|
||||
|
@ -26,16 +36,15 @@ public:
|
|||
context *next;
|
||||
|
||||
void swap(context &out);
|
||||
|
||||
void call(void *f, void *arg, void *sp);
|
||||
|
||||
// Note that this doesn't actually adjust esp. Instead, we adjust esp when
|
||||
// we actually do the call. This is needed for exception safety -- if the
|
||||
// function being called causes the task to fail, then we have to avoid
|
||||
// leaking space on the C stack.
|
||||
inline void *alloc_stack(size_t nbytes) {
|
||||
return (void *)(align_down(regs.esp - nbytes));
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
T align_down(T sp)
|
||||
{
|
||||
// There is no platform we care about that needs more than a
|
||||
// 16-byte alignment.
|
||||
return (T)((int)sp & ~(16 - 1));
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
// -I../arch/i386 -fno-stack-protector -o intrinsics.ll intrinsics.cpp`
|
||||
|
||||
#include "../rust_internal.h"
|
||||
#include "../rust_scheduler.h"
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
|
||||
|
@ -46,3 +47,4 @@ rust_intrinsic_recv(rust_task *task, void **retptr, type_desc *ty,
|
|||
rust_port *port) {
|
||||
port_recv(task, (uintptr_t*)retptr, port);
|
||||
}
|
||||
|
||||
|
|
|
@ -202,6 +202,16 @@ upcall_dynastack_free(rust_task *task, void *ptr) {
|
|||
return task->dynastack.free(ptr);
|
||||
}
|
||||
|
||||
/**
|
||||
* Allocates |nbytes| bytes in the C stack and returns a pointer to the start
|
||||
* of the allocated space.
|
||||
*/
|
||||
extern "C" CDECL void *
|
||||
upcall_alloc_c_stack(size_t nbytes) {
|
||||
rust_scheduler *sched = rust_scheduler::get_task()->sched;
|
||||
return sched->c_context.alloc_stack(nbytes);
|
||||
}
|
||||
|
||||
extern "C" _Unwind_Reason_Code
|
||||
__gxx_personality_v0(int version,
|
||||
_Unwind_Action actions,
|
||||
|
|
|
@ -65,6 +65,7 @@ task_sleep
|
|||
task_yield
|
||||
task_join
|
||||
unsupervise
|
||||
upcall_alloc_c_stack
|
||||
upcall_cmp_type
|
||||
upcall_dynastack_alloc
|
||||
upcall_dynastack_alloc_2
|
||||
|
|
Loading…
Reference in New Issue