| 
									
										
										
										
											2011-10-26 19:22:42 -04:00
										 |  |  | #include "master.hpp"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | namespace factor | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void factor_vm::dispatch_signal_handler(cell *sp, cell *pc, cell handler) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	if (!code->seg->in_segment_p(*pc) || *sp < ctx->callstack_seg->start + stack_reserved) | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2011-10-27 23:24:51 -04:00
										 |  |  | 		/* Fault came from foreign code or a callstack overflow, or we don't
 | 
					
						
							|  |  |  | 		have enough callstack room to try the resumable handler. Cut the | 
					
						
							| 
									
										
										
										
											2011-10-26 19:22:42 -04:00
										 |  |  | 		callstack down to the shallowest Factor stack frame that leaves room for | 
					
						
							| 
									
										
										
										
											2011-10-27 23:24:51 -04:00
										 |  |  | 		the signal handler to do its thing, and launch the handler without going | 
					
						
							| 
									
										
										
										
											2011-10-26 19:22:42 -04:00
										 |  |  | 		through the resumable subprimitive. */ | 
					
						
							|  |  |  | 		signal_resumable = false; | 
					
						
							| 
									
										
										
										
											2011-12-06 20:53:52 -05:00
										 |  |  | 		void *frame_top = (void*)ctx->callstack_top; | 
					
						
							| 
									
										
										
										
											2011-10-26 19:22:42 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-06 20:53:52 -05:00
										 |  |  | 		while(frame_top < ctx->callstack_bottom | 
					
						
							|  |  |  | 			&& (cell)frame_top < ctx->callstack_seg->start + stack_reserved) | 
					
						
							| 
									
										
										
										
											2011-10-26 19:22:42 -04:00
										 |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2011-12-06 20:53:52 -05:00
										 |  |  | 			frame_top = frame_predecessor(frame_top); | 
					
						
							| 
									
										
										
										
											2011-10-26 19:22:42 -04:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-06 20:53:52 -05:00
										 |  |  | 		*sp = (cell)frame_top; | 
					
						
							|  |  |  | 		ctx->callstack_top = frame_top; | 
					
						
							| 
									
										
										
										
											2011-10-26 19:22:42 -04:00
										 |  |  | 		*pc = handler; | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 		signal_resumable = true; | 
					
						
							|  |  |  | 		// Fault came from Factor, and we've got a good callstack. Route the signal
 | 
					
						
							|  |  |  | 		// handler through the resumable signal handler subprimitive.
 | 
					
						
							|  |  |  | 		cell offset = *sp % 16; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		signal_handler_addr = handler; | 
					
						
							|  |  |  | 		tagged<word> handler_word = tagged<word>(special_objects[SIGNAL_HANDLER_WORD]); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		/* True stack frames are always 16-byte aligned. Leaf procedures
 | 
					
						
							|  |  |  | 		that don't create a stack frame will be out of alignment by sizeof(cell) | 
					
						
							|  |  |  | 		bytes. */ | 
					
						
							|  |  |  | 		/* On architectures with a link register we would have to check for leafness
 | 
					
						
							|  |  |  | 		by matching the PC to a word. We should also use FRAME_RETURN_ADDRESS instead | 
					
						
							|  |  |  | 		of assuming the stack pointer is the right place to put the resume address. */ | 
					
						
							|  |  |  | 		if (offset == 0) | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			cell newsp = *sp - sizeof(cell); | 
					
						
							|  |  |  | 			*sp = newsp; | 
					
						
							|  |  |  | 			*(cell*)newsp = *pc; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		else if (offset == 16 - sizeof(cell)) | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			// Make a fake frame for the leaf procedure
 | 
					
						
							| 
									
										
										
										
											2011-12-13 22:36:05 -05:00
										 |  |  | 			FACTOR_ASSERT(code->code_block_for_address(*pc) != NULL); | 
					
						
							| 
									
										
										
										
											2011-10-26 19:22:42 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-11-25 21:58:21 -05:00
										 |  |  | 			cell newsp = *sp - LEAF_FRAME_SIZE; | 
					
						
							| 
									
										
										
										
											2011-12-13 22:36:05 -05:00
										 |  |  | 			*(cell*)newsp = *pc; | 
					
						
							| 
									
										
										
										
											2011-10-26 19:22:42 -04:00
										 |  |  | 			*sp = newsp; | 
					
						
							|  |  |  | 			handler_word = tagged<word>(special_objects[LEAF_SIGNAL_HANDLER_WORD]); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		else | 
					
						
							| 
									
										
										
										
											2011-11-17 23:42:30 -05:00
										 |  |  | 			FACTOR_ASSERT(false); | 
					
						
							| 
									
										
										
										
											2011-10-26 19:22:42 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-11-10 19:00:47 -05:00
										 |  |  | 		*pc = (cell)handler_word->entry_point; | 
					
						
							| 
									
										
										
										
											2011-10-26 19:22:42 -04:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | } |