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