mirror of
				https://github.com/python/cpython.git
				synced 2025-10-30 21:21:22 +00:00 
			
		
		
		
	GH-98831: Typed stack effects, and more instructions converted (#99764)
Stack effects can now have a type, e.g. `inst(X, (left, right -- jump/uint64_t)) { ... }`.
Instructions converted to the non-legacy format:
* COMPARE_OP
* COMPARE_OP_FLOAT_JUMP
* COMPARE_OP_INT_JUMP
* COMPARE_OP_STR_JUMP
* STORE_ATTR
* DELETE_ATTR
* STORE_GLOBAL
* STORE_ATTR_INSTANCE_VALUE
* STORE_ATTR_WITH_HINT
* STORE_ATTR_SLOT, and complete the store_attr family
* Complete the store_subscr family: STORE_SUBSCR{,DICT,LIST_INT}
  (STORE_SUBSCR was alread half converted,
  but wasn't using cache effects yet.)
* DELETE_SUBSCR
* PRINT_EXPR
* INTERPRETER_EXIT (a bit weird, ends in return)
* RETURN_VALUE
* GET_AITER (had to restructure it some)
  The original had mysterious `SET_TOP(NULL)` before `goto error`.
  I assume those just account for `obj` having been decref'ed,
  so I got rid of them in favor of the cleanup implied by `ERROR_IF()`.
* LIST_APPEND (a bit unhappy with it)
* SET_ADD (also a bit unhappy with it)
Various other improvements/refactorings as well.
			
			
This commit is contained in:
		
							parent
							
								
									35cc0ea736
								
							
						
					
					
						commit
						c85be734d1
					
				
					 4 changed files with 545 additions and 604 deletions
				
			
		|  | @ -62,7 +62,8 @@ class Block(Node): | |||
| @dataclass | ||||
| class StackEffect(Node): | ||||
|     name: str | ||||
|     # TODO: type, condition | ||||
|     type: str = "" | ||||
|     # TODO: array, condition | ||||
| 
 | ||||
| 
 | ||||
| @dataclass | ||||
|  | @ -147,7 +148,7 @@ def inst_header(self) -> InstHeader | None: | |||
|             if self.expect(lx.LPAREN) and (tkn := self.expect(lx.IDENTIFIER)): | ||||
|                 name = tkn.text | ||||
|                 if self.expect(lx.COMMA): | ||||
|                     inp, outp = self.stack_effect() | ||||
|                     inp, outp = self.io_effect() | ||||
|                     if self.expect(lx.RPAREN): | ||||
|                         if (tkn := self.peek()) and tkn.kind == lx.LBRACE: | ||||
|                             return InstHeader(kind, name, inp, outp) | ||||
|  | @ -156,7 +157,7 @@ def inst_header(self) -> InstHeader | None: | |||
|                     return InstHeader(kind, name, [], []) | ||||
|         return None | ||||
| 
 | ||||
|     def stack_effect(self) -> tuple[list[InputEffect], list[OutputEffect]]: | ||||
|     def io_effect(self) -> tuple[list[InputEffect], list[OutputEffect]]: | ||||
|         # '(' [inputs] '--' [outputs] ')' | ||||
|         if self.expect(lx.LPAREN): | ||||
|             inputs = self.inputs() or [] | ||||
|  | @ -181,23 +182,7 @@ def inputs(self) -> list[InputEffect] | None: | |||
| 
 | ||||
|     @contextual | ||||
|     def input(self) -> InputEffect | None: | ||||
|         # IDENTIFIER '/' INTEGER (CacheEffect) | ||||
|         # IDENTIFIER (StackEffect) | ||||
|         if tkn := self.expect(lx.IDENTIFIER): | ||||
|             if self.expect(lx.DIVIDE): | ||||
|                 if num := self.expect(lx.NUMBER): | ||||
|                     try: | ||||
|                         size = int(num.text) | ||||
|                     except ValueError: | ||||
|                         raise self.make_syntax_error( | ||||
|                             f"Expected integer, got {num.text!r}" | ||||
|                         ) | ||||
|                     else: | ||||
|                         return CacheEffect(tkn.text, size) | ||||
|                 raise self.make_syntax_error("Expected integer") | ||||
|             else: | ||||
|                 # TODO: Arrays, conditions | ||||
|                 return StackEffect(tkn.text) | ||||
|         return self.cache_effect() or self.stack_effect() | ||||
| 
 | ||||
|     def outputs(self) -> list[OutputEffect] | None: | ||||
|         # output (, output)* | ||||
|  | @ -214,8 +199,30 @@ def outputs(self) -> list[OutputEffect] | None: | |||
| 
 | ||||
|     @contextual | ||||
|     def output(self) -> OutputEffect | None: | ||||
|         return self.stack_effect() | ||||
| 
 | ||||
|     @contextual | ||||
|     def cache_effect(self) -> CacheEffect | None: | ||||
|         # IDENTIFIER '/' NUMBER | ||||
|         if tkn := self.expect(lx.IDENTIFIER): | ||||
|             return StackEffect(tkn.text) | ||||
|             if self.expect(lx.DIVIDE): | ||||
|                 num = self.require(lx.NUMBER).text | ||||
|                 try: | ||||
|                     size = int(num) | ||||
|                 except ValueError: | ||||
|                     raise self.make_syntax_error(f"Expected integer, got {num!r}") | ||||
|                 else: | ||||
|                     return CacheEffect(tkn.text, size) | ||||
| 
 | ||||
|     @contextual | ||||
|     def stack_effect(self) -> StackEffect | None: | ||||
|         # IDENTIFIER [':' IDENTIFIER] | ||||
|         # TODO: Arrays, conditions | ||||
|         if tkn := self.expect(lx.IDENTIFIER): | ||||
|             type = "" | ||||
|             if self.expect(lx.COLON): | ||||
|                 type = self.require(lx.IDENTIFIER).text | ||||
|             return StackEffect(tkn.text, type) | ||||
| 
 | ||||
|     @contextual | ||||
|     def super_def(self) -> Super | None: | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Guido van Rossum
						Guido van Rossum