view Python/dynload_shlib.c @ 17104:a488a63cb867 legacy-trunk

Fix PyFrame_FastToLocals() and counterpart to deal with cells and frees. Note there doesn't seem to be any way to test LocalsToFast(), because the instructions that trigger it are illegal in nested scopes with free variables. Fix allocation strategy for cells that are also formal parameters. Instead of emitting LOAD_FAST / STORE_DEREF pairs for each parameter, have the argument handling code in eval_code2() do the right thing. A side-effect of this change is that cell variables that are also arguments are listed at the front of co_cellvars in the order they appear in the argument list.
author Jeremy Hylton <jeremy@alum.mit.edu>
date Wed, 21 Mar 2001 16:43:47 +0000
parents 3b9b8f2ddfe7
children 11cb3de0823d 064de84385ca
line wrap: on
line source


/* Support for dynamic loading of extension modules */

#include "Python.h"
#include "importdl.h"

#include <sys/types.h>
#include <sys/stat.h>
#if defined(__NetBSD__) && (NetBSD < 199712)
#include <nlist.h>
#include <link.h>
#define dlerror() "error in dynamic linking"
#else
#ifdef HAVE_DLFCN_H
#include <dlfcn.h>
#endif
#endif

#ifdef __OpenBSD__
#define LEAD_UNDERSCORE "_"
#else
#define LEAD_UNDERSCORE ""
#endif

#ifndef RTLD_LAZY
#define RTLD_LAZY 1
#endif


const struct filedescr _PyImport_DynLoadFiletab[] = {
#ifdef __CYGWIN__
	{".dll", "rb", C_EXTENSION},
	{"module.dll", "rb", C_EXTENSION},
#else
	{".so", "rb", C_EXTENSION},
	{"module.so", "rb", C_EXTENSION},
#endif
	{0, 0}
};

static struct {
	dev_t dev;
	ino_t ino;
	void *handle;
} handles[128];
static int nhandles = 0;


dl_funcptr _PyImport_GetDynLoadFunc(const char *fqname, const char *shortname,
				    const char *pathname, FILE *fp)
{
	dl_funcptr p;
	void *handle;
	char funcname[258];
	char pathbuf[260];

	if (strchr(pathname, '/') == NULL) {
		/* Prefix bare filename with "./" */
		sprintf(pathbuf, "./%-.255s", pathname);
		pathname = pathbuf;
	}

	sprintf(funcname, LEAD_UNDERSCORE "init%.200s", shortname);

	if (fp != NULL) {
		int i;
		struct stat statb;
		fstat(fileno(fp), &statb);
		for (i = 0; i < nhandles; i++) {
			if (statb.st_dev == handles[i].dev &&
			    statb.st_ino == handles[i].ino) {
				p = (dl_funcptr) dlsym(handles[i].handle,
						       funcname);
				return p;
			}
		}
		if (nhandles < 128) {
			handles[nhandles].dev = statb.st_dev;
			handles[nhandles].ino = statb.st_ino;
		}
	}

#ifdef RTLD_NOW
	/* RTLD_NOW: resolve externals now
	   (i.e. core dump now if some are missing) */
	handle = dlopen(pathname, RTLD_NOW);
#else
	if (Py_VerboseFlag)
		printf("dlopen(\"%s\", %d);\n", pathname,
		       RTLD_LAZY);
	handle = dlopen(pathname, RTLD_LAZY);
#endif /* RTLD_NOW */
	if (handle == NULL) {
		PyErr_SetString(PyExc_ImportError, dlerror());
		return NULL;
	}
	if (fp != NULL && nhandles < 128)
		handles[nhandles++].handle = handle;
	p = (dl_funcptr) dlsym(handle, funcname);
	return p;
}