summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorRyan Dahl <ry@tinyclouds.org>2018-07-26 17:47:42 -0400
committerRyan Dahl <ry@tinyclouds.org>2018-07-29 00:22:39 -0400
commit20a41aa9b5c3883390d368b74d7e9e1c46efd32a (patch)
tree874ad7e3a2fe600d75aca9edbf6891200262efd5 /src
parente7445507aac75b7e1471413f862c7f72ef0d02c4 (diff)
Add from_c() to get a Deno object from ptr.
This is a utility function for CodeCache and other handlers.
Diffstat (limited to 'src')
-rw-r--r--src/binding.cc2
-rw-r--r--src/binding.rs1
-rw-r--r--src/deno.h3
-rw-r--r--src/main.rs58
4 files changed, 46 insertions, 18 deletions
diff --git a/src/binding.cc b/src/binding.cc
index 7b5da2d7f..ff2f8bd84 100644
--- a/src/binding.cc
+++ b/src/binding.cc
@@ -288,6 +288,8 @@ void deno_init() {
v8::V8::Initialize();
}
+void* deno_get_data(Deno* d) { return d->data; }
+
const char* deno_v8_version() { return v8::V8::GetVersion(); }
// TODO(ry) Remove these when we call deno_reply_start from Rust.
diff --git a/src/binding.rs b/src/binding.rs
index 1ef376dff..a846401bc 100644
--- a/src/binding.rs
+++ b/src/binding.rs
@@ -27,6 +27,7 @@ extern "C" {
pub fn deno_new(data: *const c_void, cb: DenoRecvCb) -> *const DenoC;
pub fn deno_delete(d: *const DenoC);
pub fn deno_last_exception(d: *const DenoC) -> *const c_char;
+ pub fn deno_get_data(d: *const DenoC) -> *const c_void;
pub fn deno_set_response(d: *const DenoC, buf: deno_buf);
pub fn deno_execute(
d: *const DenoC,
diff --git a/src/deno.h b/src/deno.h
index bb4c91f1c..7bde5ab9d 100644
--- a/src/deno.h
+++ b/src/deno.h
@@ -31,6 +31,9 @@ void deno_set_flags(int* argc, char** argv);
Deno* deno_new(void* data, deno_recv_cb cb);
void deno_delete(Deno* d);
+// Returns the void* data provided in deno_new.
+void* deno_get_data(Deno*);
+
// Returns false on error.
// Get error text with deno_last_exception().
// 0 = fail, 1 = success
diff --git a/src/main.rs b/src/main.rs
index 67f4473b8..38ba654b9 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -6,19 +6,15 @@ extern crate msg_rs as msg_generated;
extern crate url;
use libc::c_int;
+use libc::c_void;
use std::env;
use std::ffi::CStr;
use std::ffi::CString;
use std::mem;
-use std::ptr;
mod handlers;
pub use handlers::*;
mod binding;
-use binding::{
- deno_delete, deno_execute, deno_handle_msg_from_js, deno_init,
- deno_last_exception, deno_new, deno_set_flags, DenoC,
-};
// Returns args passed to V8, followed by args passed to JS
fn parse_core_args(args: Vec<String>) -> (Vec<String>, Vec<String>) {
@@ -71,7 +67,7 @@ fn set_flags(args: Vec<String>) -> Vec<String> {
let mut c_argc = c_argv.len() as c_int;
// Let v8 parse the arguments it recognizes and remove them from c_argv.
unsafe {
- deno_set_flags(&mut c_argc, c_argv.as_mut_ptr());
+ binding::deno_set_flags(&mut c_argc, c_argv.as_mut_ptr());
};
// If c_argc was updated we have to change the length of c_argv to match.
c_argv.truncate(c_argc as usize);
@@ -89,14 +85,28 @@ fn set_flags(args: Vec<String>) -> Vec<String> {
type DenoException<'a> = &'a str;
-struct Deno {
- ptr: *const DenoC,
+pub struct Deno {
+ ptr: *const binding::DenoC,
}
+static DENO_INIT: std::sync::Once = std::sync::ONCE_INIT;
+
impl Deno {
- fn new() -> Deno {
- let ptr = unsafe { deno_new(ptr::null(), deno_handle_msg_from_js) };
- Deno { ptr: ptr }
+ fn new<'a>() -> &'a mut Deno {
+ DENO_INIT.call_once(|| {
+ unsafe { binding::deno_init() };
+ });
+
+ let deno_box = Box::new(Deno {
+ ptr: 0 as *const binding::DenoC,
+ });
+ let deno: &'a mut Deno = Box::leak(deno_box);
+ let external_ptr = deno as *mut _ as *const c_void;
+ let internal_deno_ptr = unsafe {
+ binding::deno_new(external_ptr, binding::deno_handle_msg_from_js)
+ };
+ deno.ptr = internal_deno_ptr;
+ deno
}
fn execute(
@@ -106,10 +116,11 @@ impl Deno {
) -> Result<(), DenoException> {
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()) };
+ let r = unsafe {
+ binding::deno_execute(self.ptr, filename.as_ptr(), source.as_ptr())
+ };
if r == 0 {
- let ptr = unsafe { deno_last_exception(self.ptr) };
+ let ptr = unsafe { binding::deno_last_exception(self.ptr) };
let cstr = unsafe { CStr::from_ptr(ptr) };
return Err(cstr.to_str().unwrap());
}
@@ -119,7 +130,7 @@ impl Deno {
impl Drop for Deno {
fn drop(&mut self) {
- unsafe { deno_delete(self.ptr) }
+ unsafe { binding::deno_delete(self.ptr) }
}
}
@@ -136,6 +147,19 @@ fn test_parse_core_args_2() {
assert!(js_args == (vec!["deno".to_string()], vec!["--help".to_string()]));
}
+pub fn from_c<'a>(d: *const binding::DenoC) -> &'a mut Deno {
+ let ptr = unsafe { binding::deno_get_data(d) };
+ let deno_ptr = ptr as *mut Deno;
+ let deno_box = unsafe { Box::from_raw(deno_ptr) };
+ Box::leak(deno_box)
+}
+
+#[test]
+fn test_c_to_rust() {
+ let d = Deno::new();
+ let d2 = from_c(d.ptr);
+ assert!(d.ptr == d2.ptr);
+}
static LOGGER: Logger = Logger;
@@ -158,8 +182,6 @@ fn main() {
log::set_logger(&LOGGER).unwrap();
log::set_max_level(log::LevelFilter::Info);
- unsafe { deno_init() };
-
let _js_args = set_flags(env::args().collect());
/*
@@ -169,7 +191,7 @@ fn main() {
println!("version: {}", version);
*/
- let mut d = Deno::new();
+ let d = Deno::new();
d.execute("deno_main.js", "denoMain();")
.unwrap_or_else(|err| {