@@ -194,6 +194,7 @@ static int codegen_visit_expr(compiler *, expr_ty);
194194static int codegen_augassign (compiler * , stmt_ty );
195195static int codegen_annassign (compiler * , stmt_ty );
196196static int codegen_subscript (compiler * , expr_ty );
197+ static int codegen_slice_two_parts (compiler * , expr_ty );
197198static int codegen_slice (compiler * , expr_ty );
198199
199200static bool are_all_items_const (asdl_expr_seq * , Py_ssize_t , Py_ssize_t );
@@ -5005,12 +5006,8 @@ codegen_visit_expr(compiler *c, expr_ty e)
50055006 }
50065007 break ;
50075008 case Slice_kind :
5008- {
5009- int n = codegen_slice (c , e );
5010- RETURN_IF_ERROR (n );
5011- ADDOP_I (c , loc , BUILD_SLICE , n );
5009+ RETURN_IF_ERROR (codegen_slice (c , e ));
50125010 break ;
5013- }
50145011 case Name_kind :
50155012 return codegen_nameop (c , loc , e -> v .Name .id , e -> v .Name .ctx );
50165013 /* child nodes of List and Tuple will have expr_context set */
@@ -5023,9 +5020,22 @@ codegen_visit_expr(compiler *c, expr_ty e)
50235020}
50245021
50255022static bool
5026- is_two_element_slice (expr_ty s )
5023+ is_constant_slice (expr_ty s )
50275024{
50285025 return s -> kind == Slice_kind &&
5026+ (s -> v .Slice .lower == NULL ||
5027+ s -> v .Slice .lower -> kind == Constant_kind ) &&
5028+ (s -> v .Slice .upper == NULL ||
5029+ s -> v .Slice .upper -> kind == Constant_kind ) &&
5030+ (s -> v .Slice .step == NULL ||
5031+ s -> v .Slice .step -> kind == Constant_kind );
5032+ }
5033+
5034+ static bool
5035+ should_apply_two_element_slice_optimization (expr_ty s )
5036+ {
5037+ return !is_constant_slice (s ) &&
5038+ s -> kind == Slice_kind &&
50295039 s -> v .Slice .step == NULL ;
50305040}
50315041
@@ -5046,8 +5056,8 @@ codegen_augassign(compiler *c, stmt_ty s)
50465056 break ;
50475057 case Subscript_kind :
50485058 VISIT (c , expr , e -> v .Subscript .value );
5049- if (is_two_element_slice (e -> v .Subscript .slice )) {
5050- RETURN_IF_ERROR (codegen_slice (c , e -> v .Subscript .slice ));
5059+ if (should_apply_two_element_slice_optimization (e -> v .Subscript .slice )) {
5060+ RETURN_IF_ERROR (codegen_slice_two_parts (c , e -> v .Subscript .slice ));
50515061 ADDOP_I (c , loc , COPY , 3 );
50525062 ADDOP_I (c , loc , COPY , 3 );
50535063 ADDOP_I (c , loc , COPY , 3 );
@@ -5084,7 +5094,7 @@ codegen_augassign(compiler *c, stmt_ty s)
50845094 ADDOP_NAME (c , loc , STORE_ATTR , e -> v .Attribute .attr , names );
50855095 break ;
50865096 case Subscript_kind :
5087- if (is_two_element_slice (e -> v .Subscript .slice )) {
5097+ if (should_apply_two_element_slice_optimization (e -> v .Subscript .slice )) {
50885098 ADDOP_I (c , loc , SWAP , 4 );
50895099 ADDOP_I (c , loc , SWAP , 3 );
50905100 ADDOP_I (c , loc , SWAP , 2 );
@@ -5231,8 +5241,10 @@ codegen_subscript(compiler *c, expr_ty e)
52315241 }
52325242
52335243 VISIT (c , expr , e -> v .Subscript .value );
5234- if (is_two_element_slice (e -> v .Subscript .slice ) && ctx != Del ) {
5235- RETURN_IF_ERROR (codegen_slice (c , e -> v .Subscript .slice ));
5244+ if (should_apply_two_element_slice_optimization (e -> v .Subscript .slice ) &&
5245+ ctx != Del
5246+ ) {
5247+ RETURN_IF_ERROR (codegen_slice_two_parts (c , e -> v .Subscript .slice ));
52365248 if (ctx == Load ) {
52375249 ADDOP (c , loc , BINARY_SLICE );
52385250 }
@@ -5254,15 +5266,9 @@ codegen_subscript(compiler *c, expr_ty e)
52545266 return SUCCESS ;
52555267}
52565268
5257- /* Returns the number of the values emitted,
5258- * thus are needed to build the slice, or -1 if there is an error. */
52595269static int
5260- codegen_slice (compiler * c , expr_ty s )
5270+ codegen_slice_two_parts (compiler * c , expr_ty s )
52615271{
5262- int n = 2 ;
5263- assert (s -> kind == Slice_kind );
5264-
5265- /* only handles the cases where BUILD_SLICE is emitted */
52665272 if (s -> v .Slice .lower ) {
52675273 VISIT (c , expr , s -> v .Slice .lower );
52685274 }
@@ -5277,11 +5283,45 @@ codegen_slice(compiler *c, expr_ty s)
52775283 ADDOP_LOAD_CONST (c , LOC (s ), Py_None );
52785284 }
52795285
5286+ return 0 ;
5287+ }
5288+
5289+ static int
5290+ codegen_slice (compiler * c , expr_ty s )
5291+ {
5292+ int n = 2 ;
5293+ assert (s -> kind == Slice_kind );
5294+
5295+ if (is_constant_slice (s )) {
5296+ PyObject * start = NULL ;
5297+ if (s -> v .Slice .lower ) {
5298+ start = s -> v .Slice .lower -> v .Constant .value ;
5299+ }
5300+ PyObject * stop = NULL ;
5301+ if (s -> v .Slice .upper ) {
5302+ stop = s -> v .Slice .upper -> v .Constant .value ;
5303+ }
5304+ PyObject * step = NULL ;
5305+ if (s -> v .Slice .step ) {
5306+ step = s -> v .Slice .step -> v .Constant .value ;
5307+ }
5308+ PyObject * slice = PySlice_New (start , stop , step );
5309+ if (slice == NULL ) {
5310+ return ERROR ;
5311+ }
5312+ ADDOP_LOAD_CONST_NEW (c , LOC (s ), slice );
5313+ return SUCCESS ;
5314+ }
5315+
5316+ RETURN_IF_ERROR (codegen_slice_two_parts (c , s ));
5317+
52805318 if (s -> v .Slice .step ) {
52815319 n ++ ;
52825320 VISIT (c , expr , s -> v .Slice .step );
52835321 }
5284- return n ;
5322+
5323+ ADDOP_I (c , LOC (s ), BUILD_SLICE , n );
5324+ return SUCCESS ;
52855325}
52865326
52875327
0 commit comments