def cdlopen_close(self): libhandle = self.libhandle self.libhandle = rffi.cast(DLLHANDLE, 0) if not libhandle: raise oefmt(self.ffi.w_FFIError, "library '%s' is already closed", self.libname) # Clear the dict to force further accesses to do cdlopen_fetch() # again, and fail because the library was closed. Note that the # JIT may have elided some accesses, and so has addresses as # constants. We could work around it with a quasi-immutable flag # but unsure it's worth it. self.dict_w.clear() if dlclose(libhandle) < 0: raise oefmt(self.ffi.w_FFIError, "error closing library '%s'", self.libname)
def cdlopen_close(self): libhandle = self.libhandle self.libhandle = rffi.cast(DLLHANDLE, 0) if not libhandle: return self.may_unregister_rpython_finalizer(self.ffi.space) # Clear the dict to force further accesses to do cdlopen_fetch() # again, and fail because the library was closed. Note that the # JIT may have elided some accesses, and so has addresses as # constants. We could work around it with a quasi-immutable flag # but unsure it's worth it. self.dict_w.clear() if dlclose(libhandle) < 0: raise oefmt(self.ffi.w_FFIError, "error closing library '%s'", self.libname)
def _finalize_(self): h = self.handle if h != rffi.cast(DLLHANDLE, 0): self.handle = rffi.cast(DLLHANDLE, 0) dlclose(h)
def __del__(self): if self.lib: dlclose(self.lib) self.lib = rffi.cast(DLLHANDLE, 0)
def __del__(self): if self.lib != rffi.cast(DLLHANDLE, -1): dlclose(self.lib) self.lib = rffi.cast(DLLHANDLE, -1)
def __del__(self): h = self.handle if h != rffi.cast(DLLHANDLE, 0): self.handle = rffi.cast(DLLHANDLE, 0) dlclose(h)
class _InterpreterProxy(object): _immutable_fields_ = ['vm_initialized?'] def __init__(self): self.vm_proxy = lltype.nullptr(VMPtr.TO) self.vm_initialized = False self.space = None self._next_oop = 0 self.oop_map = {} self.object_map = {} self.loaded_modules = {} self.remappable_objects = [] self.trace_proxy = objspace.ConstantFlag() self.reset() def reset(self): self.interp = None self.s_frame = None self.argcount = 0 self.w_method = None self.fail_reason = 0 self.trace_proxy.deactivate() def call(self, signature, interp, s_frame, argcount, w_method): self.initialize_from_call(signature, interp, s_frame, argcount, w_method) try: # eventual errors are caught by the calling function (EXTERNAL_CALL) external_function = rffi.cast(func_bool_void, self.loadFunctionFrom(signature[0], signature[1])) if interp.is_tracing(): interp.print_padded("Calling %s >> %s" % (signature[0], signature[1])) external_function() if not self.fail_reason == 0: raise error.PrimitiveFailedError finally: self.reset() def loadFunctionFrom(self, module_name, function_name): from rpython.rlib.rdynload import dlsym if module_name not in self.loaded_modules: module = self.load_and_initialize(module_name) else: module = self.loaded_modules[module_name] if function_name in module[1]: return module[1][function_name] else: try: _external_function = dlsym(module[0], function_name) except KeyError: raise ProxyFunctionFailed else: module[1][function_name] = _external_function return _external_function def initialize_from_call(self, signature, interp, s_frame, argcount, w_method): self.interp = interp self.s_frame = s_frame self.argcount = argcount self.w_method = w_method self.space = interp.space self.trace_proxy.set(interp.trace_proxy.is_set()) # ensure that space.w_nil gets the first possible oop self.object_to_oop(self.space.w_nil) def failed(self, reason=1): assert reason != 0 self.fail_reason = reason def oop_to_object(self, oop): try: return self.oop_map[oop] except KeyError: raise ProxyFunctionFailed def object_to_oop(self, w_object): try: return self.object_map[w_object] except KeyError: new_index = self.next_oop() # print "Mapping new Object: %d -> %s" % (new_index, w_object) self.oop_map[new_index] = w_object self.object_map[w_object] = new_index return new_index def next_oop(self): next_oop = self._next_oop self._next_oop = next_oop + 1 return next_oop def pop_remappable(self): try: return self.remappable_objects.pop() except IndexError: self.failed() return self.space.w_nil def push_remappable(self, w_object): self.remappable_objects.append(w_object) return w_object def top_remappable(self): if len(self.remappable_objects) == 0: raise ProxyFunctionFailed return self.remappable_objects[-1] def load_and_initialize(self, module_name): from rpython.rlib.rdynload import dlopen, dlsym, dlclose, DLOpenError import os c_name = rffi.str2charp(os.path.join(IProxy.space.executable_path(), module_name)) try: module = dlopen(c_name) except DLOpenError, e: rffi.free_charp(c_name) raise error.PrimitiveFailedError try: try: _getModuleName = dlsym(module, "getModuleName") except KeyError: pass # the method does not need to exist else: getModuleName = rffi.cast(func_str_void, _getModuleName) if not rffi.charp2str(getModuleName()).startswith(module_name): raise error.PrimitiveFailedError try: _setInterpreter = dlsym(module, "setInterpreter") except KeyError: raise error.PrimitiveFailedError else: setInterpreter = rffi.cast(func_bool_vm, _setInterpreter) if not setInterpreter(getInterpreterProxy()): print "Failed setting interpreter on: %s" % module_name raise error.PrimitiveFailedError try: _initialiseModule = dlsym(module, "initialiseModule") except KeyError: pass # the method does not need to exist else: initialiseModule = rffi.cast(func_bool_void, _initialiseModule) if not initialiseModule(): print "Failed initialization of: %s" % module_name raise error.PrimitiveFailedError module_tuple = (module, {}) self.loaded_modules[module_name] = module_tuple return module_tuple except error.PrimitiveFailedError: dlclose(module) raise finally: rffi.free_charp(c_name)
def __del__(self): if self.libhandle: dlclose(self.libhandle)