mirror of
https://github.com/urbit/ares.git
synced 2024-12-24 13:55:23 +03:00
serf: ensure locals are preserved and top frame flipped after PMA save
This commit is contained in:
parent
02b1ae3dd2
commit
3acf8e74c1
@ -110,8 +110,8 @@ impl Context {
|
|||||||
Context::new(trace_info, snapshot, constant_hot_state)
|
Context::new(trace_info, snapshot, constant_hot_state)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn save(&mut self) {
|
pub unsafe fn save(&mut self) {
|
||||||
let handle = unsafe {
|
let handle = {
|
||||||
let mut snapshot = Snapshot({
|
let mut snapshot = Snapshot({
|
||||||
let snapshot_mem_ptr: *mut SnapshotMem = self.nock_context.stack.struct_alloc(1);
|
let snapshot_mem_ptr: *mut SnapshotMem = self.nock_context.stack.struct_alloc(1);
|
||||||
|
|
||||||
@ -188,7 +188,12 @@ impl Context {
|
|||||||
// Setters
|
// Setters
|
||||||
//
|
//
|
||||||
|
|
||||||
pub fn event_update(&mut self, new_event_num: u64, new_arvo: Noun) {
|
///
|
||||||
|
/// ## Safety
|
||||||
|
///
|
||||||
|
/// calls save(), which invalidates all nouns not in the context
|
||||||
|
/// until [preserve_event_update_leftovers] is called to resolve forwarding pointers.
|
||||||
|
pub unsafe fn event_update(&mut self, new_event_num: u64, new_arvo: Noun) {
|
||||||
// XX: assert event numbers are continuous
|
// XX: assert event numbers are continuous
|
||||||
self.arvo = new_arvo;
|
self.arvo = new_arvo;
|
||||||
self.event_num = new_event_num;
|
self.event_num = new_event_num;
|
||||||
@ -201,6 +206,21 @@ impl Context {
|
|||||||
self.mug = mug_u32(&mut self.nock_context.stack, self.arvo);
|
self.mug = mug_u32(&mut self.nock_context.stack, self.arvo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// ## Safety
|
||||||
|
///
|
||||||
|
/// Preserves nouns and jet states in context and then calls [flip_top_frame].
|
||||||
|
/// Other stack-allocated objects needing preservation should be preserved between
|
||||||
|
/// [event_update] and invocation of this function
|
||||||
|
pub unsafe fn preserve_event_update_leftovers(&mut self) {
|
||||||
|
let stack = &mut self.nock_context.stack;
|
||||||
|
stack.preserve(&mut self.arvo);
|
||||||
|
stack.preserve(&mut self.nock_context.cold);
|
||||||
|
stack.preserve(&mut self.nock_context.warm);
|
||||||
|
stack.preserve(&mut self.nock_context.hot);
|
||||||
|
stack.flip_top_frame(0);
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Newt functions
|
// Newt functions
|
||||||
//
|
//
|
||||||
@ -370,15 +390,6 @@ pub fn serf(constant_hot_state: &[HotEntry]) -> io::Result<()> {
|
|||||||
|
|
||||||
clear_interrupt();
|
clear_interrupt();
|
||||||
|
|
||||||
//
|
|
||||||
unsafe {
|
|
||||||
let stack = &mut context.nock_context.stack;
|
|
||||||
stack.preserve(&mut context.arvo);
|
|
||||||
stack.preserve(&mut context.nock_context.cold);
|
|
||||||
stack.preserve(&mut context.nock_context.warm);
|
|
||||||
stack.preserve(&mut context.nock_context.hot);
|
|
||||||
stack.flip_top_frame(0);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
@ -471,7 +482,10 @@ fn play_life(context: &mut Context, eve: Noun) {
|
|||||||
let eved = lent(eve).expect("serf: play: boot event number failure") as u64;
|
let eved = lent(eve).expect("serf: play: boot event number failure") as u64;
|
||||||
let arvo = slot(gat, 7).expect("serf: play: lifecycle didn't return initial Arvo");
|
let arvo = slot(gat, 7).expect("serf: play: lifecycle didn't return initial Arvo");
|
||||||
|
|
||||||
context.event_update(eved, arvo);
|
unsafe {
|
||||||
|
context.event_update(eved, arvo);
|
||||||
|
context.preserve_event_update_leftovers();
|
||||||
|
}
|
||||||
context.play_done();
|
context.play_done();
|
||||||
}
|
}
|
||||||
Err(error) => match error {
|
Err(error) => match error {
|
||||||
@ -504,7 +518,10 @@ fn play_list(context: &mut Context, mut lit: Noun) {
|
|||||||
.tail();
|
.tail();
|
||||||
eve += 1;
|
eve += 1;
|
||||||
|
|
||||||
context.event_update(eve, arvo);
|
unsafe {
|
||||||
|
context.event_update(eve, arvo);
|
||||||
|
context.preserve_event_update_leftovers();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Err(goof) => {
|
Err(goof) => {
|
||||||
return context.play_bail(goof);
|
return context.play_bail(goof);
|
||||||
@ -533,10 +550,14 @@ fn work(context: &mut Context, job: Noun) {
|
|||||||
match soft(context, job, trace_name) {
|
match soft(context, job, trace_name) {
|
||||||
Ok(res) => {
|
Ok(res) => {
|
||||||
let cell = res.as_cell().expect("serf: work: +slam returned atom");
|
let cell = res.as_cell().expect("serf: work: +slam returned atom");
|
||||||
let fec = cell.head();
|
let mut fec = cell.head();
|
||||||
let eve = context.event_num;
|
let eve = context.event_num;
|
||||||
|
|
||||||
context.event_update(eve + 1, cell.tail());
|
unsafe {
|
||||||
|
context.event_update(eve + 1, cell.tail());
|
||||||
|
context.nock_context.stack.preserve(&mut fec);
|
||||||
|
context.preserve_event_update_leftovers();
|
||||||
|
}
|
||||||
context.work_done(fec);
|
context.work_done(fec);
|
||||||
}
|
}
|
||||||
Err(goof) => {
|
Err(goof) => {
|
||||||
@ -560,7 +581,7 @@ fn work_swap(context: &mut Context, job: Noun, goof: Noun) {
|
|||||||
let now = inc(stack, job_now).as_noun();
|
let now = inc(stack, job_now).as_noun();
|
||||||
let wire = T(stack, &[D(0), D(tas!(b"arvo")), D(0)]);
|
let wire = T(stack, &[D(0), D(tas!(b"arvo")), D(0)]);
|
||||||
let crud = DirectAtom::new_panic(tas!(b"crud"));
|
let crud = DirectAtom::new_panic(tas!(b"crud"));
|
||||||
let ovo = T(stack, &[now, wire, crud.as_noun(), goof, job_cell.tail()]);
|
let mut ovo = T(stack, &[now, wire, crud.as_noun(), goof, job_cell.tail()]);
|
||||||
let trace_name = if context.nock_context.trace_info.is_some() {
|
let trace_name = if context.nock_context.trace_info.is_some() {
|
||||||
Some(work_trace_name(
|
Some(work_trace_name(
|
||||||
&mut context.nock_context.stack,
|
&mut context.nock_context.stack,
|
||||||
@ -574,10 +595,15 @@ fn work_swap(context: &mut Context, job: Noun, goof: Noun) {
|
|||||||
match soft(context, ovo, trace_name) {
|
match soft(context, ovo, trace_name) {
|
||||||
Ok(res) => {
|
Ok(res) => {
|
||||||
let cell = res.as_cell().expect("serf: work: crud +slam returned atom");
|
let cell = res.as_cell().expect("serf: work: crud +slam returned atom");
|
||||||
let fec = cell.head();
|
let mut fec = cell.head();
|
||||||
let eve = context.event_num;
|
let eve = context.event_num;
|
||||||
|
|
||||||
context.event_update(eve + 1, cell.tail());
|
unsafe {
|
||||||
|
context.event_update(eve + 1, cell.tail());
|
||||||
|
context.nock_context.stack.preserve(&mut ovo);
|
||||||
|
context.nock_context.stack.preserve(&mut fec);
|
||||||
|
context.preserve_event_update_leftovers();
|
||||||
|
}
|
||||||
context.work_swap(ovo, fec);
|
context.work_swap(ovo, fec);
|
||||||
}
|
}
|
||||||
Err(goof_crud) => {
|
Err(goof_crud) => {
|
||||||
|
Loading…
Reference in New Issue
Block a user