@@ -279,73 +279,111 @@ dummy_func(
279279
280280 family (binary_op , INLINE_CACHE_ENTRIES_BINARY_OP ) = {
281281 BINARY_OP ,
282- BINARY_OP_ADD_FLOAT ,
282+ BINARY_OP_MULTIPLY_INT ,
283283 BINARY_OP_ADD_INT ,
284- BINARY_OP_ADD_UNICODE ,
285- // BINARY_OP_INPLACE_ADD_UNICODE, // This is an odd duck.
284+ BINARY_OP_SUBTRACT_INT ,
286285 BINARY_OP_MULTIPLY_FLOAT ,
287- BINARY_OP_MULTIPLY_INT ,
286+ BINARY_OP_ADD_FLOAT ,
288287 BINARY_OP_SUBTRACT_FLOAT ,
289- BINARY_OP_SUBTRACT_INT ,
288+ BINARY_OP_ADD_UNICODE ,
289+ // BINARY_OP_INPLACE_ADD_UNICODE, // See comments at that opcode.
290290 };
291291
292-
293- inst (BINARY_OP_MULTIPLY_INT , (unused /1 , left , right -- prod )) {
292+ op (_GUARD_BOTH_INT , (left , right -- left , right )) {
294293 DEOPT_IF (!PyLong_CheckExact (left ), BINARY_OP );
295294 DEOPT_IF (!PyLong_CheckExact (right ), BINARY_OP );
295+ }
296+
297+ op (_BINARY_OP_MULTIPLY_INT , (unused /1 , left , right -- res )) {
296298 STAT_INC (BINARY_OP , hit );
297- prod = _PyLong_Multiply ((PyLongObject * )left , (PyLongObject * )right );
299+ res = _PyLong_Multiply ((PyLongObject * )left , (PyLongObject * )right );
298300 _Py_DECREF_SPECIALIZED (right , (destructor )PyObject_Free );
299301 _Py_DECREF_SPECIALIZED (left , (destructor )PyObject_Free );
300- ERROR_IF (prod == NULL , error );
302+ ERROR_IF (res == NULL , error );
301303 }
302304
303- inst (BINARY_OP_MULTIPLY_FLOAT , (unused /1 , left , right -- prod )) {
304- DEOPT_IF (!PyFloat_CheckExact (left ), BINARY_OP );
305- DEOPT_IF (!PyFloat_CheckExact (right ), BINARY_OP );
305+ op (_BINARY_OP_ADD_INT , (unused /1 , left , right -- res )) {
306306 STAT_INC (BINARY_OP , hit );
307- double dprod = ((PyFloatObject * )left )-> ob_fval *
308- ((PyFloatObject * )right )-> ob_fval ;
309- DECREF_INPUTS_AND_REUSE_FLOAT (left , right , dprod , prod );
307+ res = _PyLong_Add ((PyLongObject * )left , (PyLongObject * )right );
308+ _Py_DECREF_SPECIALIZED (right , (destructor )PyObject_Free );
309+ _Py_DECREF_SPECIALIZED (left , (destructor )PyObject_Free );
310+ ERROR_IF (res == NULL , error );
310311 }
311312
312- inst (BINARY_OP_SUBTRACT_INT , (unused /1 , left , right -- sub )) {
313- DEOPT_IF (!PyLong_CheckExact (left ), BINARY_OP );
314- DEOPT_IF (!PyLong_CheckExact (right ), BINARY_OP );
313+ op (_BINARY_OP_SUBTRACT_INT , (unused /1 , left , right -- res )) {
315314 STAT_INC (BINARY_OP , hit );
316- sub = _PyLong_Subtract ((PyLongObject * )left , (PyLongObject * )right );
315+ res = _PyLong_Subtract ((PyLongObject * )left , (PyLongObject * )right );
317316 _Py_DECREF_SPECIALIZED (right , (destructor )PyObject_Free );
318317 _Py_DECREF_SPECIALIZED (left , (destructor )PyObject_Free );
319- ERROR_IF (sub == NULL , error );
318+ ERROR_IF (res == NULL , error );
320319 }
321320
322- inst (BINARY_OP_SUBTRACT_FLOAT , (unused /1 , left , right -- sub )) {
321+ macro (BINARY_OP_MULTIPLY_INT ) =
322+ _GUARD_BOTH_INT + _BINARY_OP_MULTIPLY_INT ;
323+ macro (BINARY_OP_ADD_INT ) =
324+ _GUARD_BOTH_INT + _BINARY_OP_ADD_INT ;
325+ macro (BINARY_OP_SUBTRACT_INT ) =
326+ _GUARD_BOTH_INT + _BINARY_OP_SUBTRACT_INT ;
327+
328+ op (_GUARD_BOTH_FLOAT , (left , right -- left , right )) {
323329 DEOPT_IF (!PyFloat_CheckExact (left ), BINARY_OP );
324330 DEOPT_IF (!PyFloat_CheckExact (right ), BINARY_OP );
331+ }
332+
333+ op (_BINARY_OP_MULTIPLY_FLOAT , (unused /1 , left , right -- res )) {
325334 STAT_INC (BINARY_OP , hit );
326- double dsub = ((PyFloatObject * )left )-> ob_fval - ((PyFloatObject * )right )-> ob_fval ;
327- DECREF_INPUTS_AND_REUSE_FLOAT (left , right , dsub , sub );
335+ double dres =
336+ ((PyFloatObject * )left )-> ob_fval *
337+ ((PyFloatObject * )right )-> ob_fval ;
338+ DECREF_INPUTS_AND_REUSE_FLOAT (left , right , dres , res );
339+ }
340+
341+ op (_BINARY_OP_ADD_FLOAT , (unused /1 , left , right -- res )) {
342+ STAT_INC (BINARY_OP , hit );
343+ double dres =
344+ ((PyFloatObject * )left )-> ob_fval +
345+ ((PyFloatObject * )right )-> ob_fval ;
346+ DECREF_INPUTS_AND_REUSE_FLOAT (left , right , dres , res );
347+ }
348+
349+ op (_BINARY_OP_SUBTRACT_FLOAT , (unused /1 , left , right -- res )) {
350+ STAT_INC (BINARY_OP , hit );
351+ double dres =
352+ ((PyFloatObject * )left )-> ob_fval -
353+ ((PyFloatObject * )right )-> ob_fval ;
354+ DECREF_INPUTS_AND_REUSE_FLOAT (left , right , dres , res );
328355 }
329356
330- inst (BINARY_OP_ADD_UNICODE , (unused /1 , left , right -- res )) {
357+ macro (BINARY_OP_MULTIPLY_FLOAT ) =
358+ _GUARD_BOTH_FLOAT + _BINARY_OP_MULTIPLY_FLOAT ;
359+ macro (BINARY_OP_ADD_FLOAT ) =
360+ _GUARD_BOTH_FLOAT + _BINARY_OP_ADD_FLOAT ;
361+ macro (BINARY_OP_SUBTRACT_FLOAT ) =
362+ _GUARD_BOTH_FLOAT + _BINARY_OP_SUBTRACT_FLOAT ;
363+
364+ op (_GUARD_BOTH_UNICODE , (left , right -- left , right )) {
331365 DEOPT_IF (!PyUnicode_CheckExact (left ), BINARY_OP );
332- DEOPT_IF (Py_TYPE (right ) != Py_TYPE (left ), BINARY_OP );
366+ DEOPT_IF (!PyUnicode_CheckExact (right ), BINARY_OP );
367+ }
368+
369+ op (_BINARY_OP_ADD_UNICODE , (unused /1 , left , right -- res )) {
333370 STAT_INC (BINARY_OP , hit );
334371 res = PyUnicode_Concat (left , right );
335372 _Py_DECREF_SPECIALIZED (left , _PyUnicode_ExactDealloc );
336373 _Py_DECREF_SPECIALIZED (right , _PyUnicode_ExactDealloc );
337374 ERROR_IF (res == NULL , error );
338375 }
339376
377+ macro (BINARY_OP_ADD_UNICODE ) =
378+ _GUARD_BOTH_UNICODE + _BINARY_OP_ADD_UNICODE ;
379+
340380 // This is a subtle one. It's a super-instruction for
341381 // BINARY_OP_ADD_UNICODE followed by STORE_FAST
342382 // where the store goes into the left argument.
343383 // So the inputs are the same as for all BINARY_OP
344384 // specializations, but there is no output.
345385 // At the end we just skip over the STORE_FAST.
346- inst (BINARY_OP_INPLACE_ADD_UNICODE , (left , right -- )) {
347- DEOPT_IF (!PyUnicode_CheckExact (left ), BINARY_OP );
348- DEOPT_IF (Py_TYPE (right ) != Py_TYPE (left ), BINARY_OP );
386+ op (_BINARY_OP_INPLACE_ADD_UNICODE , (left , right -- )) {
349387 _Py_CODEUNIT true_next = next_instr [INLINE_CACHE_ENTRIES_BINARY_OP ];
350388 assert (true_next .op .code == STORE_FAST ||
351389 true_next .op .code == STORE_FAST__LOAD_FAST );
@@ -372,24 +410,8 @@ dummy_func(
372410 JUMPBY (INLINE_CACHE_ENTRIES_BINARY_OP + 1 );
373411 }
374412
375- inst (BINARY_OP_ADD_FLOAT , (unused /1 , left , right -- sum )) {
376- DEOPT_IF (!PyFloat_CheckExact (left ), BINARY_OP );
377- DEOPT_IF (Py_TYPE (right ) != Py_TYPE (left ), BINARY_OP );
378- STAT_INC (BINARY_OP , hit );
379- double dsum = ((PyFloatObject * )left )-> ob_fval +
380- ((PyFloatObject * )right )-> ob_fval ;
381- DECREF_INPUTS_AND_REUSE_FLOAT (left , right , dsum , sum );
382- }
383-
384- inst (BINARY_OP_ADD_INT , (unused /1 , left , right -- sum )) {
385- DEOPT_IF (!PyLong_CheckExact (left ), BINARY_OP );
386- DEOPT_IF (Py_TYPE (right ) != Py_TYPE (left ), BINARY_OP );
387- STAT_INC (BINARY_OP , hit );
388- sum = _PyLong_Add ((PyLongObject * )left , (PyLongObject * )right );
389- _Py_DECREF_SPECIALIZED (right , (destructor )PyObject_Free );
390- _Py_DECREF_SPECIALIZED (left , (destructor )PyObject_Free );
391- ERROR_IF (sum == NULL , error );
392- }
413+ macro (BINARY_OP_INPLACE_ADD_UNICODE ) =
414+ _GUARD_BOTH_UNICODE + _BINARY_OP_INPLACE_ADD_UNICODE ;
393415
394416 family (binary_subscr , INLINE_CACHE_ENTRIES_BINARY_SUBSCR ) = {
395417 BINARY_SUBSCR ,
0 commit comments