43 lines
1.4 KiB
Rust
43 lines
1.4 KiB
Rust
|
|
use std::mem;
|
||
|
|
use std::slice;
|
||
|
|
use std::str;
|
||
|
|
|
||
|
|
use cel::{Context, ExecutionError, Program, Value};
|
||
|
|
|
||
|
|
#[unsafe(no_mangle)]
|
||
|
|
pub extern "C" fn allocation(n: usize) -> *mut u8 {
|
||
|
|
mem::ManuallyDrop::new(Vec::with_capacity(n)).as_mut_ptr()
|
||
|
|
}
|
||
|
|
|
||
|
|
#[unsafe(no_mangle)]
|
||
|
|
pub unsafe extern "C" fn evaluate(s: *const u8) -> *mut u8 {
|
||
|
|
unsafe {
|
||
|
|
let length = u32::from_le_bytes(*(s as *const [u8; 4])) as usize;
|
||
|
|
let input = slice::from_raw_parts(s.offset(4), length);
|
||
|
|
let output = evaluate_buffers(input);
|
||
|
|
mem::ManuallyDrop::new(output).as_mut_ptr()
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
fn evaluate_buffers(input: &[u8]) -> Vec<u8> {
|
||
|
|
let contents = str::from_utf8(input).unwrap();
|
||
|
|
let result = evaluate_cel(contents);
|
||
|
|
let success = result.is_ok();
|
||
|
|
let message = result.unwrap_or_else(|e| e.to_string());
|
||
|
|
let len = message.len();
|
||
|
|
let mut buffer = Vec::with_capacity(len + 8);
|
||
|
|
buffer.push(if success { 1 } else { 0 });
|
||
|
|
buffer.extend(vec![0; 3]);
|
||
|
|
buffer.extend_from_slice(&(len as u32).to_le_bytes());
|
||
|
|
buffer.extend_from_slice(message.as_bytes());
|
||
|
|
buffer
|
||
|
|
}
|
||
|
|
|
||
|
|
fn evaluate_cel(content: &str) -> Result<String, ExecutionError> {
|
||
|
|
let program = Program::compile(content).unwrap();
|
||
|
|
let mut context = Context::default();
|
||
|
|
// context.add_function("add", |a: i64, b: i64| a + b);
|
||
|
|
let value = program.execute(&context)?;
|
||
|
|
Ok(format!("{:?}", value))
|
||
|
|
}
|