def _switch(h): # No shadowstack manipulation here (no usage of gc references) sscopy = sscopy_detach_shadow_stack() gcrootfinder.sscopy = sscopy if not sscopy: return _c.null_handle h = _c.switch(h) sscopy_attach_shadow_stack(sscopy) return h
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 _switch_callback(): # Here, we just closed the stack. Get the stack anchor, store # it in the gcrootfinder.suspstack.anchor, and switch to this # suspstack with stacklet_switch(). If this call fails, then we # are just returning NULL. oldanchor = gcrootfinder.suspstack.anchor _stack_just_closed() h = _consume_suspstack(gcrootfinder.suspstack) # # gcrootfinder.suspstack.anchor is left with the anchor of the # previous place (i.e. before the call to switch()). h2 = _c.switch(h) # if not h2: # MemoryError: restore gcrootfinder.suspstack.anchor = oldanchor gcrootfinder.suspstack.handle = h return h2
def f(): switch(rffi.cast(handle, 0))
def switch(h): h = _c.switch(h) if not h: raise MemoryError return h