2019-12-05 15:30:20 -05:00
|
|
|
use super::dispatch_json::{Deserialize, JsonOp, Value};
|
|
|
|
use crate::fs as deno_fs;
|
2020-02-23 14:51:29 -05:00
|
|
|
use crate::op_error::OpError;
|
2019-12-05 15:30:20 -05:00
|
|
|
use crate::ops::json_op;
|
2020-02-08 14:34:31 -05:00
|
|
|
use crate::state::State;
|
2020-04-19 23:54:46 -04:00
|
|
|
use deno_core::Isolate;
|
|
|
|
use deno_core::ZeroCopyBuf;
|
2019-12-05 15:30:20 -05:00
|
|
|
use dlopen::symbor::Library;
|
|
|
|
use std::ffi::OsStr;
|
2020-01-20 09:45:44 -05:00
|
|
|
use std::path::Path;
|
2019-12-05 15:30:20 -05:00
|
|
|
|
2020-04-20 10:27:15 -04:00
|
|
|
pub type PluginInitFn = fn(isolate: &mut deno_core::Isolate);
|
|
|
|
|
2020-04-19 23:54:46 -04:00
|
|
|
pub fn init(i: &mut Isolate, s: &State) {
|
2019-12-05 15:30:20 -05:00
|
|
|
i.register_op(
|
2020-02-25 09:14:27 -05:00
|
|
|
"op_open_plugin",
|
2020-04-19 23:54:46 -04:00
|
|
|
s.core_op(json_op(s.stateful_op2(op_open_plugin))),
|
2019-12-05 15:30:20 -05:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2020-02-23 14:51:29 -05:00
|
|
|
fn open_plugin<P: AsRef<OsStr>>(lib_path: P) -> Result<Library, OpError> {
|
2019-12-05 15:30:20 -05:00
|
|
|
debug!("Loading Plugin: {:#?}", lib_path.as_ref());
|
2020-02-23 14:51:29 -05:00
|
|
|
Library::open(lib_path).map_err(OpError::from)
|
2019-12-05 15:30:20 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
struct PluginResource {
|
|
|
|
lib: Library,
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Deserialize)]
|
|
|
|
#[serde(rename_all = "camelCase")]
|
|
|
|
struct OpenPluginArgs {
|
|
|
|
filename: String,
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn op_open_plugin(
|
2020-04-19 23:54:46 -04:00
|
|
|
isolate: &mut deno_core::Isolate,
|
2020-02-08 14:34:31 -05:00
|
|
|
state: &State,
|
2019-12-05 15:30:20 -05:00
|
|
|
args: Value,
|
2020-01-24 15:10:49 -05:00
|
|
|
_zero_copy: Option<ZeroCopyBuf>,
|
2020-02-23 14:51:29 -05:00
|
|
|
) -> Result<JsonOp, OpError> {
|
2020-04-20 10:27:15 -04:00
|
|
|
let args: OpenPluginArgs = serde_json::from_value(args).unwrap();
|
2020-01-20 09:45:44 -05:00
|
|
|
let filename = deno_fs::resolve_from_cwd(Path::new(&args.filename))?;
|
2019-12-05 15:30:20 -05:00
|
|
|
|
2020-01-20 09:45:44 -05:00
|
|
|
state.check_plugin(&filename)?;
|
2019-12-05 15:30:20 -05:00
|
|
|
|
2020-04-20 10:27:15 -04:00
|
|
|
let lib = open_plugin(filename).unwrap();
|
|
|
|
let plugin_resource = PluginResource { lib };
|
2020-04-21 09:48:44 -04:00
|
|
|
|
|
|
|
let mut resource_table = isolate.resource_table.borrow_mut();
|
|
|
|
let rid = resource_table.add("plugin", Box::new(plugin_resource));
|
|
|
|
let plugin_resource = resource_table.get::<PluginResource>(rid).unwrap();
|
2019-12-05 15:30:20 -05:00
|
|
|
|
2020-04-20 10:27:15 -04:00
|
|
|
let deno_plugin_init = *unsafe {
|
2019-12-05 15:30:20 -05:00
|
|
|
plugin_resource
|
|
|
|
.lib
|
|
|
|
.symbol::<PluginInitFn>("deno_plugin_init")
|
|
|
|
}
|
2020-04-20 10:27:15 -04:00
|
|
|
.unwrap();
|
2020-04-21 09:48:44 -04:00
|
|
|
drop(resource_table);
|
|
|
|
|
2020-04-20 10:27:15 -04:00
|
|
|
deno_plugin_init(isolate);
|
2019-12-05 15:30:20 -05:00
|
|
|
|
2020-04-20 10:27:15 -04:00
|
|
|
Ok(JsonOp::Sync(json!(rid)))
|
2019-12-05 15:30:20 -05:00
|
|
|
}
|