/* Look up an external library symbol referenced by a compiled code block */ cell factor_vm::compute_dlsym_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_symbol = (void*)factor::undefined_symbol; undefined_symbol = FUNCTION_CODE_POINTER(undefined_symbol); if(d != NULL && !d->handle) return (cell)undefined_symbol; switch(tagged<object>(symbol).type()) { case BYTE_ARRAY_TYPE: { symbol_char *name = alien_offset(symbol); void *sym = ffi_dlsym(d,name); if(sym) return (cell)sym; else return (cell)undefined_symbol; } 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 *sym = ffi_dlsym(d,name); if(sym) return (cell)sym; } return (cell)undefined_symbol; } default: critical_error("Bad symbol specifier",symbol); return (cell)undefined_symbol; } }
void* factor_vm::ffi_dlsym(dll* dll, symbol_char* symbol) { return FUNCTION_CODE_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)); }