Skip to content

Commit

Permalink
Make steel-core compile for wasm32-unknown-unknown (#141)
Browse files Browse the repository at this point in the history
  • Loading branch information
mattwparas authored Jan 18, 2024
1 parent 69d978f commit 232982c
Show file tree
Hide file tree
Showing 12 changed files with 131 additions and 23 deletions.
5 changes: 4 additions & 1 deletion crates/steel-core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@ weak-table = "0.3.2"
rand = "0.8.5"
# TODO: Consider only depending on the sub crate
num = "0.4.0"
which = "4.4.0"
radix_fmt = "1.0.0"

# For structs
Expand All @@ -67,6 +66,9 @@ anyhow = { version = "1", optional = true }

stacker = { version = "0.1.15", optional = true }

[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
which = { version = "4.4.0" }

[dev-dependencies]
proptest = "1.1.0"
criterion = "0.5.1"
Expand All @@ -76,6 +78,7 @@ env_logger = "0.10.0"
steel-gen = { path = "../steel-gen", version = "0.2.0" }

[features]
# TODO: Deprecate the modules feature flag, it no longer does anything
default = ["modules"]
modules = []
jit = ["dep:cranelift", "dep:cranelift-module", "dep:cranelift-jit"]
Expand Down
7 changes: 7 additions & 0 deletions crates/steel-core/src/compiler/compiler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ use super::{

use im_rc::HashMap as ImmutableHashMap;

#[cfg(feature = "profiling")]
use std::time::Instant;

// use itertools::Itertools;
Expand Down Expand Up @@ -782,13 +783,16 @@ impl Compiler {
path: Option<PathBuf>,
sources: &mut Sources,
) -> Result<Vec<ExprKind>> {
#[cfg(feature = "profiling")]
let now = Instant::now();

let mut expanded_statements =
self.expand_expressions(exprs, path, sources, builtin_modules.clone())?;

#[cfg(feature = "profiling")]
log::debug!(target: "pipeline_time", "Phase 1 module expansion time: {:?}", now.elapsed());

#[cfg(feature = "profiling")]
let now = Instant::now();

log::debug!(target: "expansion-phase", "Expanding macros -> phase 1");
Expand Down Expand Up @@ -848,13 +852,15 @@ impl Compiler {

// TODO: Check that defines are in legal positions, post expansion.

#[cfg(feature = "profiling")]
log::debug!(target: "pipeline_time", "Top level macro expansion time: {:?}", now.elapsed());

log::debug!(target: "expansion-phase", "Beginning constant folding");

let mut expanded_statements =
self.apply_const_evaluation(constants.clone(), expanded_statements, false)?;

#[cfg(feature = "profiling")]
let now = Instant::now();

// RenameShadowedVariables::rename_shadowed_vars(&mut expanded_statements);
Expand Down Expand Up @@ -955,6 +961,7 @@ impl Compiler {

semantic.replace_anonymous_function_calls_with_plain_lets();

#[cfg(feature = "profiling")]
log::info!(target: "pipeline_time", "CAT time: {:?}", now.elapsed());

self.analysis = semantic.into_analysis();
Expand Down
44 changes: 32 additions & 12 deletions crates/steel-core/src/compiler/modules.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,12 @@ use super::{

macro_rules! time {
($label:expr, $e:expr) => {{
#[cfg(feature = "profiling")]
let now = std::time::Instant::now();

let e = $e;

#[cfg(feature = "profiling")]
log::debug!(target: "pipeline_time", "{}: {:?}", $label, now.elapsed());

e
Expand Down Expand Up @@ -114,8 +116,12 @@ create_prelude!(
// for_syntax "#%private/steel/match"
);

#[cfg(not(target_arch = "wasm32"))]
pub static STEEL_HOME: Lazy<Option<String>> = Lazy::new(|| std::env::var("STEEL_HOME").ok());

#[cfg(target_arch = "wasm32")]
pub static STEEL_HOME: Lazy<Option<String>> = Lazy::new(|| None);

/// Manages the modules
/// keeps some visited state on the manager for traversal
/// Also keeps track of the metadata for each file in order to determine
Expand Down Expand Up @@ -944,18 +950,18 @@ impl ModuleManager {
(module, in_scope_macros, name_mangler)
}

#[cfg(not(feature = "modules"))]
pub(crate) fn expand_expressions(
&mut self,
global_macro_map: &mut HashMap<InternedString, SteelMacro>,
mut exprs: Vec<ExprKind>,
) -> Result<Vec<ExprKind>> {
extract_macro_defs(&mut exprs, global_macro_map)?;
exprs
.into_iter()
.map(|x| expand(x, global_macro_map))
.collect()
}
// #[cfg(not(feature = "modules"))]
// pub(crate) fn expand_expressions(
// &mut self,
// global_macro_map: &mut HashMap<InternedString, SteelMacro>,
// mut exprs: Vec<ExprKind>,
// ) -> Result<Vec<ExprKind>> {
// extract_macro_defs(&mut exprs, global_macro_map)?;
// exprs
// .into_iter()
// .map(|x| expand(x, global_macro_map))
// .collect()
// }
}

// Pre-compile module to bytecode? Is it even possible?
Expand Down Expand Up @@ -1665,12 +1671,16 @@ impl<'a> ModuleBuilder<'a> {
// change the path to not always be required
// if its not required we know its not coming in

#[cfg(not(target_arch = "wasm32"))]
let name = if let Some(p) = name {
std::fs::canonicalize(p)?
} else {
std::env::current_dir()?
};

#[cfg(target_arch = "wasm32")]
let name = PathBuf::new();

Ok(ModuleBuilder {
name,
main: true,
Expand Down Expand Up @@ -1826,6 +1836,10 @@ impl<'a> ModuleBuilder<'a> {
.filter(|x| matches!(x.path, PathOrBuiltIn::Path(_)))
.map(|x| x.path.get_path())
{
if cfg!(target_arch = "wasm32") {
stop!(Generic => "requiring modules is not supported for wasm");
}

let last_modified = std::fs::metadata(module.as_ref())?.modified()?;

// Check if we should compile based on the last time modified
Expand Down Expand Up @@ -2494,6 +2508,10 @@ impl<'a> ModuleBuilder<'a> {
return Ok(());
}

if cfg!(target_arch = "wasm32") {
stop!(Generic => "requiring modules is not supported for wasm");
}

let mut current = self.name.clone();
if current.is_file() {
current.pop();
Expand Down Expand Up @@ -2777,6 +2795,7 @@ impl<'a> ModuleBuilder<'a> {
}

fn parse_builtin(mut self, input: Cow<'static, str>) -> Result<Self> {
#[cfg(feature = "profiling")]
let now = std::time::Instant::now();

let id = self
Expand All @@ -2790,6 +2809,7 @@ impl<'a> ModuleBuilder<'a> {

self.source_ast = parsed;

#[cfg(feature = "profiling")]
log::debug!(target: "pipeline_time", "Parsing: {:?} - {:?}", self.name, now.elapsed());

// self.source_ast.pretty_print();
Expand Down
9 changes: 9 additions & 0 deletions crates/steel-core/src/compiler/passes/analysis.rs
Original file line number Diff line number Diff line change
Expand Up @@ -325,10 +325,12 @@ impl Analysis {
pub fn fresh_from_exprs(&mut self, exprs: &[ExprKind]) {
self.clear();

#[cfg(feature = "profiling")]
let now = std::time::Instant::now();

self.run(exprs);

#[cfg(feature = "profiling")]
log::debug!(target: "pipeline_time", "Analysis time: {:?}", now.elapsed());
}

Expand Down Expand Up @@ -3896,6 +3898,7 @@ impl<'a> SemanticAnalysis<'a> {
module_manager: &mut ModuleManager,
table: &mut FxHashSet<InternedString>,
) -> &mut Self {
#[cfg(feature = "profiling")]
let now = std::time::Instant::now();

let mut replacer =
Expand Down Expand Up @@ -3941,6 +3944,7 @@ impl<'a> SemanticAnalysis<'a> {
macro_replacer.visit(expr);
}

#[cfg(feature = "profiling")]
log::info!(
target: "pipeline_time",
"Replacing non shadowed globals time: {:?}",
Expand All @@ -3961,6 +3965,7 @@ impl<'a> SemanticAnalysis<'a> {
macros: &FxHashMap<InternedString, SteelMacro>,
module_manager: &ModuleManager,
) -> &mut Self {
#[cfg(feature = "profiling")]
let now = std::time::Instant::now();

let module_get_interned: InternedString = "%module-get%".into();
Expand Down Expand Up @@ -4038,6 +4043,7 @@ impl<'a> SemanticAnalysis<'a> {
}

if !found {
#[cfg(feature = "profiling")]
log::debug!(target: "pipeline_time", "Removing unused globals time: {:?}", now.elapsed());

return self;
Expand Down Expand Up @@ -4165,6 +4171,7 @@ impl<'a> SemanticAnalysis<'a> {
return true;
});

#[cfg(feature = "profiling")]
log::debug!(target: "pipeline_time", "Removing unused globals time: {:?}", now.elapsed());

// self.exprs.push(ExprKind::ident("void"));
Expand Down Expand Up @@ -4312,6 +4319,7 @@ impl<'a> SemanticAnalysis<'a> {
}

pub fn replace_anonymous_function_calls_with_plain_lets(&mut self) -> &mut Self {
#[cfg(feature = "profiling")]
let now = std::time::Instant::now();

let mut re_run_analysis = false;
Expand Down Expand Up @@ -4360,6 +4368,7 @@ impl<'a> SemanticAnalysis<'a> {

self.find_anonymous_function_calls_and_mutate_with(func);

#[cfg(feature = "profiling")]
log::debug!(target: "pipeline_time", "Anonymous function calls -> lets time: {:?}", now.elapsed());

if re_run_analysis {
Expand Down
7 changes: 5 additions & 2 deletions crates/steel-core/src/compiler/passes/begin.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
use log::debug;
use steel_parser::{
ast::{Define, If, Let, Macro, Quote, Require, Return, SyntaxRules},
tokens::MaybeBigInt,
Expand All @@ -10,6 +9,8 @@ use crate::parser::{
visitors::VisitorMutRef,
};
use crate::parser::{interner::InternedString, tokens::TokenType};

#[cfg(feature = "profiling")]
use std::time::Instant;

use super::{Folder, VisitorMutRefUnit, VisitorMutUnit};
Expand Down Expand Up @@ -284,6 +285,7 @@ impl VisitorMutRefUnit for FlattenBegin {
pub fn flatten_begins_and_expand_defines(
exprs: Vec<ExprKind>,
) -> crate::rvals::Result<Vec<ExprKind>> {
#[cfg(feature = "profiling")]
let flatten_begins_and_expand_defines_time = Instant::now();

let res = exprs
Expand All @@ -300,7 +302,8 @@ pub fn flatten_begins_and_expand_defines(
})
.collect();

debug!(
#[cfg(feature = "profiling")]
log::debug!(
target: "pipeline_time",
"Flatten begins and expand defines time: {:?}",
flatten_begins_and_expand_defines_time.elapsed()
Expand Down
41 changes: 38 additions & 3 deletions crates/steel-core/src/compiler/program.rs
Original file line number Diff line number Diff line change
Expand Up @@ -916,6 +916,38 @@ impl RawProgramWithSymbols {
self
}

pub fn debug_generate_instructions(
mut self,
symbol_map: &mut SymbolMap,
) -> Result<Vec<String>> {
let mut interner = DebruijnIndicesInterner::default();

for expression in &mut self.instructions {
interner.collect_first_pass_defines(expression, symbol_map)?
}

for expression in &mut self.instructions {
interner.collect_second_pass_defines(expression, symbol_map)?
}

// TODO try here - the loop condition local const arity two seems to rely on the
// existence of having been already adjusted by the interner
for instructions in &mut self.instructions {
// loop_condition_local_const_arity_two(instructions);
specialize_constants(instructions)?;
}

// Put the new struct functions at the front
// struct_instructions.append(&mut self.instructions);
// self.instructions = struct_instructions;

Ok(self
.instructions
.into_iter()
.map(|i| crate::core::instructions::disassemble(&i))
.collect())
}

pub fn debug_build(mut self, _name: String, symbol_map: &mut SymbolMap) -> Result<()> {
#[cfg(feature = "profiling")]
let now = Instant::now();
Expand Down Expand Up @@ -1017,7 +1049,10 @@ impl RawProgramWithSymbols {
Ok(Executable {
name: Rc::new(name),
version: Rc::new(self.version),
time_stamp: SystemTime::now(),
#[cfg(not(target_arch = "wasm32"))]
time_stamp: Some(SystemTime::now()),
#[cfg(target_arch = "wasm32")]
time_stamp: None,
instructions: instructions
.into_iter()
.map(|x| Rc::from(x.into_boxed_slice()))
Expand Down Expand Up @@ -1091,7 +1126,7 @@ fn extract_spans(
pub struct Executable {
pub(crate) name: Rc<String>,
pub(crate) version: Rc<String>,
pub(crate) time_stamp: SystemTime, // TODO -> don't use system time, probably not as portable, prefer date time
pub(crate) time_stamp: Option<SystemTime>, // TODO -> don't use system time, probably not as portable, prefer date time
pub(crate) instructions: Vec<Rc<[DenseInstruction]>>,
pub(crate) constant_map: ConstantMap,
pub(crate) spans: Vec<Rc<[Span]>>,
Expand All @@ -1102,7 +1137,7 @@ impl Executable {
&self.name
}

pub fn time_stamp(&self) -> &SystemTime {
pub fn time_stamp(&self) -> &Option<SystemTime> {
&self.time_stamp
}
}
2 changes: 2 additions & 0 deletions crates/steel-core/src/parser/kernel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -517,6 +517,7 @@ impl Kernel {
expr: ExprKind,
environment: &str,
) -> Result<ExprKind> {
#[cfg(feature = "profiling")]
let now = std::time::Instant::now();

let span = get_span(&expr);
Expand Down Expand Up @@ -550,6 +551,7 @@ impl Kernel {
// This shouldn't be lowering all the way. It should just be back to list right?
let res = TryFromSteelValVisitorForExprKind::root(&result);

#[cfg(feature = "profiling")]
log::debug!(target: "pipeline_time", "Kernel expansion time: {:?}", now.elapsed());

res
Expand Down
4 changes: 4 additions & 0 deletions crates/steel-core/src/primitives/process.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,14 @@ struct ProcessExitStatus {
}

fn binary_exists_on_path(binary: String) -> Option<String> {
#[cfg(not(target_arch = "wasm32"))]
match which::which(binary) {
Ok(v) => Some(v.into_os_string().into_string().unwrap()),
Err(_) => None,
}

#[cfg(target_arch = "wasm32")]
None
}

impl ProcessExitStatus {
Expand Down
3 changes: 2 additions & 1 deletion crates/steel-core/src/primitives/time.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ use crate::gc::Gc;
use crate::SteelVal;
use crate::{rvals::Custom, steel_vm::builtin::MarkdownDoc};
use chrono::Local;
use std::{time::Duration, time::Instant};
use std::time::Duration;
use std::time::Instant;
use steel_derive::function;

use crate::steel_vm::builtin::BuiltInModule;
Expand Down
Loading

0 comments on commit 232982c

Please sign in to comment.