@@ -482,28 +482,62 @@ extern void _Py_set_localsplus_info(int, PyObject *, unsigned char,
482482
483483static int
484484compute_localsplus_info (_PyCompile_CodeUnitMetadata * umd , int nlocalsplus ,
485- PyObject * names , PyObject * kinds )
485+ int flags , PyObject * names , PyObject * kinds )
486486{
487+ // Compute the arg flags.
488+ // Currently arg vars fill the first portion of the list.
489+ char * argkinds = PyMem_Calloc (nlocalsplus , sizeof (char ));
490+ if (argkinds == NULL ) {
491+ PyErr_NoMemory ();
492+ return ERROR ;
493+ }
494+ int numargvars = 0 ;
495+ int max = (int )umd -> u_posonlyargcount ;
496+ for (; numargvars < max ; numargvars ++ ) {
497+ argkinds [numargvars ] = CO_FAST_ARG_POS ;
498+ }
499+ max += (int )umd -> u_argcount ;
500+ for (; numargvars < max ; numargvars ++ ) {
501+ argkinds [numargvars ] = CO_FAST_ARG_POS | CO_FAST_ARG_KW ;
502+ }
503+ max += (int )umd -> u_kwonlyargcount ;
504+ for (; numargvars < max ; numargvars ++ ) {
505+ argkinds [numargvars ] = CO_FAST_ARG_KW ;
506+ }
507+ if (flags & CO_VARARGS ) {
508+ argkinds [numargvars ] = CO_FAST_ARG_VAR | CO_FAST_ARG_POS ;
509+ numargvars += 1 ;
510+ }
511+ if (flags & CO_VARKEYWORDS ) {
512+ argkinds [numargvars ] = CO_FAST_ARG_VAR | CO_FAST_ARG_KW ;
513+ numargvars += 1 ;
514+ }
515+
516+ // Set the locals kinds.
487517 PyObject * k , * v ;
488518 Py_ssize_t pos = 0 ;
489519 while (PyDict_Next (umd -> u_varnames , & pos , & k , & v )) {
490520 int offset = PyLong_AsInt (v );
491521 if (offset == -1 && PyErr_Occurred ()) {
492- return ERROR ;
522+ goto error ;
493523 }
494524 assert (offset >= 0 );
495525 assert (offset < nlocalsplus );
496526
497- // For now we do not distinguish arg kinds.
498- _PyLocals_Kind kind = CO_FAST_LOCAL ;
527+ _PyLocals_Kind kind = CO_FAST_LOCAL | argkinds [ offset ];
528+
499529 int has_key = PyDict_Contains (umd -> u_fasthidden , k );
500- RETURN_IF_ERROR (has_key );
530+ if (has_key < 0 ) {
531+ goto error ;
532+ }
501533 if (has_key ) {
502534 kind |= CO_FAST_HIDDEN ;
503535 }
504536
505537 has_key = PyDict_Contains (umd -> u_cellvars , k );
506- RETURN_IF_ERROR (has_key );
538+ if (has_key < 0 ) {
539+ goto error ;
540+ }
507541 if (has_key ) {
508542 kind |= CO_FAST_CELL ;
509543 }
@@ -517,7 +551,9 @@ compute_localsplus_info(_PyCompile_CodeUnitMetadata *umd, int nlocalsplus,
517551 pos = 0 ;
518552 while (PyDict_Next (umd -> u_cellvars , & pos , & k , & v )) {
519553 int has_name = PyDict_Contains (umd -> u_varnames , k );
520- RETURN_IF_ERROR (has_name );
554+ if (has_name < 0 ) {
555+ goto error ;
556+ }
521557 if (has_name ) {
522558 // Skip cells that are already covered by locals.
523559 numdropped += 1 ;
@@ -526,7 +562,7 @@ compute_localsplus_info(_PyCompile_CodeUnitMetadata *umd, int nlocalsplus,
526562
527563 cellvar_offset = PyLong_AsInt (v );
528564 if (cellvar_offset == -1 && PyErr_Occurred ()) {
529- return ERROR ;
565+ goto error ;
530566 }
531567 assert (cellvar_offset >= 0 );
532568 cellvar_offset += nlocals - numdropped ;
@@ -538,7 +574,7 @@ compute_localsplus_info(_PyCompile_CodeUnitMetadata *umd, int nlocalsplus,
538574 while (PyDict_Next (umd -> u_freevars , & pos , & k , & v )) {
539575 int offset = PyLong_AsInt (v );
540576 if (offset == -1 && PyErr_Occurred ()) {
541- return ERROR ;
577+ goto error ;
542578 }
543579 assert (offset >= 0 );
544580 offset += nlocals - numdropped ;
@@ -549,7 +585,12 @@ compute_localsplus_info(_PyCompile_CodeUnitMetadata *umd, int nlocalsplus,
549585 assert (offset > cellvar_offset );
550586 _Py_set_localsplus_info (offset , k , CO_FAST_FREE , names , kinds );
551587 }
588+ PyMem_Free (argkinds );
552589 return SUCCESS ;
590+
591+ error :
592+ PyMem_Free (argkinds );
593+ return ERROR ;
553594}
554595
555596static PyCodeObject *
@@ -594,8 +635,10 @@ makecode(_PyCompile_CodeUnitMetadata *umd, struct assembler *a, PyObject *const_
594635 if (localspluskinds == NULL ) {
595636 goto error ;
596637 }
597- if (compute_localsplus_info (umd , nlocalsplus ,
598- localsplusnames , localspluskinds ) == ERROR ) {
638+ if (compute_localsplus_info (
639+ umd , nlocalsplus , code_flags ,
640+ localsplusnames , localspluskinds ) == ERROR )
641+ {
599642 goto error ;
600643 }
601644
0 commit comments