Get the variable name for a localsplus index.
(&self, idx: usize)
| 1962 | |
| 1963 | /// Get the variable name for a localsplus index. |
| 1964 | fn localsplus_name(&self, idx: usize) -> &'static PyStrInterned { |
| 1965 | use rustpython_compiler_core::bytecode::{CO_FAST_CELL, CO_FAST_FREE, CO_FAST_LOCAL}; |
| 1966 | let nlocals = self.code.varnames.len(); |
| 1967 | let kind = self.code.localspluskinds.get(idx).copied().unwrap_or(0); |
| 1968 | if kind & CO_FAST_LOCAL != 0 { |
| 1969 | // Merged cell or regular local: name is in varnames |
| 1970 | self.code.varnames[idx] |
| 1971 | } else if kind & CO_FAST_FREE != 0 { |
| 1972 | // Free var: slots are at the end of localsplus |
| 1973 | let nlocalsplus = self.code.localspluskinds.len(); |
| 1974 | let nfrees = self.code.freevars.len(); |
| 1975 | let free_start = nlocalsplus - nfrees; |
| 1976 | self.code.freevars[idx - free_start] |
| 1977 | } else if kind & CO_FAST_CELL != 0 { |
| 1978 | // Non-merged cell: count how many non-merged cell slots are before |
| 1979 | // this index to find the corresponding cellvars entry. |
| 1980 | // Non-merged cellvars appear in their original order (skipping merged ones). |
| 1981 | let nonmerged_pos = self.code.localspluskinds[nlocals..idx] |
| 1982 | .iter() |
| 1983 | .filter(|&&k| k == CO_FAST_CELL) |
| 1984 | .count(); |
| 1985 | // Skip merged cellvars to find the right one |
| 1986 | let mut cv_idx = 0; |
| 1987 | let mut nonmerged_count = 0; |
| 1988 | for (i, name) in self.code.cellvars.iter().enumerate() { |
| 1989 | let is_merged = self.code.varnames.contains(name); |
| 1990 | if !is_merged { |
| 1991 | if nonmerged_count == nonmerged_pos { |
| 1992 | cv_idx = i; |
| 1993 | break; |
| 1994 | } |
| 1995 | nonmerged_count += 1; |
| 1996 | } |
| 1997 | } |
| 1998 | self.code.cellvars[cv_idx] |
| 1999 | } else { |
| 2000 | self.code.varnames[idx] |
| 2001 | } |
| 2002 | } |
| 2003 | |
| 2004 | /// Execute a single instruction. |
| 2005 | #[inline(always)] |