diff options
Diffstat (limited to 'Python/ceval.c')
| -rw-r--r-- | Python/ceval.c | 864 | 
1 files changed, 488 insertions, 376 deletions
| diff --git a/Python/ceval.c b/Python/ceval.c index f0ea7c9..7e9318b 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -138,7 +138,7 @@ static void format_exc_check_arg(PyObject *, const char *, PyObject *);  static void format_exc_unbound(PyCodeObject *co, int oparg);  static PyObject * unicode_concatenate(PyObject *, PyObject *,                                        PyFrameObject *, unsigned char *); -static PyObject * special_lookup(PyObject *, char *, PyObject **); +static PyObject * special_lookup(PyObject *, _Py_Identifier *);  #define NAME_ERROR_MSG \      "name '%.200s' is not defined" @@ -372,6 +372,7 @@ PyEval_ReleaseThread(PyThreadState *tstate)  void  PyEval_ReInitThreads(void)  { +    _Py_IDENTIFIER(_after_fork);      PyObject *threading, *result;      PyThreadState *tstate = PyThreadState_GET(); @@ -392,7 +393,7 @@ PyEval_ReInitThreads(void)          PyErr_Clear();          return;      } -    result = PyObject_CallMethod(threading, "_after_fork", NULL); +    result = _PyObject_CallMethodId(threading, &PyId__after_fork, NULL);      if (result == NULL)          PyErr_WriteUnraisable(threading);      else @@ -491,7 +492,6 @@ static struct {  } pendingcalls[NPENDINGCALLS];  static int pendingfirst = 0;  static int pendinglast = 0; -static char pendingbusy = 0;  int  Py_AddPendingCall(int (*func)(void *), void *arg) @@ -538,6 +538,7 @@ Py_AddPendingCall(int (*func)(void *), void *arg)  int  Py_MakePendingCalls(void)  { +    static int busy = 0;      int i;      int r = 0; @@ -552,9 +553,9 @@ Py_MakePendingCalls(void)      if (main_thread && PyThread_get_thread_ident() != main_thread)          return 0;      /* don't perform recursive pending calls */ -    if (pendingbusy) +    if (busy)          return 0; -    pendingbusy = 1; +    busy = 1;      /* perform a bounded number of calls, in case of recursion */      for (i=0; i<NPENDINGCALLS; i++) {          int j; @@ -583,7 +584,7 @@ Py_MakePendingCalls(void)          if (r)              break;      } -    pendingbusy = 0; +    busy = 0;      return r;  } @@ -749,6 +750,9 @@ enum why_code {          WHY_SILENCED =  0x0080  /* Exception silenced by 'with' */  }; +static void save_exc_state(PyThreadState *, PyFrameObject *); +static void swap_exc_state(PyThreadState *, PyFrameObject *); +static void restore_and_clear_exc_state(PyThreadState *, PyFrameObject *);  static enum why_code do_raise(PyObject *, PyObject *);  static int unpack_iterable(PyObject *, int, int, PyObject **); @@ -817,9 +821,9 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)      unsigned char *first_instr;      PyObject *names;      PyObject *consts; -#if defined(Py_DEBUG) || defined(LLTRACE) -    /* Make it easier to find out where we are with a debugger */ -    char *filename; + +#ifdef LLTRACE +    _Py_IDENTIFIER(__ltrace__);  #endif  /* Computed GOTOs, or @@ -1114,59 +1118,8 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)          Py_XDECREF(traceback); \      } -#define SAVE_EXC_STATE() \ -    { \ -        PyObject *type, *value, *traceback; \ -        Py_XINCREF(tstate->exc_type); \ -        Py_XINCREF(tstate->exc_value); \ -        Py_XINCREF(tstate->exc_traceback); \ -        type = f->f_exc_type; \ -        value = f->f_exc_value; \ -        traceback = f->f_exc_traceback; \ -        f->f_exc_type = tstate->exc_type; \ -        f->f_exc_value = tstate->exc_value; \ -        f->f_exc_traceback = tstate->exc_traceback; \ -        Py_XDECREF(type); \ -        Py_XDECREF(value); \ -        Py_XDECREF(traceback); \ -    } - -#define SWAP_EXC_STATE() \ -    { \ -        PyObject *tmp; \ -        tmp = tstate->exc_type; \ -        tstate->exc_type = f->f_exc_type; \ -        f->f_exc_type = tmp; \ -        tmp = tstate->exc_value; \ -        tstate->exc_value = f->f_exc_value; \ -        f->f_exc_value = tmp; \ -        tmp = tstate->exc_traceback; \ -        tstate->exc_traceback = f->f_exc_traceback; \ -        f->f_exc_traceback = tmp; \ -    } - -#define RESTORE_AND_CLEAR_EXC_STATE() \ -    { \ -        PyObject *type, *value, *tb; \ -        type = tstate->exc_type; \ -        value = tstate->exc_value; \ -        tb = tstate->exc_traceback; \ -        tstate->exc_type = f->f_exc_type; \ -        tstate->exc_value = f->f_exc_value; \ -        tstate->exc_traceback = f->f_exc_traceback; \ -        f->f_exc_type = NULL; \ -        f->f_exc_value = NULL; \ -        f->f_exc_traceback = NULL; \ -        Py_XDECREF(type); \ -        Py_XDECREF(value); \ -        Py_XDECREF(tb); \ -    } -  /* Start of code */ -    if (f == NULL) -        return NULL; -      /* push frame */      if (Py_EnterRecursiveCall(""))          return NULL; @@ -1221,6 +1174,8 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)         f->f_lasti to -1 (i.e. the index *before* the first instruction)         and YIELD_VALUE doesn't fiddle with f_lasti any more.  So this         does work.  Promise. +       YIELD_FROM sets f_lasti to itself, in order to repeated yield +       multiple values.         When the PREDICT() macros are enabled, some opcode pairs follow in         direct succession without updating f->f_lasti.  A successful @@ -1240,27 +1195,14 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)              /* We were in an except handler when we left,                 restore the exception state which was put aside                 (see YIELD_VALUE). */ -            SWAP_EXC_STATE(); -        } -        else { -            SAVE_EXC_STATE(); +            swap_exc_state(tstate, f);          } +        else +            save_exc_state(tstate, f);      }  #ifdef LLTRACE -    lltrace = PyDict_GetItemString(f->f_globals, "__lltrace__") != NULL; -#endif -#if defined(Py_DEBUG) || defined(LLTRACE) -    { -        PyObject *error_type, *error_value, *error_traceback; -        PyErr_Fetch(&error_type, &error_value, &error_traceback); -        filename = _PyUnicode_AsString(co->co_filename); -        if (filename == NULL && tstate->overflowed) { -            /* maximum recursion depth exceeded */ -            goto exit_eval_frame; -        } -        PyErr_Restore(error_type, error_value, error_traceback); -    } +    lltrace = _PyDict_GetItemId(f->f_globals, &PyId___ltrace__) != NULL;  #endif      why = WHY_NOT; @@ -1412,8 +1354,6 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)             x to NULL, err to nonzero, or why to anything but WHY_NOT,             and that no operation that succeeds does this! */ -        /* case STOP_CODE: this is an error! */ -          TARGET(NOP)              FAST_DISPATCH(); @@ -1894,6 +1834,40 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)              why = WHY_RETURN;              goto fast_block_end; +        TARGET(YIELD_FROM) +            u = POP(); +            x = TOP(); +            /* send u to x */ +            if (PyGen_CheckExact(x)) { +                retval = _PyGen_Send((PyGenObject *)x, u); +            } else { +                _Py_IDENTIFIER(send); +                if (u == Py_None) +                    retval = PyIter_Next(x); +                else +                    retval = _PyObject_CallMethodId(x, &PyId_send, "O", u); +            } +            Py_DECREF(u); +            if (!retval) { +                PyObject *val; +                x = POP(); /* Remove iter from stack */ +                Py_DECREF(x); +                err = _PyGen_FetchStopIterationValue(&val); +                if (err < 0) { +                    x = NULL; +                    break; +                } +                x = val; +                PUSH(x); +                continue; +            } +            /* x remains on stack, retval is value to be yielded */ +            f->f_stacktop = stack_pointer; +            why = WHY_YIELD; +            /* and repeat... */ +            f->f_lasti--; +            goto fast_yield; +          TARGET(YIELD_VALUE)              retval = POP();              f->f_stacktop = stack_pointer; @@ -1956,16 +1930,33 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)              break;          TARGET(LOAD_BUILD_CLASS) -            x = PyDict_GetItemString(f->f_builtins, -                                     "__build_class__"); -            if (x == NULL) { -                PyErr_SetString(PyExc_ImportError, -                                "__build_class__ not found"); -                break; +        { +            _Py_IDENTIFIER(__build_class__); + +            if (PyDict_CheckExact(f->f_builtins)) { +                x = _PyDict_GetItemId(f->f_builtins, &PyId___build_class__); +                if (x == NULL) { +                    PyErr_SetString(PyExc_NameError, +                                    "__build_class__ not found"); +                    break; +                } +                Py_INCREF(x); +            } +            else { +                PyObject *build_class_str = _PyUnicode_FromId(&PyId___build_class__); +                if (build_class_str == NULL) +                    break; +                x = PyObject_GetItem(f->f_builtins, build_class_str); +                if (x == NULL) { +                    if (PyErr_ExceptionMatches(PyExc_KeyError)) +                        PyErr_SetString(PyExc_NameError, +                                        "__build_class__ not found"); +                    break; +                }              } -            Py_INCREF(x);              PUSH(x);              break; +        }          TARGET(STORE_NAME)              w = GETITEM(names, oparg); @@ -2101,70 +2092,62 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)              }              if (x == NULL) {                  x = PyDict_GetItem(f->f_globals, w); +                Py_XINCREF(x);                  if (x == NULL) { -                    x = PyDict_GetItem(f->f_builtins, w); -                    if (x == NULL) { -                        format_exc_check_arg( -                                    PyExc_NameError, -                                    NAME_ERROR_MSG, w); -                        break; +                    if (PyDict_CheckExact(f->f_builtins)) { +                        x = PyDict_GetItem(f->f_builtins, w); +                        if (x == NULL) { +                            format_exc_check_arg( +                                        PyExc_NameError, +                                        NAME_ERROR_MSG, w); +                            break; +                        } +                        Py_INCREF(x); +                    } +                    else { +                        x = PyObject_GetItem(f->f_builtins, w); +                        if (x == NULL) { +                            if (PyErr_ExceptionMatches(PyExc_KeyError)) +                                format_exc_check_arg( +                                            PyExc_NameError, +                                            NAME_ERROR_MSG, w); +                            break; +                        }                      }                  } -                Py_INCREF(x);              }              PUSH(x);              DISPATCH();          TARGET(LOAD_GLOBAL)              w = GETITEM(names, oparg); -            if (PyUnicode_CheckExact(w)) { -                /* Inline the PyDict_GetItem() calls. -                   WARNING: this is an extreme speed hack. -                   Do not try this at home. */ -                Py_hash_t hash = ((PyUnicodeObject *)w)->hash; -                if (hash != -1) { -                    PyDictObject *d; -                    PyDictEntry *e; -                    d = (PyDictObject *)(f->f_globals); -                    e = d->ma_lookup(d, w, hash); -                    if (e == NULL) { -                        x = NULL; -                        break; -                    } -                    x = e->me_value; -                    if (x != NULL) { -                        Py_INCREF(x); -                        PUSH(x); -                        DISPATCH(); -                    } -                    d = (PyDictObject *)(f->f_builtins); -                    e = d->ma_lookup(d, w, hash); -                    if (e == NULL) { -                        x = NULL; -                        break; -                    } -                    x = e->me_value; -                    if (x != NULL) { -                        Py_INCREF(x); -                        PUSH(x); -                        DISPATCH(); -                    } -                    goto load_global_error; +            if (PyDict_CheckExact(f->f_globals) +                && PyDict_CheckExact(f->f_builtins)) { +                x = _PyDict_LoadGlobal((PyDictObject *)f->f_globals, +                                       (PyDictObject *)f->f_builtins, +                                       w); +                if (x == NULL) { +                    if (!PyErr_Occurred()) +                        format_exc_check_arg(PyExc_NameError, +                                             GLOBAL_NAME_ERROR_MSG, w); +                    break;                  } +                Py_INCREF(x);              } -            /* This is the un-inlined version of the code above */ -            x = PyDict_GetItem(f->f_globals, w); -            if (x == NULL) { -                x = PyDict_GetItem(f->f_builtins, w); +            else { +                /* Slow-path if globals or builtins is not a dict */ +                x = PyObject_GetItem(f->f_globals, w);                  if (x == NULL) { -                  load_global_error: -                    format_exc_check_arg( -                                PyExc_NameError, -                                GLOBAL_NAME_ERROR_MSG, w); -                    break; +                    x = PyObject_GetItem(f->f_builtins, w); +                    if (x == NULL) { +                        if (PyErr_ExceptionMatches(PyExc_KeyError)) +                            format_exc_check_arg( +                                        PyExc_NameError, +                                        GLOBAL_NAME_ERROR_MSG, w); +                        break; +                    }                  }              } -            Py_INCREF(x);              PUSH(x);              DISPATCH(); @@ -2313,8 +2296,10 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)              DISPATCH();          TARGET(IMPORT_NAME) +        { +            _Py_IDENTIFIER(__import__);              w = GETITEM(names, oparg); -            x = PyDict_GetItemString(f->f_builtins, "__import__"); +            x = _PyDict_GetItemId(f->f_builtins, &PyId___import__);              if (x == NULL) {                  PyErr_SetString(PyExc_ImportError,                                  "__import__ not found"); @@ -2355,6 +2340,7 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)              SET_TOP(x);              if (x != NULL) DISPATCH();              break; +        }          TARGET(IMPORT_STAR)              v = POP(); @@ -2559,13 +2545,14 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)          TARGET(SETUP_WITH)          { -            static PyObject *exit, *enter; +            _Py_IDENTIFIER(__exit__); +            _Py_IDENTIFIER(__enter__);              w = TOP(); -            x = special_lookup(w, "__exit__", &exit); +            x = special_lookup(w, &PyId___exit__);              if (!x)                  break;              SET_TOP(x); -            u = special_lookup(w, "__enter__", &enter); +            u = special_lookup(w, &PyId___enter__);              Py_DECREF(w);              if (!u) {                  x = NULL; @@ -2725,7 +2712,7 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)                  Py_DECREF(*pfunc);                  *pfunc = self;                  na++; -                n++; +                /* n++; */              } else                  Py_INCREF(func);              sp = stack_pointer; @@ -2753,9 +2740,11 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)              int kwdefaults = (oparg>>8) & 0xff;              int num_annotations = (oparg >> 16) & 0x7fff; +            w = POP(); /* qualname */              v = POP(); /* code object */ -            x = PyFunction_New(v, f->f_globals); +            x = PyFunction_NewWithQualName(v, f->f_globals, w);              Py_DECREF(v); +            Py_DECREF(w);              if (x != NULL && opcode == MAKE_CLOSURE) {                  v = POP(); @@ -3049,9 +3038,9 @@ fast_yield:                  break;          if (i == f->f_iblock)              /* We did not create this exception. */ -            RESTORE_AND_CLEAR_EXC_STATE() +            restore_and_clear_exc_state(tstate, f);          else -            SWAP_EXC_STATE() +            swap_exc_state(tstate, f);      }      if (tstate->use_tracing) { @@ -3081,7 +3070,7 @@ fast_yield:                                  PyTrace_RETURN, retval)) {                  Py_XDECREF(retval);                  retval = NULL; -                why = WHY_EXCEPTION; +                /* why = WHY_EXCEPTION; */              }          }      } @@ -3094,6 +3083,156 @@ exit_eval_frame:      return retval;  } +static void +format_missing(const char *kind, PyCodeObject *co, PyObject *names) +{ +    int err; +    Py_ssize_t len = PyList_GET_SIZE(names); +    PyObject *name_str, *comma, *tail, *tmp; + +    assert(PyList_CheckExact(names)); +    assert(len >= 1); +    /* Deal with the joys of natural language. */ +    switch (len) { +    case 1: +        name_str = PyList_GET_ITEM(names, 0); +        Py_INCREF(name_str); +        break; +    case 2: +        name_str = PyUnicode_FromFormat("%U and %U", +                                        PyList_GET_ITEM(names, len - 2), +                                        PyList_GET_ITEM(names, len - 1)); +        break; +    default: +        tail = PyUnicode_FromFormat(", %U, and %U", +                                    PyList_GET_ITEM(names, len - 2), +                                    PyList_GET_ITEM(names, len - 1)); +        if (tail == NULL) +            return; +        /* Chop off the last two objects in the list. This shouldn't actually +           fail, but we can't be too careful. */ +        err = PyList_SetSlice(names, len - 2, len, NULL); +        if (err == -1) { +            Py_DECREF(tail); +            return; +        } +        /* Stitch everything up into a nice comma-separated list. */ +        comma = PyUnicode_FromString(", "); +        if (comma == NULL) { +            Py_DECREF(tail); +            return; +        } +        tmp = PyUnicode_Join(comma, names); +        Py_DECREF(comma); +        if (tmp == NULL) { +            Py_DECREF(tail); +            return; +        } +        name_str = PyUnicode_Concat(tmp, tail); +        Py_DECREF(tmp); +        Py_DECREF(tail); +        break; +    } +    if (name_str == NULL) +        return; +    PyErr_Format(PyExc_TypeError, +                 "%U() missing %i required %s argument%s: %U", +                 co->co_name, +                 len, +                 kind, +                 len == 1 ? "" : "s", +                 name_str); +    Py_DECREF(name_str); +} + +static void +missing_arguments(PyCodeObject *co, int missing, int defcount, +                  PyObject **fastlocals) +{ +    int i, j = 0; +    int start, end; +    int positional = defcount != -1; +    const char *kind = positional ? "positional" : "keyword-only"; +    PyObject *missing_names; + +    /* Compute the names of the arguments that are missing. */ +    missing_names = PyList_New(missing); +    if (missing_names == NULL) +        return; +    if (positional) { +        start = 0; +        end = co->co_argcount - defcount; +    } +    else { +        start = co->co_argcount; +        end = start + co->co_kwonlyargcount; +    } +    for (i = start; i < end; i++) { +        if (GETLOCAL(i) == NULL) { +            PyObject *raw = PyTuple_GET_ITEM(co->co_varnames, i); +            PyObject *name = PyObject_Repr(raw); +            if (name == NULL) { +                Py_DECREF(missing_names); +                return; +            } +            PyList_SET_ITEM(missing_names, j++, name); +        } +    } +    assert(j == missing); +    format_missing(kind, co, missing_names); +    Py_DECREF(missing_names); +} + +static void +too_many_positional(PyCodeObject *co, int given, int defcount, PyObject **fastlocals) +{ +    int plural; +    int kwonly_given = 0; +    int i; +    PyObject *sig, *kwonly_sig; + +    assert((co->co_flags & CO_VARARGS) == 0); +    /* Count missing keyword-only args. */ +    for (i = co->co_argcount; i < co->co_argcount + co->co_kwonlyargcount; i++) +        if (GETLOCAL(i) != NULL) +            kwonly_given++; +    if (defcount) { +        int atleast = co->co_argcount - defcount; +        plural = 1; +        sig = PyUnicode_FromFormat("from %d to %d", atleast, co->co_argcount); +    } +    else { +        plural = co->co_argcount != 1; +        sig = PyUnicode_FromFormat("%d", co->co_argcount); +    } +    if (sig == NULL) +        return; +    if (kwonly_given) { +        const char *format = " positional argument%s (and %d keyword-only argument%s)"; +        kwonly_sig = PyUnicode_FromFormat(format, given != 1 ? "s" : "", kwonly_given, +                                              kwonly_given != 1 ? "s" : ""); +        if (kwonly_sig == NULL) { +            Py_DECREF(sig); +            return; +        } +    } +    else { +        /* This will not fail. */ +        kwonly_sig = PyUnicode_FromString(""); +        assert(kwonly_sig != NULL); +    } +    PyErr_Format(PyExc_TypeError, +                 "%U() takes %U positional argument%s but %d%U %s given", +                 co->co_name, +                 sig, +                 plural ? "s" : "", +                 given, +                 kwonly_sig, +                 given == 1 && !kwonly_given ? "was" : "were"); +    Py_DECREF(sig); +    Py_DECREF(kwonly_sig); +} +  /* This is gonna seem *real weird*, but if you put some other code between     PyEval_EvalFrame() and PyEval_EvalCodeEx() you will need to adjust     the test in the if statements in Misc/gdbinit (pystack and pystackv). */ @@ -3110,6 +3249,9 @@ PyEval_EvalCodeEx(PyObject *_co, PyObject *globals, PyObject *locals,      PyThreadState *tstate = PyThreadState_GET();      PyObject *x, *u;      int total_args = co->co_argcount + co->co_kwonlyargcount; +    int i; +    int n = argcount; +    PyObject *kwdict = NULL;      if (globals == NULL) {          PyErr_SetString(PyExc_SystemError, @@ -3126,212 +3268,153 @@ PyEval_EvalCodeEx(PyObject *_co, PyObject *globals, PyObject *locals,      fastlocals = f->f_localsplus;      freevars = f->f_localsplus + co->co_nlocals; -    if (total_args || co->co_flags & (CO_VARARGS | CO_VARKEYWORDS)) { -        int i; -        int n = argcount; -        PyObject *kwdict = NULL; -        if (co->co_flags & CO_VARKEYWORDS) { -            kwdict = PyDict_New(); -            if (kwdict == NULL) -                goto fail; -            i = total_args; -            if (co->co_flags & CO_VARARGS) -                i++; -            SETLOCAL(i, kwdict); -        } -        if (argcount > co->co_argcount) { -            if (!(co->co_flags & CO_VARARGS)) { -                PyErr_Format(PyExc_TypeError, -                    "%U() takes %s %d " -                    "positional argument%s (%d given)", -                    co->co_name, -                    defcount ? "at most" : "exactly", -                    co->co_argcount, -                    co->co_argcount == 1 ? "" : "s", -                    argcount + kwcount); -                goto fail; -            } -            n = co->co_argcount; -        } -        for (i = 0; i < n; i++) { +    /* Parse arguments. */ +    if (co->co_flags & CO_VARKEYWORDS) { +        kwdict = PyDict_New(); +        if (kwdict == NULL) +            goto fail; +        i = total_args; +        if (co->co_flags & CO_VARARGS) +            i++; +        SETLOCAL(i, kwdict); +    } +    if (argcount > co->co_argcount) +        n = co->co_argcount; +    for (i = 0; i < n; i++) { +        x = args[i]; +        Py_INCREF(x); +        SETLOCAL(i, x); +    } +    if (co->co_flags & CO_VARARGS) { +        u = PyTuple_New(argcount - n); +        if (u == NULL) +            goto fail; +        SETLOCAL(total_args, u); +        for (i = n; i < argcount; i++) {              x = args[i];              Py_INCREF(x); -            SETLOCAL(i, x); +            PyTuple_SET_ITEM(u, i-n, x);          } -        if (co->co_flags & CO_VARARGS) { -            u = PyTuple_New(argcount - n); -            if (u == NULL) -                goto fail; -            SETLOCAL(total_args, u); -            for (i = n; i < argcount; i++) { -                x = args[i]; -                Py_INCREF(x); -                PyTuple_SET_ITEM(u, i-n, x); -            } +    } +    for (i = 0; i < kwcount; i++) { +        PyObject **co_varnames; +        PyObject *keyword = kws[2*i]; +        PyObject *value = kws[2*i + 1]; +        int j; +        if (keyword == NULL || !PyUnicode_Check(keyword)) { +            PyErr_Format(PyExc_TypeError, +                         "%U() keywords must be strings", +                         co->co_name); +            goto fail;          } -        for (i = 0; i < kwcount; i++) { -            PyObject **co_varnames; -            PyObject *keyword = kws[2*i]; -            PyObject *value = kws[2*i + 1]; -            int j; -            if (keyword == NULL || !PyUnicode_Check(keyword)) { -                PyErr_Format(PyExc_TypeError, -                    "%U() keywords must be strings", -                    co->co_name); -                goto fail; -            } -            /* Speed hack: do raw pointer compares. As names are -               normally interned this should almost always hit. */ -            co_varnames = ((PyTupleObject *)(co->co_varnames))->ob_item; -            for (j = 0; j < total_args; j++) { -                PyObject *nm = co_varnames[j]; -                if (nm == keyword) -                    goto kw_found; -            } -            /* Slow fallback, just in case */ -            for (j = 0; j < total_args; j++) { -                PyObject *nm = co_varnames[j]; -                int cmp = PyObject_RichCompareBool( -                    keyword, nm, Py_EQ); -                if (cmp > 0) -                    goto kw_found; -                else if (cmp < 0) -                    goto fail; -            } -            if (j >= total_args && kwdict == NULL) { -                PyErr_Format(PyExc_TypeError, -                             "%U() got an unexpected " -                             "keyword argument '%S'", -                             co->co_name, -                             keyword); +        /* Speed hack: do raw pointer compares. As names are +           normally interned this should almost always hit. */ +        co_varnames = ((PyTupleObject *)(co->co_varnames))->ob_item; +        for (j = 0; j < total_args; j++) { +            PyObject *nm = co_varnames[j]; +            if (nm == keyword) +                goto kw_found; +        } +        /* Slow fallback, just in case */ +        for (j = 0; j < total_args; j++) { +            PyObject *nm = co_varnames[j]; +            int cmp = PyObject_RichCompareBool( +                keyword, nm, Py_EQ); +            if (cmp > 0) +                goto kw_found; +            else if (cmp < 0)                  goto fail; -            } -            PyDict_SetItem(kwdict, keyword, value); -            continue; -          kw_found: -            if (GETLOCAL(j) != NULL) { -                PyErr_Format(PyExc_TypeError, +        } +        if (j >= total_args && kwdict == NULL) { +            PyErr_Format(PyExc_TypeError, +                         "%U() got an unexpected " +                         "keyword argument '%S'", +                         co->co_name, +                         keyword); +            goto fail; +        } +        PyDict_SetItem(kwdict, keyword, value); +        continue; +      kw_found: +        if (GETLOCAL(j) != NULL) { +            PyErr_Format(PyExc_TypeError,                           "%U() got multiple " -                         "values for keyword " -                         "argument '%S'", +                         "values for argument '%S'",                           co->co_name,                           keyword); -                goto fail; -            } -            Py_INCREF(value); -            SETLOCAL(j, value); +            goto fail;          } -        if (co->co_kwonlyargcount > 0) { -            for (i = co->co_argcount; i < total_args; i++) { -                PyObject *name; -                if (GETLOCAL(i) != NULL) -                    continue; -                name = PyTuple_GET_ITEM(co->co_varnames, i); -                if (kwdefs != NULL) { -                    PyObject *def = PyDict_GetItem(kwdefs, name); -                    if (def) { -                        Py_INCREF(def); -                        SETLOCAL(i, def); -                        continue; -                    } -                } -                PyErr_Format(PyExc_TypeError, -                    "%U() needs keyword-only argument %S", -                    co->co_name, name); -                goto fail; -            } +        Py_INCREF(value); +        SETLOCAL(j, value); +    } +    if (argcount > co->co_argcount && !(co->co_flags & CO_VARARGS)) { +        too_many_positional(co, argcount, defcount, fastlocals); +        goto fail; +    } +    if (argcount < co->co_argcount) { +        int m = co->co_argcount - defcount; +        int missing = 0; +        for (i = argcount; i < m; i++) +            if (GETLOCAL(i) == NULL) +                missing++; +        if (missing) { +            missing_arguments(co, missing, defcount, fastlocals); +            goto fail;          } -        if (argcount < co->co_argcount) { -            int m = co->co_argcount - defcount; -            for (i = argcount; i < m; i++) { -                if (GETLOCAL(i) == NULL) { -                    int j, given = 0; -                    for (j = 0; j < co->co_argcount; j++) -                        if (GETLOCAL(j)) -                            given++; -                    PyErr_Format(PyExc_TypeError, -                        "%U() takes %s %d " -                        "argument%s " -                        "(%d given)", -                        co->co_name, -                        ((co->co_flags & CO_VARARGS) || -                         defcount) ? "at least" -                                   : "exactly", -                             m, m == 1 ? "" : "s", given); -                    goto fail; -                } +        if (n > m) +            i = n - m; +        else +            i = 0; +        for (; i < defcount; i++) { +            if (GETLOCAL(m+i) == NULL) { +                PyObject *def = defs[i]; +                Py_INCREF(def); +                SETLOCAL(m+i, def);              } -            if (n > m) -                i = n - m; -            else -                i = 0; -            for (; i < defcount; i++) { -                if (GETLOCAL(m+i) == NULL) { -                    PyObject *def = defs[i]; +        } +    } +    if (co->co_kwonlyargcount > 0) { +        int missing = 0; +        for (i = co->co_argcount; i < total_args; i++) { +            PyObject *name; +            if (GETLOCAL(i) != NULL) +                continue; +            name = PyTuple_GET_ITEM(co->co_varnames, i); +            if (kwdefs != NULL) { +                PyObject *def = PyDict_GetItem(kwdefs, name); +                if (def) {                      Py_INCREF(def); -                    SETLOCAL(m+i, def); +                    SETLOCAL(i, def); +                    continue;                  }              } +            missing++; +        } +        if (missing) { +            missing_arguments(co, missing, -1, fastlocals); +            goto fail;          }      } -    else if (argcount > 0 || kwcount > 0) { -        PyErr_Format(PyExc_TypeError, -                     "%U() takes no arguments (%d given)", -                     co->co_name, -                     argcount + kwcount); -        goto fail; -    } +      /* Allocate and initialize storage for cell vars, and copy free -       vars into frame.  This isn't too efficient right now. */ -    if (PyTuple_GET_SIZE(co->co_cellvars)) { -        int i, j, nargs, found; -        Py_UNICODE *cellname, *argname; +       vars into frame. */ +    for (i = 0; i < PyTuple_GET_SIZE(co->co_cellvars); ++i) {          PyObject *c; - -        nargs = total_args; -        if (co->co_flags & CO_VARARGS) -            nargs++; -        if (co->co_flags & CO_VARKEYWORDS) -            nargs++; - -        /* Initialize each cell var, taking into account -           cell vars that are initialized from arguments. - -           Should arrange for the compiler to put cellvars -           that are arguments at the beginning of the cellvars -           list so that we can march over it more efficiently? -        */ -        for (i = 0; i < PyTuple_GET_SIZE(co->co_cellvars); ++i) { -            cellname = PyUnicode_AS_UNICODE( -                PyTuple_GET_ITEM(co->co_cellvars, i)); -            found = 0; -            for (j = 0; j < nargs; j++) { -                argname = PyUnicode_AS_UNICODE( -                    PyTuple_GET_ITEM(co->co_varnames, j)); -                if (Py_UNICODE_strcmp(cellname, argname) == 0) { -                    c = PyCell_New(GETLOCAL(j)); -                    if (c == NULL) -                        goto fail; -                    GETLOCAL(co->co_nlocals + i) = c; -                    found = 1; -                    break; -                } -            } -            if (found == 0) { -                c = PyCell_New(NULL); -                if (c == NULL) -                    goto fail; -                SETLOCAL(co->co_nlocals + i, c); -            } -        } +        int arg; +        /* Possibly account for the cell variable being an argument. */ +        if (co->co_cell2arg != NULL && +            (arg = co->co_cell2arg[i]) != CO_CELL_NOT_AN_ARG) +            c = PyCell_New(GETLOCAL(arg)); +        else +            c = PyCell_New(NULL); +        if (c == NULL) +            goto fail; +        SETLOCAL(co->co_nlocals + i, c);      } -    if (PyTuple_GET_SIZE(co->co_freevars)) { -        int i; -        for (i = 0; i < PyTuple_GET_SIZE(co->co_freevars); ++i) { -            PyObject *o = PyTuple_GET_ITEM(closure, i); -            Py_INCREF(o); -            freevars[PyTuple_GET_SIZE(co->co_cellvars) + i] = o; -        } +    for (i = 0; i < PyTuple_GET_SIZE(co->co_freevars); ++i) { +        PyObject *o = PyTuple_GET_ITEM(closure, i); +        Py_INCREF(o); +        freevars[PyTuple_GET_SIZE(co->co_cellvars) + i] = o;      }      if (co->co_flags & CO_GENERATOR) { @@ -3365,18 +3448,72 @@ fail: /* Jump here from prelude on failure */  static PyObject * -special_lookup(PyObject *o, char *meth, PyObject **cache) +special_lookup(PyObject *o, _Py_Identifier *id)  {      PyObject *res; -    res = _PyObject_LookupSpecial(o, meth, cache); +    res = _PyObject_LookupSpecial(o, id);      if (res == NULL && !PyErr_Occurred()) { -        PyErr_SetObject(PyExc_AttributeError, *cache); +        PyErr_SetObject(PyExc_AttributeError, id->object);          return NULL;      }      return res;  } +/* These 3 functions deal with the exception state of generators. */ + +static void +save_exc_state(PyThreadState *tstate, PyFrameObject *f) +{ +    PyObject *type, *value, *traceback; +    Py_XINCREF(tstate->exc_type); +    Py_XINCREF(tstate->exc_value); +    Py_XINCREF(tstate->exc_traceback); +    type = f->f_exc_type; +    value = f->f_exc_value; +    traceback = f->f_exc_traceback; +    f->f_exc_type = tstate->exc_type; +    f->f_exc_value = tstate->exc_value; +    f->f_exc_traceback = tstate->exc_traceback; +    Py_XDECREF(type); +    Py_XDECREF(value); +    Py_XDECREF(traceback); +} + +static void +swap_exc_state(PyThreadState *tstate, PyFrameObject *f) +{ +    PyObject *tmp; +    tmp = tstate->exc_type; +    tstate->exc_type = f->f_exc_type; +    f->f_exc_type = tmp; +    tmp = tstate->exc_value; +    tstate->exc_value = f->f_exc_value; +    f->f_exc_value = tmp; +    tmp = tstate->exc_traceback; +    tstate->exc_traceback = f->f_exc_traceback; +    f->f_exc_traceback = tmp; +} + +static void +restore_and_clear_exc_state(PyThreadState *tstate, PyFrameObject *f) +{ +    PyObject *type, *value, *tb; +    type = tstate->exc_type; +    value = tstate->exc_value; +    tb = tstate->exc_traceback; +    tstate->exc_type = f->f_exc_type; +    tstate->exc_value = f->f_exc_value; +    tstate->exc_traceback = f->f_exc_traceback; +    f->f_exc_type = NULL; +    f->f_exc_value = NULL; +    f->f_exc_traceback = NULL; +    Py_XDECREF(type); +    Py_XDECREF(value); +    Py_XDECREF(tb); +} + +  /* Logic for the raise statement (too complicated for inlining).     This *consumes* a reference count to each of its arguments. */  static enum why_code @@ -3446,6 +3583,10 @@ do_raise(PyObject *exc, PyObject *cause)          else if (PyExceptionInstance_Check(cause)) {              fixed_cause = cause;          } +        else if (cause == Py_None) { +            Py_DECREF(cause); +            fixed_cause = NULL; +        }          else {              PyErr_SetString(PyExc_TypeError,                              "exception causes must derive from " @@ -4192,7 +4333,7 @@ ext_do_call(PyObject *func, PyObject ***pp_stack, int flags, int na, int nk)                  if (PyErr_ExceptionMatches(PyExc_TypeError)) {                      PyErr_Format(PyExc_TypeError,                                   "%.200s%.200s argument after * " -                                 "must be a sequence, not %200s", +                                 "must be a sequence, not %.200s",                                   PyEval_GetFuncName(func),                                   PyEval_GetFuncDesc(func),                                   stararg->ob_type->tp_name); @@ -4342,7 +4483,9 @@ import_from(PyObject *v, PyObject *name)  static int  import_all_from(PyObject *locals, PyObject *v)  { -    PyObject *all = PyObject_GetAttrString(v, "__all__"); +    _Py_IDENTIFIER(__all__); +    _Py_IDENTIFIER(__dict__); +    PyObject *all = _PyObject_GetAttrId(v, &PyId___all__);      PyObject *dict, *name, *value;      int skip_leading_underscores = 0;      int pos, err; @@ -4351,7 +4494,7 @@ import_all_from(PyObject *locals, PyObject *v)          if (!PyErr_ExceptionMatches(PyExc_AttributeError))              return -1; /* Unexpected error */          PyErr_Clear(); -        dict = PyObject_GetAttrString(v, "__dict__"); +        dict = _PyObject_GetAttrId(v, &PyId___dict__);          if (dict == NULL) {              if (!PyErr_ExceptionMatches(PyExc_AttributeError))                  return -1; @@ -4377,7 +4520,8 @@ import_all_from(PyObject *locals, PyObject *v)          }          if (skip_leading_underscores &&              PyUnicode_Check(name) && -            PyUnicode_AS_UNICODE(name)[0] == '_') +            PyUnicode_READY(name) != -1 && +            PyUnicode_READ_CHAR(name, 0) == '_')          {              Py_DECREF(name);              continue; @@ -4437,19 +4581,9 @@ format_exc_unbound(PyCodeObject *co, int oparg)  static PyObject *  unicode_concatenate(PyObject *v, PyObject *w, -                   PyFrameObject *f, unsigned char *next_instr) +                    PyFrameObject *f, unsigned char *next_instr)  { -    /* This function implements 'variable += expr' when both arguments -       are (Unicode) strings. */ -    Py_ssize_t v_len = PyUnicode_GET_SIZE(v); -    Py_ssize_t w_len = PyUnicode_GET_SIZE(w); -    Py_ssize_t new_len = v_len + w_len; -    if (new_len < 0) { -        PyErr_SetString(PyExc_OverflowError, -                        "strings are too large to concat"); -        return NULL; -    } - +    PyObject *res;      if (Py_REFCNT(v) == 2) {          /* In the common case, there are 2 references to the value           * stored in 'variable' when the += is performed: one on the @@ -4490,31 +4624,9 @@ unicode_concatenate(PyObject *v, PyObject *w,          }          }      } - -    if (Py_REFCNT(v) == 1 && !PyUnicode_CHECK_INTERNED(v)) { -        /* Now we own the last reference to 'v', so we can resize it -         * in-place. -         */ -        if (PyUnicode_Resize(&v, new_len) != 0) { -            /* XXX if PyUnicode_Resize() fails, 'v' has been -             * deallocated so it cannot be put back into -             * 'variable'.  The MemoryError is raised when there -             * is no value in 'variable', which might (very -             * remotely) be a cause of incompatibilities. -             */ -            return NULL; -        } -        /* copy 'w' into the newly allocated area of 'v' */ -        memcpy(PyUnicode_AS_UNICODE(v) + v_len, -               PyUnicode_AS_UNICODE(w), w_len*sizeof(Py_UNICODE)); -        return v; -    } -    else { -        /* When in-place resizing is not an option. */ -        w = PyUnicode_Concat(v, w); -        Py_DECREF(v); -        return w; -    } +    res = v; +    PyUnicode_Append(&res, w); +    return res;  }  #ifdef DYNAMIC_EXECUTION_PROFILE | 
