#include "psyco.h" #include "psyfunc.h" #include "codemanager.h" #include "stats.h" #include "profile.h" #include "dispatcher.h" #include "Python/pycompiler.h" #include "Python/frames.h" #include "alarm.h" #include "timing.h" #include "mergepoints.h" #define PSYCO_INITIALIZATION #include "initialize.h" /* generated by files.py */ static PyObject* thread_dict_key; DEFINEFN PyObject* psyco_thread_dict() { PyObject* dict = PyThreadState_GetDict(); PyObject* result; bool err; if (dict == NULL) return NULL; result = PyDict_GetItem(dict, thread_dict_key); if (result == NULL) { result = PyDict_New(); if (result == NULL) return NULL; err = PyDict_SetItem(dict, thread_dict_key, result); Py_DECREF(result); /* one reference left in 'dict' */ if (err) result = NULL; } return result; } DEFINEFN void psyco_out_of_memory(char *filename, int lineno) { char *msg; if (PyErr_Occurred()) { PyErr_Print(); msg = "psyco cannot recover from the error above"; } else msg = "psyco: out of memory"; fprintf(stderr, "%s:%d: ", filename, lineno); Py_FatalError(msg); } /***************************************************************/ /*** Implementation of the '_psyco' built-in module ***/ /***************************************************************/ DEFINEVAR PyObject* PyExc_PsycoError; DEFINEVAR long psyco_memory_usage = 0; DEFINEVAR PyObject* CPsycoModule; DEFINEVAR PyObject* psyco_logger = NULL; #if VERBOSE_LEVEL DEFINEFN void psyco_debug_printf(char* msg, ...) { va_list vargs; fprintf(stderr, "psyco: "); #ifdef HAVE_STDARG_PROTOTYPES va_start(vargs, msg); #else va_start(vargs); #endif vfprintf(stderr, msg, vargs); va_end(vargs); } #endif /* VERBOSE_LEVEL */ /* Trace */ #if defined(PSYCO_TRACE) static void* trace_buffer[4096]; static int trace_bufdata = 4096; static FILE* trace_f = NULL; DEFINEFN void psyco_trace_execution(char* msg, void* code_position) { if (trace_bufdata == 4096) { if (trace_f == NULL) trace_f = fopen(PSYCO_TRACE, "wb"); else fwrite(trace_buffer, sizeof(void*), 4096, trace_f); trace_bufdata = 0; } trace_buffer[trace_bufdata++] = code_position; } static void trace_flush(void) { if (trace_f != NULL) { fwrite(trace_buffer, sizeof(void*), trace_bufdata, trace_f); fclose(trace_f); trace_f = NULL; trace_bufdata = 4096; } } #elif VERBOSE_LEVEL >= 4 DEFINEFN void psyco_trace_execution(char* msg, void* code_position) { debug_printf(4, ("trace %p for %s\n", code_position, msg)); } DEFINEFN void psyco_trace_execution_noerr(char* msg, void* code_position) { debug_printf(4, ("trace %p for %s\n", code_position, msg)); psyco_assert(!PyErr_Occurred()); } #endif DEFINEFN void psyco_flog(char* msg, ...) { va_list vargs; PyObject* s; PyObject* r; PyObject *etype, *evalue, *etb; extra_assert(psyco_logger != NULL); PyErr_Fetch(&etype, &evalue, &etb); #ifdef HAVE_STDARG_PROTOTYPES va_start(vargs, msg); #else va_start(vargs); #endif s = PyString_FromFormatV(msg, vargs); va_end(vargs); if (s == NULL) OUT_OF_MEMORY(); r = PyObject_CallFunction(psyco_logger, "O", s); if (r == NULL) PyErr_WriteUnraisable(psyco_logger); else Py_DECREF(r); Py_DECREF(s); PyErr_Restore(etype, evalue, etb); } DEFINEFN int psyco_fatal_error(char* msg, char* filename, int lineno) { fprintf(stderr, "\n%s:%d: %s\n", filename, lineno, msg); Py_FatalError("Psyco assertion failed"); return 0; } #if CODE_DUMP static void vinfo_array_dump(vinfo_array_t* array, FILE* f, PyObject* d) { int i = array->count; fprintf(f, "%d\n", i); while (i--) { vinfo_t* vi = array->items[i]; PyObject* key = PyInt_FromLong((long)vi); psyco_assert(key); fprintf(f, "%ld\n", (long)vi); if (vi != NULL && !PyDict_GetItem(d, key)) { switch (gettime(vi->source)) { case CompileTime: fprintf(f, "ct %ld %ld\n", CompileTime_Get(vi->source)->refcount1_flags, CompileTime_Get(vi->source)->value); break; case RunTime: fprintf(f, "rt %ld\n", vi->source); break; case VirtualTime: fprintf(f, "vt 0x%lx\n", (long) VirtualTime_Get(vi->source)); break; default: psyco_fatal_msg("gettime() corrupted"); } PyDict_SetItem(d, key, Py_None); vinfo_array_dump(vi->array, f, d); } Py_DECREF(key); } } #ifndef MS_WIN32 static void vinfo_dump_a1(vinfo_array_t* array) { char cmdline[999]; FILE* f; sprintf(cmdline, "\"%s\" ../py-utils/vinfo_dump.py", Py_GetProgramFullPath()); f = popen(cmdline, "w"); if (f == NULL) fprintf(stderr, "shell cannot execute: %s\n", cmdline); else { PyObject* d = PyDict_New(); psyco_assert(d); vinfo_array_dump(array, f, d); Py_DECREF(d); pclose(f); } } DEFINEFN void vinfo_dump(vinfo_t* vi) { /* use this interactively, within the C debugger. Unix only */ vinfo_array_t array; array.count = 1; array.items[0] = vi; vinfo_dump_a1(&array); if (&vinfo_dump) ; /* force the compiler to consider it as used */ } DEFINEFN void po_dump(PsycoObject* po) { /* use this interactively, within the C debugger. Unix only */ vinfo_dump_a1(&po->vlocals); if (&po_dump) ; /* force the compiler to consider it as used */ } DEFINEFN void po_inlined_in(PsycoObject* po) { if (po->pr.is_inlining) { fprintf(stderr, "inlined from position %d in\n", (int) (CompileTime_Get(po->vlocals.items[0]-> array->items[1]->source)->value)); _PyObject_Dump((PyObject*) (CompileTime_Get(po->vlocals.items[0]-> array->items[0]->source)->value)); } else fprintf(stderr, "not inlined\n"); if (&po_inlined_in) ; /* force the compiler to consider it as used */ } #endif /* !MS_WIN32 */ #if !ALL_STATIC EXTERNFN int psyco_top_array_count(FrozenPsycoObject* fpo); /*in dispatcher.c*/ #else # define psyco_top_array_count fz_top_array_count #endif DEFINEFN void psyco_dump_code_buffers(void) { static int is_dumping = 0; FILE* f; #if CODE_DUMP >= 3 static int alt = 1; char filename[200]; sprintf(filename, "%s-%d", CODE_DUMP_FILE, alt); alt = 3-alt; #else char* filename = CODE_DUMP_FILE; #endif #if defined(PSYCO_TRACE) trace_flush(); #endif if (is_dumping) return; is_dumping = 1; f = fopen(filename, "wb"); if (f != NULL) { CodeBufferObject* obj; PyObject *exc, *val, *tb; long buftablepos; void** chain; int bufcount = 0; long* buftable; PyErr_Fetch(&exc, &val, &tb); debug_printf(1, ("writing %s\n", filename)); for (obj=psyco_codebuf_chained_list; obj != NULL; obj=obj->chained_list) bufcount++; buftable = PyMem_NEW(long, bufcount); fprintf(f, "Psyco dump [%s]\n", MACHINE_CODE_FORMAT); fwrite(&bufcount, sizeof(bufcount), 1, f); buftablepos = ftell(f); fwrite(buftable, sizeof(long), bufcount, f); /* give the address of an arbitrary symbol from the Python interpreter and from the Psyco module */ fprintf(f, "PyInt_FromLong: 0x%lx\n", (long) &PyInt_FromLong); fprintf(f, "psyco_dump_code_buffers: 0x%lx\n", (long) &psyco_dump_code_buffers); for (obj=psyco_codebuf_chained_list; obj != NULL; obj=obj->chained_list) { PyCodeObject* co = obj->snapshot.fz_pyc_data ? obj->snapshot.fz_pyc_data->co : NULL; fprintf(f, "CodeBufferObject 0x%lx %d '%s' '%s' %d '%s'\n", (long) obj->codestart, get_stack_depth(&obj->snapshot), co?PyString_AsString(co->co_filename):"", co?PyCodeObject_NAME(co):"", co?obj->snapshot.fz_pyc_data->next_instr:-1, obj->codemode); } psyco_dump_bigbuffers(f); for (chain = psyco_codebuf_spec_dict_list; chain; chain=(void**)*chain) { PyObject* spec_dict = (PyObject*)(chain[-1]); int i = 0; PyObject *key, *value; fprintf(f, "spec_dict 0x%lx\n", (long) chain); while (PyDict_Next(spec_dict, &i, &key, &value)) { PyObject* repr; if (PyInt_Check(key)) { repr = (key->ob_type->tp_as_number->nb_hex)(key); } else { repr = PyObject_Repr(key); } psyco_assert(!PyErr_Occurred()); psyco_assert(PyString_Check(repr)); psyco_assert(CodeBuffer_Check(value)); fprintf(f, "0x%lx %s\n", (long)((CodeBufferObject*)value)->codestart, PyString_AsString(repr)); Py_DECREF(repr); } fprintf(f, "\n"); } { int i = 0; fprintf(f, "vinfo_array\n"); for (obj=psyco_codebuf_chained_list; obj != NULL; obj=obj->chained_list) { PsycoObject* live_po; PyObject* d; if (psyco_top_array_count(&obj->snapshot) > 0) live_po = fpo_unfreeze(&obj->snapshot); else live_po = NULL; d = PyDict_New(); psyco_assert(d); buftable[i++] = ftell(f); vinfo_array_dump(live_po ? &live_po->vlocals : NullArray, f, d); Py_DECREF(d); if (live_po) PsycoObject_Delete(live_po); } psyco_assert(i==bufcount); fseek(f, buftablepos, 0); fwrite(buftable, sizeof(long), bufcount, f); } PyMem_FREE(buftable); psyco_assert(!PyErr_Occurred()); fclose(f); PyErr_Restore(exc, val, tb); } is_dumping = 0; } static PyObject* Psyco_dumpcodebuf(PyObject* self, PyObject* args) { psyco_dump_code_buffers(); Py_INCREF(Py_None); return Py_None; } #endif /* CODE_DUMP */ /***************************************************************/ /*** Replacements for PyEval_GetXxx() ***/ DEFINEFN PyObject* need_cpsyco_obj(char* name) { PyObject* d = PyModule_GetDict(CPsycoModule); PyObject* result = PyDict_GetItemString(d, name); if (result == NULL) PyErr_Format(PyExc_PsycoError, "missing _psyco.%s", name); return result; } static PyObject* psyco_get_locals_msg(char* msg, int flag) { static int already_logged = 0; PyObject* o; PyObject* result; o = psyco_find_frame(Py_False); if (o == NULL) return PyDict_New(); /* no frame at all -- no locals */ if (!PyFrame_Check(o)) { /* it is a Psyco frame -- no locals available */ char buffer[400]; int i; PyObject* w = need_cpsyco_obj("NoLocalsWarning"); if (w == NULL) { Py_DECREF(o); return NULL; } for (i=0; msg[i] != '\\' && msg[i] != 0; i++) buffer[i] = msg[i]; if (psyco_logger && (flag & already_logged) == 0) { already_logged |= flag; buffer[i] = '\n'; buffer[i+1] = 0; debug_printf(1, (buffer)); } if (msg[i] == '\\') { buffer[i++] = ' '; for (; msg[i] != 0; i++) buffer[i] = msg[i]; } buffer[i] = 0; if (PyErr_Warn(w, buffer)) result = NULL; else result = PyDict_New(); } else { PyFrame_FastToLocals((PyFrameObject*) o); result = ((PyFrameObject*) o)->f_locals; Py_INCREF(result); } Py_DECREF(o); return result; } static PyObject* psyco_get_locals(void) { return psyco_get_locals_msg("no locals() in functions bound by Psyco", 0x01); } #define WARN_IMPLICIT_LOCALS " cannot see the locals\\in functions bound by " \ "Psyco; consider using eval() in its two- or " \ "three-arguments form" /*****************************************************************/ static PyObject* Psyco_proxycode(PyObject* self, PyObject* args) { int recursion = DEFAULT_RECURSION; PyFunctionObject* function; if (!PyArg_ParseTuple(args, "O!|i", &PyFunction_Type, &function, &recursion)) return NULL; return psyco_proxycode(function, recursion); } static PyObject* Psyco_unproxycode(PyObject* self, PyObject* args) { PyCodeObject* code; PsycoFunctionObject* proxy; PyObject* func; if (!PyArg_ParseTuple(args, "O!", &PyCode_Type, &code)) return NULL; if (!is_proxycode(code)) { PyErr_SetString(PyExc_PsycoError, "code object is not a proxy"); return NULL; } proxy = (PsycoFunctionObject*) PyTuple_GET_ITEM(code->co_consts, 1); func = PyFunction_New((PyObject*) proxy->psy_code, proxy->psy_globals); if (func == NULL) return NULL; if (proxy->psy_defaults != NULL && PyFunction_SetDefaults(func, proxy->psy_defaults)) { Py_DECREF(func); return NULL; } return func; } static PyObject* Psyco_cannotcompile(PyObject* self, PyObject* args) { PyCodeObject* code; PyCodeStats* cs; if (!PyArg_ParseTuple(args, "O!", &PyCode_Type, &code)) return NULL; cs = PyCodeStats_Get(code); if (cs->st_mergepoints == NULL) { Py_INCREF(Py_None); cs->st_mergepoints = Py_None; } else if (cs->st_mergepoints != Py_None) { PyErr_SetString(PyExc_PsycoError, "code is already compiled"); return NULL; } Py_INCREF(Py_None); return Py_None; } static PyObject* Psyco_setfilter(PyObject* self, PyObject* args) { PyObject* func; PyObject* prev; if (!PyArg_ParseTuple(args, "O", &func)) return NULL; if (func == Py_None) func = NULL; else { if (!PyCallable_Check(func)) { PyErr_SetString(PyExc_TypeError, "setfilter() arg must be callable"); return NULL; } Py_INCREF(func); } prev = psyco_codeobj_filter_fn; psyco_codeobj_filter_fn = func; if (prev == NULL) { prev = Py_None; Py_INCREF(prev); } return prev; } /* replacement for sys._getframe() (together with _getframe() in support.py) */ static PyObject* Psyco_getframe(PyObject* self, PyObject* args) { PyObject* o = Py_False; int emulate = 0; if (!PyArg_ParseTuple(args, "|Oi:getframe", &o, &emulate)) return NULL; o = psyco_find_frame(o); if (emulate && o != NULL) { PyObject* f = (PyObject*) psyco_emulate_frame(o); Py_DECREF(o); return f; } else return o; } /* replacement for __builtin__.globals() */ static PyObject * Psyco_globals(PyObject* self, PyObject* args) { PyObject *d; if (!PyArg_ParseTuple(args, ":globals")) return NULL; d = psyco_get_globals(); Py_INCREF(d); return d; } /* replacement for __builtin__.locals() */ static PyObject * Psyco_locals(PyObject* self, PyObject* args) { if (!PyArg_ParseTuple(args, ":locals")) return NULL; return psyco_get_locals(); } static PyObject* builtinevaluator(PyObject* args, char* oname) { PyObject *o; PyObject *cmd; PyObject *freeme; PyObject *globals = Py_None, *locals = Py_None; o = need_cpsyco_obj(oname); if (o == NULL) return NULL; if (!PyArg_ParseTuple(args, "O|O!O!", &cmd, &PyDict_Type, &globals, &PyDict_Type, &locals)) { /* let the original function report the problem, if any */ PyErr_Clear(); } else if (globals == Py_None) { globals = psyco_get_globals(); if (locals == Py_None) { locals = psyco_get_locals_msg("eval()/execfile()" WARN_IMPLICIT_LOCALS, 0x02); if (locals == NULL) return NULL; freeme = locals; } else { freeme = NULL; } o = PyObject_CallFunction(o, "OOO", cmd, globals, locals); Py_XDECREF(freeme); return o; } /* fallback */ return PyObject_CallObject(o, args); } /* replacement for __builtin__.eval() */ static PyObject * Psyco_eval(PyObject* self, PyObject* args) { return builtinevaluator(args, "original_eval"); } /* replacement for __builtin__.execfile() */ static PyObject * Psyco_execfile(PyObject *self, PyObject *args) { return builtinevaluator(args, "original_execfile"); } /* replacement for __builtin__.vars() */ static PyObject * Psyco_vars(PyObject *self, PyObject *args) { PyObject* o; if (PyTuple_Size(args) == 0) { return psyco_get_locals(); } /* fallback */ o = need_cpsyco_obj("original_vars"); if (o == NULL) return NULL; return PyObject_CallObject(o, args); } /* replacement for __builtin__.dir() */ static PyObject * Psyco_dir(PyObject *self, PyObject *args) { PyObject* o; if (PyTuple_Size(args) == 0) { PyObject* locals = psyco_get_locals(); if (locals == NULL) return NULL; o = PyMapping_Keys(locals); Py_DECREF(locals); if (o == NULL) return NULL; if (!PyList_Check(o)) { Py_DECREF(o); PyErr_SetString(PyExc_TypeError, "Expected keys() to be a list."); return NULL; } if (PyList_Sort(o) != 0) { Py_DECREF(o); return NULL; } return o; } /* fallback */ o = need_cpsyco_obj("original_dir"); if (o == NULL) return NULL; return PyObject_CallObject(o, args); } /* replacement for __builtin__.input() */ static PyObject * Psyco_input(PyObject *self, PyObject *args) { PyObject* cmd; PyObject* o = need_cpsyco_obj("original_raw_input"); if (o == NULL) return NULL; cmd = PyObject_CallObject(o, args); if (cmd != NULL) { PyObject* globals = psyco_get_globals(); PyObject* locals = psyco_get_locals_msg("input()" WARN_IMPLICIT_LOCALS, 0x04); if (locals == NULL) { o = NULL; } else { o = need_cpsyco_obj("original_eval"); if (o != NULL) o = PyObject_CallFunction(o, "OOO", cmd, globals, locals); Py_DECREF(locals); } Py_DECREF(cmd); return o; } /* error in original_raw_input() */ return NULL; } static PyObject* hooks_busy(void) { PyErr_SetString(PyExc_PsycoError, "Python trace/profile hooks are busy"); return NULL; } /* Enable or disable profiling. */ static PyObject* Psyco_profiling(PyObject* self, PyObject* args) { char mode; void (*rs)(void*, int); if (!PyArg_ParseTuple(args, "c", &mode)) return NULL; switch (mode) { case 'p': rs = &psyco_rs_profile; break; #if HAVE_DYN_COMPILE case 'f': rs = &psyco_rs_fullcompile; break; case 'n': rs = &psyco_rs_nocompile; break; #endif case '.': rs = NULL; break; default: PyErr_SetString(PyExc_ValueError, "unknown or unsupported mode"); return NULL; } if (!psyco_set_profiler(rs)) return hooks_busy(); Py_INCREF(Py_None); return Py_None; } #if HAVE_DYN_COMPILE /* turbo-mark a frame or all frames running a given code */ static PyObject* Psyco_turbo_frame(PyObject* self, PyObject* args) { PyObject* o = NULL; if (!PyArg_ParseTuple(args, "O", &o)) return NULL; if (PyCode_Check(o)) psyco_turbo_frames((PyCodeObject*) o); else if (PyFrame_Check(o)) { if (!psyco_turbo_frame((PyFrameObject*) o)) return hooks_busy(); } else { PyErr_SetString(PyExc_TypeError, "frame or code object"); return NULL; } Py_INCREF(Py_None); return Py_None; } /* turbo-mark a code object (does not affect frames currently running it) */ static PyObject* Psyco_turbo_code(PyObject* self, PyObject* args) { int rec = DEFAULT_RECURSION; PyCodeObject* co; if (!PyArg_ParseTuple(args, "O!|i", &PyCode_Type, &co, &rec)) return NULL; psyco_turbo_code(co, rec); Py_INCREF(Py_None); return Py_None; } #endif /* HAVE_DYN_COMPILE */ /* update collected statistics */ static PyObject* Psyco_statcollect(PyObject* self, PyObject* args) { psyco_profile_threads(1); psyco_stats_collect(); Py_INCREF(Py_None); return Py_None; } /* return the top n code objects */ static PyObject* Psyco_stattop(PyObject* self, PyObject* args) { int n; if (!PyArg_ParseTuple(args, "i", &n)) return NULL; return psyco_stats_top(n); } /* clear all collected statistics now */ static PyObject* Psyco_statreset(PyObject* self, PyObject* args) { if (!PyArg_ParseTuple(args, "")) return NULL; psyco_stats_reset(); Py_INCREF(Py_None); return Py_None; } /* get tunable parameters */ static PyObject* Psyco_statread(PyObject* self, PyObject* args) { char* name; if (!PyArg_ParseTuple(args, "s", &name)) return NULL; return psyco_stats_read(name); } /* set tunable parameters */ static PyObject* Psyco_statwrite(PyObject* self, PyObject* args, PyObject* kwds) { if (!psyco_stats_write(args, kwds)) return NULL; Py_INCREF(Py_None); return Py_None; } /* return a dump of all current statistics (it also prints a nice table to stderr in verbose mode) */ static PyObject* Psyco_statdump(PyObject* self, PyObject* args) { if (!PyArg_ParseTuple(args, "")) return NULL; psyco_stats_collect(); return psyco_stats_dump(); } /* get the current usage charge of a code object */ static PyObject* Psyco_getcharge(PyObject* self, PyObject* args) { PyCodeStats* cs; PyCodeObject* co; if (!PyArg_ParseTuple(args, "O!", &PyCode_Type, &co)) return NULL; cs = PyCodeStats_Get(co); return PyFloat_FromDouble((double) cs->st_charge); } /* set the usage charge of a code object */ static PyObject* Psyco_setcharge(PyObject* self, PyObject* args) { PyCodeStats* cs; PyCodeObject* co; float new_charge; if (!PyArg_ParseTuple(args, "O!f", &PyCode_Type, &co, &new_charge)) return NULL; cs = PyCodeStats_Get(co); cs->st_charge = new_charge; Py_INCREF(Py_None); return Py_None; } static PyObject* Psyco_memory(PyObject* self, PyObject* args) { if (!PyArg_ParseTuple(args, "")) return NULL; return PyInt_FromLong(psyco_memory_usage / 1024); } #if 0 --- disabled --- static PyObject* t_finalizer(PyObject* self, PyObject* args, PyObject* kwds) { PyObject* f; PyObject* g; PyObject* fres; PyObject* gres; PyObject *exc, *val, *tb; if (!PyArg_ParseTuple(self, "OO:finalizer", &f, &g)) return NULL; fres = PyEval_CallObjectWithKeywords(f, args, kwds); PyErr_Fetch(&exc, &val, &tb); gres = PyEval_CallObject(g, NULL); if (gres == NULL) { Py_XDECREF(exc); Py_XDECREF(val); Py_XDECREF(tb); Py_XDECREF(fres); return NULL; } else { Py_DECREF(gres); PyErr_Restore(exc, val, tb); return fres; } } static PyMethodDef m_finalizer = { "finalizer_fn", (PyCFunction)t_finalizer, METH_VARARGS|METH_KEYWORDS }; /* finalizer(f,g) returns a built-in function object h such that h(*args, **kw) is equivalent to try: f(*args, **kw) finally: g() The purpose is for g() to be a lock.release() so that when the lock is released we are sure that the thread will not run any Python code any more (which cannot be done in Python). */ static PyObject* Psyco_finalizer(PyObject* self, PyObject* args) { return PyCFunction_New(&m_finalizer, args); } #endif /*****************************************************************/ static char proxycode_doc[] = "proxycode(func[, rec]) -> code object\n\ \n\ Return a proxy code object that invokes Psyco on the argument. The code\n\ object can be used to replace func.func_code. Raise psyco.error if func\n\ uses unsupported features. Return func.func_code itself if it is already\n\ a proxy code object. The optional second argument specifies the number of\n\ recursive compilation levels: all functions called by func are compiled\n\ up to the given depth of indirection."; static char unproxycode_doc[] = "unproxycode(code) -> function object\n\ \n\ Return a new copy of the original function that was used to build the\n\ given proxy code object. Raise psyco.error if code is not a proxy."; static char getframe_doc[] = "getframe([location, emulate]) -> frameobject or (code, globals, addr)\n\ \n\ Return a frame object from the call stack.\n\ If location is an integer, return the nth frame (0=top).\n\ If location was returned by a previous call to getframe(),\n\ return the previous frame (as if by reading f_back)."; static char globals_doc[] = "globals() -> dictionary\n\ \n\ Return the dictionary containing the current scope's global variables.\n\ This is the Psyco-aware version."; static char gennolocals_doc[] = "This is the Psyco-aware version of the builtin function of the same name.\n\ For more information see psyco._psyco.original_<<>>.__doc__.\n\ \n\ Functions have no locals() dictionary with Psyco.\n\ Accessing it returns {} and throws a NoLocalsWarning."; static char setfilter_doc[] = "setfilter(func or None) -> previous filter or None\n\ \n\ Set a global filter function: func(co) will be called once per code object\n\ 'co' considered by Psyco. If it returns False, the code object will not\n\ be compiled."; static PyMethodDef PsycoMethods[] = { {"proxycode", &Psyco_proxycode, METH_VARARGS, proxycode_doc}, {"unproxycode", &Psyco_unproxycode, METH_VARARGS, unproxycode_doc}, {"getframe", &Psyco_getframe, METH_VARARGS, getframe_doc}, {"globals", &Psyco_globals, METH_VARARGS, globals_doc}, {"eval", &Psyco_eval, METH_VARARGS, gennolocals_doc}, {"execfile", &Psyco_execfile, METH_VARARGS, gennolocals_doc}, {"locals", &Psyco_locals, METH_VARARGS, gennolocals_doc}, {"vars", &Psyco_vars, METH_VARARGS, gennolocals_doc}, {"dir", &Psyco_dir, METH_VARARGS, gennolocals_doc}, {"input", &Psyco_input, METH_VARARGS, gennolocals_doc}, {"profiling", &Psyco_profiling, METH_VARARGS}, #if HAVE_DYN_COMPILE {"turbo_frame", &Psyco_turbo_frame, METH_VARARGS}, {"turbo_code", &Psyco_turbo_code, METH_VARARGS}, #endif {"statcollect", &Psyco_statcollect, METH_VARARGS}, {"stattop", &Psyco_stattop, METH_VARARGS}, {"statreset", &Psyco_statreset, METH_VARARGS}, /*{"statread", &Psyco_statread, METH_VARARGS},*/ {"statwrite", (PyCFunction)&Psyco_statwrite, METH_VARARGS|METH_KEYWORDS}, {"statread", &Psyco_statread, METH_VARARGS}, {"statdump", &Psyco_statdump, METH_VARARGS}, {"getcharge", &Psyco_getcharge, METH_VARARGS}, {"setcharge", &Psyco_setcharge, METH_VARARGS}, {"memory", &Psyco_memory, METH_VARARGS}, {"cannotcompile",&Psyco_cannotcompile, METH_VARARGS}, {"setfilter", &Psyco_setfilter, METH_VARARGS, setfilter_doc}, #if 0 {"finalizer", &Psyco_finalizer, METH_VARARGS}, #endif #if CODE_DUMP {"dumpcodebuf", &Psyco_dumpcodebuf, METH_VARARGS}, #endif ALARM_FUNCTIONS, {NULL, NULL} /* Sentinel */ }; /* Initialization */ PyMODINIT_FUNC init_psyco(void) { PsycoFunction_Type.ob_type = &PyType_Type; CodeBuffer_Type.ob_type = &PyType_Type; thread_dict_key = PyString_InternFromString("PsycoT"); if (thread_dict_key == NULL) return; CPsycoModule = Py_InitModule("_psyco", PsycoMethods); if (CPsycoModule == NULL) return; PyExc_PsycoError = PyErr_NewException("psyco.error", NULL, NULL); if (PyExc_PsycoError == NULL) return; Py_INCREF(PyExc_PsycoError); if (PyModule_AddObject(CPsycoModule, "error", PyExc_PsycoError)) return; Py_INCREF(&PsycoFunction_Type); if (PyModule_AddObject(CPsycoModule, "PsycoFunctionType", (PyObject*) &PsycoFunction_Type)) return; /*if (PyModule_AddIntConstant(CPsycoModule, "DEFAULT_RECURSION", DEFAULT_RECURSION)) return;*/ #if ALL_CHECKS if (PyModule_AddIntConstant(CPsycoModule, "ALL_CHECKS", ALL_CHECKS)) return; #endif #if VERBOSE_LEVEL if (PyModule_AddIntConstant(CPsycoModule, "VERBOSE_LEVEL", VERBOSE_LEVEL)) return; #endif #ifdef PY_PSYCO_MODULE PyPsycoModule = PyImport_ImportModule("psyco"); if (PyPsycoModule == NULL) return; #endif if (PyModule_AddIntConstant(CPsycoModule, "PYVER", PY_VERSION_HEX)) return; if (PyModule_AddIntConstant(CPsycoModule, "PSYVER", PSYCO_VERSION_HEX)) return; if (PyModule_AddIntConstant(CPsycoModule, "MEASURE_ALL_THREADS", MEASURE_ALL_THREADS)) return; if (PyModule_AddStringConstant(CPsycoModule, "PROCESSOR", MACHINE_CODE_FORMAT)) return; initialize_all_files(); }