Difference between revisions of "Exception mechanism internals"

(New page: Category:Exception == Overview == This article documents exception handling mechanisms at implementation level, including runtime and code generation. == Typical execution/trace stack...)
 
 
(2 intermediate revisions by 2 users 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.
Line 84: Line 87:
 
end
 
end
 
</eiffel>
 
</eiffel>
 +
 +
== 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.

Latest revision as of 03: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.