void memory_signal_handler_impl()
{
- return vm->memory_signal_handler_impl();
+ SIGNAL_VM_PTR->misc_signal_handler_impl();
}
void factorvm::misc_signal_handler_impl()
void misc_signal_handler_impl()
{
- vm->misc_signal_handler_impl();
+ SIGNAL_VM_PTR->misc_signal_handler_impl();
}
void factorvm::fp_signal_handler_impl()
void fp_signal_handler_impl()
{
- vm->fp_signal_handler_impl();
+ SIGNAL_VM_PTR->fp_signal_handler_impl();
}
}
PRIMITIVE(call_clear);
PRIMITIVE(unimplemented);
-/* Global variables used to pass fault handler state from signal handler to
-user-space */
-extern cell signal_number;
-extern cell signal_fault_addr;
-extern unsigned int signal_fpu_status;
-extern stack_frame *signal_callstack_top;
-
void memory_signal_handler_impl();
void fp_signal_handler_impl();
void misc_signal_handler_impl();
factorvm *vm;
+unordered_map<long,factorvm*> thread_vms;
+
+factorvm *lookup_vm(long threadid)
+{
+ return thread_vms[threadid];
+}
+
+void register_vm(long threadid, factorvm *vm)
+{
+ thread_vms[threadid] = vm;
+}
+
+
void factorvm::default_parameters(vm_parameters *p)
{
p->image_path = NULL;
void factorvm::start_standalone_factor(int argc, vm_char **argv)
{
+ printf("thread id is %d\n",GetCurrentThreadId());fflush(stdout);
+ register_vm(GetCurrentThreadId(),this);
vm_parameters p;
default_parameters(&p);
init_parameters_from_args(&p,argc,argv);
/* Are we in compiled Factor code? Then use the current stack pointer */
if(vm->in_code_heap_p(MACH_PROGRAM_COUNTER(thread_state)))
- signal_callstack_top = (stack_frame *)MACH_STACK_POINTER(thread_state);
+ vm->signal_callstack_top = (stack_frame *)MACH_STACK_POINTER(thread_state);
/* Are we in C? Then use the saved callstack top */
else
- signal_callstack_top = NULL;
+ vm->signal_callstack_top = NULL;
MACH_STACK_POINTER(thread_state) = fix_stack_pointer(MACH_STACK_POINTER(thread_state));
/* Now we point the program counter at the right handler function. */
if(exception == EXC_BAD_ACCESS)
{
- signal_fault_addr = MACH_EXC_STATE_FAULT(exc_state);
+ vm->signal_fault_addr = MACH_EXC_STATE_FAULT(exc_state);
MACH_PROGRAM_COUNTER(thread_state) = (cell)memory_signal_handler_impl;
}
else if(exception == EXC_ARITHMETIC && code != MACH_EXC_INTEGER_DIV)
}
else
{
- signal_number = (exception == EXC_ARITHMETIC ? SIGFPE : SIGABRT);
+ vm->signal_number = (exception == EXC_ARITHMETIC ? SIGFPE : SIGABRT);
MACH_PROGRAM_COUNTER(thread_state) = (cell)misc_signal_handler_impl;
}
}
void memory_signal_handler(int signal, siginfo_t *siginfo, void *uap)
{
- signal_fault_addr = (cell)siginfo->si_addr;
- signal_callstack_top = uap_stack_pointer(uap);
+ vm->signal_fault_addr = (cell)siginfo->si_addr;
+ vm->signal_callstack_top = uap_stack_pointer(uap);
UAP_PROGRAM_COUNTER(uap) = (cell)memory_signal_handler_impl;
}
void misc_signal_handler(int signal, siginfo_t *siginfo, void *uap)
{
- signal_number = signal;
- signal_callstack_top = uap_stack_pointer(uap);
+ vm->signal_number = signal;
+ vm->signal_callstack_top = uap_stack_pointer(uap);
UAP_PROGRAM_COUNTER(uap) = (cell)misc_signal_handler_impl;
}
void open_console();
+#define SIGNAL_VM_PTR vm
}
namespace factor
{
-void start_thread(void *(*start_routine)(void *),void *args){
- CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)start_routine, args, 0, 0);
+void *start_thread(void *(*start_routine)(void *),void *args){
+ return CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)start_routine, args, 0, 0);
}
FACTOR_STDCALL LONG exception_handler(PEXCEPTION_POINTERS pe)
{
+ printf("exception handler %d\n",GetCurrentThreadId());
+ factorvm *myvm = lookup_vm(GetCurrentThreadId());
PEXCEPTION_RECORD e = (PEXCEPTION_RECORD)pe->ExceptionRecord;
CONTEXT *c = (CONTEXT*)pe->ContextRecord;
- if(vm->in_code_heap_p(c->EIP))
- signal_callstack_top = (stack_frame *)c->ESP;
+ if(myvm->in_code_heap_p(c->EIP))
+ myvm->signal_callstack_top = (stack_frame *)c->ESP;
else
- signal_callstack_top = NULL;
+ myvm->signal_callstack_top = NULL;
- switch (e->ExceptionCode)
- {
- case EXCEPTION_ACCESS_VIOLATION:
- signal_fault_addr = e->ExceptionInformation[1];
+ switch (e->ExceptionCode) {
+ case EXCEPTION_ACCESS_VIOLATION:
+ myvm->signal_fault_addr = e->ExceptionInformation[1];
c->EIP = (cell)memory_signal_handler_impl;
break;
case STATUS_FLOAT_UNDERFLOW:
case STATUS_FLOAT_MULTIPLE_FAULTS:
case STATUS_FLOAT_MULTIPLE_TRAPS:
- signal_fpu_status = fpu_status(X87SW(c) | MXCSR(c));
+ myvm->signal_fpu_status = fpu_status(X87SW(c) | MXCSR(c));
X87SW(c) = 0;
MXCSR(c) &= 0xffffffc0;
c->EIP = (cell)fp_signal_handler_impl;
enabled. Don't really have any idea what this exception means. */
break;
default:
- signal_number = e->ExceptionCode;
+ myvm->signal_number = e->ExceptionCode;
c->EIP = (cell)misc_signal_handler_impl;
break;
}
FACTOR_STDCALL LONG exception_handler(PEXCEPTION_POINTERS pe);
-
// SSE traps raise these exception codes, which are defined in internal NT headers
// but not winbase.h
#define STATUS_FLOAT_MULTIPLE_FAULTS 0xC00002B4
#define STATUS_FLOAT_MULTIPLE_TRAPS 0xC00002B5
-void start_thread(void *(*start_routine)(void *),void *args);
+void *start_thread(void *(*start_routine)(void *),void *args);
+
+#define SIGNAL_VM_PTR lookup_vm(GetCurrentThreadId())
}
inline void vmprim_profiling();
// errors
+ /* Global variables used to pass fault handler state from signal handler to
+ user-space */
+ cell signal_number;
+ cell signal_fault_addr;
+ unsigned int signal_fpu_status;
+ stack_frame *signal_callstack_top;
void out_of_memory();
void fatal_error(const char* msg, cell tagged);
void critical_error(const char* msg, cell tagged);
extern factorvm *vm;
+extern factorvm *lookup_vm(long threadid);
+extern void register_vm(long threadid,factorvm *vm);
}