[Skip Montanaro] > ... > The whole think makes sense to me if it avoids the possible two > PyDict_GetItem calls in the LOAD_GLOBAL opcode. As I understand it, if > accessed inside a function, LOAD_GLOBAL could be implemented > something like this: > > case LOAD_GLOBAL: > cell = func_cells[oparg]; > if (cell.objptr) x = cell->objptr; > else x = cell->cellptr->objptr; > if (x == NULL) { > ... error recovery ... > break; > } > Py_INCREF(x); > continue; > > This looks a lot better to me (no complex function calls). Something much like that. Guido added code to the PEP (280). My suggested modifications reduce it to: case LOAD_GLOBAL_CELL: cell = func_cells[oparg]; x = cell->objptr; if (x != NULL) { Py_INCREF(x); continue; } ... error recovery ... break; Another difference is hiding in the "... error recovery ..." elisions. In Guido's scheme, this must also include code to deal with the possibility that a global went away and thereby uncovered a builtin that popped into existence after the module globals were initialized. Then it's still a non-error case, but the cell->cellptr has gotten out of synch with reality. In the variation, the caches are never allowed to get out of synch, so "... error recovery .." there should really be "... error reporting ...": you can't there in the variant unless NameError is certain. Hmm: We *all* seem to be missing a PUSH(x), so all of our schemes are dead wrong <wink>. Speaking of which, why does LOAD_FAST waste time checking against NULL twice?! case LOAD_FAST: x = GETLOCAL(oparg); if (x == NULL) { format_exc_check_arg( PyExc_UnboundLocalError, UNBOUNDLOCAL_ERROR_MSG, PyTuple_GetItem(co->co_varnames, oparg) ); break; } Py_INCREF(x); PUSH(x); if (x != NULL) continue; break; I'll fix that ...
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4