/* Copyright (C) 1989, 1990, 1993 by Xerox Corporation.  All rights reserved. */
typedef unsigned word, *ptr;
typedef struct {void (*proc)(); word link;} PDBody0;
typedef struct {word (*proc)(); word link;} PDBody1;
extern word XR←Aborted;
#include <xr/Threads.h>

static PDBody0 catchDesc = {0, 0};
static PDBody1 startDesc = {0, 0};

static struct XR←JmpBufRep jmpBuf;

/* BulletproofVestImpl: */ 
extern void XR←run←BulletproofVestImpl ()
{
/* removed because PPCR doesn't support XR←GetTopLevelJumpBuf */
	 
 /*XR←PushAllocedHandler((word) 0, &catchDesc, XR←GetTopLevelJumpBuf() );  */
}

static void catchProc(rtns, context, signal, signalRtns, signalArgs)
	 ptr rtns;
	 ptr context; 	/* ignored */
	 word signal;
	 word signalRtns; /* ignored */
	 word signalArgs; /* ignored */
{
	 if ((signal == XR←Aborted)) {
		(*  rtns ) = 2;         /* GOTO . . . */
		(* (rtns + 1) ) = 1;   /* . . . case 1 */
		return;
		};
		
	 (*  rtns ) = 0;  /* REJECT */
	 (* (rtns + 1) ) = 0;  /* not used */
	 return;
	 }
	 
typedef struct {
	   PDBody1 *forkedProc;
	   word forkedProcResult; } ForkFrame;
	   
static word protectedStartProc(context)
	 ForkFrame *context;
{
	/* NOTE: we must return the result of the procedure if we
		get a normal termination!  Otherwise no JOIN will work
		if it returns a value! */
	word result;
	context->forkedProcResult = 
		(context->forkedProc->proc)(context->forkedProc);
	return(0);
	} 

static word startProc(forkedProc, ignored)
	 PDBody1 *forkedProc;
	 word ignored;
{
	/* NOTE: we must return the result of the forked procedure if we
		get a normal termination!  Otherwise no JOIN will work
		if it returns a value */
	word result;
	ForkFrame forkFrame;
	forkFrame.forkedProc = forkedProc;
	forkFrame.forkedProcResult = 0;
	result = XR←Enable( protectedStartProc, catchProc, &forkFrame );
	if (result==0) return(forkFrame.forkedProcResult); else return(0);
	} 

extern void XR←install←BulletproofVestImpl() {
	catchDesc.proc = catchProc;
	startDesc.proc = startProc;
	XR←RegisterThreadStartProc(&startDesc);
	}