fluentbase_runtime/
context_wrapper.rs1use crate::{syscall_handler::*, RuntimeContext};
2use alloc::borrow::Cow;
3use fluentbase_types::{BytecodeOrHash, ExitCode, NativeAPI, UnwrapExitCode};
4use std::cell::RefCell;
5
6#[derive(Default)]
7pub struct RuntimeContextWrapper {
8 pub ctx: RefCell<RuntimeContext>,
9}
10
11impl RuntimeContextWrapper {
12 pub fn new(ctx: RuntimeContext) -> Self {
13 Self {
14 ctx: RefCell::new(ctx),
15 }
16 }
17 pub fn into_inner(self) -> RuntimeContext {
18 self.ctx.into_inner()
19 }
20}
21
22impl NativeAPI for RuntimeContextWrapper {
23 fn exit(&self, exit_code: ExitCode) -> ! {
24 syscall_exit_impl(&mut self.ctx.borrow_mut(), exit_code).unwrap_exit_code();
25 unreachable!("exit code: {}", exit_code)
26 }
27
28 fn state(&self) -> u32 {
29 syscall_state_impl(&self.ctx.borrow())
30 }
31
32 fn read(&self, target: &mut [u8], offset: u32) {
33 let result =
34 syscall_read_input_impl(&mut self.ctx.borrow_mut(), offset, target.len() as u32)
35 .unwrap();
36 target.copy_from_slice(&result);
37 }
38
39 fn input_size(&self) -> u32 {
40 syscall_input_size_impl(&self.ctx.borrow())
41 }
42
43 fn write(&self, value: &[u8]) {
44 syscall_write_output_impl(&mut self.ctx.borrow_mut(), value)
45 }
46
47 fn output_size(&self) -> u32 {
48 syscall_output_size_impl(&self.ctx.borrow())
49 }
50
51 fn read_output(&self, target: &mut [u8], offset: u32) {
52 let result =
53 syscall_read_output_impl(&mut self.ctx.borrow_mut(), offset, target.len() as u32)
54 .unwrap();
55 target.copy_from_slice(&result);
56 }
57
58 fn exec(
59 &self,
60 code_hash: BytecodeOrHash,
61 input: Cow<'_, [u8]>,
62 fuel_limit: Option<u64>,
63 state: u32,
64 ) -> (u64, i64, i32) {
65 let (fuel_consumed, fuel_refunded, exit_code) = syscall_exec_impl(
66 &mut self.ctx.borrow_mut(),
67 code_hash,
68 input,
69 fuel_limit.unwrap_or(u64::MAX),
70 state,
71 );
72 (fuel_consumed, fuel_refunded, exit_code)
73 }
74
75 fn resume(
76 &self,
77 call_id: u32,
78 return_data: &[u8],
79 exit_code: i32,
80 fuel_consumed: u64,
81 fuel_refunded: i64,
82 ) -> (u64, i64, i32) {
83 let (fuel_consumed, fuel_refunded, exit_code) = syscall_resume_impl(
84 &mut self.ctx.borrow_mut(),
85 call_id,
86 return_data,
87 exit_code,
88 fuel_consumed,
89 fuel_refunded,
90 0,
91 )
92 .unwrap_exit_code();
93 (fuel_consumed, fuel_refunded, exit_code)
94 }
95
96 fn forward_output(&self, offset: u32, len: u32) {
97 syscall_forward_output_impl(&mut self.ctx.borrow_mut(), offset, len).unwrap_exit_code()
98 }
99
100 #[inline(always)]
101 fn fuel(&self) -> u64 {
102 syscall_fuel_impl(&self.ctx.borrow())
103 }
104
105 fn debug_log(message: &str) {
106 syscall_debug_log_impl(message.as_bytes())
107 }
108
109 fn charge_fuel(&self, fuel_consumed: u64) {
110 syscall_charge_fuel_impl(&mut self.ctx.borrow_mut(), fuel_consumed).unwrap();
111 }
112
113 fn enter_unconstrained(&self) {
114 syscall_enter_leave_unconstrained_impl(&mut self.ctx.borrow_mut());
115 }
116
117 fn exit_unconstrained(&self) {
118 syscall_enter_leave_unconstrained_impl(&mut self.ctx.borrow_mut());
119 }
120
121 fn write_fd(&self, fd: u32, slice: &[u8]) {
122 syscall_write_fd_impl(&mut self.ctx.borrow_mut(), fd, slice).unwrap_exit_code();
123 }
124}