Commit c9cfb3d
authored
Bytecode parity (#7504)
* Match CPython LOAD_SPECIAL stack semantics for with/async-with
LOAD_SPECIAL now pushes (callable, self_or_null) matching CPython's
CALL convention, instead of a single bound method:
- Function descriptors: push (func, self)
- Plain attributes: push (bound, NULL)
Updated all with-statement paths:
- Entry: add SWAP 3 after SWAP 2, remove PUSH_NULL before CALL 0
- Normal exit: remove PUSH_NULL before CALL 3
- Exception handler (WITH_EXCEPT_START): read exit_func at TOS-4
and self_or_null at TOS-3
- Suppress block: 3 POP_TOPs after POP_EXCEPT (was 2)
- FBlock exit (preserve_tos): SWAP 3 + SWAP 2 rotation
- UnwindAction::With: remove PUSH_NULL
Stack effects updated: LoadSpecial (2,1), WithExceptStart (7,6)
* Normalize LOAD_FAST_CHECK and JUMP_BACKWARD_NO_INTERRUPT
Add LOAD_FAST_CHECK → LOAD_FAST and JUMP_BACKWARD_NO_INTERRUPT →
JUMP_BACKWARD to opname normalization in dis_dump.py. These are
optimization variants with identical semantics.
* Add EXTENDED_ARG to SKIP_OPS, normalize LOAD_FAST_CHECK and JUMP_BACKWARD_NO_INTERRUPT
* Remove duplicate return-None when block already has return
Skip duplicate_end_returns for blocks that already end with
LOAD_CONST + RETURN_VALUE. Run DCE + unreachable elimination
after duplication to remove the now-unreachable original return
block.
* Improve __static_attributes__ collection accuracy
- Support tuple/list unpacking targets: (self.x, self.y) = val
- Skip @staticmethod and @classmethod decorated methods
- Use scan_target_for_attrs helper for recursive target scanning
* Use method mode for function-local import attribute calls
Function-local imports (scope is Local+IMPORTED) should use method
mode LOAD_ATTR like regular names, not plain mode. Only module/class
scope imports use plain LOAD_ATTR + PUSH_NULL.
* Optimize constant iterable before GET_ITER to LOAD_CONST tuple
Convert BUILD_LIST/SET 0 + LOAD_CONST + LIST_EXTEND/SET_UPDATE + GET_ITER
to just LOAD_CONST (tuple) + GET_ITER, matching CPython's optimization
for constant list/set literals in for-loop iterables.
Also fix is_name_imported to use method mode for function-local imports,
and improve __static_attributes__ accuracy (skip @classmethod/@staticmethod,
handle tuple/list unpacking targets).
* Fix cell variable ordering: parameters first, then alphabetical
CPython orders cell variables with parameter cells first (in
parameter definition order), then non-parameter cells sorted
alphabetically. Previously all cells were sorted alphabetically.
Also add for-loop iterable optimization: constant BUILD_LIST/SET
before GET_ITER is folded to just LOAD_CONST tuple.
* Emit COPY_FREE_VARS before MAKE_CELL matching CPython order
CPython emits COPY_FREE_VARS first, then MAKE_CELL instructions.
Previously RustPython emitted them in reverse order.
* Fix RESUME AfterYield encoding to match CPython 3.14 (value 5)
CPython 3.14 uses RESUME arg=5 for after-yield, not 1.
Also reorder COPY_FREE_VARS before MAKE_CELL and fix cell
variable ordering (parameters first, then alphabetical).
* Address code review feedback from #7481
- Set is_generator flag for generator expressions in scan_comprehension
- Fix posonlyargs priority in collect_static_attributes first param
- Add match statement support to scan_store_attrs
- Fix stale decorator stack comment
- Reorder NOP removal after fold_unary_negative for better collection folding
* Fold constant list/set/tuple literals in compiler
When all elements of a list/set/tuple literal are constants and
there are 3+ elements, fold them into a single constant:
- list: BUILD_LIST 0 + LOAD_CONST (tuple) + LIST_EXTEND 1
- set: BUILD_SET 0 + LOAD_CONST (tuple) + SET_UPDATE 1
- tuple: LOAD_CONST (tuple)
This matches CPython's compiler optimization and fixes the most
common bytecode difference (92/200 sampled files).
Also add bytecode comparison scripts (dis_dump.py, compare_bytecode.py)
for systematic parity tracking.
* Use BUILD_MAP 0 + MAP_ADD for large dicts (>= 16 pairs)
Match CPython's compiler behavior: dicts with 16+ key-value pairs
use BUILD_MAP 0 followed by MAP_ADD for each pair, instead of
pushing all keys/values on the stack and calling BUILD_MAP N.
* Fix clippy warnings and cargo fmt
* fix surrogate1 parent e1ecb87 commit c9cfb3d
File tree
10 files changed
+371
-200
lines changed- crates
- codegen/src
- snapshots
- compiler-core/src/bytecode
- vm/src
10 files changed
+371
-200
lines changedLarge diffs are not rendered by default.
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
191 | 191 | | |
192 | 192 | | |
193 | 193 | | |
| 194 | + | |
194 | 195 | | |
195 | 196 | | |
196 | 197 | | |
| 198 | + | |
| 199 | + | |
197 | 200 | | |
198 | 201 | | |
199 | 202 | | |
| |||
214 | 217 | | |
215 | 218 | | |
216 | 219 | | |
| 220 | + | |
| 221 | + | |
217 | 222 | | |
218 | 223 | | |
219 | 224 | | |
| |||
876 | 881 | | |
877 | 882 | | |
878 | 883 | | |
| 884 | + | |
| 885 | + | |
| 886 | + | |
| 887 | + | |
| 888 | + | |
| 889 | + | |
| 890 | + | |
| 891 | + | |
| 892 | + | |
| 893 | + | |
| 894 | + | |
| 895 | + | |
| 896 | + | |
| 897 | + | |
| 898 | + | |
| 899 | + | |
| 900 | + | |
| 901 | + | |
| 902 | + | |
| 903 | + | |
| 904 | + | |
| 905 | + | |
| 906 | + | |
| 907 | + | |
| 908 | + | |
| 909 | + | |
| 910 | + | |
| 911 | + | |
| 912 | + | |
| 913 | + | |
| 914 | + | |
| 915 | + | |
| 916 | + | |
| 917 | + | |
| 918 | + | |
| 919 | + | |
| 920 | + | |
| 921 | + | |
| 922 | + | |
| 923 | + | |
| 924 | + | |
| 925 | + | |
| 926 | + | |
879 | 927 | | |
880 | 928 | | |
881 | 929 | | |
| |||
1987 | 2035 | | |
1988 | 2036 | | |
1989 | 2037 | | |
| 2038 | + | |
1990 | 2039 | | |
1991 | 2040 | | |
1992 | 2041 | | |
| |||
2010 | 2059 | | |
2011 | 2060 | | |
2012 | 2061 | | |
2013 | | - | |
2014 | | - | |
2015 | | - | |
| 2062 | + | |
| 2063 | + | |
2016 | 2064 | | |
2017 | 2065 | | |
2018 | | - | |
| 2066 | + | |
| 2067 | + | |
| 2068 | + | |
| 2069 | + | |
| 2070 | + | |
| 2071 | + | |
| 2072 | + | |
| 2073 | + | |
| 2074 | + | |
| 2075 | + | |
| 2076 | + | |
| 2077 | + | |
2019 | 2078 | | |
2020 | 2079 | | |
2021 | 2080 | | |
| |||
Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 66 additions & 65 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
2136 | 2136 | | |
2137 | 2137 | | |
2138 | 2138 | | |
| 2139 | + | |
| 2140 | + | |
2139 | 2141 | | |
2140 | 2142 | | |
2141 | 2143 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1020 | 1020 | | |
1021 | 1021 | | |
1022 | 1022 | | |
1023 | | - | |
| 1023 | + | |
1024 | 1024 | | |
1025 | 1025 | | |
1026 | 1026 | | |
| |||
1085 | 1085 | | |
1086 | 1086 | | |
1087 | 1087 | | |
1088 | | - | |
| 1088 | + | |
1089 | 1089 | | |
1090 | 1090 | | |
1091 | 1091 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
290 | 290 | | |
291 | 291 | | |
292 | 292 | | |
293 | | - | |
| 293 | + | |
294 | 294 | | |
295 | 295 | | |
296 | 296 | | |
| |||
302 | 302 | | |
303 | 303 | | |
304 | 304 | | |
305 | | - | |
| 305 | + | |
306 | 306 | | |
307 | 307 | | |
308 | 308 | | |
| |||
0 commit comments