
*	Maxon C++ Library:
*	Modul "exc.o"
*	Funktionen für Exception Handling (ab V 3.0)
*	Jens Gelhar 07.05.94

	xdef	lib_throw,lib_rethrow
	xdef	lib_catch,lib_catchclass
	xdef	sym_handlers
	xdef	_INIT_0_exc_o_GruesseAnDietrichJuergenStoffelUli
	xref	abort_

	
lib_throw:
	move.l	lastexception,(a7)	; Return-Adresse ist egal,
	; stattdessen merken wir uns diesen alten Wert
	move.l	a7,lastexception
throwthis:
	move.l	sym_handlers,a0
	move.l	(a0),sym_handlers	; einen Stackeintrag poppen
	move.l	8(a0),d0
	beq.b	.handler
	; Destruktor-Aufruf:
	move.l	d0,-(a7)	; Adresse des Objekts
	move.l	4(a0),a0	; Adresse des Destruktors
	jsr	(a0)		; Destruktor aufrufeb
	addq.l	#4,a7
	bra.b	throwthis

.handler ; Echten Exception Handler gefunden:
	move.l	a0,lasthandler
	move.l	4(a0),-(a7)		; Handleradresse merken
	movem.l	12(a0),d0-d7/a0-a6	; Register (außer Stack) restoren
	rts				; Handler anspringen


lib_rethrow:
	move.l	lastexception,d0
	beq.b	.abort
	move.l	d0,a7
	bra	throwthis
.abort	; es wurde keine unaufgefangene Exception geschmissen:
	jmp	abort_


lib_catch: ; Handler wurde abgearbeitet - jetzt Stack korrigieren etc.:
	move.l	4(a7),lastexception
	move.l	a0,-(a7)
	move.l	lasthandler,a0
	move.l	12+15*4(a0),a0	; neuer Stackpointer
	move.l	4(a7),-(a0)	; Rückkehradresse
	move.l	(a7),-(a0)	; gemerkter Wert von "a0"
	move.l	a0,a7		; jetzt Stackpointer umsetzen
	move.l	(a7)+,a0
	rts


lib_catchclass: ; falls Klassen-Handle d0 in Tabelle 8(a7) steht,
	; Offset in 16(a7) ablegen und "ne", sonst "eq"
	move.l	a1,-(a7)
	move.l	12(a7),a1
.loop	tst.l	(a1)
	beq.b	.0
	cmp.l	(a1)+,d0
	beq.b	.ok
	addq.l	#4,a1
	bra.b	.loop
.ok	move.l	(a1),20(a7)
	cmp.w	#0,a7
.0	move.l	(a7)+,a1
	rts


_INIT_0_exc_o_GruesseAnDietrichJuergenStoffelUli:
	move.l	a7,stckptr
	move.l	#handlerstruct,sym_handlers
	rts

; initialer Eintrag auf dem Exception-Stack:

handlerstruct:
	dc.l	0	; link: Ende der Liste
	dc.l	abort_	; letzter "Handler" ist Ausstieg
	dc.l	0	; NULL als Kennzeichnung
	ds.l	15	; die meisten Register sind egal
stckptr	ds.l	1	; Stackpointer wird gespeichert (ist besser)


	SECTION D,DATA

sym_handlers:		; Stackpointer für Exception Handlers und Destruktoren
	dc.l	0

lastexception:
	dc.l	0	; Zeiger auf zuletzt geworfene Exception

lasthandler:
	dc.l	0	; zuletzt ausprobierter Exception Handler

	END
