diff options
author | Ryan Dahl <ry@tinyclouds.org> | 2018-06-22 23:19:43 +0200 |
---|---|---|
committer | Ryan Dahl <ry@tinyclouds.org> | 2018-07-03 21:22:39 +0200 |
commit | cf07ec5b63de58b27611a6c87d2084b7cbb73ba8 (patch) | |
tree | 552f4e4efaa4657b3b0e7b1cbd2054019928f2dc /src | |
parent | 6c9598d35830625ebbefe0716b4ec0853ff279d6 (diff) |
Call into JS from rust
Diffstat (limited to 'src')
-rw-r--r-- | src/main.rs | 81 |
1 files changed, 76 insertions, 5 deletions
diff --git a/src/main.rs b/src/main.rs index 2ba31a16c..2ec347e6e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,14 +1,38 @@ extern crate libc; use libc::c_char; use libc::c_int; +use libc::c_void; use std::ffi::CStr; use std::ffi::CString; +use std::ptr; + +#[repr(C)] +struct deno_buf { + data: *const c_char, + len: c_int, // TODO(ry) should be size_t. +} + +#[repr(C)] +struct DenoC { + _unused: [u8; 0], +} + +type DenoSubCb = extern "C" fn(d: *const DenoC, channel: *const c_char, buf: deno_buf); #[link(name = "deno", kind = "static")] extern "C" { - fn deno_v8_version() -> *const c_char; fn deno_init(); + #[allow(dead_code)] + fn deno_v8_version() -> *const c_char; fn deno_set_flags(argc: *mut c_int, argv: *mut *mut c_char); + + fn deno_new(data: *const c_void, cb: DenoSubCb) -> *const DenoC; + fn deno_delete(d: *const DenoC); + fn deno_last_exception(d: *const DenoC) -> *const c_char; + #[allow(dead_code)] + fn deno_set_response(d: *const DenoC, buf: deno_buf); + fn deno_execute(d: *const DenoC, js_filename: *const c_char, js_source: *const c_char) + -> c_int; } // Pass the command line arguments to v8. @@ -46,15 +70,62 @@ fn set_flags() -> Vec<String> { .collect::<Vec<_>>() } +extern "C" fn on_message(_d: *const DenoC, channel_ptr: *const c_char, _buf: deno_buf) { + let channel: &str = unsafe { + let cstr = CStr::from_ptr(channel_ptr); + cstr.to_str().unwrap() + }; + println!("got message in rust {}", channel); +} + +struct Deno { + ptr: *const DenoC, +} + +impl Deno { + fn new() -> Deno { + let ptr = unsafe { deno_new(ptr::null(), on_message) }; + Deno { ptr: ptr } + } + + fn execute(&self, js_filename: &str, js_source: &str) -> bool { + let filename = CString::new(js_filename).unwrap(); + let source = CString::new(js_source).unwrap(); + let r = unsafe { deno_execute(self.ptr, filename.as_ptr(), source.as_ptr()) }; + r != 0 + } + + fn last_exception(&self) -> &str { + let ptr = unsafe { deno_last_exception(self.ptr) }; + let cstr = unsafe { CStr::from_ptr(ptr) }; + cstr.to_str().unwrap() + } + + fn destroy(self) { + unsafe { deno_delete(self.ptr) } + } +} + fn main() { - println!("Hi"); - let args = set_flags(); unsafe { deno_init() }; + + set_flags(); + + /* let v = unsafe { deno_v8_version() }; let c_str = unsafe { CStr::from_ptr(v) }; let version = c_str.to_str().unwrap(); println!("version: {}", version); - for arg in args { - println!("arg: {}", arg); + */ + + let d = Deno::new(); + + let ok = d.execute("deno_main.js", "denoMain();"); + if !ok { + let e = d.last_exception(); + println!("Error {}\n", e); + std::process::exit(1); } + + d.destroy(); } |