mirror of
https://github.com/urbit/ares.git
synced 2024-11-26 09:57:56 +03:00
Revert "wip: use only one jmp_buf
; add NockStackSnapshot
"
This reverts commit 1980ca7fd6
.
This commit is contained in:
parent
1980ca7fd6
commit
8bcbf6adca
@ -65,8 +65,8 @@ impl<'closure> CCallback<'closure> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn call_with_guard<F: FnMut() -> Result>(
|
pub fn call_with_guard<F: FnMut() -> Result>(
|
||||||
stack_pp: *const *mut u64,
|
stack_pp: *const *const u64,
|
||||||
alloc_pp: *const *mut u64,
|
alloc_pp: *const *const u64,
|
||||||
closure: &mut F,
|
closure: &mut F,
|
||||||
) -> Result {
|
) -> Result {
|
||||||
let cb = CCallback::new(closure);
|
let cb = CCallback::new(closure);
|
||||||
@ -100,7 +100,8 @@ pub fn call_with_guard<F: FnMut() -> Result>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn interpret_with_guard(context: &mut Context, eve: Noun, lyf: Noun) -> Result {
|
pub fn interpret_with_guard(context: &mut Context, eve: Noun, lyf: Noun) -> Result {
|
||||||
let stack_pp = context.stack.get_stack_pointer_pointer() as *const *mut u64;
|
let stack_pp = context.stack.get_stack_pointer_pointer() as *const *const u64;
|
||||||
let alloc_pp = context.stack.get_alloc_pointer_pointer() as *const *mut u64;
|
let alloc_pp = context.stack.get_alloc_pointer_pointer() as *const *const u64;
|
||||||
|
|
||||||
call_with_guard(stack_pp, alloc_pp, &mut || interpret(context, eve, lyf))
|
call_with_guard(stack_pp, alloc_pp, &mut || interpret(context, eve, lyf))
|
||||||
}
|
}
|
||||||
|
@ -32,13 +32,6 @@ fn indirect_raw_size(atom: IndirectAtom) -> usize {
|
|||||||
atom.size() + 2
|
atom.size() + 2
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
|
||||||
pub struct NockStackSnapshot {
|
|
||||||
frame_pointer: *mut u64,
|
|
||||||
stack_pointer: *mut u64,
|
|
||||||
alloc_pointer: *mut u64,
|
|
||||||
}
|
|
||||||
|
|
||||||
/** A stack for Nock computation, which supports stack allocation and delimited copying collection
|
/** A stack for Nock computation, which supports stack allocation and delimited copying collection
|
||||||
* for returned nouns
|
* for returned nouns
|
||||||
*/
|
*/
|
||||||
@ -94,20 +87,6 @@ impl NockStack {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn save(&self) -> NockStackSnapshot {
|
|
||||||
NockStackSnapshot {
|
|
||||||
frame_pointer: self.frame_pointer,
|
|
||||||
stack_pointer: self.stack_pointer,
|
|
||||||
alloc_pointer: self.alloc_pointer,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn restore(&mut self, saved: &NockStackSnapshot) {
|
|
||||||
self.frame_pointer = saved.frame_pointer;
|
|
||||||
self.stack_pointer = saved.stack_pointer;
|
|
||||||
self.alloc_pointer = saved.alloc_pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Resets the NockStack but flipping the top-frame polarity and unsetting PC. Sets the alloc
|
/** Resets the NockStack but flipping the top-frame polarity and unsetting PC. Sets the alloc
|
||||||
* pointer to the "previous" alloc pointer stored in the top frame to keep things "preserved"
|
* pointer to the "previous" alloc pointer stored in the top frame to keep things "preserved"
|
||||||
* from the top frame. This allows us to do a copying GC on the top frame without erroneously
|
* from the top frame. This allows us to do a copying GC on the top frame without erroneously
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
static uintptr_t guard_p = 0;
|
static uintptr_t guard_p = 0;
|
||||||
static const uintptr_t *stack_pp = NULL;
|
static const uintptr_t *stack_pp = NULL;
|
||||||
static const uintptr_t *alloc_pp = NULL;
|
static const uintptr_t *alloc_pp = NULL;
|
||||||
static jmp_buf env_buffer;
|
static BufListNode *buffer_list = NULL;
|
||||||
static struct sigaction prev_sa;
|
static struct sigaction prev_sa;
|
||||||
|
|
||||||
static int32_t
|
static int32_t
|
||||||
@ -113,7 +113,7 @@ _signal_handler(int sig, siginfo_t *si, void *unused)
|
|||||||
if (sig != SIGSEGV) {
|
if (sig != SIGSEGV) {
|
||||||
fprintf(stderr, "guard: sig_handle: invalid signal\r\n");
|
fprintf(stderr, "guard: sig_handle: invalid signal\r\n");
|
||||||
// XX: do we even want to jump? if this is fatal error, maybe just die now
|
// XX: do we even want to jump? if this is fatal error, maybe just die now
|
||||||
siglongjmp(env_buffer, guard_signal);
|
siglongjmp(buffer_list->buffer, guard_signal);
|
||||||
}
|
}
|
||||||
|
|
||||||
sig_addr = (uintptr_t)si->si_addr;
|
sig_addr = (uintptr_t)si->si_addr;
|
||||||
@ -126,7 +126,7 @@ _signal_handler(int sig, siginfo_t *si, void *unused)
|
|||||||
err = _focus_guard();
|
err = _focus_guard();
|
||||||
if (err) {
|
if (err) {
|
||||||
fprintf(stderr, "guard: sig_handle: focus error\r\n");
|
fprintf(stderr, "guard: sig_handle: focus error\r\n");
|
||||||
siglongjmp(env_buffer, err);
|
siglongjmp(buffer_list->buffer, err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -173,10 +173,11 @@ int32_t
|
|||||||
guard(
|
guard(
|
||||||
callback f,
|
callback f,
|
||||||
void *closure,
|
void *closure,
|
||||||
const uintptr_t *s_pp,
|
const uintptr_t *const s_pp,
|
||||||
const uintptr_t *a_pp,
|
const uintptr_t *const a_pp,
|
||||||
void ** ret
|
void ** ret
|
||||||
) {
|
) {
|
||||||
|
BufListNode *new_buffer;
|
||||||
int32_t err = 0;
|
int32_t err = 0;
|
||||||
int32_t td_err = 0;
|
int32_t td_err = 0;
|
||||||
|
|
||||||
@ -184,6 +185,8 @@ guard(
|
|||||||
fprintf(stderr, "guard: setup: alloc pointer at %p\r\n", (void *)(*a_pp));
|
fprintf(stderr, "guard: setup: alloc pointer at %p\r\n", (void *)(*a_pp));
|
||||||
|
|
||||||
if (guard_p == 0) {
|
if (guard_p == 0) {
|
||||||
|
assert(buffer_list == NULL);
|
||||||
|
|
||||||
stack_pp = s_pp;
|
stack_pp = s_pp;
|
||||||
alloc_pp = a_pp;
|
alloc_pp = a_pp;
|
||||||
|
|
||||||
@ -198,26 +201,58 @@ guard(
|
|||||||
fprintf(stderr, "guard: setup _register_handler error\r\n");
|
fprintf(stderr, "guard: setup _register_handler error\r\n");
|
||||||
goto clean;
|
goto clean;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
assert(buffer_list != NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Setup new longjmp buffer
|
||||||
|
new_buffer = (BufListNode *)malloc(sizeof(BufListNode));
|
||||||
|
if (new_buffer == NULL) {
|
||||||
|
fprintf(stderr, "guard: malloc error\r\n");
|
||||||
|
fprintf(stderr, "%s\r\n", strerror(errno));
|
||||||
|
err = guard_malloc | errno;
|
||||||
|
goto skip;
|
||||||
|
}
|
||||||
|
new_buffer->next = buffer_list;
|
||||||
|
buffer_list = new_buffer;
|
||||||
|
|
||||||
// Run given closure
|
// Run given closure
|
||||||
fprintf(stderr, "guard: run\r\n");
|
fprintf(stderr, "guard: run\r\n");
|
||||||
if (!(err = sigsetjmp(env_buffer, 1))) {
|
if (!(err = sigsetjmp(buffer_list->buffer, 1))) {
|
||||||
*ret = f(closure);
|
*ret = f(closure);
|
||||||
}
|
}
|
||||||
|
|
||||||
clean:
|
// Restore previous longjmp buffer
|
||||||
// Unmark guard page
|
buffer_list = buffer_list->next;
|
||||||
assert(guard_p != 0);
|
free((void *)new_buffer);
|
||||||
td_err = _unmark_page((void *)guard_p);
|
|
||||||
if (td_err) {
|
skip:
|
||||||
fprintf(stderr, "guard: unmark error\r\n");
|
// If no more guarded closures, then...
|
||||||
fprintf(stderr, "%s\r\n", strerror(errno));
|
if (buffer_list == NULL) {
|
||||||
if (!err) {
|
// Remove new signal handler
|
||||||
err = td_err;
|
if (sigaction(SIGSEGV, &prev_sa, NULL)) {
|
||||||
|
fprintf(stderr, "guard: sigaction error\r\n");
|
||||||
|
fprintf(stderr, "%s\r\n", strerror(errno));
|
||||||
|
td_err = guard_sigaction | errno;
|
||||||
|
|
||||||
|
if (!err) {
|
||||||
|
err = td_err;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
clean:
|
||||||
|
// Unmark guard page
|
||||||
|
assert(guard_p != 0);
|
||||||
|
td_err = _unmark_page((void *)guard_p);
|
||||||
|
if (td_err) {
|
||||||
|
fprintf(stderr, "guard: unmark error\r\n");
|
||||||
|
fprintf(stderr, "%s\r\n", strerror(errno));
|
||||||
|
if (!err) {
|
||||||
|
err = td_err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
guard_p = 0;
|
||||||
}
|
}
|
||||||
guard_p = 0;
|
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
fprintf(stderr, "guard: return\r\n");
|
fprintf(stderr, "guard: return\r\n");
|
||||||
|
@ -4,6 +4,14 @@
|
|||||||
#include <setjmp.h>
|
#include <setjmp.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
typedef struct _buf_list_node {
|
||||||
|
jmp_buf buffer;
|
||||||
|
struct _buf_list_node *next;
|
||||||
|
} BufListNode;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Error codes and flags.
|
* Error codes and flags.
|
||||||
*
|
*
|
||||||
@ -52,8 +60,8 @@ int32_t
|
|||||||
guard(
|
guard(
|
||||||
callback f,
|
callback f,
|
||||||
void *closure,
|
void *closure,
|
||||||
const uintptr_t *s_pp,
|
const uintptr_t *const s_pp,
|
||||||
const uintptr_t *a_pp,
|
const uintptr_t *const a_pp,
|
||||||
void **ret
|
void **ret
|
||||||
);
|
);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user