示例#1
0
文件: throw.c 项目: BillTheBest/k42
void
__rethrow(void *index)
{
    struct eh_context *eh = (*get_eh_context) ();
    void *pc, *handler;
    long offset;

    frame_state my_ustruct, *my_udata = &my_ustruct;

    if (! eh->info) {
	__terminate ();
    }

    eh->table_index = index;
label:
    my_udata = __frame_state_for (&&label, my_udata);
    if (! my_udata) {
	__terminate ();
    }
    my_udata->cfa = __builtin_dwarf_cfa ();
    __builtin_unwind_init ();
    pc = __builtin_extract_return_addr (__builtin_return_address (0)) - 1;
    handler = throw_helper (eh, pc, my_udata, &offset);
    __builtin_eh_return ((void *)eh, offset, handler);
}
示例#2
0
文件: proc.c 项目: Sunmonds/gcc
static void
runtime_mcall(void (*pfn)(G*))
{
#ifndef USING_SPLIT_STACK
	int i;
#endif

	// Ensure that all registers are on the stack for the garbage
	// collector.
	__builtin_unwind_init();

	if(g == m->g0)
		runtime_throw("runtime: mcall called on m->g0 stack");

	if(g != nil) {

#ifdef USING_SPLIT_STACK
		__splitstack_getcontext(&g->stack_context[0]);
#else
		g->gcnext_sp = &i;
#endif
		g->fromgogo = false;
		getcontext(&g->context);
	}
	if (g == nil || !g->fromgogo) {
#ifdef USING_SPLIT_STACK
		__splitstack_setcontext(&m->g0->stack_context[0]);
#endif
		m->g0->entry = (byte*)pfn;
		m->g0->param = g;
		g = m->g0;
		setcontext(&m->g0->context);
		runtime_throw("runtime: mcall function returned");
	}
}
示例#3
0
/* ctxt is either a pointer to a ucontext_t we generated, or NULL.	*/
void GC_with_callee_saves_pushed(void (*fn)(ptr_t, void *),
				 ptr_t arg)
{
    word dummy;
    void * context = 0;

#   if defined(HAVE_PUSH_REGS)
      GC_push_regs();
#   elif defined(UNIX_LIKE) && !defined(DARWIN) && !defined(ARM32)
      /* Older versions of Darwin seem to lack getcontext(). */
      /* ARM Linux often doesn't support a real getcontext(). */
      ucontext_t ctxt;
      if (getcontext(&ctxt) < 0)
	ABORT ("Getcontext failed: Use another register retrieval method?");
      context = &ctxt;
#     if defined(SPARC) || defined(IA64)
        /* On a register window machine, we need to save register	*/
        /* contents on the stack for this to work.  This may already be	*/
        /* subsumed by the getcontext() call.				*/
        {
          GC_save_regs_ret_val = GC_save_regs_in_stack();
        }
#     endif /* register windows. */
#   elif defined(HAVE_BUILTIN_UNWIND_INIT)
      /* This was suggested by Richard Henderson as the way to	*/
      /* force callee-save registers and register windows onto	*/
      /* the stack.						*/
      __builtin_unwind_init();
#   else /* !HAVE_BUILTIN_UNWIND_INIT && !UNIX_LIKE  */
         /* && !HAVE_PUSH_REGS			     */
        /* Generic code                          */
        /* The idea is due to Parag Patel at HP. */
        /* We're not sure whether he would like  */
        /* to be he acknowledged for it or not.  */
        jmp_buf regs;
        register word * i = (word *) regs;
        register ptr_t lim = (ptr_t)(regs) + (sizeof regs);

        /* Setjmp doesn't always clear all of the buffer.		*/
        /* That tends to preserve garbage.  Clear it.   		*/
	for (; (char *)i < lim; i++) {
	    *i = 0;
	}
#       if defined(MSWIN32) || defined(MSWINCE) \
                  || defined(UTS4) || defined(LINUX) || defined(EWS4800)
	  (void) setjmp(regs);
#       else
          (void) _setjmp(regs);
	  /* We don't want to mess with signals. According to	*/
	  /* SUSV3, setjmp() may or may not save signal mask.	*/
	  /* _setjmp won't, but is less portable.		*/
#       endif
#   endif /* !HAVE_PUSH_REGS ... */
    fn(arg, context);
    /* Strongly discourage the compiler from treating the above	*/
    /* as a tail-call, since that would pop the register 	*/
    /* contents before we get a chance to look at them.		*/
    GC_noop1((word)(&dummy));
}
示例#4
0
static void
runtime_mcall(void (*pfn)(G*))
{
	M *mp;
	G *gp;
#ifndef USING_SPLIT_STACK
	int i;
#endif

	// Ensure that all registers are on the stack for the garbage
	// collector.
	__builtin_unwind_init();

	mp = m;
	gp = g;
	if(gp == mp->g0)
		runtime_throw("runtime: mcall called on m->g0 stack");

	if(gp != nil) {

#ifdef USING_SPLIT_STACK
		__splitstack_getcontext(&g->stack_context[0]);
#else
		gp->gcnext_sp = &i;
#endif
		gp->fromgogo = false;
		getcontext(&gp->context);

		// When we return from getcontext, we may be running
		// in a new thread.  That means that m and g may have
		// changed.  They are global variables so we will
		// reload them, but the addresses of m and g may be
		// cached in our local stack frame, and those
		// addresses may be wrong.  Call functions to reload
		// the values for this thread.
		mp = runtime_m();
		gp = runtime_g();

		if(gp->traceback != nil)
			gtraceback(gp);
	}
	if (gp == nil || !gp->fromgogo) {
#ifdef USING_SPLIT_STACK
		__splitstack_setcontext(&mp->g0->stack_context[0]);
#endif
		mp->g0->entry = (byte*)pfn;
		mp->g0->param = gp;

		// It's OK to set g directly here because this case
		// can not occur if we got here via a setcontext to
		// the getcontext call just above.
		g = mp->g0;

		fixcontext(&mp->g0->context);
		setcontext(&mp->g0->context);
		runtime_throw("runtime: mcall function returned");
	}
}
示例#5
0
void VMPI_callWithRegistersSaved(void (*fn)(void* stackPointer, void* arg), void* arg)
{
#if defined MMGC_IA32
    void* buf = NULL;
    __builtin_unwind_init();                    // Save registers - GCC intrinsic.  Not reliable on 10.4 PPC or 64-bit
#else
    jmp_buf buf;
    VMPI_setjmpNoUnwind(buf);                   // Save registers - not always reliable
#endif
    CallWithRegistersSaved2(fn, arg, &buf);     // Computes the stack pointer, calls fn
    CallWithRegistersSaved3(fn, &arg, &buf);    // Probably prevents the previous call from being a tail call
}
示例#6
0
NOCOMPRESSION void
foo (int x)
{
  __builtin_unwind_init ();
  __builtin_eh_return (x, bar);
}
示例#7
0
void VMPI_callWithRegistersSaved(void (*fn)(void* stackPointer, void* arg), void* arg)
{
    __builtin_unwind_init();                    // Save registers - GCC intrinsic
    CallWithRegistersSaved2(fn, arg, NULL);     // Computes the stack pointer, calls fn
    CallWithRegistersSaved3(fn, &arg, NULL);    // Probably prevents the previous call from being a tail call
}
示例#8
0
void foo(void)
{
  __builtin_unwind_init ();
  setup_offset();
  __builtin_eh_return (offset, handler);
}