From: Armin R. <ar...@us...> - 2002-03-18 19:04:29
|
Update of /cvsroot/psyco/psyco/c/Python In directory usw-pr-cvs1:/tmp/cvs-serv25360/c/Python Modified Files: pbltinmodule.c pycheader.h pycompiler.c pycompiler.h Log Message: tracebacks -- import statements -- bug fixes Index: pbltinmodule.c =================================================================== RCS file: /cvsroot/psyco/psyco/c/Python/pbltinmodule.c,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 *** pbltinmodule.c 26 Feb 2002 23:08:00 -0000 1.7 --- pbltinmodule.c 18 Mar 2002 19:04:23 -0000 1.8 *************** *** 65,73 **** vinfo_t* vlen; ! vstart = get_array_item(po, rangelst, RANGE_START); if (vstart == NULL) return false; ! vlen = get_array_item(po, rangelst, RANGE_LEN); if (vlen == NULL) return false; --- 65,73 ---- vinfo_t* vlen; ! vstart = vinfo_getitem(rangelst, RANGE_START); if (vstart == NULL) return false; ! vlen = vinfo_getitem(rangelst, RANGE_LEN); if (vlen == NULL) return false; Index: pycheader.h =================================================================== RCS file: /cvsroot/psyco/psyco/c/Python/pycheader.h,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** pycheader.h 28 Feb 2002 11:55:52 -0000 1.6 --- pycheader.h 18 Mar 2002 19:04:23 -0000 1.7 *************** *** 60,64 **** --- 60,67 ---- vinfo_t* exc; /* current compile-time (pseudo) exception, see below */ vinfo_t* val; /* exception value */ + vinfo_t* tb; /* traceback object */ PyObject* f_builtins; + PyObject* changing_globals; /* dict of names of globals that are detected to + change */ } pyc_data_t; Index: pycompiler.c =================================================================== RCS file: /cvsroot/psyco/psyco/c/Python/pycompiler.c,v retrieving revision 1.21 retrieving revision 1.22 diff -C2 -d -r1.21 -r1.22 *** pycompiler.c 28 Feb 2002 11:55:52 -0000 1.21 --- pycompiler.c 18 Mar 2002 19:04:23 -0000 1.22 *************** *** 300,313 **** } - DEFINEFN - void pyc_data_release(pyc_data_t* pyc) - { - vinfo_xdecref(pyc->val, NULL); - vinfo_xdecref(pyc->exc, NULL); - /* vinfo_xdecref(pyc->f_exc_type, NULL); */ - /* vinfo_xdecref(pyc->f_exc_value, NULL); */ - /* vinfo_xdecref(pyc->f_exc_traceback, NULL); */ - } - static void block_setup(PsycoObject* po, int type, int handler, int level) { --- 300,303 ---- *************** *** 575,579 **** { extra_assert(PycException_Occurred(po)); ! if (po->pr.val != NULL) { vinfo_decref(po->pr.val, po); po->pr.val = NULL; --- 565,573 ---- { extra_assert(PycException_Occurred(po)); ! if (po->pr.tb != NULL) { ! vinfo_decref(po->pr.tb, po); ! po->pr.tb = NULL; ! } ! if (po->pr.val != NULL) { vinfo_decref(po->pr.val, po); po->pr.val = NULL; *************** *** 600,620 **** at run-time). */ PyObject *exc, *val, *tb; PyErr_Fetch(&exc, &val, &tb); extra_assert(exc != NULL); ! PycException_Raise(po, ! vinfo_new(CompileTime_NewSk(sk_new((long) exc, ! SkFlagPyObj))), ! vinfo_new(CompileTime_NewSk(sk_new((long) val, ! SkFlagPyObj)))); ! Py_XDECREF(tb); /* XXX implement tracebacks */ } static void cimpl_pyerr_fetch(PyObject* target[]) { - PyObject* tb; extra_assert(PyErr_Occurred()); ! PyErr_Fetch(target+0, target+1, &tb); ! Py_XDECREF(tb); /* XXX implement tracebacks */ if (target[0] == NULL) { target[0] = Py_None; --- 594,612 ---- at run-time). */ PyObject *exc, *val, *tb; + vinfo_t *vexc, *vval, *vtb; PyErr_Fetch(&exc, &val, &tb); extra_assert(exc != NULL); ! vexc = vinfo_new(CompileTime_NewSk(sk_new((long) exc, SkFlagPyObj))); ! vval = vinfo_new(CompileTime_NewSk(sk_new((long) val, SkFlagPyObj))); ! vtb = tb == NULL ? NULL : ! vinfo_new(CompileTime_NewSk(sk_new((long) tb, SkFlagPyObj))); ! PycException_Restore(po, vexc, vval, vtb); } static void cimpl_pyerr_fetch(PyObject* target[]) { extra_assert(PyErr_Occurred()); ! PyErr_Fetch(target+0, target+1, target+2); if (target[0] == NULL) { target[0] = Py_None; *************** *** 625,628 **** --- 617,624 ---- Py_INCREF(Py_None); } + if (target[2] == NULL) { + target[2] = Py_None; + Py_INCREF(Py_None); + } } *************** *** 654,658 **** } ! inline void cimpl_set_exc_info(PyObject* target[], PyObject* tb, PyObject** f_exc_type, PyObject** f_exc_value, --- 650,654 ---- } ! inline void cimpl_set_exc_info(PyObject* target[], PyObject** f_exc_type, PyObject** f_exc_value, *************** *** 661,670 **** /* Equivalent of PyErr_NormalizeException() + set_exc_info() */ PyThreadState *tstate = PyThreadState_GET(); ! PyObject *type, *value; PyObject *tmp_type, *tmp_value, *tmp_tb; ! PyErr_NormalizeException(target+0, target+1, &tb); type = target[0]; value = target[1]; if (*f_exc_type == NULL) { --- 657,667 ---- /* Equivalent of PyErr_NormalizeException() + set_exc_info() */ PyThreadState *tstate = PyThreadState_GET(); ! PyObject *type, *value, *tb; PyObject *tmp_type, *tmp_value, *tmp_tb; ! PyErr_NormalizeException(target+0, target+1, target+2); type = target[0]; value = target[1]; + tb = target[2]; if (*f_exc_type == NULL) { *************** *** 699,704 **** PySys_SetObject("exc_value", value); PySys_SetObject("exc_traceback", tb); - - Py_XDECREF(tb); /* XXX implement tracebacks */ } --- 696,699 ---- *************** *** 708,719 **** PyObject** f_exc_traceback) { - PyObject* tb; extra_assert(PyErr_Occurred()); ! PyErr_Fetch(target+0, target+1, &tb); ! cimpl_set_exc_info(target, tb, f_exc_type, f_exc_value, f_exc_traceback); } ! static void cimpl_pyerr_normalize(PyObject* exc, PyObject* val, PyObject* target[], PyObject** f_exc_type, --- 703,713 ---- PyObject** f_exc_traceback) { extra_assert(PyErr_Occurred()); ! PyErr_Fetch(target+0, target+1, target+2); ! cimpl_set_exc_info(target, f_exc_type, f_exc_value, f_exc_traceback); } ! static void cimpl_pyerr_normalize(PyObject* exc, PyObject* val, PyObject* tb, PyObject* target[], PyObject** f_exc_type, *************** *** 722,727 **** { target[0] = exc; Py_INCREF(exc); ! target[1] = val; Py_INCREF(val); ! cimpl_set_exc_info(target, NULL, f_exc_type, f_exc_value, f_exc_traceback); } --- 716,722 ---- { target[0] = exc; Py_INCREF(exc); ! target[1] = val; Py_XINCREF(val); ! target[2] = tb; Py_XINCREF(tb); ! cimpl_set_exc_info(target, f_exc_type, f_exc_value, f_exc_traceback); } *************** *** 737,745 **** /* "rrr", exc, val, tb); */ /* vinfo_decref(tb, po); */ ! vinfo_array_t* array = array_new(2); psyco_generic_call(po, cimpl_pyerr_fetch, CfNoReturnValue, "A", array); clear_pseudo_exception(po); ! PycException_Raise(po, array->items[0], array->items[1]); array_release(array); } --- 732,742 ---- /* "rrr", exc, val, tb); */ /* vinfo_decref(tb, po); */ ! vinfo_array_t* array = array_new(3); psyco_generic_call(po, cimpl_pyerr_fetch, CfNoReturnValue, "A", array); clear_pseudo_exception(po); ! po->pr.exc = array->items[0]; ! po->pr.val = array->items[1]; /* po->pr.val!=NULL after this */ ! po->pr.tb = array->items[2]; /* po->pr.tb!=NULL after this */ array_release(array); } *************** *** 749,753 **** { vinfo_t* result; ! vinfo_array_t* array = array_new(2); vinfo_array_t* f_exc = LOC_CONTINUATION->array; --- 746,750 ---- { vinfo_t* result; ! vinfo_array_t* array = array_new(3); vinfo_array_t* f_exc = LOC_CONTINUATION->array; *************** *** 756,760 **** array[0] -- exc_type new exception, normalized array[1] -- exc_value new exception, normalized ! no traceback yet */ extra_assert(f_exc->count >= 3); --- 753,757 ---- array[0] -- exc_type new exception, normalized array[1] -- exc_value new exception, normalized ! array[2] -- exc_traceback new exception, normalized */ extra_assert(f_exc->count >= 3); *************** *** 768,775 **** } else { /* normalize the already-given exception */ result = psyco_generic_call(po, cimpl_pyerr_normalize, ! CfNoReturnValue, "vvArrr", ! po->pr.exc, po->pr.val, array, f_exc->items[0], f_exc->items[1], --- 765,782 ---- } else { + char args[8]; + args[0] = 'v'; + args[1] = po->pr.val == NULL ? 'l' : 'v'; + args[2] = po->pr.tb == NULL ? 'l' : 'v'; + args[3] = 'A'; + args[4] = 'r'; + args[5] = 'r'; + args[6] = 'r'; + args[7] = 0; /* normalize the already-given exception */ result = psyco_generic_call(po, cimpl_pyerr_normalize, ! CfNoReturnValue, args, ! po->pr.exc, po->pr.val, po->pr.tb, ! array, f_exc->items[0], f_exc->items[1], *************** *** 781,789 **** } clear_pseudo_exception(po); ! PycException_Raise(po, array->items[0], array->items[1]); array_release(array); return true; } --- 788,879 ---- } clear_pseudo_exception(po); ! po->pr.exc = array->items[0]; ! po->pr.val = array->items[1]; /* po->pr.val!=NULL after this */ ! po->pr.tb = array->items[2]; /* po->pr.tb!=NULL after this */ array_release(array); return true; } + static PyFrameObject* cimpl_new_frame(PyThreadState* tstate, PyCodeObject* code, + PyObject* globals, int lasti, int lineno) + { + /* Make a minimalistic frame object, working around the specific + expectations of PyFrame_New(), which is the only reasonable way + to create frame objects (because of free lists etc) */ + PyFrameObject* result; + PyFrameObject* back = tstate->frame; + tstate->frame = NULL; /* frame objects are not created in stack order + with Psyco, so it's probably better not to + create plain wrong chained lists */ + result = PyFrame_New(tstate, code, globals, NULL); + tstate->frame = back; + if (result != NULL) { + result->f_lasti = lasti; + result->f_lineno = lineno; + } + return result; + } + + static void cimpl_rt_traceback(PyCodeObject* code, PyObject* globals, + int lasti, int lineno) + { + PyThreadState* tstate = PyThreadState_GET(); + PyFrameObject* f = cimpl_new_frame(tstate, code, globals, lasti, lineno); + /* an out-of-memory error just replaces the current exception */ + if (f != NULL) { + PyTraceBack_Here(f); + Py_DECREF(f); + } + } + + static PyObject* cimpl_vt_traceback(PyCodeObject* code, PyObject* globals, + int lasti, int lineno) + { + /* This is a hack around the limited interface to tracebacks. + PyTraceBack_Here() seems to be the only clean way to create new + traceback objects. */ + PyObject* oldtb; + PyObject* newtb; + PyThreadState* tstate = PyThreadState_GET(); + PyFrameObject* f = cimpl_new_frame(tstate, code, globals, lasti, lineno); + if (f == NULL) { + /* out-of-memory error */ + Py_INCREF(Py_None); + return Py_None; + } + oldtb = tstate->curexc_traceback; /* might be NULL */ + Py_XINCREF(oldtb); + if (PyTraceBack_Here(f)) { + /* out-of-memory error */ + Py_XDECREF(oldtb); + Py_DECREF(f); + Py_INCREF(Py_None); + return Py_None; + } + /* the new traceback is now in curexc_traceback */ + newtb = tstate->curexc_traceback; /* extracts the reference */ + tstate->curexc_traceback = oldtb; /* consumes the reference */ + Py_DECREF(f); + return newtb; + } + + inline void PsycoTraceBack_Here(PsycoObject* po, int lasti) + { + if (PycException_Is(po, &ERtPython)) { + /* Python exception is actually set at run-time */ + psyco_generic_call(po, cimpl_rt_traceback, + CfNoReturnValue, "lvl", + (long) po->pr.co, LOC_GLOBALS, lasti); + } + else { + /* We only have a virtual-time exception (not set in Python), + so we build po->pr.tb without actually setting it either */ + extra_assert(po->pr.tb == NULL); + po->pr.tb = psyco_generic_call(po, cimpl_vt_traceback, + CfReturnRef, "lvl", + (long) po->pr.co, LOC_GLOBALS, + lasti); + } + } *************** *** 871,874 **** --- 961,975 ---- + static void mark_varying(PsycoObject* po, PyObject* key) + { + if (po->pr.changing_globals == NULL) { + po->pr.changing_globals = PyDict_New(); + if (po->pr.changing_globals == NULL) + OUT_OF_MEMORY(); + } + if (PyDict_SetItem(po->pr.changing_globals, key, Py_True)) + OUT_OF_MEMORY(); + } + /* 'compilation pause' stuff, similar to psyco_coding_pause() */ typedef struct { *************** *** 885,894 **** PyObject* key = cg->varname; code_t* code = cg->originalmacrocode; - vinfo_t* v; - vinfo_t** stack_a = po->vlocals.items + po->pr.stack_base; - mergepoint_t* mp; KNOWN_VAR(PyDictObject*, globals, LOC_GLOBALS); PyDictEntry* ep; - void* dict_subscript; code_t* target; --- 986,991 ---- *************** *** 907,941 **** } ! /* un-promote the global variable to run-time and write code that ! calls dict_subscript(). Warning: we assume this will not overflow ! the (relatively large) code previously written by the macro ! DICT_ITEM_IFCHANGED at the same place. ! ! We call dict_subscript() instead of PyDict_GetItem() for the extra ! reference; indeed, we cannot be sure how long we will need the ! object so we must own a reference. dict_subscript() could be ! inlined too (but be careful about the overflow problem above!) ! ! XXX what occurs if the global has been deleted ? ! */ ! SAVE_REGS_FN_CALLS; ! CALL_SET_ARG_IMMED((long) key, 1, 2); ! CALL_SET_ARG_IMMED((long) globals, 0, 2); - v = new_rtvinfo(po, REG_FUNCTIONS_RETURN, true); - PUSH(v); /* 'v' is now run-time, recompile */ ! mp = psyco_exact_merge_point(po->pr.merge_points, po->pr.next_instr); ! target = psyco_compile_code(po, mp)->codeptr; /* XXX don't know what to do with the reference returned by XXX psyco_compile_code() */ ! dict_subscript = PyDict_Type.tp_as_mapping->mp_subscript; ! CALL_C_FUNCTION_AND_JUMP(dict_subscript, 2, target); ! /* cannot Py_DECREF(cg->self) because the current function is returning into that code now, but any time later is fine: use the trash of codemanager.h */ psyco_trash_object((PyObject*) cg->self); ! return cg->originalmacrocode; } --- 1004,1023 ---- } ! /* Mark the global variable as varying and compile again */ ! mark_varying(po, key); /* 'v' is now run-time, recompile */ ! target = psyco_compile_code(po, NULL)->codeptr; /* XXX don't know what to do with the reference returned by XXX psyco_compile_code() */ ! extra_assert(target != code); ! JUMP_TO(target); /* code a jump from the original code */ ! ! Py_DECREF(cg->previousvalue); /* cannot Py_DECREF(cg->self) because the current function is returning into that code now, but any time later is fine: use the trash of codemanager.h */ psyco_trash_object((PyObject*) cg->self); ! return target; } *************** *** 1034,1048 **** po = PsycoObject_Duplicate(po); - /* The global object has not been PUSHed on the Python stack - yet. However, if we enter do_changed_global() later and - figure out the value changed, do_changed_global() will - emit code that loads the run-time value of the global - and emulate the LOAD_GLOBAL opcode by PUSHing a run-time - vinfo_t. This means the recompilation triggered by - do_changed_global() must restart *after* the LOAD_GLOBAL - instruction and not *at* it, so we store the next - instruction position in the new 'po': */ - SAVE_NEXT_INSTR(next_instr); - code = onchangebuf->codeptr; TEMP_SAVE_REGS_FN_CALLS; --- 1116,1119 ---- *************** *** 1069,1075 **** po->code = code; dump_code_buffers(); - - Py_INCREF(result); - return result; } else if (strcmp(PyString_AS_STRING(key), "__in_psyco__") == 0) { --- 1140,1143 ---- *************** *** 1079,1083 **** by Psyco. */ result = Py_True; - Py_INCREF(result); } else { --- 1147,1150 ---- *************** *** 1088,1099 **** result = PyDict_GetItem(po->pr.f_builtins, key); ! /* found at all? */ ! if (result != NULL) ! Py_INCREF(result); ! else ! PycException_SetFormat(po, PyExc_NameError, ! GLOBAL_NAME_ERROR_MSG, ! PyString_AS_STRING(key)); } return result; } --- 1155,1166 ---- result = PyDict_GetItem(po->pr.f_builtins, key); ! if (result == NULL) { ! /* name not found. Maybe it will exist at run-time ! in the globals. Fall back to the safe ! cimpl_load_global(). */ ! return NULL; ! } } + Py_INCREF(result); return result; } *************** *** 1607,1611 **** /* copied from ceval.c where it is private */ static PyObject* ! build_class(PyObject *methods, PyObject *bases, PyObject *name) { PyObject *metaclass = NULL, *result, *base; --- 1674,1679 ---- /* copied from ceval.c where it is private */ static PyObject* ! cimpl_build_class(PyObject* g, /* globals */ ! PyObject *methods, PyObject *bases, PyObject *name) { PyObject *metaclass = NULL, *result, *base; *************** *** 1625,1630 **** } else { ! PyObject *g = PyEval_GetGlobals(); ! if (g != NULL && PyDict_Check(g)) metaclass = PyDict_GetItemString(g, "__metaclass__"); if (metaclass == NULL) --- 1693,1697 ---- } else { ! /*if (g != NULL && PyDict_Check(g))*/ metaclass = PyDict_GetItemString(g, "__metaclass__"); if (metaclass == NULL) *************** *** 1637,1640 **** --- 1704,1730 ---- } + static PyObject* cimpl_import_name(PyObject* globals, PyObject* name, + PyObject* fromlist) + { + PyObject* w; + PyObject* x = PyDict_GetItemString(psy_get_builtins(globals), + "__import__"); + if (x == NULL) { + PyErr_SetString(PyExc_ImportError, + "__import__ not found"); + return NULL; + } + w = Py_BuildValue("(OOOO)", + name, + globals, + Py_None, + fromlist); + if (w == NULL) + return NULL; + x = PyEval_CallObject(x, w); + Py_DECREF(w); + return x; + } + /***************************************************************/ *************** *** 1659,1668 **** /* load the return value */ vinfo_t* retval = po->pr.val; retsource = vinfo_compute(retval, po); if (retsource == SOURCE_ERROR) return NULL; ! if (!eat_reference(retval)) { ! /* return a new reference */ ! psyco_incref_v(po, retval); ! } if (retval->array->count > 0) { array_delete(retval->array, po); --- 1749,1757 ---- /* load the return value */ vinfo_t* retval = po->pr.val; + extra_assert(retval != NULL); retsource = vinfo_compute(retval, po); if (retsource == SOURCE_ERROR) return NULL; ! /* return a new reference */ ! consume_reference(po, retval); if (retval->array->count > 0) { array_delete(retval->array, po); *************** *** 1679,1688 **** /* In the other cases (virtual exception), compute and raise the exception now. */ ! if (psyco_generic_call(po, PyErr_SetObject, ! CfNoReturnValue, "vv", ! po->pr.exc, po->pr.val) == NULL) return NULL; - clear_pseudo_exception(po); } retsource = CompileTime_NewSk(&psyco_skZero); /*to return NULL */ } --- 1768,1794 ---- /* In the other cases (virtual exception), compute and raise the exception now. */ ! char args[4]; ! args[3] = 0; ! if (po->pr.tb == NULL) ! args[2] = 'l'; ! else { ! args[2] = 'v'; ! consume_reference(po, po->pr.tb); ! } ! if (po->pr.val == NULL) ! args[1] = 'l'; ! else { ! args[1] = 'v'; ! consume_reference(po, po->pr.val); ! } ! args[0] = 'v'; ! consume_reference(po, po->pr.exc); ! if (psyco_generic_call(po, PyErr_Restore, ! CfNoReturnValue, args, ! po->pr.exc, po->pr.val, ! po->pr.tb) == NULL) return NULL; } + clear_pseudo_exception(po); retsource = CompileTime_NewSk(&psyco_skZero); /*to return NULL */ } *************** *** 1700,1703 **** --- 1806,1811 ---- /* 'stack_a' is the Python stack base pointer */ vinfo_t** stack_a = po->vlocals.items + po->pr.stack_base; + int opcode=0; /* Current opcode */ + int oparg=0; /* Current opcode argument, if any */ code_t* code1; *************** *** 1720,1725 **** PyCodeObject* co = po->pr.co; unsigned char* bytecode = (unsigned char*) PyString_AS_STRING(co->co_code); - int opcode=0; /* Current opcode */ - int oparg=0; /* Current opcode argument, if any */ vinfo_t *u, *v, /* temporary objects */ *w, *x; /* popped off the stack */ --- 1828,1831 ---- *************** *** 2122,2125 **** --- 2228,2235 ---- case END_FINALLY: + /* First make extra sure no exception is pending */ + if (PycException_Occurred(po)) + Py_FatalError("psyco: undetected exception " + "in END_FINALLY"); POP(v); if (is_compiletime(v->source) && *************** *** 2145,2150 **** po->pr.val = PsycoTuple_GET_ITEM(v, 1); PsycoTuple_GET_ITEM(v, 1) = NULL; ! /* XXX no traceback support */ ! /* tb will be decref'ed by vinfo_decref(v) below */ vinfo_decref(v, po); break; --- 2255,2260 ---- po->pr.val = PsycoTuple_GET_ITEM(v, 1); PsycoTuple_GET_ITEM(v, 1) = NULL; ! po->pr.tb = PsycoTuple_GET_ITEM(v, 2); ! PsycoTuple_GET_ITEM(v, 2) = NULL; vinfo_decref(v, po); break; *************** *** 2152,2169 **** else { /* end of an EXCEPT block, re-raise the exception ! stored in the stack. ! XXX when implementing tracebacks find a trick to ! mark this as a re-raising */ po->pr.exc = v; POP(po->pr.val); ! POP(v); ! vinfo_decref(v, po); /* XXX traceback */ break; } case BUILD_CLASS: ! x = psyco_generic_call(po, build_class, CfReturnRef|CfPyErrIfNull, ! "vvv", NTOP(1), NTOP(2), NTOP(3)); if (x == NULL) break; --- 2262,2280 ---- else { /* end of an EXCEPT block, re-raise the exception ! stored in the stack. As in Python, no extra ! traceback is recorded, but instead of the ! WHY_RERAISE trick we simply record no traceback ! if the opcode is END_FINALLY. */ po->pr.exc = v; POP(po->pr.val); ! POP(po->pr.tb); break; } case BUILD_CLASS: ! x = psyco_generic_call(po, cimpl_build_class, CfReturnRef|CfPyErrIfNull, ! "vvvv", LOC_GLOBALS, ! NTOP(1), NTOP(2), NTOP(3)); if (x == NULL) break; *************** *** 2287,2291 **** { PyObject* w = GETNAMEV(oparg); ! if (!psyco_generic_call(po, PyDict_SetItem, CfNoReturnValue|CfPyErrIfNonNull, --- 2398,2402 ---- { PyObject* w = GETNAMEV(oparg); ! mark_varying(po, w); if (!psyco_generic_call(po, PyDict_SetItem, CfNoReturnValue|CfPyErrIfNonNull, *************** *** 2299,2303 **** { PyObject* w = GETNAMEV(oparg); ! if (runtime_NON_NULL_f(po, psyco_generic_call(po, PyDict_DelItem, CfReturnNormal, "vl", LOC_GLOBALS, w))) { --- 2410,2414 ---- { PyObject* w = GETNAMEV(oparg); ! mark_varying(po, w); if (runtime_NON_NULL_f(po, psyco_generic_call(po, PyDict_DelItem, CfReturnNormal, "vl", LOC_GLOBALS, w))) { *************** *** 2322,2341 **** PyObject* namev = GETNAMEV(oparg); PyObject* value; ! if (is_compiletime(LOC_GLOBALS->source)) { ! /* Common case */ value = load_global(po, namev, next_instr); ! if (value == NULL) ! break; ! v = vinfo_new(CompileTime_NewSk(sk_new((long) value, ! SkFlagPyObj))); ! } ! else { ! /* Globals dict is unknown at compile-time */ ! v = psyco_generic_call(po, cimpl_load_global, ! CfReturnRef|CfPyErrIfNull, ! "vl", LOC_GLOBALS, namev); ! if (v == NULL) ! break; } PUSH(v); goto fine; --- 2433,2457 ---- PyObject* namev = GETNAMEV(oparg); PyObject* value; ! if (is_compiletime(LOC_GLOBALS->source) && ! (po->pr.changing_globals == NULL || ! PyDict_GetItem(po->pr.changing_globals, namev) == NULL)) { ! /* Common case: fast global loading */ value = load_global(po, namev, next_instr); ! if (value != NULL) { ! /* success */ ! v = vinfo_new(CompileTime_NewSk( ! sk_new((long) value, SkFlagPyObj))); ! PUSH(v); ! goto fine; ! } ! /* else { variable not found at all } */ } + /* else { Globals dict is unknown at compile-time, + or the global has been marked as varying } */ + v = psyco_generic_call(po, cimpl_load_global, + CfReturnRef|CfPyErrIfNull, + "vl", LOC_GLOBALS, namev); + if (v == NULL) + break; PUSH(v); goto fine; *************** *** 2492,2498 **** } ! /*MISSING_OPCODE(IMPORT_NAME); ! MISSING_OPCODE(IMPORT_STAR); ! MISSING_OPCODE(IMPORT_FROM);*/ case JUMP_FORWARD: --- 2608,2649 ---- } ! case IMPORT_NAME: ! { ! PyObject* w = GETNAMEV(oparg); ! ! x = psyco_generic_call(po, cimpl_import_name, ! CfReturnRef|CfPyErrIfNull, ! "vlv", LOC_GLOBALS, w, TOP()); ! if (x == NULL) ! break; ! POP_DECREF(); ! PUSH(x); ! goto fine; ! } ! ! /*MISSING_OPCODE(IMPORT_STAR);*/ ! ! case IMPORT_FROM: ! { ! PyObject* name = GETNAMEV(oparg); ! w = vinfo_new(CompileTime_New(((long) name))); ! v = TOP(); ! x = PsycoObject_GetAttr(po, v, w); ! vinfo_decref(w, po); ! if (x == NULL) { ! extra_assert(PycException_Occurred(po)); ! ! /* catch PyExc_AttributeError */ ! v = PycException_Matches(po, PyExc_AttributeError); ! if (runtime_NON_NULL_t(po, v) == true) { ! PycException_SetFormat(po, PyExc_ImportError, ! "cannot import name %.230s", ! PyString_AsString(name)); ! } ! break; ! } ! PUSH(x); ! goto fine; ! } case JUMP_FORWARD: *************** *** 2760,2763 **** --- 2911,2925 ---- /* At this point, we got a real pseudo-exception. */ + + if (PycException_IsPython(po) && opcode != END_FINALLY) + { + /* log traceback info for real Python exceptions, + unless re-raised by END_FINALLY */ + int lasti = po->pr.next_instr - 1; + if (HAS_ARG(opcode)) + lasti -= 2; + PsycoTraceBack_Here(po, lasti); + } + /* Unwind the Python stack until we find a handler for the (pseudo) exception. You will recognize here *************** *** 2802,2807 **** --- 2964,2971 ---- exc_info->array->items[TUPLE_OB_ITEM + 0] = po->pr.exc; exc_info->array->items[TUPLE_OB_ITEM + 1] = po->pr.val; + exc_info->array->items[TUPLE_OB_ITEM + 2] = po->pr.tb; po->pr.exc = NULL; po->pr.val = NULL; + po->pr.tb = NULL; PUSH(exc_info); JUMPTO(b->b_handler); *************** *** 2824,2828 **** /* XXX check that this empty loop cannot be endless */ } ! PUSH(psyco_vi_None()); PUSH(po->pr.val); po->pr.val = NULL; PUSH(po->pr.exc); po->pr.exc = NULL; --- 2988,2994 ---- /* XXX check that this empty loop cannot be endless */ } ! extra_assert(po->pr.val != NULL); ! extra_assert(po->pr.tb != NULL); ! PUSH(po->pr.tb); po->pr.tb = NULL; PUSH(po->pr.val); po->pr.val = NULL; PUSH(po->pr.exc); po->pr.exc = NULL; Index: pycompiler.h =================================================================== RCS file: /cvsroot/psyco/psyco/c/Python/pycompiler.h,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -d -r1.8 -r1.9 *** pycompiler.h 26 Feb 2002 23:08:00 -0000 1.8 --- pycompiler.h 18 Mar 2002 19:04:23 -0000 1.9 *************** *** 112,115 **** --- 112,120 ---- po->pr.val = val; } + inline void PycException_Restore(PsycoObject* po, vinfo_t* exc, + vinfo_t* val, vinfo_t* tb) { + PycException_Raise(po, exc, val); + po->pr.tb = tb; + } /* for Python exceptions detected at compile-time */ *************** *** 342,350 **** /* construction for non-frozen snapshots */ EXTERNFN void pyc_data_build(PsycoObject* po, PyObject* merge_points); ! EXTERNFN void pyc_data_release(pyc_data_t* pyc); inline void pyc_data_duplicate(pyc_data_t* target, pyc_data_t* source) { memcpy(target, source, sizeof(pyc_data_t)); target->exc = NULL; target->val = NULL; } --- 347,361 ---- /* construction for non-frozen snapshots */ EXTERNFN void pyc_data_build(PsycoObject* po, PyObject* merge_points); ! inline void pyc_data_release(pyc_data_t* pyc) { ! vinfo_xdecref(pyc->val, NULL); ! vinfo_xdecref(pyc->exc, NULL); ! vinfo_xdecref(pyc->tb, NULL); ! Py_XDECREF(pyc->changing_globals); ! } inline void pyc_data_duplicate(pyc_data_t* target, pyc_data_t* source) { memcpy(target, source, sizeof(pyc_data_t)); target->exc = NULL; target->val = NULL; + Py_XINCREF(target->changing_globals); } |