WIP: Source Maps
This commit is contained in:
parent
eb9fed759a
commit
f32b8af9ff
10 changed files with 486 additions and 373 deletions
|
|
@ -2,6 +2,7 @@ use crate::{ContextRef, Runtime, ValueResult};
|
|||
use oden_js_sys as sys;
|
||||
use std::ops::Deref;
|
||||
|
||||
#[derive(Eq, PartialEq, Debug, Hash)]
|
||||
pub struct AtomRef {
|
||||
pub(crate) atom: sys::JSAtom,
|
||||
}
|
||||
|
|
@ -56,3 +57,17 @@ impl Drop for Atom {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq for Atom {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.atom == other.atom
|
||||
}
|
||||
}
|
||||
|
||||
impl Eq for Atom {}
|
||||
|
||||
impl std::hash::Hash for Atom {
|
||||
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
|
||||
self.atom.hash(state)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
use super::ModuleRef;
|
||||
use crate::{throw_error, ContextRef, Error, Result};
|
||||
use oden_js_sys as sys;
|
||||
use crate::{Atom, AtomRef, ContextRef, Error, Result};
|
||||
use std::path::Path;
|
||||
|
||||
pub enum ModuleSource<'a> {
|
||||
|
|
@ -9,7 +8,7 @@ pub enum ModuleSource<'a> {
|
|||
}
|
||||
|
||||
pub trait ModuleLoader {
|
||||
fn load(&self, context: &ContextRef, name: &str) -> Result<ModuleSource>;
|
||||
fn load<'a>(&mut self, context: &'a ContextRef, name: &str) -> Result<ModuleSource<'a>>;
|
||||
}
|
||||
|
||||
pub struct DefaultModuleLoader {}
|
||||
|
|
@ -21,7 +20,7 @@ impl DefaultModuleLoader {
|
|||
}
|
||||
|
||||
impl ModuleLoader for DefaultModuleLoader {
|
||||
fn load(&self, _context: &ContextRef, name: &str) -> Result<ModuleSource> {
|
||||
fn load<'a>(&mut self, _context: &'a ContextRef, name: &str) -> Result<ModuleSource<'a>> {
|
||||
// Attempt to open the file.
|
||||
let path = Path::new(name);
|
||||
match std::fs::read_to_string(path) {
|
||||
|
|
@ -31,23 +30,6 @@ impl ModuleLoader for DefaultModuleLoader {
|
|||
}
|
||||
}
|
||||
|
||||
pub(crate) fn load_module(
|
||||
context: &ContextRef,
|
||||
name: &str,
|
||||
loader: &Box<dyn ModuleLoader>,
|
||||
) -> *mut sys::JSModuleDef {
|
||||
match loader.load(context, name) {
|
||||
Ok(ModuleSource::Native(native)) => native.module,
|
||||
Ok(ModuleSource::JavaScript(js)) => match context.eval_module(&js, name) {
|
||||
Ok(v) => v.module,
|
||||
Err(e) => {
|
||||
throw_error(context, e);
|
||||
return std::ptr::null_mut();
|
||||
}
|
||||
},
|
||||
Err(e) => {
|
||||
throw_error(context, e);
|
||||
return std::ptr::null_mut();
|
||||
}
|
||||
}
|
||||
pub trait SourceMapper {
|
||||
fn map_source(&self, context: &ContextRef, file: &AtomRef, line: u32) -> Result<(Atom, u32)>;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ pub mod native;
|
|||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct ModuleRef {
|
||||
module: *mut sys::JSModuleDef,
|
||||
pub(crate) module: *mut sys::JSModuleDef,
|
||||
}
|
||||
|
||||
impl ModuleRef {
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
use crate::{
|
||||
module::loader::{load_module, DefaultModuleLoader, ModuleLoader},
|
||||
module::loader::{DefaultModuleLoader, ModuleLoader, ModuleSource, SourceMapper},
|
||||
promise::{PromiseEvent, PromiseHandle},
|
||||
ContextRef, DefaultRejectedPromiseTracker, Promise, RejectedPromiseTracker, Result, Value,
|
||||
ValueRef,
|
||||
throw_error, ContextRef, DefaultRejectedPromiseTracker, Promise, RejectedPromiseTracker,
|
||||
Result, Value, ValueRef,
|
||||
};
|
||||
use oden_js_sys as sys;
|
||||
use std::cell::{RefCell, RefMut};
|
||||
|
|
@ -42,11 +42,12 @@ impl Drop for PromiseEntry {
|
|||
|
||||
struct PrivateState {
|
||||
refs: u64,
|
||||
loader: Arc<Box<dyn ModuleLoader>>,
|
||||
loader: Arc<RefCell<Box<dyn ModuleLoader>>>,
|
||||
promise_send: Sender<(PromiseHandle, PromiseEvent)>,
|
||||
promise_recv: Receiver<(PromiseHandle, PromiseEvent)>,
|
||||
promise_table: HashMap<PromiseHandle, PromiseEntry>, // !
|
||||
rejection_tracker: Arc<Box<dyn RejectedPromiseTracker>>,
|
||||
source_mapper: Option<Arc<Box<dyn SourceMapper>>>,
|
||||
}
|
||||
|
||||
impl PrivateState {
|
||||
|
|
@ -54,11 +55,12 @@ impl PrivateState {
|
|||
let (send, recv) = channel();
|
||||
Box::new(RefCell::new(PrivateState {
|
||||
refs: 1,
|
||||
loader: Arc::new(Box::new(DefaultModuleLoader::new())),
|
||||
loader: Arc::new(RefCell::new(Box::new(DefaultModuleLoader::new()))),
|
||||
promise_send: send,
|
||||
promise_recv: recv,
|
||||
promise_table: HashMap::new(),
|
||||
rejection_tracker: Arc::new(Box::new(DefaultRejectedPromiseTracker::new())),
|
||||
source_mapper: None,
|
||||
}))
|
||||
}
|
||||
|
||||
|
|
@ -90,7 +92,26 @@ impl PrivateState {
|
|||
.clone()
|
||||
};
|
||||
let context = ContextRef::from_raw(ctx);
|
||||
load_module(&context, path, &loader)
|
||||
|
||||
let result = {
|
||||
let mut loader = loader.borrow_mut();
|
||||
loader.load(&context, path)
|
||||
};
|
||||
|
||||
match result {
|
||||
Ok(ModuleSource::Native(native)) => native.module,
|
||||
Ok(ModuleSource::JavaScript(js)) => match context.eval_module(&js, path) {
|
||||
Ok(v) => v.module,
|
||||
Err(e) => {
|
||||
throw_error(&context, e);
|
||||
std::ptr::null_mut()
|
||||
}
|
||||
},
|
||||
Err(e) => {
|
||||
throw_error(&context, e);
|
||||
std::ptr::null_mut()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unsafe extern "C" fn promise_rejection_tracker(
|
||||
|
|
@ -171,7 +192,7 @@ impl Runtime {
|
|||
T: ModuleLoader + 'static,
|
||||
{
|
||||
let mut state = unsafe { PrivateState::from_rt_mut(self.rt) };
|
||||
state.loader = Arc::new(Box::new(loader));
|
||||
state.loader = Arc::new(RefCell::new(Box::new(loader)));
|
||||
}
|
||||
|
||||
/// Set a tracker to be notified whenever a promise is rejected. By
|
||||
|
|
@ -184,6 +205,16 @@ impl Runtime {
|
|||
state.rejection_tracker = Arc::new(Box::new(tracker));
|
||||
}
|
||||
|
||||
/// Set the source map handler. By default this is unset, and no source
|
||||
/// mapping occurs.
|
||||
pub fn set_source_mapper<T>(&mut self, mapper: T)
|
||||
where
|
||||
T: SourceMapper + 'static,
|
||||
{
|
||||
let mut state = unsafe { PrivateState::from_rt_mut(self.rt) };
|
||||
state.source_mapper = Some(Arc::new(Box::new(mapper)));
|
||||
}
|
||||
|
||||
pub fn run_gc(&mut self) {
|
||||
unsafe {
|
||||
sys::JS_RunGC(self.rt);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue