The new signal handler dispatch is logic is CISC-centric; defer fixing it until we find someone who cares
+PLAF_DLL_OBJS += vm/cpu-x86.o
+PLAF_DLL_OBJS += vm/cpu-x86.o
return stack;
}
-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)
- {
- /* Fault came from foreign code, a callstack overflow, or we would probably
- overflow if we tried the resumable handler. We can't resume, so cut the
- callstack down to the shallowest Factor stack frame that leaves room for
- the signal handler to do its thing and launch the handler without going
- through the resumable subprimitive. */
- signal_resumable = false;
- stack_frame *frame = ctx->callstack_bottom - 1;
-
- while((cell)frame >= *sp
- && frame >= ctx->callstack_top
- && (cell)frame >= ctx->callstack_seg->start + stack_reserved)
- {
- frame = frame_successor(frame);
- }
-
- // XXX FRAME_RETURN_ADDRESS
- cell newsp = (cell)(frame+1);
- *sp = newsp;
- ctx->callstack_top = (stack_frame*)newsp;
- *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]);
-
- /* XXX horribly x86-centric */
- /* 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
- code_block *leaf_block = code->code_block_for_address(*pc);
- assert(leaf_block != NULL);
-
- // XXX get platform-appropriate stack frame size
- cell newsp = *sp - 32;
- *(cell*)(newsp + 32 - sizeof(cell)) = 32;
- *(cell*)(newsp + 32 - 2*sizeof(cell)) = (cell)leaf_block->entry_point();
- *(cell*) newsp = *pc;
- *sp = newsp;
- handler_word = tagged<word>(special_objects[LEAF_SIGNAL_HANDLER_WORD]);
- }
- else
- {
- fatal_error("Invalid stack frame during signal handler", *sp);
- }
-
- *pc = (cell)handler_word->code->entry_point();
- }
-}
-
/* We ignore the two topmost frames, the 'callstack' primitive
frame itself, and the frame calling the 'callstack' primitive,
so that set-callstack doesn't get stuck in an infinite loop.
--- /dev/null
+#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)
+ {
+ /* Fault came from foreign code, a callstack overflow, or we would probably
+ overflow if we tried the resumable handler. We can't resume, so cut the
+ callstack down to the shallowest Factor stack frame that leaves room for
+ the signal handler to do its thing and launch the handler without going
+ through the resumable subprimitive. */
+ signal_resumable = false;
+ stack_frame *frame = ctx->callstack_bottom - 1;
+
+ while((cell)frame >= *sp
+ && frame >= ctx->callstack_top
+ && (cell)frame >= ctx->callstack_seg->start + stack_reserved)
+ {
+ frame = frame_successor(frame);
+ }
+
+ cell newsp = (cell)(frame+1);
+ *sp = newsp;
+ ctx->callstack_top = (stack_frame*)newsp;
+ *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
+ code_block *leaf_block = code->code_block_for_address(*pc);
+ assert(leaf_block != NULL);
+
+ cell newsp = *sp - 32;
+ *(cell*)(newsp + 32 - sizeof(cell)) = 32;
+ *(cell*)(newsp + 32 - 2*sizeof(cell)) = (cell)leaf_block->entry_point();
+ *(cell*) newsp = *pc;
+ *sp = newsp;
+ handler_word = tagged<word>(special_objects[LEAF_SIGNAL_HANDLER_WORD]);
+ }
+ else
+ {
+ fatal_error("Invalid stack frame during signal handler", *sp);
+ }
+
+ *pc = (cell)handler_word->code->entry_point();
+ }
+}
+
+}
assert(handler != 0);
dispatch_signal_handler(
- &MACH_STACK_POINTER(thread_state),
- &MACH_PROGRAM_COUNTER(thread_state),
- handler
+ (cell*)&MACH_STACK_POINTER(thread_state),
+ (cell*)&MACH_PROGRAM_COUNTER(thread_state),
+ (cell)handler
);
}
factor_vm *current_vm_p()
{
- factor_vm *vm = (factor_vm*)pthread_getspecific(current_vm_tls_key);
- return vm;
+ return (factor_vm*)pthread_getspecific(current_vm_tls_key);
}
}
void factor_vm::dispatch_signal(void *uap, void (handler)())
{
dispatch_signal_handler(
- &UAP_STACK_POINTER(uap),
- &UAP_PROGRAM_COUNTER(uap),
- FUNCTION_CODE_POINTER(handler)
+ (cell*)&UAP_STACK_POINTER(uap),
+ (cell*)&UAP_PROGRAM_COUNTER(uap),
+ (cell)FUNCTION_CODE_POINTER(handler)
);
UAP_SET_TOC_POINTER(uap, (cell)FUNCTION_TOC_POINTER(handler));
}
void primitive_set_innermost_stack_frame_quot();
void primitive_callstack_bounds();
template<typename Iterator> void iterate_callstack(context *ctx, Iterator &iterator);
- void dispatch_signal_handler(cell *sp, cell *pc, cell newpc);
- void dispatch_signal_handler_from_leaf(cell *sp, cell *pc, cell newpc);
- template<typename CellA, typename CellB, typename CellC>
- void dispatch_signal_handler(CellA *sp, CellB *pc, CellC newpc)
- {
- dispatch_signal_handler(
- reinterpret_cast<cell*>(sp),
- reinterpret_cast<cell*>(pc),
- (cell)newpc
- );
- }
+ // cpu-*
+ void dispatch_signal_handler(cell *sp, cell *pc, cell newpc);
// alien
char *pinned_alien_offset(cell obj);