Skip to content

Commit 8d5588d

Browse files
authored
Merge pull request RustPython#2532 from Pluriscient/documentation/common-start
Documentation of VM & Bytecode
2 parents f0e28be + 7881fb8 commit 8d5588d

File tree

4 files changed

+134
-3
lines changed

4 files changed

+134
-3
lines changed

bytecode/src/lib.rs

Lines changed: 89 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,35 +21,51 @@ pub struct Location {
2121
}
2222

2323
impl Location {
24+
/// Creates a new Location object at the given row and column.
25+
///
26+
/// # Example
27+
/// ```
28+
/// use rustpython_bytecode::Location;
29+
/// let loc = Location::new(10, 10);
30+
/// ```
2431
pub fn new(row: usize, column: usize) -> Self {
2532
Location { row, column }
2633
}
2734

35+
/// Current row
2836
pub fn row(&self) -> usize {
2937
self.row
3038
}
3139

40+
/// Current column
3241
pub fn column(&self) -> usize {
3342
self.column
3443
}
3544
}
3645

3746
pub trait Constant: Sized {
3847
type Name: AsRef<str>;
48+
49+
/// Tranforms the given Constant to a BorrowedConstant
3950
fn borrow_constant(&self) -> BorrowedConstant<Self>;
51+
/// Get the data this Constant holds.
4052
fn into_data(self) -> ConstantData {
4153
self.borrow_constant().into_data()
4254
}
55+
/// Map this Constant to a Bag's constant
4356
fn map_constant<Bag: ConstantBag>(self, bag: &Bag) -> Bag::Constant {
4457
bag.make_constant(self.into_data())
4558
}
59+
60+
/// Maps the name for the given Bag.
4661
fn map_name<Bag: ConstantBag>(
4762
name: Self::Name,
4863
bag: &Bag,
4964
) -> <Bag::Constant as Constant>::Name {
5065
bag.make_name_ref(name.as_ref())
5166
}
5267
}
68+
5369
impl Constant for ConstantData {
5470
type Name = String;
5571
fn borrow_constant(&self) -> BorrowedConstant<Self> {
@@ -77,6 +93,7 @@ impl Constant for ConstantData {
7793
}
7894
}
7995

96+
/// A Constant Bag
8097
pub trait ConstantBag: Sized {
8198
type Constant: Constant;
8299
fn make_constant(&self, constant: ConstantData) -> Self::Constant;
@@ -91,6 +108,7 @@ pub trait ConstantBag: Sized {
91108

92109
#[derive(Clone)]
93110
pub struct BasicBag;
111+
94112
impl ConstantBag for BasicBag {
95113
type Constant = ConstantData;
96114
fn make_constant(&self, constant: ConstantData) -> Self::Constant {
@@ -108,13 +126,15 @@ pub struct CodeObject<C: Constant = ConstantData> {
108126
pub instructions: Box<[Instruction]>,
109127
pub locations: Box<[Location]>,
110128
pub flags: CodeFlags,
111-
pub posonlyarg_count: usize, // Number of positional-only arguments
129+
pub posonlyarg_count: usize,
130+
// Number of positional-only arguments
112131
pub arg_count: usize,
113132
pub kwonlyarg_count: usize,
114133
pub source_path: C::Name,
115134
pub first_line_number: usize,
116135
pub max_stacksize: u32,
117-
pub obj_name: C::Name, // Name of the object that created this code object
136+
pub obj_name: C::Name,
137+
// Name of the object that created this code object
118138
pub cell2arg: Option<Box<[isize]>>,
119139
pub constants: Box<[C]>,
120140
#[serde(bound(
@@ -157,6 +177,7 @@ impl CodeFlags {
157177
// XXX: if you add a new instruction that stores a Label, make sure to add it in
158178
// Instruction::label_arg{,_mut}
159179
pub struct Label(pub u32);
180+
160181
impl fmt::Display for Label {
161182
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
162183
self.0.fmt(f)
@@ -176,6 +197,7 @@ pub enum ConversionFlag {
176197
Repr,
177198
}
178199

200+
/// The kind of Raise that occurred.
179201
#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)]
180202
pub enum RaiseKind {
181203
Reraise,
@@ -188,11 +210,15 @@ pub type NameIdx = u32;
188210
/// A Single bytecode instruction.
189211
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
190212
pub enum Instruction {
213+
/// Importing by name
191214
ImportName {
192215
idx: NameIdx,
193216
},
217+
/// Importing without name
194218
ImportNameless,
219+
/// Import *
195220
ImportStar,
221+
/// from ... import ...
196222
ImportFrom {
197223
idx: NameIdx,
198224
},
@@ -412,6 +438,15 @@ bitflags! {
412438
}
413439
}
414440

441+
/// A Constant (which usually encapsulates data within it)
442+
///
443+
/// # Examples
444+
/// ```
445+
/// use rustpython_bytecode::ConstantData;
446+
/// let a = ConstantData::Float {value: 120f64};
447+
/// let b = ConstantData::Boolean {value: false};
448+
/// assert_ne!(a, b);
449+
/// ```
415450
#[derive(Debug, Clone, Serialize, Deserialize)]
416451
pub enum ConstantData {
417452
Tuple { elements: Vec<ConstantData> },
@@ -448,6 +483,7 @@ impl PartialEq for ConstantData {
448483
}
449484
}
450485
}
486+
451487
impl Eq for ConstantData {}
452488

453489
impl hash::Hash for ConstantData {
@@ -472,6 +508,7 @@ impl hash::Hash for ConstantData {
472508
}
473509
}
474510

511+
/// A borrowed Constant
475512
pub enum BorrowedConstant<'a, C: Constant> {
476513
Integer { value: &'a BigInt },
477514
Float { value: f64 },
@@ -484,7 +521,9 @@ pub enum BorrowedConstant<'a, C: Constant> {
484521
None,
485522
Ellipsis,
486523
}
524+
487525
type BorrowedTupleIter<'a, C> = Box<dyn Iterator<Item = BorrowedConstant<'a, C>> + 'a>;
526+
488527
impl<C: Constant> BorrowedConstant<'_, C> {
489528
// takes `self` because we need to consume the iterator
490529
pub fn fmt_display(self, f: &mut fmt::Formatter) -> fmt::Result {
@@ -542,6 +581,7 @@ impl<C: Constant> BorrowedConstant<'_, C> {
542581
}
543582
}
544583

584+
/// The possible comparison operators
545585
#[derive(Debug, Copy, Clone, PartialEq, Serialize, Deserialize)]
546586
pub enum ComparisonOperator {
547587
Greater,
@@ -554,9 +594,18 @@ pub enum ComparisonOperator {
554594
NotIn,
555595
Is,
556596
IsNot,
597+
/// two exceptions that match?
557598
ExceptionMatch,
558599
}
559600

601+
/// The possible Binary operators
602+
/// # Examples
603+
///
604+
/// ```
605+
/// use rustpython_bytecode::Instruction::BinaryOperation;
606+
/// use rustpython_bytecode::BinaryOperator::Add;
607+
/// let op = BinaryOperation {op: Add};
608+
/// ```
560609
#[derive(Debug, Copy, Clone, PartialEq, Serialize, Deserialize)]
561610
pub enum BinaryOperator {
562611
Power,
@@ -574,6 +623,7 @@ pub enum BinaryOperator {
574623
Or,
575624
}
576625

626+
/// The possible unary operators
577627
#[derive(Debug, Copy, Clone, PartialEq, Serialize, Deserialize)]
578628
pub enum UnaryOperator {
579629
Not,
@@ -590,6 +640,7 @@ pub enum BlockType {
590640
}
591641
*/
592642

643+
/// Argument structure
593644
pub struct Arguments<'a, N: AsRef<str>> {
594645
pub posonlyargs: &'a [N],
595646
pub args: &'a [N],
@@ -616,7 +667,8 @@ impl<N: AsRef<str>> fmt::Debug for Arguments<'_, N> {
616667
}
617668

618669
impl<C: Constant> CodeObject<C> {
619-
// like inspect.getargs
670+
/// Get all arguments of the code object
671+
/// like inspect.getargs
620672
pub fn arg_names(&self) -> Arguments<C::Name> {
621673
let nargs = self.arg_count;
622674
let nkwargs = self.kwonlyarg_count;
@@ -647,6 +699,7 @@ impl<C: Constant> CodeObject<C> {
647699
}
648700
}
649701

702+
/// Return the labels targeted by the instructions of this CodeObject
650703
pub fn label_targets(&self) -> BTreeSet<Label> {
651704
let mut label_targets = BTreeSet::new();
652705
for instruction in &*self.instructions {
@@ -689,6 +742,7 @@ impl<C: Constant> CodeObject<C> {
689742
Ok(())
690743
}
691744

745+
/// Recursively display this CodeObject
692746
pub fn display_expand_codeobjects(&self) -> impl fmt::Display + '_ {
693747
struct Display<'a, C: Constant>(&'a CodeObject<C>);
694748
impl<C: Constant> fmt::Display for Display<'_, C> {
@@ -699,6 +753,7 @@ impl<C: Constant> CodeObject<C> {
699753
Display(self)
700754
}
701755

756+
/// Map this CodeObject to one that holds a Bag::Constant
702757
pub fn map_bag<Bag: ConstantBag>(self, bag: &Bag) -> CodeObject<Bag::Constant> {
703758
let map_names = |names: Box<[C::Name]>| {
704759
names
@@ -733,6 +788,7 @@ impl<C: Constant> CodeObject<C> {
733788
}
734789
}
735790

791+
/// Same as `map_bag` but clones `self`
736792
pub fn map_clone_bag<Bag: ConstantBag>(&self, bag: &Bag) -> CodeObject<Bag::Constant> {
737793
let map_names = |names: &[C::Name]| {
738794
names
@@ -766,12 +822,16 @@ impl<C: Constant> CodeObject<C> {
766822
}
767823
}
768824

825+
/// Error that occurs during code deserialization
769826
#[derive(Debug)]
770827
#[non_exhaustive]
771828
pub enum CodeDeserializeError {
829+
/// Unexpected End Of File
772830
Eof,
831+
/// Invalid Bytecode
773832
Other,
774833
}
834+
775835
impl fmt::Display for CodeDeserializeError {
776836
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
777837
match self {
@@ -780,6 +840,7 @@ impl fmt::Display for CodeDeserializeError {
780840
}
781841
}
782842
}
843+
783844
impl std::error::Error for CodeDeserializeError {}
784845

785846
impl CodeObject<ConstantData> {
@@ -862,13 +923,35 @@ impl Instruction {
862923
}
863924
}
864925

926+
/// Whether this is an unconditional branching
927+
///
928+
/// # Examples
929+
///
930+
/// ```
931+
/// use rustpython_bytecode::{Instruction, Label};
932+
/// let label = Label(0xF);
933+
/// let jump_inst = Instruction::Jump {target: label};
934+
/// assert!(jump_inst.unconditional_branch())
935+
/// ```
865936
pub fn unconditional_branch(&self) -> bool {
866937
matches!(
867938
self,
868939
Jump { .. } | Continue { .. } | Break | ReturnValue | Raise { .. }
869940
)
870941
}
871942

943+
/// What effect this instruction has on the stack
944+
///
945+
/// # Examples
946+
///
947+
/// ```
948+
/// use rustpython_bytecode::{Instruction, Label, UnaryOperator};
949+
/// let jump_instruction = Instruction::Jump {target: Label(0xF)};
950+
/// let invert_instruction = Instruction::UnaryOperation {op: UnaryOperator::Invert};
951+
/// assert_eq!(jump_instruction.stack_effect(true), 0);
952+
/// assert_eq!(invert_instruction.stack_effect(false), 0);
953+
/// ```
954+
///
872955
pub fn stack_effect(&self, jump: bool) -> i32 {
873956
match self {
874957
ImportName { .. } | ImportNameless => -1,
@@ -1154,6 +1237,7 @@ impl<C: Constant> fmt::Debug for CodeObject<C> {
11541237
}
11551238
}
11561239

1240+
/// A frozen module. Holds a code object and whether it is part of a package
11571241
#[derive(Serialize, Deserialize, Debug)]
11581242
pub struct FrozenModule<C: Constant = ConstantData> {
11591243
#[serde(bound(
@@ -1170,6 +1254,7 @@ pub mod frozen_lib {
11701254
use std::convert::TryInto;
11711255
use std::io;
11721256

1257+
/// Decode a library to a iterable of frozen modules
11731258
pub fn decode_lib(bytes: &[u8]) -> FrozenModulesIter {
11741259
let data = lz4_flex::decompress_size_prepended(bytes).unwrap();
11751260
let r = VecReader { data, pos: 0 };
@@ -1207,6 +1292,7 @@ pub mod frozen_lib {
12071292

12081293
impl ExactSizeIterator for FrozenModulesIter {}
12091294

1295+
/// Encode the given iterator of frozen modules into a compressed vector of bytes
12101296
pub fn encode_lib<'a, I>(lib: I) -> Vec<u8>
12111297
where
12121298
I: IntoIterator<Item = (&'a str, &'a FrozenModule)>,

common/src/float_ops.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,22 @@ pub fn ufrexp(value: f64) -> (f64, i32) {
1313
}
1414
}
1515

16+
/// Equate an integer to a float.
17+
///
18+
/// Returns true if and only if, when converted to each others types, both are equal.
19+
///
20+
/// # Examples
21+
///
22+
/// ```
23+
/// use num_bigint::BigInt;
24+
/// use rustpython_common::float_ops::eq_int;
25+
/// let a = 1.0f64;
26+
/// let b = BigInt::from(1);
27+
/// let c = 2.0f64;
28+
/// assert!(eq_int(a, &b));
29+
/// assert!(!eq_int(c, &b));
30+
/// ```
31+
///
1632
pub fn eq_int(value: f64, other: &BigInt) -> bool {
1733
if let (Some(self_int), Some(other_float)) = (value.to_bigint(), other.to_f64()) {
1834
value == other_float && self_int == *other

derive/src/compile_bytecode.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,11 @@ static CARGO_MANIFEST_DIR: Lazy<PathBuf> = Lazy::new(|| {
3232
});
3333

3434
enum CompilationSourceKind {
35+
/// Source is a File (Path)
3536
File(PathBuf),
37+
/// Direct Raw sourcecode
3638
SourceCode(String),
39+
/// Source is a directory
3740
Dir(PathBuf),
3841
}
3942

0 commit comments

Comments
 (0)