// look up a symbol in a native library // Allocates memory void factor_vm::primitive_dlsym() { data_root<object> library(ctx->pop(), this); data_root<byte_array> name(ctx->peek(), this); check_tagged(name); symbol_char* sym = name->data<symbol_char>(); if (to_boolean(library.value())) { dll* d = untag_check<dll>(library.value()); if (d->handle == NULL) ctx->replace(false_object); else ctx->replace(allot_alien(ffi_dlsym(d, sym))); } else ctx->replace(allot_alien(ffi_dlsym(NULL, sym))); }
/* Look up an external library symbol referenced by a compiled code block */ void *factor_vm::get_rel_symbol(array *literals, cell index) { cell symbol = array_nth(literals,index); cell library = array_nth(literals,index + 1); dll *d = (library == F ? NULL : untag<dll>(library)); if(d != NULL && !d->dll) return (void *)factor::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 sym; else { return (void *)factor::undefined_symbol; } } case ARRAY_TYPE: { cell i; array *names = untag<array>(symbol); for(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 sym; } return (void *)factor::undefined_symbol; } default: critical_error("Bad symbol specifier",symbol); return (void *)factor::undefined_symbol; } }
/* 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; } }
/* look up a symbol in a native library */ inline void factorvm::vmprim_dlsym() { gc_root<object> library(dpop(),this); gc_root<byte_array> name(dpop(),this); name.untag_check(this); symbol_char *sym = name->data<symbol_char>(); if(library.value() == F) box_alien(ffi_dlsym(NULL,sym)); else { dll *d = untag_check<dll>(library.value()); if(d->dll == NULL) dpush(F); else box_alien(ffi_dlsym(d,sym)); } }
cell factor_vm::ffi_dlsym_raw(dll* dll, symbol_char* symbol) { return ffi_dlsym(dll, symbol); }