Skip to main content

nifty_codegen/compile/
runtime.rs

1//! The runtime calls compiled code makes, each imported once with its C signature.
2
3use cranelift_codegen::ir::types::{F64, I8, I32, I64};
4use cranelift_module::{DataId, FuncId, Module};
5use nifty_rt::symbols;
6
7use crate::CodegenError;
8use crate::emit::Emitter;
9
10/// Pointers and slots are both 64 bits on the systems Nifty runs on.
11const P: cranelift_codegen::ir::Type = I64;
12const S: cranelift_codegen::ir::Type = I64;
13/// `bool` results.
14const B: cranelift_codegen::ir::Type = I8;
15/// `u32` ids: states, spans, views, lists, functions and windows, and dialog kinds and
16/// window actions.
17const U: cranelift_codegen::ir::Type = I32;
18
19macro_rules! runtime {
20    ($($field:ident = $symbol:ident ($($param:expr),*) $(-> $result:expr)?;)*) => {
21        #[derive(Debug)]
22        pub(super) struct Runtime {
23            $(pub $field: FuncId,)*
24            pub int: DataId,
25            pub float: DataId,
26            pub bool: DataId,
27            pub string: DataId,
28        }
29
30        impl Runtime {
31            pub fn import<M: Module>(emitter: &mut Emitter<M>) -> Result<Self, CodegenError> {
32                Ok(Self {
33                    $($field: {
34                        let signature = emitter.signature(&[$($param),*], &[$($result)?]);
35                        emitter.import_function(symbols::$symbol, &signature)?
36                    },)*
37                    int: emitter.import_data(symbols::TYPE_INT)?,
38                    float: emitter.import_data(symbols::TYPE_FLOAT)?,
39                    bool: emitter.import_data(symbols::TYPE_BOOL)?,
40                    string: emitter.import_data(symbols::TYPE_STRING)?,
41                })
42            }
43        }
44    };
45}
46
47runtime! {
48    retain = RETAIN(S, P);
49    release = RELEASE(S, P);
50    equal = EQUAL(S, S, P) -> B;
51    store = STORE(P, S, P);
52    float_rem = FLOAT_REM(F64, F64) -> F64;
53    string_new = STRING_NEW(P, I64) -> S;
54    string_concat = STRING_CONCAT(S, S) -> S;
55    string_len = STRING_LEN(S) -> I64;
56    string_compare = STRING_COMPARE(S, S) -> I32;
57    text_new = TEXT_NEW() -> P;
58    text_push_str = TEXT_PUSH_STR(P, P, I64);
59    text_push = TEXT_PUSH(P, S, P);
60    text_finish = TEXT_FINISH(P) -> S;
61    list_new = LIST_NEW(P, P, I64) -> S;
62    list_len = LIST_LEN(S) -> I64;
63    list_get = LIST_GET(P, S, I64, U, P) -> B;
64    list_push = LIST_PUSH(P, S);
65    list_remove = LIST_REMOVE(P, P, I64, U) -> B;
66    list_item_mut = LIST_ITEM_MUT(P, P, I64, U, P) -> B;
67    struct_new = STRUCT_NEW(P, P) -> S;
68    struct_get = STRUCT_GET(S, I64) -> S;
69    struct_field_mut = STRUCT_FIELD_MUT(P, I64) -> P;
70    state = STATE(P, U) -> S;
71    state_mut = STATE_MUT(P, U) -> P;
72    enter = ENTER(P, U, U) -> B;
73    leave = LEAVE(P);
74    fail_divide_by_zero = FAIL_DIVIDE_BY_ZERO(P, U);
75    fail_too_large = FAIL_TOO_LARGE(P, U);
76    fail_download_into_variable = FAIL_DOWNLOAD_INTO_VARIABLE(P, U);
77    fail_dialog_into_variable = FAIL_DIALOG_INTO_VARIABLE(P, U);
78    show_same = SHOW_SAME(P, U);
79    show_item = SHOW_ITEM(P, U) -> P;
80    show_view = SHOW_VIEW(P, U) -> P;
81    download = DOWNLOAD(P, P, U) -> B;
82    format_bytes = FORMAT_BYTES(I64) -> S;
83    download_command = DOWNLOAD_COMMAND(P, U, S);
84    pick = PICK(P, U, P, S, S, S, S, U) -> B;
85    window = WINDOW(P, U, U);
86}