bloqade_lanes_bytecode/ffi/
validate.rs1use std::os::raw::c_char;
2
3use bloqade_lanes_bytecode_core::isa::validate;
4
5use super::error::{LanesStatus, clear_last_error, set_last_error};
6use super::handles::{LANESArchSpec, LANESProgram, LANESValidationErrors};
7
8#[unsafe(no_mangle)]
10pub unsafe extern "C" fn lanes_validate_structure(
11 prog: *const LANESProgram,
12 out: *mut *mut LANESValidationErrors,
13) -> LanesStatus {
14 clear_last_error();
15
16 if prog.is_null() || out.is_null() {
17 set_last_error("null pointer argument");
18 return LanesStatus::ErrNullPtr;
19 }
20
21 let prog = unsafe { &*prog };
22 let errors = validate::validate_structure(&prog.inner);
23 let status = if errors.is_empty() {
24 LanesStatus::Ok
25 } else {
26 LanesStatus::ErrValidation
27 };
28 let handle = Box::new(LANESValidationErrors::from_errors(errors));
29 unsafe { *out = Box::into_raw(handle) };
30 status
31}
32
33#[unsafe(no_mangle)]
35pub unsafe extern "C" fn lanes_validate_addresses(
36 prog: *const LANESProgram,
37 arch: *const LANESArchSpec,
38 out: *mut *mut LANESValidationErrors,
39) -> LanesStatus {
40 clear_last_error();
41
42 if prog.is_null() || arch.is_null() || out.is_null() {
43 set_last_error("null pointer argument");
44 return LanesStatus::ErrNullPtr;
45 }
46
47 let prog = unsafe { &*prog };
48 let arch = unsafe { &*arch };
49 let errors = validate::validate(&prog.inner, Some(&arch.inner));
50 let status = if errors.is_empty() {
51 LanesStatus::Ok
52 } else {
53 LanesStatus::ErrValidation
54 };
55 let handle = Box::new(LANESValidationErrors::from_errors(errors));
56 unsafe { *out = Box::into_raw(handle) };
57 status
58}
59
60#[unsafe(no_mangle)]
63pub unsafe extern "C" fn lanes_simulate_stack(
64 prog: *const LANESProgram,
65 out: *mut *mut LANESValidationErrors,
66) -> LanesStatus {
67 clear_last_error();
68
69 if prog.is_null() || out.is_null() {
70 set_last_error("null pointer argument");
71 return LanesStatus::ErrNullPtr;
72 }
73
74 let prog = unsafe { &*prog };
75 let errors = validate::simulate_stack(&prog.inner, None);
76 let status = if errors.is_empty() {
77 LanesStatus::Ok
78 } else {
79 LanesStatus::ErrValidation
80 };
81 let handle = Box::new(LANESValidationErrors::from_errors(errors));
82 unsafe { *out = Box::into_raw(handle) };
83 status
84}
85
86#[unsafe(no_mangle)]
88pub unsafe extern "C" fn lanes_validation_errors_count(errs: *const LANESValidationErrors) -> u32 {
89 if errs.is_null() {
90 return 0;
91 }
92 let errs = unsafe { &*errs };
93 errs.errors.len() as u32
94}
95
96#[unsafe(no_mangle)]
99pub unsafe extern "C" fn lanes_validation_error_message(
100 errs: *const LANESValidationErrors,
101 index: u32,
102) -> *const c_char {
103 if errs.is_null() {
104 return std::ptr::null();
105 }
106 let errs = unsafe { &*errs };
107 match errs.messages.get(index as usize) {
108 Some(cstr) => cstr.as_ptr(),
109 None => std::ptr::null(),
110 }
111}
112
113#[unsafe(no_mangle)]
115pub unsafe extern "C" fn lanes_validation_errors_free(errs: *mut LANESValidationErrors) {
116 if !errs.is_null() {
117 drop(unsafe { Box::from_raw(errs) });
118 }
119}