Skip to main content

oxilean_kernel/no_std_compat/
functions.rs

1//! Auto-generated module
2//!
3//! 🤖 Generated with [SplitRS](https://github.com/cool-japan/splitrs)
4
5use super::types::{
6    AddrRange, AllocConfig, AllocStats, AtomicVersion, Budget, BuildInfo, BumpAlloc, ByteOrder,
7    CapabilitySet, CfgSnapshot, CodeSection, CompatLayer, CompatMatrix, CompatibilityReport,
8    CompileFlags, ConditionalInit, CounterCell, CrossPlatformTimer, ErrorCode, FeatureFlags,
9    InstructionBuffer, LibraryManifest, LinearScanAllocator, MemoryLayout, ObjectFile, OsResource,
10    PageMap, PlatformCaps, PlatformInfo, RelocEntry, RuntimeVersion, ScratchBuffer, ShimRegistry,
11    SpinFlag, StackGuard, StaticStr, StdCompat, SymbolTable, VersionConstraint, WasmFeatureSet,
12    WasmMemRegion, WasmMemTable,
13};
14
15/// Macro that documents what would change in a `no_std` build.
16///
17/// In std mode this expands to nothing. In a hypothetical `no_std` build,
18/// the `$no_std_block` would be active instead of `$std_block`.
19#[macro_export]
20macro_rules! cfg_if_std {
21    (if_std { $($std_item:item)* } else { $($no_std_item:item)* }) => {
22        $($std_item)*
23    };
24}
25#[cfg(test)]
26mod tests {
27    use super::*;
28    #[test]
29    fn test_std_compat_alloc_types() {
30        let types = StdCompat::required_alloc_types();
31        assert!(types.contains(&"Vec"));
32        assert!(types.contains(&"HashMap"));
33        assert!(types.contains(&"Box"));
34        assert!(types.contains(&"String"));
35    }
36    #[test]
37    fn test_std_compat_required_features() {
38        let features = StdCompat::required_features();
39        assert!(features.contains(&"alloc"));
40        assert!(features.contains(&"core"));
41    }
42    #[test]
43    fn test_std_compat_wasm_limitations() {
44        let limitations = StdCompat::wasm_limitations();
45        assert!(limitations.contains(&"No file I/O"));
46        assert!(limitations.contains(&"No threads"));
47        assert!(limitations.contains(&"No env vars"));
48    }
49    #[test]
50    fn test_alloc_config_default() {
51        let cfg = AllocConfig::default();
52        assert!(cfg.use_global_allocator);
53        assert!(cfg.max_heap_bytes.is_none());
54    }
55    #[test]
56    fn test_alloc_config_for_wasm() {
57        let cfg = AllocConfig::for_wasm();
58        assert!(cfg.use_global_allocator);
59        assert_eq!(cfg.max_heap_bytes, Some(256 * 1024 * 1024));
60        let desc = cfg.describe();
61        assert!(desc.contains("256"));
62    }
63    #[test]
64    fn test_platform_info() {
65        assert!(!PlatformInfo::is_no_std());
66        let ps = PlatformInfo::pointer_size();
67        assert!(ps == 4 || ps == 8);
68        assert!(!PlatformInfo::platform_name().is_empty());
69    }
70    #[test]
71    fn test_wasm_feature_set() {
72        let mut set = WasmFeatureSet::new();
73        assert!(!set.has("bulk-memory"));
74        set.require("bulk-memory");
75        assert!(set.has("bulk-memory"));
76        set.require("bulk-memory");
77        assert_eq!(set.features.len(), 1);
78        let standard = WasmFeatureSet::standard_wasm_features();
79        assert!(standard.has("mutable-globals"));
80        assert!(standard.has("bulk-memory"));
81        assert!(standard.has("reference-types"));
82    }
83    #[test]
84    fn test_compatibility_report() {
85        let report = CompatibilityReport::generate();
86        assert!(!report.platform.is_empty());
87        assert!(report.std_available);
88        assert!(report.alloc_available);
89        if !PlatformInfo::is_wasm() {
90            assert!(report.is_compatible());
91        }
92        let summary = report.report_string();
93        assert!(summary.contains("Platform:"));
94        assert!(summary.contains("std available:"));
95    }
96}
97#[cfg(test)]
98mod tests_compat_ext {
99    use super::*;
100    #[test]
101    fn test_feature_flags() {
102        let _ = FeatureFlags::parallel_enabled();
103        let _ = FeatureFlags::serde_enabled();
104        let feats = FeatureFlags::known_features();
105        assert!(!feats.is_empty());
106    }
107    #[test]
108    fn test_conditional_init() {
109        let mut slot: ConditionalInit<u32> = ConditionalInit::uninit();
110        assert!(!slot.is_init());
111        slot.init(42);
112        assert!(slot.is_init());
113        assert_eq!(*slot.get(), 42);
114    }
115    #[test]
116    #[should_panic]
117    fn test_conditional_init_double_init() {
118        let mut slot: ConditionalInit<u32> = ConditionalInit::uninit();
119        slot.init(1);
120        slot.init(2);
121    }
122    #[test]
123    fn test_platform_caps() {
124        let caps = PlatformCaps::detect();
125        assert!(caps.heap);
126    }
127    #[test]
128    fn test_byte_order_round_trip() {
129        let val = 0xDEAD_BEEF_CAFE_BABEu64;
130        let le_bytes = ByteOrder::LittleEndian.u64_to_bytes(val);
131        let back = ByteOrder::LittleEndian.u64_from_bytes(le_bytes);
132        assert_eq!(back, val);
133        let be_bytes = ByteOrder::BigEndian.u64_to_bytes(val);
134        let back_be = ByteOrder::BigEndian.u64_from_bytes(be_bytes);
135        assert_eq!(back_be, val);
136    }
137    #[test]
138    fn test_static_str() {
139        let s = StaticStr::from_static("hello");
140        assert_eq!(s.as_str(), "hello");
141        assert!(!s.is_empty());
142        assert_eq!(s.len(), 5);
143        let owned = StaticStr::from_owned("world".to_string());
144        assert_eq!(owned.as_str(), "world");
145        assert_eq!(format!("{owned}"), "world");
146    }
147    #[test]
148    fn test_alloc_stats() {
149        let mut stats = AllocStats::new();
150        stats.record_alloc(100);
151        stats.record_alloc(200);
152        assert_eq!(stats.alloc_count, 2);
153        assert_eq!(stats.current_bytes, 300);
154        assert_eq!(stats.peak_bytes, 300);
155        stats.record_dealloc(100);
156        assert_eq!(stats.live_allocs(), 1);
157        assert_eq!(stats.current_bytes, 200);
158    }
159    #[test]
160    fn test_scratch_buffer() {
161        let mut buf = ScratchBuffer::with_capacity(64);
162        assert!(buf.capacity() >= 64);
163        {
164            let v = buf.fresh();
165            v.push(1);
166            v.push(2);
167        }
168        assert_eq!(buf.len(), 2);
169        buf.fresh();
170        assert_eq!(buf.len(), 0);
171    }
172    #[test]
173    fn test_spin_flag() {
174        let flag = SpinFlag::new(false);
175        assert!(!flag.get());
176        flag.set();
177        assert!(flag.get());
178        let old = flag.test_and_set();
179        assert!(old);
180        flag.clear();
181        assert!(!flag.get());
182    }
183    #[test]
184    fn test_counter_cell() {
185        let c = CounterCell::zero();
186        assert_eq!(c.get(), 0);
187        c.inc();
188        c.inc();
189        assert_eq!(c.get(), 2);
190        c.add(10);
191        assert_eq!(c.get(), 12);
192        c.reset();
193        assert_eq!(c.get(), 0);
194    }
195    #[test]
196    fn test_os_resource() {
197        let r = OsResource::FileDescriptor(3);
198        assert!(r.is_available());
199        assert_eq!(r.fd(), Some(3));
200        let u = OsResource::Unavailable;
201        assert!(!u.is_available());
202        assert_eq!(u.fd(), None);
203    }
204    #[test]
205    fn test_runtime_version() {
206        let v = RuntimeVersion::CURRENT;
207        let s = v.as_str();
208        assert!(s.starts_with('0'));
209        let other = RuntimeVersion {
210            major: 0,
211            minor: 99,
212            patch: 0,
213            pre: None,
214        };
215        assert!(v.is_compatible_with(&other));
216        let incompat = RuntimeVersion {
217            major: 1,
218            minor: 0,
219            patch: 0,
220            pre: None,
221        };
222        assert!(!v.is_compatible_with(&incompat));
223    }
224    #[test]
225    fn test_build_info() {
226        assert!(!BuildInfo::version().is_empty());
227        assert!(!BuildInfo::package_name().is_empty());
228        assert!(!BuildInfo::summary().is_empty());
229    }
230    #[test]
231    fn test_memory_layout() {
232        let _align = MemoryLayout::simd_alignment();
233        let _cl = MemoryLayout::cache_line_size();
234        let ncpus = MemoryLayout::num_cpus();
235        assert!(ncpus >= 1);
236    }
237    #[test]
238    fn test_compat_layer() {
239        let diag = CompatLayer::diagnostics();
240        assert!(!diag.is_empty());
241    }
242}
243/// A `Result` type parameterised over `ErrorCode` for platform operations.
244#[allow(dead_code)]
245pub type PlatformResult<T> = Result<T, ErrorCode>;
246/// Converts a boolean success flag into a `PlatformResult<()>`.
247#[allow(dead_code)]
248pub fn bool_to_platform_result(ok: bool) -> PlatformResult<()> {
249    if ok {
250        Ok(())
251    } else {
252        Err(ErrorCode::Fail)
253    }
254}
255/// Converts a `&str` to an OS path-like byte sequence.
256///
257/// On Unix, this is a no-op (UTF-8 bytes). On Windows, this would convert to
258/// WTF-16 in a full implementation; here we return the UTF-8 bytes unchanged.
259#[allow(dead_code)]
260pub fn str_to_os_bytes(s: &str) -> Vec<u8> {
261    s.as_bytes().to_vec()
262}
263/// Converts OS path bytes back to a `String`, replacing invalid UTF-8.
264#[allow(dead_code)]
265pub fn os_bytes_to_string(b: &[u8]) -> String {
266    String::from_utf8_lossy(b).into_owned()
267}
268#[cfg(test)]
269mod tests_compat_ext2 {
270    use super::*;
271    #[test]
272    fn test_error_code() {
273        assert!(ErrorCode::Ok.is_ok());
274        assert!(!ErrorCode::Fail.is_ok());
275        assert!(!ErrorCode::Oom.description().is_empty());
276        assert_eq!(ErrorCode::Ok.as_i32(), 0);
277    }
278    #[test]
279    fn test_bool_to_platform_result() {
280        assert!(bool_to_platform_result(true).is_ok());
281        assert!(bool_to_platform_result(false).is_err());
282    }
283    #[test]
284    fn test_stack_guard() {
285        let mut depth = 0usize;
286        {
287            let g = StackGuard::new(&mut depth, 10);
288            assert_eq!(g.current_depth(), 1);
289        }
290        assert_eq!(depth, 0);
291    }
292    #[test]
293    fn test_budget() {
294        let mut b = Budget::new(10);
295        assert!(b.consume(5).is_ok());
296        assert_eq!(b.remaining(), 5);
297        assert!(b.consume(6).is_err());
298        b.refuel(20);
299        assert!(b.has_remaining());
300    }
301    #[test]
302    fn test_compat_matrix() {
303        let mut m = CompatMatrix::new();
304        let a = m.add_component("alpha");
305        let b = m.add_component("beta");
306        assert!(m.is_compatible(a, a));
307        assert!(!m.is_compatible(a, b));
308        m.mark_compatible(a, b);
309        assert!(m.is_compatible(a, b));
310        assert!(m.is_compatible(b, a));
311    }
312    #[test]
313    fn test_version_constraint() {
314        let c = VersionConstraint::major_minor(0, 1);
315        let v_ok = RuntimeVersion {
316            major: 0,
317            minor: 1,
318            patch: 0,
319            pre: None,
320        };
321        let v_bad = RuntimeVersion {
322            major: 1,
323            minor: 0,
324            patch: 0,
325            pre: None,
326        };
327        assert!(c.satisfied_by(&v_ok));
328        assert!(!c.satisfied_by(&v_bad));
329    }
330    #[test]
331    fn test_atomic_version() {
332        let av = AtomicVersion::new();
333        assert_eq!(av.current(), 0);
334        assert_eq!(av.bump(), 1);
335        assert_eq!(av.bump(), 2);
336    }
337    #[test]
338    fn test_capability_set() {
339        let mut caps = CapabilitySet::empty();
340        caps.add(CapabilitySet::THREADS);
341        assert!(caps.has(CapabilitySet::THREADS));
342        assert!(!caps.has(CapabilitySet::NETWORK));
343        caps.remove(CapabilitySet::THREADS);
344        assert!(!caps.has(CapabilitySet::THREADS));
345    }
346    #[test]
347    fn test_shim_registry() {
348        let mut reg = ShimRegistry::new();
349        let i0 = reg.register("file_shim", true);
350        let i1 = reg.register("net_shim", false);
351        assert!(reg.is_enabled(i0));
352        assert!(!reg.is_enabled(i1));
353        assert_eq!(reg.name(i0), Some("file_shim"));
354        assert_eq!(reg.count(), 2);
355        assert_eq!(reg.enabled_count(), 1);
356    }
357    #[test]
358    fn test_compile_flags() {
359        let s = CompileFlags::summary();
360        assert!(s.contains("debug="));
361        assert!(s.contains("edition=2021"));
362    }
363    #[test]
364    fn test_library_manifest() {
365        let lib = LibraryManifest::required("core", "1.0.0");
366        assert!(!lib.optional);
367        let desc = lib.describe();
368        assert!(desc.contains("core"));
369        let opt = LibraryManifest::optional("tracing", "0.1.0");
370        assert!(opt.optional);
371    }
372    #[test]
373    fn test_cfg_snapshot() {
374        let snap = CfgSnapshot::capture();
375        assert!(!snap.arch.is_empty());
376        assert!(!snap.os.is_empty());
377        let s = snap.to_string();
378        assert!(s.contains("arch="));
379    }
380    #[test]
381    fn test_cross_platform_timer() {
382        let timer = CrossPlatformTimer::start();
383        let micros = timer.elapsed_micros();
384        assert!(micros < 10_000_000);
385    }
386    #[test]
387    fn test_os_bytes_round_trip() {
388        let s = "hello/world";
389        let b = str_to_os_bytes(s);
390        let s2 = os_bytes_to_string(&b);
391        assert_eq!(s, s2);
392    }
393}
394#[cfg(test)]
395mod tests_compat_ext3 {
396    use super::*;
397    #[test]
398    fn test_wasm_mem_region() {
399        let r = WasmMemRegion::new(0, 1024, 4096, "heap");
400        assert_eq!(r.end(), 5120);
401        assert!(r.contains(1024));
402        assert!(r.contains(5119));
403        assert!(!r.contains(5120));
404    }
405    #[test]
406    fn test_wasm_mem_table() {
407        let mut tbl = WasmMemTable::new();
408        tbl.add(WasmMemRegion::new(0, 0, 1024, "stack"));
409        tbl.add(WasmMemRegion::new(1, 1024, 4096, "heap"));
410        assert_eq!(tbl.len(), 2);
411        let found = tbl.find(2000);
412        assert!(found.is_some());
413        assert_eq!(found.expect("found should be valid").label, "heap");
414        assert!(tbl.find(5200).is_none());
415    }
416    #[test]
417    fn test_bump_alloc() {
418        let mut alloc = BumpAlloc::new(0, 1024);
419        let a = alloc.alloc(64, 8).expect("a should be present");
420        assert_eq!(a, 0);
421        let b = alloc.alloc(64, 8).expect("b should be present");
422        assert_eq!(b, 64);
423        assert_eq!(alloc.used(), 128);
424        alloc.reset();
425        assert_eq!(alloc.used(), 0);
426        assert_eq!(alloc.remaining(), 1024);
427    }
428    #[test]
429    fn test_bump_alloc_oom() {
430        let mut alloc = BumpAlloc::new(0, 16);
431        assert!(alloc.alloc(17, 1).is_none());
432    }
433    #[test]
434    fn test_addr_range() {
435        let r = AddrRange::new(100, 200);
436        assert_eq!(r.size(), 100);
437        assert!(r.contains(100));
438        assert!(r.contains(199));
439        assert!(!r.contains(200));
440        let r2 = AddrRange::new(150, 250);
441        assert!(r.overlaps(&r2));
442        let r3 = AddrRange::new(200, 300);
443        assert!(!r.overlaps(&r3));
444    }
445}
446#[cfg(test)]
447mod tests_compat_final {
448    use super::*;
449    #[test]
450    fn test_page_map() {
451        let mut pm = PageMap::new(4096);
452        pm.map_page(0, "null_page");
453        pm.map_page(4096, "code");
454        pm.map_page(8192, "data");
455        assert_eq!(pm.page_count(), 3);
456        assert_eq!(pm.label_for(0), Some("null_page"));
457        assert_eq!(pm.label_for(4096), Some("code"));
458        assert_eq!(pm.label_for(100), Some("null_page"));
459        assert_eq!(pm.label_for(99999), None);
460    }
461    #[test]
462    fn test_linear_scan_allocator() {
463        let mut alloc = LinearScanAllocator::new(3);
464        alloc.add_interval(0, 5);
465        alloc.add_interval(2, 8);
466        alloc.add_interval(6, 10);
467        alloc.allocate();
468        assert_eq!(alloc.allocated_count(), 3);
469    }
470    #[test]
471    fn test_instruction_buffer() {
472        let mut buf = InstructionBuffer::new();
473        assert!(buf.is_empty());
474        buf.emit(0xDEAD_BEEF);
475        buf.emit(0x1234_5678);
476        assert_eq!(buf.len(), 2);
477        assert_eq!(buf.get(0), Some(0xDEAD_BEEF));
478        buf.patch(0, 0x0000_0001);
479        assert_eq!(buf.get(0), Some(0x0000_0001));
480        let s = buf.as_slice();
481        assert_eq!(s.len(), 2);
482    }
483}
484/// Standard ELF-like section layout for a kernel binary.
485#[allow(dead_code)]
486pub const STANDARD_SECTIONS: &[CodeSection] = &[
487    CodeSection::new(".text", 0x0001_0000, 0x0010_0000, true, false),
488    CodeSection::new(".rodata", 0x0011_0000, 0x0004_0000, false, false),
489    CodeSection::new(".data", 0x0015_0000, 0x0002_0000, false, true),
490    CodeSection::new(".bss", 0x0017_0000, 0x0001_0000, false, true),
491];
492#[cfg(test)]
493mod tests_compat_final2 {
494    use super::*;
495    #[test]
496    fn test_code_section() {
497        let sec = CodeSection::new(".text", 0x1000, 0x2000, true, false);
498        assert_eq!(sec.vend(), 0x3000);
499        assert!(sec.contains(0x1000));
500        assert!(sec.contains(0x2FFF));
501        assert!(!sec.contains(0x3000));
502    }
503    #[test]
504    fn test_standard_sections() {
505        assert!(!STANDARD_SECTIONS.is_empty());
506        let text = STANDARD_SECTIONS.iter().find(|s| s.name == ".text");
507        assert!(text.is_some());
508        assert!(text.expect("text should be valid").executable);
509    }
510    #[test]
511    fn test_symbol_table() {
512        let mut tbl = SymbolTable::new();
513        tbl.add("main", 0x1000);
514        tbl.add("start", 0x0FFF);
515        assert_eq!(tbl.lookup("main"), Some(0x1000));
516        assert_eq!(tbl.lookup("missing"), None);
517        assert_eq!(tbl.nearest(0x1004), Some("main"));
518        assert_eq!(tbl.len(), 2);
519    }
520    #[test]
521    fn test_reloc_entry() {
522        let r = RelocEntry::new(0x10, "foo", 8);
523        let patched = r.apply(0x2000);
524        assert_eq!(patched, 0x2008);
525    }
526    #[test]
527    fn test_object_file() {
528        let mut obj = ObjectFile::new();
529        obj.add_section(".text", vec![0x90u8; 16]);
530        obj.add_symbol("foo", 0x0);
531        obj.add_reloc(RelocEntry::new(4, "bar", 0));
532        assert_eq!(obj.num_sections(), 1);
533        assert_eq!(obj.num_relocs(), 1);
534        assert_eq!(obj.section_size(".text"), Some(16));
535        assert_eq!(obj.section_size(".data"), None);
536    }
537}