cairo_lang_executable/
executable.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
use cairo_lang_casm::assembler::AssembledCairoProgram;
use cairo_lang_casm::casm;
use cairo_vm::types::builtin_name::BuiltinName;
use itertools::chain;
use serde::{Deserialize, Serialize};

use crate::compile::CompiledFunction;

/// Structure to hold the executable represenstation of a program.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Executable {
    /// The bytecode of the program.
    pub program: AssembledCairoProgram,
    /// The available entrypoints for the program.
    pub entrypoints: Vec<ExecutableEntryPoint>,
}

impl Executable {
    /// Create a new executable program from a compiled function.
    pub fn new(compiled: CompiledFunction) -> Self {
        let non_returning_header = casm! {
            ap += (compiled.wrapper.builtins.len());
            call rel 4;
            jmp rel 0;
        };
        Self {
            program: compiled.program.assemble_ex(
                chain!(&non_returning_header.instructions, &compiled.wrapper.header),
                &compiled.wrapper.footer,
            ),
            entrypoints: vec![
                ExecutableEntryPoint {
                    builtins: compiled.wrapper.builtins.clone(),
                    offset: 0,
                    kind: EntryPointKind::NonReturning,
                },
                ExecutableEntryPoint {
                    builtins: compiled.wrapper.builtins,
                    offset: non_returning_header.current_code_offset,
                    kind: EntryPointKind::Function,
                },
            ],
        }
    }
}

/// Information about a executable entrypoint.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ExecutableEntryPoint {
    /// The used builtins of the function.
    pub builtins: Vec<BuiltinName>,
    /// The offset of the entrypoint in the bytecode.
    pub offset: usize,
    /// The kind of the entrypoint.
    pub kind: EntryPointKind,
}

/// The kind of an entrypoint.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum EntryPointKind {
    /// The entrypoint is a function, ending with a `ret`, expecting the builtins as its parameters.
    Function,
    /// The entrypoint starts with `ap += <builtins.len()>` and expected the builtins to be injected
    /// there, and ends with an infinite loop.
    NonReturning,
}