summaryrefslogtreecommitdiff
path: root/src/isolate.rs
blob: b4cb138ffa61e5f71ab6bb0acde8101b2a338c1f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
// Copyright 2018 the Deno authors. All rights reserved. MIT license.
use deno_dir;
use flags;
use futures;
use handlers;
use libc::c_void;
use libdeno;
use std;
use std::collections::HashMap;
use std::ffi::CStr;
use std::ffi::CString;
use tokio;

type DenoException<'a> = &'a str;

pub struct Isolate {
  pub ptr: *const libdeno::DenoC,
  pub dir: deno_dir::DenoDir,
  pub rt: tokio::runtime::current_thread::Runtime,
  pub timers: HashMap<u32, futures::sync::oneshot::Sender<()>>,
  pub argv: Vec<String>,
  pub flags: flags::DenoFlags,
}

static DENO_INIT: std::sync::Once = std::sync::ONCE_INIT;

impl Isolate {
  pub fn new(argv: Vec<String>) -> Box<Isolate> {
    DENO_INIT.call_once(|| {
      unsafe { libdeno::deno_init() };
    });

    let (flags, argv_rest) = flags::set_flags(argv);

    let mut deno_box = Box::new(Isolate {
      ptr: 0 as *const libdeno::DenoC,
      dir: deno_dir::DenoDir::new(flags.reload, None).unwrap(),
      rt: tokio::runtime::current_thread::Runtime::new().unwrap(),
      timers: HashMap::new(),
      argv: argv_rest,
      flags,
    });

    (*deno_box).ptr = unsafe {
      libdeno::deno_new(
        deno_box.as_ref() as *const _ as *const c_void,
        handlers::msg_from_js,
      )
    };

    deno_box
  }

  pub fn execute(
    &self,
    js_filename: &str,
    js_source: &str,
  ) -> Result<(), DenoException> {
    let filename = CString::new(js_filename).unwrap();
    let source = CString::new(js_source).unwrap();
    let r = unsafe {
      libdeno::deno_execute(self.ptr, filename.as_ptr(), source.as_ptr())
    };
    if r == 0 {
      let ptr = unsafe { libdeno::deno_last_exception(self.ptr) };
      let cstr = unsafe { CStr::from_ptr(ptr) };
      return Err(cstr.to_str().unwrap());
    }
    Ok(())
  }
}

impl Drop for Isolate {
  fn drop(&mut self) {
    unsafe { libdeno::deno_delete(self.ptr) }
  }
}

pub fn from_c<'a>(d: *const libdeno::DenoC) -> &'a mut Isolate {
  let ptr = unsafe { libdeno::deno_get_data(d) };
  let ptr = ptr as *mut Isolate;
  let isolate_box = unsafe { Box::from_raw(ptr) };
  Box::leak(isolate_box)
}

#[test]
fn test_c_to_rust() {
  let argv = vec![String::from("./deno"), String::from("hello.js")];
  let isolate = Isolate::new(argv);
  let isolate2 = from_c(isolate.ptr);
  assert_eq!(isolate.ptr, isolate2.ptr);
  assert_eq!(
    isolate.dir.root.join("gen"),
    isolate.dir.gen,
    "Sanity check"
  );
}