@@ -136,6 +136,8 @@ static PyObject * import_from(PyObject *, PyObject *);
136136static int import_all_from (PyObject * , PyObject * );
137137static void format_exc_check_arg (PyObject * , const char * , PyObject * );
138138static void format_exc_unbound (PyCodeObject * co , int oparg );
139+ static PyObject * unicode_concatenate (PyObject * , PyObject * ,
140+ PyFrameObject * , unsigned char * );
139141static PyObject * special_lookup (PyObject * , char * , PyObject * * );
140142
141143#define NAME_ERROR_MSG \
@@ -1507,8 +1509,17 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)
15071509 TARGET (BINARY_ADD )
15081510 w = POP ();
15091511 v = TOP ();
1510- x = PyNumber_Add (v , w );
1512+ if (PyUnicode_CheckExact (v ) &&
1513+ PyUnicode_CheckExact (w )) {
1514+ x = unicode_concatenate (v , w , f , next_instr );
1515+ /* unicode_concatenate consumed the ref to v */
1516+ goto skip_decref_vx ;
1517+ }
1518+ else {
1519+ x = PyNumber_Add (v , w );
1520+ }
15111521 Py_DECREF (v );
1522+ skip_decref_vx :
15121523 Py_DECREF (w );
15131524 SET_TOP (x );
15141525 if (x != NULL ) DISPATCH ();
@@ -1659,8 +1670,17 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)
16591670 TARGET (INPLACE_ADD )
16601671 w = POP ();
16611672 v = TOP ();
1662- x = PyNumber_InPlaceAdd (v , w );
1673+ if (PyUnicode_CheckExact (v ) &&
1674+ PyUnicode_CheckExact (w )) {
1675+ x = unicode_concatenate (v , w , f , next_instr );
1676+ /* unicode_concatenate consumed the ref to v */
1677+ goto skip_decref_v ;
1678+ }
1679+ else {
1680+ x = PyNumber_InPlaceAdd (v , w );
1681+ }
16631682 Py_DECREF (v );
1683+ skip_decref_v :
16641684 Py_DECREF (w );
16651685 SET_TOP (x );
16661686 if (x != NULL ) DISPATCH ();
@@ -3399,7 +3419,7 @@ save_exc_state(PyThreadState *tstate, PyFrameObject *f)
33993419 f -> f_exc_traceback = tstate -> exc_traceback ;
34003420 Py_XDECREF (type );
34013421 Py_XDECREF (value );
3402- Py_XDECREF (traceback );
3422+ Py_XDECREF (traceback );
34033423}
34043424
34053425static void
@@ -4495,6 +4515,56 @@ format_exc_unbound(PyCodeObject *co, int oparg)
44954515 }
44964516}
44974517
4518+ static PyObject *
4519+ unicode_concatenate (PyObject * v , PyObject * w ,
4520+ PyFrameObject * f , unsigned char * next_instr )
4521+ {
4522+ PyObject * res ;
4523+ if (Py_REFCNT (v ) == 2 ) {
4524+ /* In the common case, there are 2 references to the value
4525+ * stored in 'variable' when the += is performed: one on the
4526+ * value stack (in 'v') and one still stored in the
4527+ * 'variable'. We try to delete the variable now to reduce
4528+ * the refcnt to 1.
4529+ */
4530+ switch (* next_instr ) {
4531+ case STORE_FAST :
4532+ {
4533+ int oparg = PEEKARG ();
4534+ PyObject * * fastlocals = f -> f_localsplus ;
4535+ if (GETLOCAL (oparg ) == v )
4536+ SETLOCAL (oparg , NULL );
4537+ break ;
4538+ }
4539+ case STORE_DEREF :
4540+ {
4541+ PyObject * * freevars = (f -> f_localsplus +
4542+ f -> f_code -> co_nlocals );
4543+ PyObject * c = freevars [PEEKARG ()];
4544+ if (PyCell_GET (c ) == v )
4545+ PyCell_Set (c , NULL );
4546+ break ;
4547+ }
4548+ case STORE_NAME :
4549+ {
4550+ PyObject * names = f -> f_code -> co_names ;
4551+ PyObject * name = GETITEM (names , PEEKARG ());
4552+ PyObject * locals = f -> f_locals ;
4553+ if (PyDict_CheckExact (locals ) &&
4554+ PyDict_GetItem (locals , name ) == v ) {
4555+ if (PyDict_DelItem (locals , name ) != 0 ) {
4556+ PyErr_Clear ();
4557+ }
4558+ }
4559+ break ;
4560+ }
4561+ }
4562+ }
4563+ res = v ;
4564+ PyUnicode_Append (& res , w );
4565+ return res ;
4566+ }
4567+
44984568#ifdef DYNAMIC_EXECUTION_PROFILE
44994569
45004570static PyObject *
0 commit comments