def switch(suspstack): # suspstack has a handle to target, i.e. where to switch to ll_assert(suspstack != gcrootfinder.oldsuspstack, "stacklet: invalid use") gcrootfinder.newsuspstack = suspstack h = llop.gc_shadowstackref_context(llmemory.Address, suspstack) h = llmemory.cast_adr_to_ptr(h, _c.handle) prepare_old_suspstack() h = _c.switch(h) return get_result_suspstack(h)
def _new_callback(h, arg): # We still have the old shadowstack active at this point; save it # away, and start a fresh new one oldsuspstack = gcrootfinder.oldsuspstack h = llmemory.cast_ptr_to_adr(h) llop.gc_save_current_state_away(lltype.Void, oldsuspstack, h) llop.gc_start_fresh_new_state(lltype.Void) gcrootfinder.oldsuspstack = NULL_SUSPSTACK # newsuspstack = gcrootfinder.callback(oldsuspstack, arg) # # Finishing this stacklet. gcrootfinder.oldsuspstack = NULL_SUSPSTACK gcrootfinder.newsuspstack = newsuspstack h = llop.gc_shadowstackref_context(llmemory.Address, newsuspstack) return llmemory.cast_adr_to_ptr(h, _c.handle)