mirror of
				https://github.com/python/cpython.git
				synced 2025-10-31 05:31:20 +00:00 
			
		
		
		
	[3.9] bpo-39934: Account for control blocks in 'except' in compiler. (GH-22395) (GH-23303)
* bpo-39934: backport PR 22395 to 3.9
This commit is contained in:
		
							parent
							
								
									05a5d697f4
								
							
						
					
					
						commit
						48a9c0eb2a
					
				
					 3 changed files with 23 additions and 8 deletions
				
			
		|  | @ -84,8 +84,8 @@ It's called a frame block to distinguish it from a basic block in the | |||
| compiler IR. | ||||
| */ | ||||
| 
 | ||||
| enum fblocktype { WHILE_LOOP, FOR_LOOP, EXCEPT, FINALLY_TRY, FINALLY_END, | ||||
|                   WITH, ASYNC_WITH, HANDLER_CLEANUP, POP_VALUE }; | ||||
| enum fblocktype { WHILE_LOOP, FOR_LOOP, TRY_EXCEPT, FINALLY_TRY, FINALLY_END, | ||||
|                   WITH, ASYNC_WITH, HANDLER_CLEANUP, POP_VALUE, EXCEPTION_HANDLER }; | ||||
| 
 | ||||
| struct fblockinfo { | ||||
|     enum fblocktype fb_type; | ||||
|  | @ -1624,9 +1624,7 @@ compiler_push_fblock(struct compiler *c, enum fblocktype t, basicblock *b, | |||
| { | ||||
|     struct fblockinfo *f; | ||||
|     if (c->u->u_nfblocks >= CO_MAXBLOCKS) { | ||||
|         PyErr_SetString(PyExc_SyntaxError, | ||||
|                         "too many statically nested blocks"); | ||||
|         return 0; | ||||
|         return compiler_error(c, "too many statically nested blocks"); | ||||
|     } | ||||
|     f = &c->u->u_fblock[c->u->u_nfblocks++]; | ||||
|     f->fb_type = t; | ||||
|  | @ -1666,6 +1664,7 @@ compiler_unwind_fblock(struct compiler *c, struct fblockinfo *info, | |||
| { | ||||
|     switch (info->fb_type) { | ||||
|         case WHILE_LOOP: | ||||
|         case EXCEPTION_HANDLER: | ||||
|             return 1; | ||||
| 
 | ||||
|         case FOR_LOOP: | ||||
|  | @ -1676,7 +1675,7 @@ compiler_unwind_fblock(struct compiler *c, struct fblockinfo *info, | |||
|             ADDOP(c, POP_TOP); | ||||
|             return 1; | ||||
| 
 | ||||
|         case EXCEPT: | ||||
|         case TRY_EXCEPT: | ||||
|             ADDOP(c, POP_BLOCK); | ||||
|             return 1; | ||||
| 
 | ||||
|  | @ -3064,14 +3063,17 @@ compiler_try_except(struct compiler *c, stmt_ty s) | |||
|         return 0; | ||||
|     ADDOP_JREL(c, SETUP_FINALLY, except); | ||||
|     compiler_use_next_block(c, body); | ||||
|     if (!compiler_push_fblock(c, EXCEPT, body, NULL, NULL)) | ||||
|     if (!compiler_push_fblock(c, TRY_EXCEPT, body, NULL, NULL)) | ||||
|         return 0; | ||||
|     VISIT_SEQ(c, stmt, s->v.Try.body); | ||||
|     ADDOP(c, POP_BLOCK); | ||||
|     compiler_pop_fblock(c, EXCEPT, body); | ||||
|     compiler_pop_fblock(c, TRY_EXCEPT, body); | ||||
|     ADDOP_JREL(c, JUMP_FORWARD, orelse); | ||||
|     n = asdl_seq_LEN(s->v.Try.handlers); | ||||
|     compiler_use_next_block(c, except); | ||||
|     /* Runtime will push a block here, so we need to account for that */ | ||||
|     if (!compiler_push_fblock(c, EXCEPTION_HANDLER, NULL, NULL, NULL)) | ||||
|         return 0; | ||||
|     for (i = 0; i < n; i++) { | ||||
|         excepthandler_ty handler = (excepthandler_ty)asdl_seq_GET( | ||||
|             s->v.Try.handlers, i); | ||||
|  | @ -3156,6 +3158,7 @@ compiler_try_except(struct compiler *c, stmt_ty s) | |||
|         } | ||||
|         compiler_use_next_block(c, except); | ||||
|     } | ||||
|     compiler_pop_fblock(c, EXCEPTION_HANDLER, NULL); | ||||
|     ADDOP(c, RERAISE); | ||||
|     compiler_use_next_block(c, orelse); | ||||
|     VISIT_SEQ(c, stmt, s->v.Try.orelse); | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Irit Katriel
						Irit Katriel