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)]
65pub unsafe extern "C" fn lanes_simulate_stack(
66 prog: *const LANESProgram,
67 out: *mut *mut LANESValidationErrors,
68) -> LanesStatus {
69 unsafe { lanes_simulate_stack_with_arch(prog, std::ptr::null(), out) }
70}
71
72#[unsafe(no_mangle)]
78pub unsafe extern "C" fn lanes_simulate_stack_with_arch(
79 prog: *const LANESProgram,
80 arch: *const LANESArchSpec,
81 out: *mut *mut LANESValidationErrors,
82) -> LanesStatus {
83 clear_last_error();
84
85 if prog.is_null() || out.is_null() {
86 set_last_error("null pointer argument");
87 return LanesStatus::ErrNullPtr;
88 }
89
90 let prog = unsafe { &*prog };
91 let arch = if arch.is_null() {
92 None
93 } else {
94 Some(unsafe { &(*arch).inner })
95 };
96 let errors = validate::simulate_stack(&prog.inner, arch);
97 let status = if errors.is_empty() {
98 LanesStatus::Ok
99 } else {
100 LanesStatus::ErrValidation
101 };
102 let handle = Box::new(LANESValidationErrors::from_errors(errors));
103 unsafe { *out = Box::into_raw(handle) };
104 status
105}
106
107#[unsafe(no_mangle)]
109pub unsafe extern "C" fn lanes_validation_errors_count(errs: *const LANESValidationErrors) -> u32 {
110 if errs.is_null() {
111 return 0;
112 }
113 let errs = unsafe { &*errs };
114 errs.errors.len() as u32
115}
116
117#[unsafe(no_mangle)]
120pub unsafe extern "C" fn lanes_validation_error_message(
121 errs: *const LANESValidationErrors,
122 index: u32,
123) -> *const c_char {
124 if errs.is_null() {
125 return std::ptr::null();
126 }
127 let errs = unsafe { &*errs };
128 match errs.messages.get(index as usize) {
129 Some(cstr) => cstr.as_ptr(),
130 None => std::ptr::null(),
131 }
132}
133
134#[unsafe(no_mangle)]
136pub unsafe extern "C" fn lanes_validation_errors_free(errs: *mut LANESValidationErrors) {
137 if !errs.is_null() {
138 drop(unsafe { Box::from_raw(errs) });
139 }
140}