feat: some shit
This commit is contained in:
@@ -9,12 +9,12 @@ use syn::parse_macro_input;
|
||||
use syn::spanned::Spanned;
|
||||
|
||||
fn add_line_numbers(input: String) -> String {
|
||||
return input
|
||||
input
|
||||
.split('\n')
|
||||
.enumerate()
|
||||
.map(|(i, line)| format!("{:2}: {}", i + 1, line))
|
||||
.collect::<Vec<String>>()
|
||||
.join("\n");
|
||||
.join("\n")
|
||||
}
|
||||
|
||||
fn read_node_definition(file_path: &Path) -> NodeDefinition {
|
||||
@@ -72,7 +72,7 @@ pub fn nodarium_execute(_attr: TokenStream, item: TokenStream) -> TokenStream {
|
||||
let total_c_params = param_count * 2;
|
||||
|
||||
let arg_names: Vec<_> = (0..total_c_params)
|
||||
.map(|i| syn::Ident::new(&format!("arg{}", i), input_fn.sig.span()))
|
||||
.map(|i| syn::Ident::new(&format!("arg{i}"), input_fn.sig.span()))
|
||||
.collect();
|
||||
|
||||
let mut tuple_args = Vec::new();
|
||||
@@ -89,7 +89,20 @@ pub fn nodarium_execute(_attr: TokenStream, item: TokenStream) -> TokenStream {
|
||||
|
||||
extern "C" {
|
||||
fn __nodarium_log(ptr: *const u8, len: usize);
|
||||
fn __nodarium_log_panic(ptr: *const u8, len: usize);
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
fn init_panic_hook() {
|
||||
std::panic::set_hook(Box::new(|_info| {
|
||||
unsafe {
|
||||
__nodarium_log(b"PANIC\0".as_ptr(), 5);
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn init_allocator() {
|
||||
nodarium_utils::allocator::ALLOCATOR.init();
|
||||
}
|
||||
|
||||
#fn_vis fn #inner_fn_name(#( #input_param_names: (i32, i32) ),*) -> Vec<i32> {
|
||||
@@ -99,11 +112,14 @@ pub fn nodarium_execute(_attr: TokenStream, item: TokenStream) -> TokenStream {
|
||||
#[no_mangle]
|
||||
#fn_vis extern "C" fn execute(output_pos: i32, #( #arg_names: i32 ),*) -> i32 {
|
||||
|
||||
nodarium_utils::allocator::ALLOCATOR.init();
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
init_panic_hook();
|
||||
nodarium_utils::log!("before_fn");
|
||||
let result = #inner_fn_name(
|
||||
#( #tuple_args ),*
|
||||
);
|
||||
nodarium_utils::log!("after_fn");
|
||||
nodarium_utils::log!("after_fn: result_len={}", result.len());
|
||||
|
||||
let len_bytes = result.len() * 4;
|
||||
unsafe {
|
||||
@@ -137,7 +153,7 @@ fn validate_signature(fn_sig: &syn::Signature, expected_inputs: usize, def: &Nod
|
||||
.map(|i| i.keys().collect::<Vec<_>>())
|
||||
.unwrap_or_default(),
|
||||
(0..expected_inputs)
|
||||
.map(|i| format!("arg{}: (i32, i32)", i))
|
||||
.map(|i| format!("arg{i}: (i32, i32)"))
|
||||
.collect::<Vec<_>>()
|
||||
.join(", ")
|
||||
);
|
||||
@@ -155,9 +171,7 @@ fn validate_signature(fn_sig: &syn::Signature, expected_inputs: usize, def: &Nod
|
||||
.to_string();
|
||||
if !clean_type.contains("(") && !clean_type.contains(",") {
|
||||
panic!(
|
||||
"Parameter {} has type '{}' but should be a tuple (i32, i32) representing (start, end) positions in memory",
|
||||
i,
|
||||
clean_type
|
||||
"Parameter {i} has type '{clean_type}' but should be a tuple (i32, i32) representing (start, end) positions in memory",
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -197,10 +211,7 @@ pub fn nodarium_definition_file(input: TokenStream) -> TokenStream {
|
||||
let full_path = Path::new(&project_dir).join(&file_path);
|
||||
|
||||
let json_content = fs::read_to_string(&full_path).unwrap_or_else(|err| {
|
||||
panic!(
|
||||
"Failed to read JSON file at '{}/{}': {}",
|
||||
project_dir, file_path, err
|
||||
)
|
||||
panic!("Failed to read JSON file at '{project_dir}/{file_path}': {err}",)
|
||||
});
|
||||
|
||||
let _: NodeDefinition = serde_json::from_str(&json_content).unwrap_or_else(|err| {
|
||||
|
||||
68
packages/utils/src/allocator.rs
Normal file
68
packages/utils/src/allocator.rs
Normal file
@@ -0,0 +1,68 @@
|
||||
use core::alloc::{GlobalAlloc, Layout};
|
||||
use core::sync::atomic::{AtomicUsize, Ordering};
|
||||
|
||||
extern "C" {
|
||||
fn __wasm_memory_size() -> usize;
|
||||
fn __nodarium_manual_end() -> usize;
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
const WASM_PAGE_SIZE: usize = 64 * 1024;
|
||||
|
||||
pub struct DownwardBumpAllocator {
|
||||
heap_top: AtomicUsize,
|
||||
}
|
||||
|
||||
impl Default for DownwardBumpAllocator {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
impl DownwardBumpAllocator {
|
||||
pub const fn new() -> Self {
|
||||
Self {
|
||||
heap_top: AtomicUsize::new(0),
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn init(&self) {
|
||||
let pages = unsafe { __wasm_memory_size() };
|
||||
let mem_size = pages * WASM_PAGE_SIZE;
|
||||
self.heap_top.store(mem_size, Ordering::Relaxed);
|
||||
}
|
||||
}
|
||||
|
||||
#[global_allocator]
|
||||
pub static ALLOCATOR: DownwardBumpAllocator = DownwardBumpAllocator::new();
|
||||
|
||||
unsafe impl GlobalAlloc for DownwardBumpAllocator {
|
||||
unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
|
||||
let align = layout.align();
|
||||
let size = layout.size();
|
||||
|
||||
let mut current = self.heap_top.load(Ordering::Relaxed);
|
||||
|
||||
loop {
|
||||
let aligned = (current - size) & !(align - 1);
|
||||
|
||||
let manual_end = unsafe { __nodarium_manual_end() };
|
||||
if aligned < manual_end {
|
||||
return core::ptr::null_mut();
|
||||
}
|
||||
|
||||
match self.heap_top.compare_exchange(
|
||||
current,
|
||||
aligned,
|
||||
Ordering::SeqCst,
|
||||
Ordering::Relaxed,
|
||||
) {
|
||||
Ok(_) => return aligned as *mut u8,
|
||||
Err(next) => current = next,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unsafe fn dealloc(&self, _: *mut u8, _: Layout) {}
|
||||
}
|
||||
@@ -1,3 +1,5 @@
|
||||
use crate::log;
|
||||
|
||||
pub fn encode_float(f: f32) -> i32 {
|
||||
// Convert f32 to u32 using to_bits, then safely cast to i32
|
||||
let bits = f.to_bits();
|
||||
@@ -12,6 +14,7 @@ pub fn decode_float(bits: i32) -> f32 {
|
||||
|
||||
#[inline]
|
||||
pub fn read_i32(ptr: i32) -> i32 {
|
||||
log!("read_i32 ptr: {:?}", ptr);
|
||||
unsafe {
|
||||
let _ptr = ptr as *const i32;
|
||||
*_ptr
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
pub mod allocator;
|
||||
mod encoding;
|
||||
mod nodes;
|
||||
mod tree;
|
||||
@@ -11,7 +12,7 @@ extern "C" {
|
||||
pub fn __nodarium_log(ptr: *const u8, len: usize);
|
||||
}
|
||||
|
||||
#[cfg(debug_assertions)]
|
||||
// #[cfg(debug_assertions)]
|
||||
#[macro_export]
|
||||
macro_rules! log {
|
||||
($($t:tt)*) => {{
|
||||
@@ -25,13 +26,13 @@ macro_rules! log {
|
||||
}}
|
||||
}
|
||||
|
||||
#[cfg(not(debug_assertions))]
|
||||
#[macro_export]
|
||||
macro_rules! log {
|
||||
($($arg:tt)*) => {{
|
||||
// This will expand to nothing in release builds
|
||||
}};
|
||||
}
|
||||
// #[cfg(not(debug_assertions))]
|
||||
// #[macro_export]
|
||||
// macro_rules! log {
|
||||
// ($($arg:tt)*) => {{
|
||||
// // This will expand to nothing in release builds
|
||||
// }};
|
||||
// }
|
||||
|
||||
#[allow(dead_code)]
|
||||
#[rustfmt::skip]
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
interface NodariumExports extends WebAssembly.Exports {
|
||||
memory: WebAssembly.Memory;
|
||||
execute: (outputPos: number, ...args: number[]) => number;
|
||||
init_allocator: () => void;
|
||||
}
|
||||
|
||||
export function createWasmWrapper(buffer: ArrayBuffer, memory: WebAssembly.Memory) {
|
||||
let exports: NodariumExports;
|
||||
|
||||
let end = 0;
|
||||
const importObject = {
|
||||
env: {
|
||||
memory: memory,
|
||||
@@ -25,14 +27,11 @@ export function createWasmWrapper(buffer: ArrayBuffer, memory: WebAssembly.Memor
|
||||
const module = new WebAssembly.Module(buffer);
|
||||
const instance = new WebAssembly.Instance(module, importObject);
|
||||
exports = instance.exports as NodariumExports;
|
||||
exports.init_allocator();
|
||||
|
||||
function execute(outputPos: number, args: number[]): number {
|
||||
try {
|
||||
return exports.execute(outputPos, ...args);
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
return -1;
|
||||
}
|
||||
end = outputPos;
|
||||
return exports.execute(outputPos, ...args);
|
||||
}
|
||||
|
||||
function get_definition() {
|
||||
|
||||
Reference in New Issue
Block a user