cell factor_vm::compute_dlsym_toc_address(array *parameters, cell index) { cell symbol = array_nth(parameters,index); cell library = array_nth(parameters,index + 1); dll *d = (to_boolean(library) ? untag<dll>(library) : NULL); void* undefined_toc = (void*)factor::undefined_symbol; undefined_toc = FUNCTION_TOC_POINTER(undefined_toc); if(d != NULL && !d->handle) return (cell)undefined_toc; switch(tagged<object>(symbol).type()) { case BYTE_ARRAY_TYPE: { symbol_char *name = alien_offset(symbol); void* toc = ffi_dlsym_toc(d,name); if(toc) return (cell)toc; else return (cell)undefined_toc; } case ARRAY_TYPE: { array *names = untag<array>(symbol); for(cell i = 0; i < array_capacity(names); i++) { symbol_char *name = alien_offset(array_nth(names,i)); void *toc = ffi_dlsym_toc(d,name); if(toc) return (cell)toc; } return (cell)undefined_toc; } default: critical_error("Bad symbol specifier",symbol); return (cell)undefined_toc; } }
void* factor_vm::ffi_dlsym_toc(dll* dll, symbol_char* symbol) { return FUNCTION_TOC_POINTER(ffi_dlsym_raw(dll, symbol)); }
void factor_vm::dispatch_signal(void* uap, void(handler)()) { dispatch_signal_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)); }