@@ -980,6 +980,8 @@ PyCompile_OpcodeStackEffect(int opcode, int oparg)
980980 return 1 - (oparg & 0xFF );
981981 case BUILD_MAP :
982982 return 1 - 2 * oparg ;
983+ case BUILD_CONST_KEY_MAP :
984+ return - oparg ;
983985 case LOAD_ATTR :
984986 return 0 ;
985987 case COMPARE_OP :
@@ -1234,6 +1236,15 @@ compiler_addop_j(struct compiler *c, int opcode, basicblock *b, int absolute)
12341236 return 0; \
12351237}
12361238
1239+ /* Same as ADDOP_O, but steals a reference. */
1240+ #define ADDOP_N (C , OP , O , TYPE ) { \
1241+ if (!compiler_addop_o((C), (OP), (C)->u->u_ ## TYPE, (O))) { \
1242+ Py_DECREF((O)); \
1243+ return 0; \
1244+ } \
1245+ Py_DECREF((O)); \
1246+ }
1247+
12371248#define ADDOP_NAME (C , OP , O , TYPE ) { \
12381249 if (!compiler_addop_name((C), (OP), (C)->u->u_ ## TYPE, (O))) \
12391250 return 0; \
@@ -1309,6 +1320,44 @@ compiler_isdocstring(stmt_ty s)
13091320 return 0 ;
13101321}
13111322
1323+ static int
1324+ is_const (expr_ty e )
1325+ {
1326+ switch (e -> kind ) {
1327+ case Constant_kind :
1328+ case Num_kind :
1329+ case Str_kind :
1330+ case Bytes_kind :
1331+ case Ellipsis_kind :
1332+ case NameConstant_kind :
1333+ return 1 ;
1334+ default :
1335+ return 0 ;
1336+ }
1337+ }
1338+
1339+ static PyObject *
1340+ get_const_value (expr_ty e )
1341+ {
1342+ switch (e -> kind ) {
1343+ case Constant_kind :
1344+ return e -> v .Constant .value ;
1345+ case Num_kind :
1346+ return e -> v .Num .n ;
1347+ case Str_kind :
1348+ return e -> v .Str .s ;
1349+ case Bytes_kind :
1350+ return e -> v .Bytes .s ;
1351+ case Ellipsis_kind :
1352+ return Py_Ellipsis ;
1353+ case NameConstant_kind :
1354+ return e -> v .NameConstant .value ;
1355+ default :
1356+ assert (!is_const (e ));
1357+ return NULL ;
1358+ }
1359+ }
1360+
13121361/* Compile a sequence of statements, checking for a docstring. */
13131362
13141363static int
@@ -2604,19 +2653,9 @@ compiler_visit_stmt_expr(struct compiler *c, expr_ty value)
26042653 return 1 ;
26052654 }
26062655
2607- switch (value -> kind )
2608- {
2609- case Str_kind :
2610- case Num_kind :
2611- case Ellipsis_kind :
2612- case Bytes_kind :
2613- case NameConstant_kind :
2614- case Constant_kind :
2656+ if (is_const (value )) {
26152657 /* ignore constant statement */
26162658 return 1 ;
2617-
2618- default :
2619- break ;
26202659 }
26212660
26222661 VISIT (c , expr , value );
@@ -3095,6 +3134,49 @@ compiler_set(struct compiler *c, expr_ty e)
30953134 BUILD_SET , BUILD_SET_UNPACK );
30963135}
30973136
3137+ static int
3138+ are_all_items_const (asdl_seq * seq , Py_ssize_t begin , Py_ssize_t end )
3139+ {
3140+ Py_ssize_t i ;
3141+ for (i = begin ; i < end ; i ++ ) {
3142+ expr_ty key = (expr_ty )asdl_seq_GET (seq , i );
3143+ if (key == NULL || !is_const (key ))
3144+ return 0 ;
3145+ }
3146+ return 1 ;
3147+ }
3148+
3149+ static int
3150+ compiler_subdict (struct compiler * c , expr_ty e , Py_ssize_t begin , Py_ssize_t end )
3151+ {
3152+ Py_ssize_t i , n = end - begin ;
3153+ PyObject * keys , * key ;
3154+ if (n > 1 && are_all_items_const (e -> v .Dict .keys , begin , end )) {
3155+ for (i = begin ; i < end ; i ++ ) {
3156+ VISIT (c , expr , (expr_ty )asdl_seq_GET (e -> v .Dict .values , i ));
3157+ }
3158+ keys = PyTuple_New (n );
3159+ if (keys == NULL ) {
3160+ return 0 ;
3161+ }
3162+ for (i = begin ; i < end ; i ++ ) {
3163+ key = get_const_value ((expr_ty )asdl_seq_GET (e -> v .Dict .keys , i ));
3164+ Py_INCREF (key );
3165+ PyTuple_SET_ITEM (keys , i - begin , key );
3166+ }
3167+ ADDOP_N (c , LOAD_CONST , keys , consts );
3168+ ADDOP_I (c , BUILD_CONST_KEY_MAP , n );
3169+ }
3170+ else {
3171+ for (i = begin ; i < end ; i ++ ) {
3172+ VISIT (c , expr , (expr_ty )asdl_seq_GET (e -> v .Dict .keys , i ));
3173+ VISIT (c , expr , (expr_ty )asdl_seq_GET (e -> v .Dict .values , i ));
3174+ }
3175+ ADDOP_I (c , BUILD_MAP , n );
3176+ }
3177+ return 1 ;
3178+ }
3179+
30983180static int
30993181compiler_dict (struct compiler * c , expr_ty e )
31003182{
@@ -3107,7 +3189,8 @@ compiler_dict(struct compiler *c, expr_ty e)
31073189 for (i = 0 ; i < n ; i ++ ) {
31083190 is_unpacking = (expr_ty )asdl_seq_GET (e -> v .Dict .keys , i ) == NULL ;
31093191 if (elements == 0xFFFF || (elements && is_unpacking )) {
3110- ADDOP_I (c , BUILD_MAP , elements );
3192+ if (!compiler_subdict (c , e , i - elements , i ))
3193+ return 0 ;
31113194 containers ++ ;
31123195 elements = 0 ;
31133196 }
@@ -3116,13 +3199,12 @@ compiler_dict(struct compiler *c, expr_ty e)
31163199 containers ++ ;
31173200 }
31183201 else {
3119- VISIT (c , expr , (expr_ty )asdl_seq_GET (e -> v .Dict .keys , i ));
3120- VISIT (c , expr , (expr_ty )asdl_seq_GET (e -> v .Dict .values , i ));
31213202 elements ++ ;
31223203 }
31233204 }
31243205 if (elements || containers == 0 ) {
3125- ADDOP_I (c , BUILD_MAP , elements );
3206+ if (!compiler_subdict (c , e , n - elements , n ))
3207+ return 0 ;
31263208 containers ++ ;
31273209 }
31283210 /* If there is more than one dict, they need to be merged into a new
@@ -3266,6 +3348,42 @@ compiler_formatted_value(struct compiler *c, expr_ty e)
32663348 return 1 ;
32673349}
32683350
3351+ static int
3352+ compiler_subkwargs (struct compiler * c , asdl_seq * keywords , Py_ssize_t begin , Py_ssize_t end )
3353+ {
3354+ Py_ssize_t i , n = end - begin ;
3355+ keyword_ty kw ;
3356+ PyObject * keys , * key ;
3357+ assert (n > 0 );
3358+ if (n > 1 ) {
3359+ for (i = begin ; i < end ; i ++ ) {
3360+ kw = asdl_seq_GET (keywords , i );
3361+ VISIT (c , expr , kw -> value );
3362+ }
3363+ keys = PyTuple_New (n );
3364+ if (keys == NULL ) {
3365+ return 0 ;
3366+ }
3367+ for (i = begin ; i < end ; i ++ ) {
3368+ key = ((keyword_ty ) asdl_seq_GET (keywords , i ))-> arg ;
3369+ Py_INCREF (key );
3370+ PyTuple_SET_ITEM (keys , i - begin , key );
3371+ }
3372+ ADDOP_N (c , LOAD_CONST , keys , consts );
3373+ ADDOP_I (c , BUILD_CONST_KEY_MAP , n );
3374+ }
3375+ else {
3376+ /* a for loop only executes once */
3377+ for (i = begin ; i < end ; i ++ ) {
3378+ kw = asdl_seq_GET (keywords , i );
3379+ ADDOP_O (c , LOAD_CONST , kw -> arg , consts );
3380+ VISIT (c , expr , kw -> value );
3381+ }
3382+ ADDOP_I (c , BUILD_MAP , n );
3383+ }
3384+ return 1 ;
3385+ }
3386+
32693387/* shared code between compiler_call and compiler_class */
32703388static int
32713389compiler_call_helper (struct compiler * c ,
@@ -3332,29 +3450,38 @@ compiler_call_helper(struct compiler *c,
33323450 if (kw -> arg == NULL ) {
33333451 /* A keyword argument unpacking. */
33343452 if (nseen ) {
3335- ADDOP_I (c , BUILD_MAP , nseen );
3453+ if (nsubkwargs ) {
3454+ if (!compiler_subkwargs (c , keywords , i - nseen , i ))
3455+ return 0 ;
3456+ nsubkwargs ++ ;
3457+ }
3458+ else {
3459+ Py_ssize_t j ;
3460+ for (j = 0 ; j < nseen ; j ++ ) {
3461+ VISIT (c , keyword , asdl_seq_GET (keywords , j ));
3462+ }
3463+ nkw = nseen ;
3464+ }
33363465 nseen = 0 ;
3337- nsubkwargs ++ ;
33383466 }
33393467 VISIT (c , expr , kw -> value );
33403468 nsubkwargs ++ ;
33413469 }
3342- else if (nsubkwargs ) {
3343- /* A keyword argument and we already have a dict. */
3344- ADDOP_O (c , LOAD_CONST , kw -> arg , consts );
3345- VISIT (c , expr , kw -> value );
3346- nseen ++ ;
3347- }
33483470 else {
3349- /* keyword argument */
3350- VISIT (c , keyword , kw )
3351- nkw ++ ;
3471+ nseen ++ ;
33523472 }
33533473 }
33543474 if (nseen ) {
3355- /* Pack up any trailing keyword arguments. */
3356- ADDOP_I (c , BUILD_MAP , nseen );
3357- nsubkwargs ++ ;
3475+ if (nsubkwargs ) {
3476+ /* Pack up any trailing keyword arguments. */
3477+ if (!compiler_subkwargs (c , keywords , nelts - nseen , nelts ))
3478+ return 0 ;
3479+ nsubkwargs ++ ;
3480+ }
3481+ else {
3482+ VISIT_SEQ (c , keyword , keywords );
3483+ nkw = nseen ;
3484+ }
33583485 }
33593486 if (nsubkwargs ) {
33603487 code |= 2 ;
0 commit comments