mirror of
https://github.com/exoticorn/curlywas.git
synced 2026-01-20 11:46:43 +01:00
always return dependencies, even when hitting an error
This commit is contained in:
106
src/lib.rs
106
src/lib.rs
@@ -28,65 +28,71 @@ pub struct CompiledModule {
|
|||||||
pub dependencies: Vec<PathBuf>,
|
pub dependencies: Vec<PathBuf>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn compile_file<P: AsRef<Path>>(path: P, options: Options) -> Result<CompiledModule> {
|
pub fn compile_file<P: AsRef<Path>>(path: P, options: Options) -> (Result<Vec<u8>>, Vec<PathBuf>) {
|
||||||
let mut dependencies = HashSet::new();
|
fn compile_file_inner(
|
||||||
|
path: &Path,
|
||||||
|
options: Options,
|
||||||
|
dependencies: &mut HashSet<PathBuf>,
|
||||||
|
) -> Result<Vec<u8>> {
|
||||||
|
let mut script = ast::Script::default();
|
||||||
|
|
||||||
let path = path.as_ref();
|
let mut sources = Sources::new();
|
||||||
let mut script = ast::Script::default();
|
|
||||||
|
|
||||||
let mut sources = Sources::new();
|
let mut pending_files = vec![(path.to_path_buf(), None)];
|
||||||
|
while let Some((path, span)) = pending_files.pop() {
|
||||||
|
match sources.add(&path) {
|
||||||
|
Ok((id, true)) => {
|
||||||
|
dependencies.insert(path.clone());
|
||||||
|
let mut new_script = match parser::parse(&sources, id) {
|
||||||
|
Ok(script) => script,
|
||||||
|
Err(_) => bail!("Parse failed"),
|
||||||
|
};
|
||||||
|
|
||||||
let mut pending_files = vec![(path.to_path_buf(), None)];
|
includes::resolve_includes(&mut new_script, dependencies, &path)?;
|
||||||
while let Some((path, span)) = pending_files.pop() {
|
|
||||||
match sources.add(&path) {
|
|
||||||
Ok((id, true)) => {
|
|
||||||
dependencies.insert(path.clone());
|
|
||||||
let mut new_script = match parser::parse(&sources, id) {
|
|
||||||
Ok(script) => script,
|
|
||||||
Err(_) => bail!("Parse failed"),
|
|
||||||
};
|
|
||||||
|
|
||||||
includes::resolve_includes(&mut new_script, &mut dependencies, &path)?;
|
for include in std::mem::take(&mut new_script.includes) {
|
||||||
|
let mut path = path
|
||||||
|
.parent()
|
||||||
|
.expect("Script path has no parent")
|
||||||
|
.to_path_buf();
|
||||||
|
path.push(include.path);
|
||||||
|
pending_files.push((path, Some(include.span)));
|
||||||
|
}
|
||||||
|
|
||||||
for include in std::mem::take(&mut new_script.includes) {
|
script.merge(new_script);
|
||||||
let mut path = path
|
|
||||||
.parent()
|
|
||||||
.expect("Script path has no parent")
|
|
||||||
.to_path_buf();
|
|
||||||
path.push(include.path);
|
|
||||||
pending_files.push((path, Some(include.span)));
|
|
||||||
}
|
}
|
||||||
|
Ok((_, false)) => (), // already parsed this include
|
||||||
script.merge(new_script);
|
Err(err) => {
|
||||||
}
|
if let Some(span) = span {
|
||||||
Ok((_, false)) => (), // already parsed this include
|
let _ = typecheck::report_error(&err.to_string(), &span, &sources);
|
||||||
Err(err) => {
|
} else {
|
||||||
if let Some(span) = span {
|
eprintln!("Failed to load script {}: {}", path.display(), err);
|
||||||
let _ = typecheck::report_error(&err.to_string(), &span, &sources);
|
}
|
||||||
} else {
|
bail!("Parse failed");
|
||||||
eprintln!("Failed to load script {}: {}", path.display(), err);
|
|
||||||
}
|
}
|
||||||
bail!("Parse failed");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if constfold::fold_script(&mut script, &sources).is_err() {
|
||||||
|
bail!("Constant folding failed");
|
||||||
|
}
|
||||||
|
if typecheck::tc_script(&mut script, &sources).is_err() {
|
||||||
|
bail!("Type check failed");
|
||||||
|
}
|
||||||
|
let wasm = emit::emit(
|
||||||
|
&script,
|
||||||
|
&path
|
||||||
|
.file_stem()
|
||||||
|
.unwrap_or_else(|| OsStr::new("unknown"))
|
||||||
|
.to_string_lossy(),
|
||||||
|
&options,
|
||||||
|
);
|
||||||
|
Ok(wasm)
|
||||||
}
|
}
|
||||||
|
|
||||||
if constfold::fold_script(&mut script, &sources).is_err() {
|
let mut dependencies = HashSet::new();
|
||||||
bail!("Constant folding failed");
|
|
||||||
}
|
let result = compile_file_inner(path.as_ref(), options, &mut dependencies);
|
||||||
if typecheck::tc_script(&mut script, &sources).is_err() {
|
|
||||||
bail!("Type check failed");
|
(result, dependencies.into_iter().collect())
|
||||||
}
|
|
||||||
let wasm = emit::emit(
|
|
||||||
&script,
|
|
||||||
&path
|
|
||||||
.file_stem()
|
|
||||||
.unwrap_or_else(|| OsStr::new("unknown"))
|
|
||||||
.to_string_lossy(),
|
|
||||||
&options,
|
|
||||||
);
|
|
||||||
Ok(CompiledModule {
|
|
||||||
wasm,
|
|
||||||
dependencies: dependencies.into_iter().collect(),
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,12 +15,12 @@ fn main() -> Result<()> {
|
|||||||
|
|
||||||
let mut filename = args.free_from_os_str::<PathBuf, bool>(|s| Ok(s.into()))?;
|
let mut filename = args.free_from_os_str::<PathBuf, bool>(|s| Ok(s.into()))?;
|
||||||
|
|
||||||
let module = compile_file(&filename, options)?;
|
let wasm = compile_file(&filename, options).0?;
|
||||||
|
|
||||||
wasmparser::validate(&module.wasm)?;
|
wasmparser::validate(&wasm)?;
|
||||||
|
|
||||||
filename.set_extension("wasm");
|
filename.set_extension("wasm");
|
||||||
File::create(filename)?.write_all(&module.wasm)?;
|
File::create(filename)?.write_all(&wasm)?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user