Difference between revisions of "Exception mechanism internals"

 
(One intermediate revision by the same user not shown)
Line 1: Line 1:
 
[[Category:Exception]]
 
[[Category:Exception]]
 +
[[Category:Code Generation]]
 +
[[Category:Eiffel Language]]
 +
 
== Overview ==
 
== Overview ==
 
This article documents exception handling mechanisms at implementation level, including runtime and code generation.
 
This article documents exception handling mechanisms at implementation level, including runtime and code generation.

Latest revision as of 04:17, 21 January 2016


Overview

This article documents exception handling mechanisms at implementation level, including runtime and code generation.

Typical execution/trace stack operation in a routine

Once or routine with old variable is slightly different. See following pseudocode:

-- entry
 
new_exset
	do
		-- eif_stack: Create a new vector EX_CALL on eif_stack.
	end
 
 
if not setjmp then
 
	-- Routine body
 
else
 
	exresc
 
	do
 
		-- eif_trace: Check the stack of eif_trace top element must be EN_FAIL or EN_RES
 
		-- eif_trace: Mark top node as rescued
 
		-- eif_trace: Create new EN_ILVL item on eif_trace, indicating entering a new level
 
		-- eif_stack: Create new EX_RESC vector on eif_stack.
 
	end
 
	Rescue_body
 
		-- If there is retry clause, it calls 
 
	exret
 
	do
 
		-- eif_stack: Check top vector of eif_stack is EX_RESC
 
		-- eif_stack: Override top item of eif_stack with the vector of current routine (saved as local). Change the type of the vector to EX_RETY
 
		-- eif_trace: Pop off eif_trace, which must be EN_ILVL item
 
		-- eif_trace: unwind_trace, pop items from eif_trace until EN_ILVL item is found. Restore `exdata' at previous level.
 
	end
 
		-- If no retry is called, call at the end:
 
	exfail
 
	do
 
		-- eif_stack: pop EX_RESC from eif_stack
 
		-- eif_trace: pop EN_ILVL from eif_trace, leaving call failures created by `draise' on stack.
 
		-- create last_exception (ROUTINE_FAILURE)
 
		-- eif_stack: call `backtrack' which will pop eif_stack until find the top most jmpbuf.
 
		-- Call longjmp with the found jmpbuf.
 
	end
 
end
 
exok
 
do
 
	-- eif_stack: Pop eif_stack until a EX_CALL, EX_RESC, EX_RETY or EX_OSTK is found and popped.
 
	-- eif_trace: unwind_trace, pop item from eif_trace until we find EN_ILVL item. Restore `exdata' at previous level.
 
end

Raise an exception (draise, eraise, com_raise, )

  • Create a new item on eif_trace, with the type the exception.
  • Pop and push back eif_stack in order to get information. Fill those information into `exdata'.
  • Setup information for top node in eif_trace.
  • In make_exception, when building trace, traverse eif_stack, and push corresponding items into eif_trace, until jmp pointer is found. In the meantime, if the item is EX_RESC, we change it to EN_OLVL and put into eif_trace.
  • Continue buidling trace from the rest element of eif_stack until root node is reached.
  • Call `back_track' to really pop off items in eif_stack and call longjmp when the first jmp pointer is found.

System signal handler

  • Push an EN_ILVL item on eif_trace
  • Push an EX_HDLR item on eif_stack and setup a jmpbuf
  • Call exception handler and be ready to longjmp back and call eraise to populate the exception.