1#![doc = include_str!("readme.md")]
2use crate::instructions::PythonInstruction;
3use serde::{Deserialize, Serialize};
4use std::fmt::Debug;
5
6#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
8pub enum PythonVersion {
9 #[default]
10 Unknown,
12 Python3_7,
14 Python3_8,
16 Python3_9,
18 Python3_10,
20 Python3_11,
22 Python3_12,
24 Python3_13,
26 Python3_14,
28}
29
30impl PythonVersion {
31 pub fn from_magic(magic: [u8; 4]) -> Self {
34 match magic {
35 [66, 13, 13, 10] => PythonVersion::Python3_7,
37 [85, 13, 13, 10] => PythonVersion::Python3_8,
39 [97, 13, 13, 10] => PythonVersion::Python3_9,
41 [112, 13, 13, 10] => PythonVersion::Python3_10,
43 [168, 13, 13, 10] => PythonVersion::Python3_11,
45 [203, 13, 13, 10] => PythonVersion::Python3_12,
47 [243, 13, 13, 10] => PythonVersion::Python3_13,
49 [43, 14, 13, 10] => PythonVersion::Python3_14,
51 _ => PythonVersion::Unknown,
52 }
53 }
54
55 pub fn as_magic(&self) -> [u8; 4] {
57 match self {
58 PythonVersion::Python3_7 => [66, 13, 13, 10],
60 PythonVersion::Python3_8 => [85, 13, 13, 10],
62 PythonVersion::Python3_9 => [97, 13, 13, 10],
64 PythonVersion::Python3_10 => [112, 13, 13, 10],
66 PythonVersion::Python3_11 => [168, 13, 13, 10],
68 PythonVersion::Python3_12 => [203, 13, 13, 10],
70 PythonVersion::Python3_13 => [243, 13, 13, 10],
72 PythonVersion::Python3_14 => [43, 14, 13, 10],
74 PythonVersion::Unknown => [0, 0, 0, 0],
75 }
76 }
77}
78
79#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
81pub struct PycHeader {
82 pub magic: [u8; 4],
84 pub flags: u32,
86 pub timestamp: u32,
88 pub size: u32,
90}
91
92impl Default for PycHeader {
93 fn default() -> Self {
94 Self { magic: [0; 4], flags: 0, timestamp: 0, size: 0 }
95 }
96}
97
98#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
100pub struct Upvalue {
101 pub in_stack: u8,
103 pub idx: u8,
105 pub name: String,
107}
108
109#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
111pub struct LocalVar {
112 pub name: String,
114 pub start_pc: u32,
116 pub end_pc: u32,
118}
119
120#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default)]
122pub enum PythonObject {
123 Str(String),
125 Int(i32),
127 Integer(i64),
129 Float(f64),
131 Bool(bool),
133 String(String),
135 List(Vec<PythonObject>),
137 Tuple(Vec<PythonObject>),
139 Bytes(Vec<u8>),
141 Code(PythonCodeObject),
143 #[default]
144 None,
146}
147
148#[derive(Debug, Clone, PartialEq, Default, Serialize, Deserialize)]
150pub struct PythonCodeObject {
151 pub name: String,
153 pub qualname: String,
155 pub source_name: String,
157 pub first_line: u32,
159 pub last_line: u32,
161 pub co_argcount: u8,
163 pub co_posonlyargcount: u8,
165 pub co_kwonlyargcount: u8,
167 pub co_nlocals: u8,
169 pub co_stacksize: u8,
171 pub co_flags: u32,
173 pub co_code: Vec<PythonInstruction>,
175 pub co_consts: Vec<PythonObject>,
177 pub co_names: Vec<String>,
179 pub co_localsplusnames: Vec<String>,
181 pub co_localspluskinds: Vec<u8>,
183 pub co_linetable: Vec<u8>,
185 pub co_exceptiontable: Vec<u8>,
187}
188
189#[derive(Debug, Clone, PartialEq, Default, Serialize, Deserialize)]
192pub struct PythonProgram {
193 pub header: PycHeader,
195 pub code_object: PythonCodeObject,
197 pub version: PythonVersion,
199}