#![allow(non_upper_case_globals)] #![allow(non_camel_case_types)] #![allow(non_snake_case)] include!(concat!(env!("OUT_DIR"), "/duktape_bindings.rs")); use std::ffi; pub unsafe fn duk_create_heap_default() -> *mut duk_context { use std::ptr::null_mut; let ctx = duk_create_heap(None, None, None, null_mut(), None); unsafe extern "C" fn printc(c: *mut duk_context) -> i32 { let cstr = ffi::CStr::from_ptr(duk_to_string(c, 0)); println!("{0}", cstr.to_str().unwrap()); 0 } duk_push_global_function(ctx, "print", Some(printc), 1); ctx } pub unsafe fn duk_eval_string(ctx: *mut duk_context, code: &str) -> u32 { let filename = "input"; duk_push_lstring(ctx, filename.as_ptr() as *const i8, filename.len() as duk_size_t); duk_eval_raw(ctx, code.as_ptr() as *const i8, code.len() as duk_size_t, DUK_COMPILE_EVAL | DUK_COMPILE_NOSOURCE | DUK_COMPILE_SAFE) as u32 } pub unsafe fn duk_push_global_function(ctx: *mut duk_context, name: &str, f: duk_c_function, args: i32) -> bool { duk_push_c_function(ctx, f, args); duk_put_global_lstring(ctx, name.as_ptr() as *const i8, name.len() as duk_size_t) == 0 } extern "C" { /// A wrapper around duk_push_error_object, which relies on varargs in /// the original API. /// NOTE: Pulled from duktape crate duktape_sys/src/glue.rs pub fn duk_push_error_object_string( ctx: *mut duk_context, err_code: duk_errcode_t, filename: *const i8, line: duk_int_t, message: *const i8) -> duk_idx_t; } #[cfg(test)] mod tests { #[test] fn test_eval() { use super::*; unsafe { // Pulled from duktape crate duktape_sys/src/lib.rs | Modified to compile. // Create a heap. let ctx = duk_create_heap_default(); // Run a short code snippet. let code = "2+3"; let result = duk_eval_string(ctx, code); assert_eq!(DUK_EXEC_SUCCESS, result); // Get the result and make sure it's correct. assert_eq!(1, duk_is_number(ctx, -1)); assert_eq!(5.0, duk_get_number(ctx, -1)); duk_pop(ctx); duk_destroy_heap(ctx); } } }