-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* compiler wasm export API; start working on export dialog * dialogs done. needs cleanup * clean up * clean up comments * upgrade rust to 1.76
- Loading branch information
1 parent
46710c8
commit 5ccb484
Showing
31 changed files
with
915 additions
and
221 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
use std::cell::RefCell; | ||
|
||
use log::info; | ||
|
||
use celerc::PreparedContext; | ||
|
||
use crate::loader::{self, LoadFileOutput, LoaderInWasm}; | ||
|
||
thread_local! { | ||
static CACHED_COMPILER_CONTEXT: RefCell<Option<PreparedContext<LoaderInWasm>>> = RefCell::new(None); | ||
} | ||
|
||
/// Guard for acquiring the cached context and takes care of releasing it | ||
pub struct CachedContextGuard(Option<PreparedContext<LoaderInWasm>>); | ||
impl CachedContextGuard { | ||
/// Acquire the cached context if it's valid | ||
pub async fn acquire(entry_path: Option<&String>) -> Option<Self> { | ||
match CACHED_COMPILER_CONTEXT.with_borrow_mut(|x| x.take()) { | ||
Some(prep_ctx) => { | ||
// check if cache is still valid | ||
if prep_ctx.entry_path.as_ref() != entry_path { | ||
info!("invalidating compiler cache because entry path changed"); | ||
return None; | ||
} | ||
// TODO #173: prep phase need to output local dependencies | ||
let mut dependencies = vec!["/project.yaml".to_string()]; | ||
if let Some(entry_path) = entry_path { | ||
dependencies.push(entry_path.clone()); | ||
} | ||
for dep in &dependencies { | ||
// strip leading slash if needed | ||
let dep_path = match dep.strip_prefix('/') { | ||
Some(x) => x, | ||
None => dep, | ||
}; | ||
let changed = loader::load_file_check_changed(dep_path).await; | ||
if !matches!(changed, Ok(LoadFileOutput::NotModified)) { | ||
info!("invalidating compiler cache because dependency changed: {dep}"); | ||
return None; | ||
} | ||
} | ||
Some(CachedContextGuard(Some(prep_ctx))) | ||
} | ||
None => None, | ||
} | ||
} | ||
|
||
/// Put a new context into the cache upon drop | ||
pub fn new(prep_ctx: PreparedContext<LoaderInWasm>) -> Self { | ||
CachedContextGuard(Some(prep_ctx)) | ||
} | ||
} | ||
impl Drop for CachedContextGuard { | ||
fn drop(&mut self) { | ||
CACHED_COMPILER_CONTEXT.with_borrow_mut(|x| *x = self.0.take()); | ||
} | ||
} | ||
impl AsRef<PreparedContext<LoaderInWasm>> for CachedContextGuard { | ||
fn as_ref(&self) -> &PreparedContext<LoaderInWasm> { | ||
self.0.as_ref().unwrap() | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
use instant::Instant; | ||
use log::{error, info}; | ||
use wasm_bindgen::prelude::*; | ||
|
||
use celerc::pack::PackError; | ||
use celerc::{Compiler, ExpoDoc, ExportRequest, PluginOptions, PreparedContext}; | ||
|
||
use crate::loader::LoaderInWasm; | ||
use crate::plugin; | ||
|
||
use super::CachedContextGuard; | ||
|
||
pub async fn export_document( | ||
entry_path: Option<String>, | ||
use_cache: bool, | ||
req: ExportRequest, | ||
) -> Result<ExpoDoc, JsValue> { | ||
info!("exporting document"); | ||
let plugin_options = match plugin::get_plugin_options() { | ||
Ok(x) => x, | ||
Err(message) => { | ||
let message = format!("Failed to load user plugin options: {message}"); | ||
error!("{message}"); | ||
return Ok(ExpoDoc::Error(message)); | ||
} | ||
}; | ||
|
||
if use_cache { | ||
if let Some(guard) = CachedContextGuard::acquire(entry_path.as_ref()).await { | ||
info!("using cached compiler context"); | ||
let start_time = Instant::now(); | ||
return export_in_context(guard.as_ref(), Some(start_time), plugin_options, req).await; | ||
} | ||
} | ||
|
||
// create a new context | ||
info!("creating new compiler context"); | ||
let start_time = Instant::now(); | ||
let prep_ctx = match super::new_context(entry_path).await { | ||
Ok(x) => x, | ||
Err(e) => { | ||
return Ok(ExpoDoc::Error(e.to_string())); | ||
} | ||
}; | ||
let guard = CachedContextGuard::new(prep_ctx); | ||
export_in_context(guard.as_ref(), Some(start_time), plugin_options, req).await | ||
} | ||
|
||
async fn export_in_context( | ||
prep_ctx: &PreparedContext<LoaderInWasm>, | ||
start_time: Option<Instant>, | ||
plugin_options: Option<PluginOptions>, | ||
req: ExportRequest, | ||
) -> Result<ExpoDoc, JsValue> { | ||
let mut comp_ctx = prep_ctx.new_compilation(start_time).await; | ||
match comp_ctx.configure_plugins(plugin_options).await { | ||
Err(e) => export_with_pack_error(e), | ||
Ok(_) => match prep_ctx.create_compiler(comp_ctx).await { | ||
Ok(x) => export_with_compiler(x, req).await, | ||
Err((e, _)) => export_with_pack_error(e), | ||
}, | ||
} | ||
} | ||
|
||
fn export_with_pack_error(error: PackError) -> Result<ExpoDoc, JsValue> { | ||
Ok(ExpoDoc::Error(error.to_string())) | ||
} | ||
|
||
async fn export_with_compiler( | ||
compiler: Compiler<'_>, | ||
req: ExportRequest, | ||
) -> Result<ExpoDoc, JsValue> { | ||
let mut comp_doc = compiler.compile().await; | ||
if let Some(expo_doc) = comp_doc.run_exporter(&req) { | ||
return Ok(expo_doc); | ||
} | ||
let exec_ctx = comp_doc.execute().await; | ||
Ok(exec_ctx.run_exporter(req)) | ||
} |
Oops, something went wrong.