v8/
isolate_create_params.rs1use crate::ExternalReference;
2use crate::array_buffer;
3use crate::array_buffer::Allocator as ArrayBufferAllocator;
4use crate::cppgc::Heap;
5use crate::snapshot::RawStartupData;
6use crate::snapshot::StartupData;
7use crate::support::Opaque;
8use crate::support::SharedPtr;
9use crate::support::UniqueRef;
10use crate::support::char;
11use crate::support::int;
12use crate::support::intptr_t;
13
14use std::any::Any;
15use std::borrow::Cow;
16use std::iter::once;
17use std::mem::MaybeUninit;
18use std::mem::size_of;
19use std::ptr::null;
20
21pub type CounterLookupCallback =
24 unsafe extern "C" fn(name: *const char) -> *mut i32;
25
26#[must_use]
28#[derive(Debug, Default)]
29pub struct CreateParams {
30 raw: raw::CreateParams,
31 allocations: CreateParamAllocations,
32}
33
34impl CreateParams {
35 pub fn counter_lookup_callback(
38 mut self,
39 callback: CounterLookupCallback,
40 ) -> Self {
41 self.raw.counter_lookup_callback = Some(callback);
42 self
43 }
44
45 pub fn snapshot_blob(mut self, data: StartupData) -> Self {
47 let header = Box::new(RawStartupData {
48 data: data.as_ptr() as _,
49 raw_size: data.len() as _,
50 });
51 self.raw.snapshot_blob = &*header;
52 self.allocations.snapshot_blob_data = Some(data);
53 self.allocations.snapshot_blob_header = Some(header);
54 self
55 }
56
57 pub fn array_buffer_allocator(
60 mut self,
61 array_buffer_allocator: impl Into<SharedPtr<ArrayBufferAllocator>>,
62 ) -> Self {
63 self.raw.array_buffer_allocator_shared = array_buffer_allocator.into();
64 self
65 }
66
67 pub fn has_set_array_buffer_allocator(&self) -> bool {
71 !self.raw.array_buffer_allocator_shared.is_null()
72 }
73
74 pub fn external_references(
79 mut self,
80 ext_refs: Cow<'static, [ExternalReference]>,
81 ) -> Self {
82 let ext_refs = if ext_refs.last()
83 == Some(&ExternalReference {
84 pointer: std::ptr::null_mut(),
85 }) {
86 ext_refs
87 } else {
88 Cow::from(
89 ext_refs
90 .into_owned()
91 .into_iter()
92 .chain(once(ExternalReference {
93 pointer: std::ptr::null_mut(),
94 }))
95 .collect::<Vec<_>>(),
96 )
97 };
98
99 self.allocations.external_references = Some(ext_refs);
100 self.raw.external_references = self
101 .allocations
102 .external_references
103 .as_ref()
104 .map(|c| c.as_ptr() as _)
105 .unwrap_or_else(null);
106
107 self
108 }
109
110 pub fn allow_atomics_wait(mut self, value: bool) -> Self {
113 self.raw.allow_atomics_wait = value;
114 self
115 }
116
117 pub fn embedder_wrapper_type_info_offsets(
121 mut self,
122 embedder_wrapper_type_index: int,
123 embedder_wrapper_object_index: int,
124 ) -> Self {
125 self.raw.embedder_wrapper_type_index = embedder_wrapper_type_index;
126 self.raw.embedder_wrapper_object_index = embedder_wrapper_object_index;
127 self
128 }
129
130 pub fn heap_limits(mut self, initial: usize, max: usize) -> Self {
152 self
153 .raw
154 .constraints
155 .configure_defaults_from_heap_size(initial, max);
156 self
157 }
158
159 pub fn heap_limits_from_system_memory(
179 mut self,
180 physical_memory: u64,
181 virtual_memory_limit: u64,
182 ) -> Self {
183 self
184 .raw
185 .constraints
186 .configure_defaults(physical_memory, virtual_memory_limit);
187 self
188 }
189
190 pub fn cpp_heap(mut self, heap: UniqueRef<Heap>) -> Self {
193 self.raw.cpp_heap = heap.into_raw();
194 self
195 }
196
197 pub(crate) fn finalize(mut self) -> (raw::CreateParams, Box<dyn Any>) {
198 if self.raw.array_buffer_allocator_shared.is_null() {
199 self = self.array_buffer_allocator(array_buffer::new_default_allocator());
200 }
201 let Self { raw, allocations } = self;
202 (raw, Box::new(allocations))
203 }
204}
205
206#[derive(Debug, Default)]
207struct CreateParamAllocations {
208 snapshot_blob_data: Option<StartupData>,
210 snapshot_blob_header: Option<Box<RawStartupData>>,
214 external_references: Option<Cow<'static, [ExternalReference]>>,
215}
216
217#[test]
218fn create_param_defaults() {
219 let params = CreateParams::default();
220 assert_eq!(params.raw.embedder_wrapper_type_index, -1);
221 assert_eq!(params.raw.embedder_wrapper_object_index, -1);
222 assert!(params.raw.allow_atomics_wait);
223}
224
225pub(crate) mod raw {
226 use super::*;
227
228 #[repr(C)]
229 #[derive(Debug)]
230 pub(crate) struct CreateParams {
231 pub code_event_handler: *const Opaque, pub constraints: ResourceConstraints,
233 pub snapshot_blob: *const RawStartupData,
234 pub counter_lookup_callback: Option<CounterLookupCallback>,
235 pub create_histogram_callback: *const Opaque, pub add_histogram_sample_callback: *const Opaque, pub array_buffer_allocator: *mut ArrayBufferAllocator,
238 pub array_buffer_allocator_shared: SharedPtr<ArrayBufferAllocator>,
239 pub external_references: *const intptr_t,
240 pub allow_atomics_wait: bool,
241 pub embedder_wrapper_type_index: int,
242 pub embedder_wrapper_object_index: int,
243 _fatal_error_handler: *const Opaque, _oom_error_handler: *const Opaque, pub cpp_heap: *const Heap,
246 }
247
248 unsafe extern "C" {
249 fn v8__Isolate__CreateParams__CONSTRUCT(
250 buf: *mut MaybeUninit<CreateParams>,
251 );
252 fn v8__Isolate__CreateParams__SIZEOF() -> usize;
253 }
254
255 impl Default for CreateParams {
256 fn default() -> Self {
257 let size = unsafe { v8__Isolate__CreateParams__SIZEOF() };
258 assert_eq!(size, size_of::<Self>());
259 let mut buf = MaybeUninit::<Self>::uninit();
260 unsafe { v8__Isolate__CreateParams__CONSTRUCT(&mut buf) };
261 unsafe { buf.assume_init() }
262 }
263 }
264
265 #[repr(C)]
266 #[derive(Debug)]
267 pub(crate) struct ResourceConstraints {
268 code_range_size_: usize,
269 max_old_generation_size_: usize,
270 max_young_generation_size_: usize,
271 initial_old_generation_size_: usize,
272 initial_young_generation_size_: usize,
273 physical_memory_size_: u64,
274 stack_limit_: *mut u32,
275 }
276
277 unsafe extern "C" {
278 fn v8__ResourceConstraints__ConfigureDefaultsFromHeapSize(
279 constraints: *mut ResourceConstraints,
280 initial_heap_size_in_bytes: usize,
281 maximum_heap_size_in_bytes: usize,
282 );
283 fn v8__ResourceConstraints__ConfigureDefaults(
284 constraints: *mut ResourceConstraints,
285 physical_memory: u64,
286 virtual_memory_limit: u64,
287 );
288 }
289
290 impl ResourceConstraints {
291 pub fn configure_defaults_from_heap_size(
292 &mut self,
293 initial_heap_size_in_bytes: usize,
294 maximum_heap_size_in_bytes: usize,
295 ) {
296 unsafe {
297 v8__ResourceConstraints__ConfigureDefaultsFromHeapSize(
298 self,
299 initial_heap_size_in_bytes,
300 maximum_heap_size_in_bytes,
301 );
302 };
303 }
304
305 pub fn configure_defaults(
306 &mut self,
307 physical_memory: u64,
308 virtual_memory_limit: u64,
309 ) {
310 unsafe {
311 v8__ResourceConstraints__ConfigureDefaults(
312 self,
313 physical_memory,
314 virtual_memory_limit,
315 );
316 }
317 }
318 }
319}