feat: make all nodes work with new runtime
This commit is contained in:
@@ -68,40 +68,48 @@ pub fn nodarium_execute(_attr: TokenStream, item: TokenStream) -> TokenStream {
|
||||
})
|
||||
.collect();
|
||||
|
||||
let arg_names: Vec<_> = (0..input_count)
|
||||
let param_count = input_fn.sig.inputs.len();
|
||||
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()))
|
||||
.collect();
|
||||
|
||||
let mut tuple_args = Vec::new();
|
||||
for i in 0..param_count {
|
||||
let start_name = &arg_names[i * 2];
|
||||
let end_name = &arg_names[i * 2 + 1];
|
||||
let tuple_arg = quote! {
|
||||
(#start_name, #end_name)
|
||||
};
|
||||
tuple_args.push(tuple_arg);
|
||||
}
|
||||
|
||||
let expanded = quote! {
|
||||
|
||||
extern "C" {
|
||||
fn __nodarium_log(ptr: *const u8, len: usize);
|
||||
fn __nodarium_log_panic(ptr: *const u8, len: usize);
|
||||
}
|
||||
|
||||
#fn_vis fn #inner_fn_name(#( #input_param_names: *const i32 ),*) -> Vec<i32> {
|
||||
#fn_vis fn #inner_fn_name(#( #input_param_names: (i32, i32) ),*) -> Vec<i32> {
|
||||
#fn_body
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
#fn_vis extern "C" fn execute(output_pos: i32, #( #arg_names: i32 ),*) -> i32 {
|
||||
static PANIC_HOOK_SET: std::sync::atomic::AtomicBool = std::sync::atomic::AtomicBool::new(false);
|
||||
|
||||
if !PANIC_HOOK_SET.load(std::sync::atomic::Ordering::SeqCst) {
|
||||
std::panic::set_hook(Box::new(|info| {
|
||||
let msg = info.to_string();
|
||||
unsafe { __nodarium_log_panic(msg.as_ptr(), msg.len()); }
|
||||
}));
|
||||
PANIC_HOOK_SET.store(true, std::sync::atomic::Ordering::SeqCst);
|
||||
}
|
||||
|
||||
// log!("before_fn");
|
||||
let result = #inner_fn_name(
|
||||
#( #arg_names as *const i32 ),*
|
||||
#( #tuple_args ),*
|
||||
);
|
||||
// log!("after_fn");
|
||||
|
||||
let len_bytes = result.len() * 4;
|
||||
unsafe {
|
||||
let src = result.as_ptr() as *const u8;
|
||||
let dst = output_pos as *mut u8;
|
||||
// log!("writing output_pos={:?} src={:?} len_bytes={:?}", output_pos, src, len_bytes);
|
||||
dst.copy_from_nonoverlapping(src, len_bytes);
|
||||
}
|
||||
|
||||
@@ -116,7 +124,9 @@ pub fn nodarium_execute(_attr: TokenStream, item: TokenStream) -> TokenStream {
|
||||
|
||||
fn validate_signature(fn_sig: &syn::Signature, expected_inputs: usize, def: &NodeDefinition) {
|
||||
let param_count = fn_sig.inputs.len();
|
||||
if param_count != expected_inputs {
|
||||
let expected_params = expected_inputs;
|
||||
|
||||
if param_count != expected_params {
|
||||
panic!(
|
||||
"Execute function has {} parameters but definition has {} inputs\n\
|
||||
Definition inputs: {:?}\n\
|
||||
@@ -129,12 +139,36 @@ 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{}: *const i32", i))
|
||||
.map(|i| format!("arg{}: (i32, i32)", i))
|
||||
.collect::<Vec<_>>()
|
||||
.join(", ")
|
||||
);
|
||||
}
|
||||
|
||||
for (i, arg) in fn_sig.inputs.iter().enumerate() {
|
||||
match arg {
|
||||
syn::FnArg::Typed(pat_type) => {
|
||||
let type_str = quote! { #pat_type.ty }.to_string();
|
||||
let clean_type = type_str
|
||||
.trim()
|
||||
.trim_start_matches("_")
|
||||
.trim_end_matches(".ty")
|
||||
.trim()
|
||||
.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
|
||||
);
|
||||
}
|
||||
}
|
||||
syn::FnArg::Receiver(_) => {
|
||||
panic!("Execute function cannot have 'self' parameter");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
match &fn_sig.output {
|
||||
syn::ReturnType::Type(_, ty) => {
|
||||
let is_vec = match &**ty {
|
||||
|
||||
@@ -21,7 +21,7 @@ export type NodeRuntimeState = {
|
||||
parents?: NodeInstance[];
|
||||
children?: NodeInstance[];
|
||||
inputNodes?: Record<string, NodeInstance>;
|
||||
type?: NodeDefinition;
|
||||
type?: NodeDefinition; // we should probably remove this and rely on registry.getNode(nodeType)
|
||||
downX?: number;
|
||||
downY?: number;
|
||||
x?: number;
|
||||
|
||||
@@ -11,51 +11,38 @@ pub fn decode_float(bits: i32) -> f32 {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub unsafe fn read_i32(ptr: *const i32) -> i32 {
|
||||
*ptr
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub unsafe fn read_f32(ptr: *const i32) -> f32 {
|
||||
f32::from_bits(*ptr as u32)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub unsafe fn read_bool(ptr: *const i32) -> bool {
|
||||
*ptr != 0
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub unsafe fn read_vec3(ptr: *const i32) -> [f32; 3] {
|
||||
let p = ptr as *const f32;
|
||||
[p.read(), p.add(1).read(), p.add(2).read()]
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub unsafe fn read_i32_slice(ptr: *const i32, len: usize) -> Vec<i32> {
|
||||
std::slice::from_raw_parts(ptr, len).to_vec()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub unsafe fn read_f32_slice(ptr: *const i32, len: usize) -> Vec<f32> {
|
||||
std::slice::from_raw_parts(ptr as *const f32, len).to_vec()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub unsafe fn read_f32_default(ptr: *const i32, default: f32) -> f32 {
|
||||
if ptr.is_null() {
|
||||
default
|
||||
} else {
|
||||
read_f32(ptr)
|
||||
pub fn read_i32(ptr: i32) -> i32 {
|
||||
unsafe {
|
||||
let _ptr = ptr as *const i32;
|
||||
*_ptr
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub unsafe fn read_i32_default(ptr: *const i32, default: i32) -> i32 {
|
||||
if ptr.is_null() {
|
||||
default
|
||||
} else {
|
||||
read_i32(ptr)
|
||||
pub fn read_f32(ptr: i32) -> f32 {
|
||||
unsafe {
|
||||
let _ptr = ptr as *const i32;
|
||||
f32::from_bits(*_ptr as u32)
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn read_i32_slice(tuple: (i32, i32)) -> Vec<i32> {
|
||||
unsafe {
|
||||
let start = tuple.0 as *const i32;
|
||||
let end = tuple.1 as *const i32;
|
||||
let len = (end as usize - start as usize) / 4;
|
||||
std::slice::from_raw_parts(start, len).to_vec()
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn read_f32_slice(tuple: (i32, i32)) -> Vec<f32> {
|
||||
unsafe {
|
||||
let start = tuple.0 as *const f32;
|
||||
let end = tuple.1 as *const f32;
|
||||
let len = (end as usize - start as usize) / 4;
|
||||
std::slice::from_raw_parts(start, len).to_vec()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -27,7 +27,6 @@ export function createWasmWrapper(buffer: ArrayBuffer, memory: WebAssembly.Memor
|
||||
exports = instance.exports as NodariumExports;
|
||||
|
||||
function execute(outputPos: number, args: number[]): number {
|
||||
console.log('WASM_WRAPPER', { outputPos, args });
|
||||
return exports.execute(outputPos, ...args);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user