Fork of daniellemaywood.uk/gleam — Wasm codegen work
2

Configure Feed

Select the types of activity you want to include in your feed.

Begin implementation of Wasm codegen

author
Danielle Maywood
committer
nandi
date (Jul 26, 2026, 12:13 PM -0700) commit 4343dd43 parent c3c41d93 change-id vyvwuuvm
+222 -846
+1 -1
compiler-cli/src/compile_package.rs
··· 45 45 .javascript_prelude 46 46 .ok_or_else(|| Error::JavaScriptPreludeRequired)?, 47 47 }, 48 - Target::Cranelift => TargetCodegenConfiguration::Cranelift {}, 48 + Target::Wasm => TargetCodegenConfiguration::Wasm {}, 49 49 }; 50 50 51 51 tracing::info!("Compiling package");
+1 -1
compiler-cli/src/publish.rs
··· 545 545 let generated_files = match target { 546 546 Target::Erlang => generated_erlang_files(paths, &built.root_package)?, 547 547 Target::JavaScript => vec![], 548 - Target::Cranelift => vec![], 548 + Target::Wasm => vec![], 549 549 }; 550 550 let src_files = project_files(Utf8Path::new(""))?; 551 551 let contents_tar_gz = contents_tarball(paths, &src_files, &generated_files)?;
+1 -1
compiler-cli/src/run.rs
··· 157 157 run_javascript_bun_command(paths, &main_function.package, &module, arguments) 158 158 } 159 159 }, 160 - Target::Cranelift => todo!("run"), 160 + Target::Wasm => todo!("run"), 161 161 } 162 162 } 163 163
+2
compiler-core/Cargo.toml
··· 47 47 # Sourcemap generation 48 48 sourcemap = "9" 49 49 indexmap = "2.12.1" 50 + # Wasm binary emission 51 + wasm-encoder = "0.239.0" 50 52 51 53 num-bigint.workspace = true 52 54 num-traits.workspace = true
+13 -13
compiler-core/src/analyse.rs
··· 457 457 has_body: true, 458 458 has_erlang_external: false, 459 459 has_javascript_external: false, 460 - has_cranelift_external: false, 460 + has_wasm_external: false, 461 461 }; 462 462 let mut expr_typer = ExprTyper::new(environment, definition, &mut self.problems); 463 463 let typed_expr = expr_typer.infer_const(&annotation, *value); ··· 551 551 deprecation, 552 552 external_erlang, 553 553 external_javascript, 554 - external_cranelift, 554 + external_wasm, 555 555 return_type: (), 556 556 implementations: _, 557 557 purity: _, ··· 580 580 target, 581 581 &external_erlang, 582 582 &external_javascript, 583 - &external_cranelift, 583 + &external_wasm, 584 584 ); 585 585 586 586 // The function must have at least one implementation somewhere. ··· 604 604 has_body, 605 605 has_erlang_external: external_erlang.is_some(), 606 606 has_javascript_external: external_javascript.is_some(), 607 - has_cranelift_external: external_cranelift.is_some(), 607 + has_wasm_external: external_wasm.is_some(), 608 608 }; 609 609 610 610 // We have already registered the function in the `register_value_from_function` ··· 798 798 external_javascript: external_javascript 799 799 .as_ref() 800 800 .map(|(m, f, _)| (m.clone(), f.clone())), 801 - external_cranelift: external_javascript 801 + external_wasm: external_wasm 802 802 .as_ref() 803 803 .map(|(m, f, _)| (m.clone(), f.clone())), 804 804 field_map, ··· 841 841 body, 842 842 external_erlang, 843 843 external_javascript, 844 - external_cranelift, 844 + external_wasm, 845 845 implementations, 846 846 purity, 847 847 }; ··· 1606 1606 documentation, 1607 1607 external_erlang, 1608 1608 external_javascript, 1609 - external_cranelift, 1609 + external_wasm, 1610 1610 deprecation, 1611 1611 end_position: _, 1612 1612 body: _, ··· 1686 1686 external_javascript: external_javascript 1687 1687 .as_ref() 1688 1688 .map(|(m, f, _)| (m.clone(), f.clone())), 1689 - external_cranelift: external_cranelift 1689 + external_wasm: external_wasm 1690 1690 .as_ref() 1691 1691 .map(|(m, f, _)| (m.clone(), f.clone())), 1692 1692 module: environment.current_module.clone(), ··· 1788 1788 target: Target, 1789 1789 external_erlang: &'a Option<(EcoString, EcoString, SrcSpan)>, 1790 1790 external_javascript: &'a Option<(EcoString, EcoString, SrcSpan)>, 1791 - external_cranelift: &'a Option<(EcoString, EcoString, SrcSpan)>, 1791 + external_wasm: &'a Option<(EcoString, EcoString, SrcSpan)>, 1792 1792 ) -> &'a Option<(EcoString, EcoString, SrcSpan)> { 1793 1793 match target { 1794 1794 Target::Erlang => external_erlang, 1795 1795 Target::JavaScript => external_javascript, 1796 - Target::Cranelift => external_cranelift, 1796 + Target::Wasm => external_wasm, 1797 1797 } 1798 1798 } 1799 1799 ··· 1957 1957 return_type, 1958 1958 external_erlang, 1959 1959 external_javascript, 1960 - external_cranelift, 1960 + external_wasm, 1961 1961 implementations, 1962 1962 purity, 1963 1963 } = function; ··· 1984 1984 external_javascript: external_javascript 1985 1985 .as_ref() 1986 1986 .map(|(m, f, _)| (m.clone(), f.clone())), 1987 - external_cranelift: external_javascript 1987 + external_wasm: external_javascript 1988 1988 .as_ref() 1989 1989 .map(|(m, f, _)| (m.clone(), f.clone())), 1990 1990 module: module_name.clone(), ··· 2024 2024 body, 2025 2025 external_erlang, 2026 2026 external_javascript, 2027 - external_cranelift, 2027 + external_wasm, 2028 2028 implementations, 2029 2029 purity, 2030 2030 }
+1 -1
compiler-core/src/ast.rs
··· 870 870 pub documentation: Option<(u32, EcoString)>, 871 871 pub external_erlang: Option<(EcoString, EcoString, SrcSpan)>, 872 872 pub external_javascript: Option<(EcoString, EcoString, SrcSpan)>, 873 - pub external_cranelift: Option<(EcoString, EcoString, SrcSpan)>, 873 + pub external_wasm: Option<(EcoString, EcoString, SrcSpan)>, 874 874 pub implementations: Implementations, 875 875 pub purity: Purity, 876 876 }
+1 -1
compiler-core/src/ast/tests.rs
··· 167 167 has_body: true, 168 168 has_erlang_external: false, 169 169 has_javascript_external: false, 170 - has_cranelift_external: false, 170 + has_wasm_external: false, 171 171 }, 172 172 &mut problems, 173 173 )
+5 -5
compiler-core/src/build.rs
··· 73 73 #[serde(alias = "js")] 74 74 #[clap(alias = "js")] 75 75 JavaScript, 76 - #[strum(serialize = "cranelift")] 77 - #[serde(rename = "cranelift")] 78 - Cranelift, 76 + #[strum(serialize = "wasm")] 77 + #[serde(rename = "wasm")] 78 + Wasm, 79 79 } 80 80 81 81 impl Target { ··· 188 188 Erlang { 189 189 app_file: Option<ErlangAppCodegenConfiguration>, 190 190 }, 191 - Cranelift {}, 191 + Wasm {}, 192 192 } 193 193 194 194 impl TargetCodegenConfiguration { ··· 196 196 match self { 197 197 Self::JavaScript { .. } => Target::JavaScript, 198 198 Self::Erlang { .. } => Target::Erlang, 199 - Self::Cranelift { .. } => Target::Cranelift, 199 + Self::Wasm { .. } => Target::Wasm, 200 200 } 201 201 } 202 202 }
+8 -2
compiler-core/src/build/package_compiler.rs
··· 8 8 use crate::build::package_loader::CacheFiles; 9 9 10 10 use crate::error::{DefinedModuleOrigin, FailedModule, SkipReason, SkippedModule}; 11 + use crate::codegen::Wasm; 12 + use crate::inline; 11 13 use crate::io::files_with_extension; 12 14 use crate::line_numbers::{self, LineNumbers}; 13 15 use crate::type_::PRELUDE_MODULE_NAME; ··· 376 378 TargetCodegenConfiguration::Erlang { app_file } => { 377 379 self.perform_erlang_codegen(modules, cached_module_names, app_file.as_ref()) 378 380 } 379 - TargetCodegenConfiguration::Cranelift {} => { 380 - todo!("codegen") 381 + TargetCodegenConfiguration::Wasm {} => { 382 + self.perform_wasm_codegen(modules) 381 383 } 382 384 } 385 + } 386 + 387 + fn perform_wasm_codegen(&mut self, modules: &[Module]) -> Result<(), Error> { 388 + Wasm::new(&self.out).render(&self.io, modules) 383 389 } 384 390 385 391 fn perform_erlang_codegen(
+1 -1
compiler-core/src/build/project_compiler.rs
··· 619 619 prelude_location: Utf8PathBuf::from("../prelude.mjs"), 620 620 }, 621 621 622 - Target::Cranelift => super::TargetCodegenConfiguration::Cranelift {}, 622 + Target::Wasm => super::TargetCodegenConfiguration::Wasm {}, 623 623 }; 624 624 625 625 let mut compiler = PackageCompiler::new(
+5 -5
compiler-core/src/call_graph/into_dependency_order_tests.rs
··· 47 47 documentation: None, 48 48 external_erlang: None, 49 49 external_javascript: None, 50 - external_cranelift: None, 50 + external_wasm: None, 51 51 implementations: Implementations { 52 52 gleam: true, 53 53 uses_erlang_externals: true, 54 54 uses_javascript_externals: false, 55 - uses_cranelift_externals: false, 55 + uses_wasm_externals: false, 56 56 can_run_on_erlang: true, 57 57 can_run_on_javascript: true, 58 - can_run_on_cranelift: true, 58 + can_run_on_wasm: true, 59 59 }, 60 60 purity: Purity::Impure, 61 61 }) ··· 76 76 gleam: true, 77 77 uses_erlang_externals: true, 78 78 uses_javascript_externals: false, 79 - uses_cranelift_externals: false, 79 + uses_wasm_externals: false, 80 80 can_run_on_erlang: true, 81 81 can_run_on_javascript: true, 82 - can_run_on_cranelift: true, 82 + can_run_on_wasm: true, 83 83 }, 84 84 type_: (), 85 85 deprecation: Deprecation::NotDeprecated,
+8 -7
compiler-core/src/codegen.rs
··· 7 7 ErlangAppCodegenConfiguration, Module, module_erlang_name, package_compiler::StdlibPackage, 8 8 }, 9 9 config::PackageConfig, 10 - cranelift, erlang, 10 + erlang, 11 11 io::FileSystemWriter, 12 12 javascript::{self, ModuleConfig}, 13 13 line_numbers::LineNumbers, 14 + wasm, 14 15 }; 15 16 use ecow::EcoString; 16 17 use erlang::escape_atom_string; ··· 340 341 } 341 342 342 343 #[derive(Debug)] 343 - pub struct Cranelift<'a> { 344 + pub struct Wasm<'a> { 344 345 output_directory: &'a Utf8Path, 345 346 } 346 347 347 - impl<'a> Cranelift<'a> { 348 + impl<'a> Wasm<'a> { 348 349 pub fn new(output_directory: &'a Utf8Path) -> Self { 349 350 Self { output_directory } 350 351 } ··· 352 353 pub fn render(&self, writer: &impl FileSystemWriter, modules: &[Module]) -> Result<()> { 353 354 let modules: Vec<_> = modules 354 355 .iter() 355 - .map(|module| cranelift::mir::Translator::new(&module.ast).translate()) 356 + .map(|module| wasm::mir::Translator::new(&module.ast).translate()) 356 357 .collect(); 357 358 358 - let monomorphized = cranelift::mir::lower::lower(modules); 359 + let monomorphized = wasm::mir::lower::lower(modules); 359 360 360 361 for module in monomorphized { 361 362 let path = self 362 363 .output_directory 363 - .join(&format!("{}.o", module.name.clone())); 364 + .join(&format!("{}.wasm", module.name.clone())); 364 365 365 - let object = cranelift::compile(module); 366 + let object = wasm::compile(module); 366 367 367 368 writer.write_bytes(&path, &object)?; 368 369 }
-635
compiler-core/src/cranelift.rs
··· 1 - use std::collections::HashMap; 2 - 3 - use cranelift::{ 4 - codegen::{ 5 - Context, 6 - ir::{BlockArg, immediates::Offset32}, 7 - }, 8 - prelude::*, 9 - }; 10 - use cranelift_module::{Linkage, Module, default_libcall_names}; 11 - use cranelift_object::{ObjectBuilder, ObjectModule}; 12 - use ecow::{EcoString, eco_format}; 13 - use itertools::Itertools as _; 14 - 15 - use crate::cranelift::mir::ast; 16 - 17 - pub mod mir; 18 - 19 - struct CodeGen<M: Module> { 20 - module: M, 21 - context: Context, 22 - function_context: FunctionBuilderContext, 23 - } 24 - 25 - pub fn compile(module: ast::Module<ast::CompleteType>) -> Vec<u8> { 26 - let mut flag_builder = settings::builder(); 27 - 28 - flag_builder 29 - .set("is_pic", "true") 30 - .expect("unable to set `is_pic` to false"); 31 - 32 - let isa = cranelift_native::builder() 33 - .unwrap_or_else(|reason| panic!("host machine not support: {reason}")) 34 - .finish(settings::Flags::new(flag_builder)) 35 - .expect("unable to build isa target"); 36 - 37 - let mut cranelift = { 38 - let module = ObjectModule::new( 39 - ObjectBuilder::new(isa, module.name.to_string(), default_libcall_names()) 40 - .expect("unable to build object builder"), 41 - ); 42 - 43 - CodeGen { 44 - function_context: FunctionBuilderContext::new(), 45 - context: module.make_context(), 46 - module, 47 - } 48 - }; 49 - 50 - for function in module.functions { 51 - FunctionTranslator::new(&mut cranelift).translate(module.name.clone(), function); 52 - } 53 - 54 - let product = cranelift.module.finish(); 55 - 56 - product.emit().expect("unable to emit finished product") 57 - } 58 - 59 - struct FunctionTranslator<'m, M: Module> { 60 - cg: &'m mut CodeGen<M>, 61 - } 62 - 63 - fn mangle_type_name(type_: &ast::CompleteType) -> EcoString { 64 - match type_ { 65 - ast::CompleteType::Int => "I".into(), 66 - ast::CompleteType::Float => "F".into(), 67 - ast::CompleteType::Bool => "B".into(), 68 - ast::CompleteType::String => "S".into(), 69 - ast::CompleteType::Func { arguments, returns } => { 70 - let arguments = arguments 71 - .iter() 72 - .map(mangle_type_name) 73 - .map(|s| eco_format!("{}{}", s.len(), s)) 74 - .join(""); 75 - 76 - let returns = mangle_type_name(returns); 77 - 78 - eco_format!("F{}f{}R{}", arguments.len(), arguments, returns) 79 - } 80 - ast::CompleteType::Tuple { elements } => { 81 - let elements = elements 82 - .iter() 83 - .map(mangle_type_name) 84 - .map(|s| eco_format!("{}{}", s.len(), s)) 85 - .join(""); 86 - 87 - eco_format!("T{}t{}", elements.len(), elements) 88 - } 89 - ast::CompleteType::Struct { elements } => { 90 - let elements = elements 91 - .iter() 92 - .map(mangle_type_name) 93 - .map(|s| eco_format!("{}{}", s.len(), s)) 94 - .join(""); 95 - 96 - eco_format!("C{}c{}", elements.len(), elements) 97 - } 98 - ast::CompleteType::List(element_type) => { 99 - let element = mangle_type_name(element_type); 100 - 101 - eco_format!("L{}{}", element.len(), element) 102 - } 103 - } 104 - } 105 - 106 - fn mangled_function_name( 107 - module: EcoString, 108 - name: EcoString, 109 - arguments: &[ast::CompleteType], 110 - returns: &ast::CompleteType, 111 - ) -> EcoString { 112 - let arguments = arguments 113 - .iter() 114 - .map(mangle_type_name) 115 - .map(|s| eco_format!("{}{}", s.len(), s)) 116 - .join(""); 117 - let returns = mangle_type_name(returns); 118 - 119 - eco_format!( 120 - "M{}{}_{}{}_A{}a{}_R{}", 121 - module.len(), 122 - module.replace("/", "_"), 123 - name.len(), 124 - name, 125 - arguments.len(), 126 - arguments, 127 - returns, 128 - ) 129 - } 130 - 131 - impl<'m, M: Module> FunctionTranslator<'m, M> { 132 - fn new(cg: &'m mut CodeGen<M>) -> Self { 133 - Self { cg } 134 - } 135 - 136 - fn translate(self, module: EcoString, function: ast::Function<ast::CompleteType>) { 137 - let arguments: Vec<_> = function 138 - .parameters 139 - .iter() 140 - .map(|parameter| parameter.type_.clone()) 141 - .collect(); 142 - 143 - let name = mangled_function_name( 144 - module, 145 - function.name.clone(), 146 - &arguments, 147 - &function.return_type, 148 - ); 149 - 150 - self.cg.context.func.signature = self.signature_from_function(&function); 151 - 152 - let mut builder = 153 - FunctionBuilder::new(&mut self.cg.context.func, &mut self.cg.function_context); 154 - 155 - let entry = builder.create_block(); 156 - builder.append_block_params_for_function_params(entry); 157 - builder.switch_to_block(entry); 158 - builder.seal_block(entry); 159 - 160 - let value = { 161 - let mut translator = ExpressionTranslator::new(&mut self.cg.module, &mut builder); 162 - 163 - for (index, parameter) in function.parameters.iter().enumerate() { 164 - if let Some(name) = &parameter.name { 165 - let var_type = translate_type(&parameter.type_); 166 - let var = translator.builder.declare_var(var_type); 167 - _ = translator.vars.insert(name.clone(), var); 168 - 169 - let val = translator.builder.block_params(entry)[index]; 170 - translator.builder.def_var(var, val); 171 - } 172 - } 173 - 174 - translator.translate(function.body) 175 - }; 176 - 177 - _ = builder.ins().return_(&[value]); 178 - 179 - builder.finalize(); 180 - 181 - let id = self 182 - .cg 183 - .module 184 - .declare_function(&name, Linkage::Export, &self.cg.context.func.signature) 185 - .expect("unable to declare function"); 186 - 187 - self.cg 188 - .module 189 - .define_function(id, &mut self.cg.context) 190 - .expect("unable to define function"); 191 - 192 - self.cg.module.clear_context(&mut self.cg.context); 193 - } 194 - 195 - fn signature_from_function(&self, function: &ast::Function<ast::CompleteType>) -> Signature { 196 - let mut sig = self.cg.module.make_signature(); 197 - 198 - for parameter in &function.parameters { 199 - sig.params 200 - .push(AbiParam::new(translate_type(&parameter.type_))); 201 - } 202 - 203 - sig.returns 204 - .push(AbiParam::new(translate_type(&function.return_type))); 205 - 206 - return sig; 207 - } 208 - } 209 - 210 - fn translate_type(type_: &ast::CompleteType) -> Type { 211 - match type_ { 212 - ast::CompleteType::Int => types::I64, 213 - ast::CompleteType::Float => types::F64, 214 - ast::CompleteType::Bool => types::I64, // wasteful but whatever 215 - ast::CompleteType::String => types::I64, 216 - ast::CompleteType::Func { 217 - arguments: _, 218 - returns: _, 219 - } => types::I64, 220 - ast::CompleteType::Tuple { elements: _ } => types::I64, 221 - ast::CompleteType::Struct { elements: _ } => types::I64, 222 - ast::CompleteType::List(_complete_type) => types::I64, 223 - } 224 - } 225 - 226 - struct ExpressionTranslator<'m, 'b, M: Module> { 227 - module: &'m mut M, 228 - builder: &'m mut FunctionBuilder<'b>, 229 - vars: HashMap<EcoString, Variable>, 230 - } 231 - 232 - impl<'m, 'b, M: Module> ExpressionTranslator<'m, 'b, M> { 233 - fn new(module: &'m mut M, builder: &'m mut FunctionBuilder<'b>) -> Self { 234 - Self { 235 - module, 236 - builder, 237 - vars: Default::default(), 238 - } 239 - } 240 - 241 - fn translate(&mut self, expression: ast::Expression<ast::CompleteType>) -> Value { 242 - _ = self.module; 243 - 244 - match expression { 245 - ast::Expression::Block(expressions) => expressions 246 - .into_iter() 247 - .map(|expression| self.translate(expression)) 248 - .last() 249 - .expect("block should be non-empty"), 250 - ast::Expression::FunctionRef { 251 - module, 252 - name, 253 - arity: _, 254 - type_, 255 - } => { 256 - let ast::CompleteType::Func { arguments, returns } = type_ else { 257 - unreachable!("function ref should have func type") 258 - }; 259 - 260 - let name = mangled_function_name(module, name, &arguments, &returns); 261 - let sig = { 262 - let mut sig = self.module.make_signature(); 263 - for argument in arguments { 264 - sig.params.push(AbiParam::new(translate_type(&argument))); 265 - } 266 - sig.returns.push(AbiParam::new(translate_type(&returns))); 267 - sig 268 - }; 269 - 270 - let id = self 271 - .module 272 - .declare_function(&name, Linkage::Import, &sig) 273 - .expect("unable to declare function for import"); 274 - 275 - let func = self.module.declare_func_in_func(id, self.builder.func); 276 - 277 - self.builder.ins().func_addr(types::I64, func) 278 - } 279 - ast::Expression::Var(var) => { 280 - let var = self 281 - .vars 282 - .get(&var.name) 283 - .cloned() 284 - .expect("variable to be defined"); 285 - 286 - self.builder.use_var(var) 287 - } 288 - ast::Expression::Int { value } => { 289 - let value = i64::try_from(value).expect("integer value too large"); 290 - 291 - self.builder.ins().iconst(types::I64, value) 292 - } 293 - ast::Expression::Float { value } => { 294 - let value: f64 = value.parse().expect("invalid float value"); 295 - 296 - self.builder.ins().f64const(value) 297 - } 298 - ast::Expression::Bool { value } => match value { 299 - true => self.builder.ins().iconst(types::I64, 1), 300 - false => self.builder.ins().iconst(types::I64, 0), 301 - }, 302 - ast::Expression::String { value: _ } => todo!(), 303 - ast::Expression::Equals { lhs, rhs } => match lhs.type_() { 304 - ast::CompleteType::Int => { 305 - let lhs = self.translate(*lhs); 306 - let rhs = self.translate(*rhs); 307 - 308 - self.builder.ins().icmp(IntCC::Equal, lhs, rhs) 309 - } 310 - ast::CompleteType::Float => todo!(), 311 - ast::CompleteType::Bool => todo!(), 312 - ast::CompleteType::String => todo!(), 313 - ast::CompleteType::Func { 314 - arguments: _, 315 - returns: _, 316 - } => todo!(), 317 - ast::CompleteType::Tuple { elements: _ } => todo!(), 318 - ast::CompleteType::Struct { elements: _ } => todo!(), 319 - ast::CompleteType::List(_complete_type) => todo!(), 320 - }, 321 - ast::Expression::NotEquals { lhs: _, rhs: _ } => todo!(), 322 - ast::Expression::IntGt { lhs, rhs } => { 323 - let lhs = self.translate(*lhs); 324 - let rhs = self.translate(*rhs); 325 - 326 - self.builder.ins().icmp(IntCC::SignedGreaterThan, lhs, rhs) 327 - } 328 - ast::Expression::IntGtEq { lhs, rhs } => { 329 - let lhs = self.translate(*lhs); 330 - let rhs = self.translate(*rhs); 331 - 332 - self.builder 333 - .ins() 334 - .icmp(IntCC::SignedGreaterThanOrEqual, lhs, rhs) 335 - } 336 - ast::Expression::IntLt { lhs, rhs } => { 337 - let lhs = self.translate(*lhs); 338 - let rhs = self.translate(*rhs); 339 - 340 - self.builder.ins().icmp(IntCC::SignedLessThan, lhs, rhs) 341 - } 342 - ast::Expression::IntLtEq { lhs, rhs } => { 343 - let lhs = self.translate(*lhs); 344 - let rhs = self.translate(*rhs); 345 - 346 - self.builder 347 - .ins() 348 - .icmp(IntCC::SignedLessThanOrEqual, lhs, rhs) 349 - } 350 - ast::Expression::IntAdd { lhs, rhs } => { 351 - let lhs = self.translate(*lhs); 352 - let rhs = self.translate(*rhs); 353 - 354 - self.builder.ins().iadd(lhs, rhs) 355 - } 356 - ast::Expression::IntSub { lhs, rhs } => { 357 - let lhs = self.translate(*lhs); 358 - let rhs = self.translate(*rhs); 359 - 360 - self.builder.ins().isub(lhs, rhs) 361 - } 362 - ast::Expression::IntMul { lhs, rhs } => { 363 - let lhs = self.translate(*lhs); 364 - let rhs = self.translate(*rhs); 365 - 366 - self.builder.ins().imul(lhs, rhs) 367 - } 368 - ast::Expression::IntDiv { lhs, rhs } => { 369 - let lhs = self.translate(*lhs); 370 - let rhs = self.translate(*rhs); 371 - 372 - self.builder.ins().sdiv(lhs, rhs) 373 - } 374 - ast::Expression::IntRem { lhs, rhs } => { 375 - let lhs = self.translate(*lhs); 376 - let rhs = self.translate(*rhs); 377 - 378 - self.builder.ins().srem(lhs, rhs) 379 - } 380 - ast::Expression::FloatGt { lhs, rhs } => { 381 - let lhs = self.translate(*lhs); 382 - let rhs = self.translate(*rhs); 383 - 384 - self.builder.ins().fcmp(FloatCC::GreaterThan, lhs, rhs) 385 - } 386 - ast::Expression::FloatGtEq { lhs, rhs } => { 387 - let lhs = self.translate(*lhs); 388 - let rhs = self.translate(*rhs); 389 - 390 - self.builder 391 - .ins() 392 - .fcmp(FloatCC::GreaterThanOrEqual, lhs, rhs) 393 - } 394 - ast::Expression::FloatLt { lhs, rhs } => { 395 - let lhs = self.translate(*lhs); 396 - let rhs = self.translate(*rhs); 397 - 398 - self.builder.ins().fcmp(FloatCC::LessThan, lhs, rhs) 399 - } 400 - ast::Expression::FloatLtEq { lhs, rhs } => { 401 - let lhs = self.translate(*lhs); 402 - let rhs = self.translate(*rhs); 403 - 404 - self.builder.ins().fcmp(FloatCC::LessThanOrEqual, lhs, rhs) 405 - } 406 - ast::Expression::FloatAdd { lhs, rhs } => { 407 - let lhs = self.translate(*lhs); 408 - let rhs = self.translate(*rhs); 409 - 410 - self.builder.ins().fadd(lhs, rhs) 411 - } 412 - ast::Expression::FloatSub { lhs, rhs } => { 413 - let lhs = self.translate(*lhs); 414 - let rhs = self.translate(*rhs); 415 - 416 - self.builder.ins().fsub(lhs, rhs) 417 - } 418 - ast::Expression::FloatMul { lhs, rhs } => { 419 - let lhs = self.translate(*lhs); 420 - let rhs = self.translate(*rhs); 421 - 422 - self.builder.ins().fmul(lhs, rhs) 423 - } 424 - ast::Expression::FloatDiv { lhs, rhs } => { 425 - let lhs = self.translate(*lhs); 426 - let rhs = self.translate(*rhs); 427 - 428 - self.builder.ins().fdiv(lhs, rhs) 429 - } 430 - ast::Expression::StringConcat { lhs: _, rhs: _ } => todo!(), 431 - ast::Expression::List { 432 - items: _, 433 - tail: _, 434 - type_: _, 435 - } => todo!(), 436 - ast::Expression::Tuple { items, type_: _ } => { 437 - let mut sig = self.module.make_signature(); 438 - sig.params.push(AbiParam::new(types::I64)); 439 - sig.returns.push(AbiParam::new(types::I64)); 440 - 441 - let id = self 442 - .module 443 - .declare_function("malloc", Linkage::Import, &sig) 444 - .expect("failed to declare malloc"); 445 - 446 - let malloc = self.module.declare_func_in_func(id, &mut self.builder.func); 447 - 448 - let size_arg = self 449 - .builder 450 - .ins() 451 - .iconst(types::I64, (items.len() as i64) * 8); 452 - 453 - let call = self.builder.ins().call(malloc, &[size_arg]); 454 - let ptr = self.builder.inst_results(call)[0]; 455 - 456 - for (index, item) in items.into_iter().enumerate() { 457 - let index = index as i32; 458 - 459 - let value = self.translate(item); 460 - 461 - _ = self.builder.ins().store( 462 - MemFlags::new(), 463 - value, 464 - ptr, 465 - Offset32::new(index * 8), 466 - ); 467 - } 468 - 469 - ptr 470 - } 471 - ast::Expression::TupleAccess { 472 - value, 473 - index, 474 - type_, 475 - } => { 476 - let ptr = self.translate(*value); 477 - 478 - self.builder.ins().load( 479 - translate_type(&type_), 480 - MemFlags::new(), 481 - ptr, 482 - Offset32::new(index as i32 * 8), 483 - ) 484 - } 485 - ast::Expression::Struct { 486 - tag, 487 - items, 488 - type_: _, 489 - } => { 490 - let mut sig = self.module.make_signature(); 491 - sig.params.push(AbiParam::new(types::I64)); 492 - sig.returns.push(AbiParam::new(types::I64)); 493 - 494 - let id = self 495 - .module 496 - .declare_function("malloc", Linkage::Import, &sig) 497 - .expect("failed to declare malloc"); 498 - 499 - let malloc = self.module.declare_func_in_func(id, &mut self.builder.func); 500 - 501 - let size_arg = self 502 - .builder 503 - .ins() 504 - .iconst(types::I64, (items.len() as i64) * 8 + 8); 505 - 506 - let call = self.builder.ins().call(malloc, &[size_arg]); 507 - let ptr = self.builder.inst_results(call)[0]; 508 - 509 - let tag = self.builder.ins().iconst(types::I64, i64::from(tag)); 510 - _ = self 511 - .builder 512 - .ins() 513 - .store(MemFlags::new(), tag, ptr, Offset32::new(0)); 514 - 515 - for (index, item) in items.into_iter().enumerate() { 516 - let index = index as i32 + 1; 517 - 518 - let value = self.translate(item); 519 - 520 - _ = self.builder.ins().store( 521 - MemFlags::new(), 522 - value, 523 - ptr, 524 - Offset32::new(index * 8), 525 - ); 526 - } 527 - 528 - ptr 529 - } 530 - ast::Expression::StructTag { value } => { 531 - let ptr = self.translate(*value); 532 - 533 - self.builder 534 - .ins() 535 - .load(types::I64, MemFlags::new(), ptr, Offset32::new(0)) 536 - } 537 - ast::Expression::StructAccess { 538 - value, 539 - index, 540 - type_, 541 - } => { 542 - let ptr = self.translate(*value); 543 - 544 - self.builder.ins().load( 545 - translate_type(&type_), 546 - MemFlags::new(), 547 - ptr, 548 - Offset32::new(index as i32 * 8 + 8), 549 - ) 550 - } 551 - ast::Expression::Set { name, value } => { 552 - let var = self.builder.declare_var(translate_type(&value.type_())); 553 - _ = self.vars.insert(name.name, var); 554 - 555 - let val = self.translate(*value); 556 - self.builder.def_var(var, val); 557 - self.builder.use_var(var) 558 - } 559 - ast::Expression::If { cond, then, else_ } => { 560 - let cond = self.translate(*cond); 561 - 562 - let then_block = self.builder.create_block(); 563 - let else_block = self.builder.create_block(); 564 - let merge_block = self.builder.create_block(); 565 - 566 - _ = self 567 - .builder 568 - .append_block_param(merge_block, translate_type(&then.type_())); 569 - 570 - _ = self 571 - .builder 572 - .ins() 573 - .brif(cond, then_block, &[], else_block, &[]); 574 - 575 - self.builder.switch_to_block(then_block); 576 - self.builder.seal_block(then_block); 577 - 578 - let then_return = self.translate(*then); 579 - _ = self 580 - .builder 581 - .ins() 582 - .jump(merge_block, &[BlockArg::Value(then_return)]); 583 - 584 - self.builder.switch_to_block(else_block); 585 - self.builder.seal_block(else_block); 586 - 587 - let else_return = self.translate(*else_); 588 - _ = self 589 - .builder 590 - .ins() 591 - .jump(merge_block, &[BlockArg::Value(else_return)]); 592 - 593 - self.builder.switch_to_block(merge_block); 594 - self.builder.seal_block(merge_block); 595 - 596 - self.builder.block_params(merge_block)[0] 597 - } 598 - ast::Expression::Call { 599 - target, 600 - args, 601 - type_, 602 - } => { 603 - let mut signature = self.module.make_signature(); 604 - 605 - for arg in &args { 606 - signature 607 - .params 608 - .push(AbiParam::new(translate_type(&arg.type_()))); 609 - } 610 - signature 611 - .returns 612 - .push(AbiParam::new(translate_type(&type_))); 613 - 614 - let target = self.translate(*target); 615 - let args: Vec<_> = args.into_iter().map(|arg| self.translate(arg)).collect(); 616 - 617 - let sig = self.builder.import_signature(signature); 618 - let call = self.builder.ins().call_indirect(sig, target, &args); 619 - 620 - self.builder.inst_results(call)[0] 621 - } 622 - ast::Expression::Panic { type_, .. } => match type_ { 623 - ast::CompleteType::Func { .. } 624 - | ast::CompleteType::Tuple { .. } 625 - | ast::CompleteType::Struct { .. } 626 - | ast::CompleteType::List(_) 627 - | ast::CompleteType::String 628 - | ast::CompleteType::Bool 629 - | ast::CompleteType::Int => self.builder.ins().iconst(types::I64, 0), 630 - 631 - ast::CompleteType::Float => self.builder.ins().f64const(0.0), 632 - }, 633 - } 634 - } 635 - }
+5 -4
compiler-core/src/cranelift/mir.rs compiler-core/src/wasm/mir.rs
··· 2 2 3 3 use ecow::{EcoString, eco_format}; 4 4 use num_bigint::BigInt; 5 - use vec1::Vec1; 6 5 7 6 use crate::{ 8 - cranelift::mir::{ast::*, visit::Visit}, 7 + wasm::mir::{ast::*, visit::Visit}, 9 8 exhaustiveness, parse, type_, 10 9 }; 11 10 ··· 329 328 result 330 329 } 331 330 332 - fn translate(mut self, body: &Vec1<crate::ast::TypedStatement>) -> Expression<IncompleteType> { 331 + fn translate(mut self, body: &[crate::ast::TypedStatement]) -> Expression<IncompleteType> { 333 332 self.translate_statements(body) 334 333 } 335 334 ··· 446 445 implementations: _, 447 446 external_erlang: _, 448 447 external_javascript: _, 449 - external_cranelift: _, 448 + external_wasm: _, 450 449 purity: _, 451 450 } => Expression::FunctionRef { 452 451 module: module.clone(), ··· 602 601 label: _, 603 602 index, 604 603 record, 604 + documentation: _, 605 605 } => Expression::StructAccess { 606 606 value: Box::new(self.translate_expression(record)), 607 607 index: *index, ··· 699 699 crate::ast::TypedExpr::Invalid { 700 700 location: _, 701 701 type_: _, 702 + extra_information: _, 702 703 } => todo!(), 703 704 } 704 705 }
compiler-core/src/cranelift/mir/ast.rs compiler-core/src/wasm/mir/ast.rs
+1 -1
compiler-core/src/cranelift/mir/lower.rs compiler-core/src/wasm/mir/lower.rs
··· 2 2 3 3 use ecow::EcoString; 4 4 5 - use crate::cranelift::mir::{ 5 + use crate::wasm::mir::{ 6 6 ast::{CompleteType, Expression, Function, FunctionParameter, IncompleteType, Module, Var}, 7 7 visit::Visit, 8 8 };
+1 -1
compiler-core/src/cranelift/mir/visit.rs compiler-core/src/wasm/mir/visit.rs
··· 1 1 use ecow::EcoString; 2 2 use num_bigint::BigInt; 3 3 4 - use crate::cranelift::mir::ast::{Expression, Function, Module, Var}; 4 + use crate::wasm::mir::ast::{Expression, Function, Module, Var}; 5 5 6 6 pub trait Visit<'mir, T> { 7 7 fn visit_module(&mut self, module: &'mir mut Module<T>) {
compiler-core/src/cranelift/snapshots/gleam_core__cranelift__mir__tests__translates_samples-10.snap compiler-core/src/wasm/snapshots/gleam_core__cranelift__mir__tests__translates_samples-10.snap
compiler-core/src/cranelift/snapshots/gleam_core__cranelift__mir__tests__translates_samples-11.snap compiler-core/src/wasm/snapshots/gleam_core__cranelift__mir__tests__translates_samples-11.snap
compiler-core/src/cranelift/snapshots/gleam_core__cranelift__mir__tests__translates_samples-12.snap compiler-core/src/wasm/snapshots/gleam_core__cranelift__mir__tests__translates_samples-12.snap
compiler-core/src/cranelift/snapshots/gleam_core__cranelift__mir__tests__translates_samples-13.snap compiler-core/src/wasm/snapshots/gleam_core__cranelift__mir__tests__translates_samples-13.snap
compiler-core/src/cranelift/snapshots/gleam_core__cranelift__mir__tests__translates_samples-14.snap compiler-core/src/wasm/snapshots/gleam_core__cranelift__mir__tests__translates_samples-14.snap
compiler-core/src/cranelift/snapshots/gleam_core__cranelift__mir__tests__translates_samples-2.snap compiler-core/src/wasm/snapshots/gleam_core__cranelift__mir__tests__translates_samples-2.snap
compiler-core/src/cranelift/snapshots/gleam_core__cranelift__mir__tests__translates_samples-3.snap compiler-core/src/wasm/snapshots/gleam_core__cranelift__mir__tests__translates_samples-3.snap
compiler-core/src/cranelift/snapshots/gleam_core__cranelift__mir__tests__translates_samples-4.snap compiler-core/src/wasm/snapshots/gleam_core__cranelift__mir__tests__translates_samples-4.snap
compiler-core/src/cranelift/snapshots/gleam_core__cranelift__mir__tests__translates_samples-5.snap compiler-core/src/wasm/snapshots/gleam_core__cranelift__mir__tests__translates_samples-5.snap
compiler-core/src/cranelift/snapshots/gleam_core__cranelift__mir__tests__translates_samples-6.snap compiler-core/src/wasm/snapshots/gleam_core__cranelift__mir__tests__translates_samples-6.snap
compiler-core/src/cranelift/snapshots/gleam_core__cranelift__mir__tests__translates_samples-7.snap compiler-core/src/wasm/snapshots/gleam_core__cranelift__mir__tests__translates_samples-7.snap
compiler-core/src/cranelift/snapshots/gleam_core__cranelift__mir__tests__translates_samples-8.snap compiler-core/src/wasm/snapshots/gleam_core__cranelift__mir__tests__translates_samples-8.snap
compiler-core/src/cranelift/snapshots/gleam_core__cranelift__mir__tests__translates_samples-9.snap compiler-core/src/wasm/snapshots/gleam_core__cranelift__mir__tests__translates_samples-9.snap
compiler-core/src/cranelift/snapshots/gleam_core__cranelift__mir__tests__translates_samples.snap compiler-core/src/wasm/snapshots/gleam_core__cranelift__mir__tests__translates_samples.snap
+4
compiler-core/src/error.rs
··· 2437 2437 "You can not set a runtime for Erlang. Did you mean to target JavaScript?" 2438 2438 .into(), 2439 2439 ), 2440 + Target::Wasm => Some( 2441 + "You can not set a runtime for Wasm. Did you mean to target JavaScript?" 2442 + .into(), 2443 + ), 2440 2444 }; 2441 2445 2442 2446 vec![Diagnostic {
+1 -1
compiler-core/src/inline.rs
··· 2005 2005 implementations: Implementations::supporting_all(), 2006 2006 external_erlang: None, 2007 2007 external_javascript: None, 2008 - external_cranelift: None, 2008 + external_wasm: None, 2009 2009 purity: Purity::Unknown, 2010 2010 } 2011 2011 }
+1 -1
compiler-core/src/lib.rs
··· 72 72 pub mod build; 73 73 pub mod codegen; 74 74 pub mod config; 75 - pub mod cranelift; 75 + pub mod wasm; 76 76 pub mod dependency; 77 77 pub mod diagnostic; 78 78 pub mod docs;
+32 -32
compiler-core/src/metadata/tests.rs
··· 60 60 gleam: true, 61 61 uses_erlang_externals: false, 62 62 uses_javascript_externals: false, 63 - uses_cranelift_externals: false, 63 + uses_wasm_externals: false, 64 64 can_run_on_erlang: true, 65 65 can_run_on_javascript: true, 66 - can_run_on_cranelift: true, 66 + can_run_on_wasm: true, 67 67 }, 68 68 name: "one".into(), 69 69 }, ··· 540 540 }, 541 541 external_erlang: None, 542 542 external_javascript: None, 543 - external_cranelift: None, 543 + external_wasm: None, 544 544 implementations: Implementations { 545 545 gleam: true, 546 546 uses_erlang_externals: false, 547 547 uses_javascript_externals: false, 548 - uses_cranelift_externals: false, 548 + uses_wasm_externals: false, 549 549 can_run_on_erlang: true, 550 550 can_run_on_javascript: true, 551 - can_run_on_cranelift: true, 551 + can_run_on_wasm: true, 552 552 }, 553 553 purity: Purity::Pure, 554 554 }, ··· 599 599 }, 600 600 external_erlang: None, 601 601 external_javascript: None, 602 - external_cranelift: None, 602 + external_wasm: None, 603 603 implementations: Implementations { 604 604 gleam: true, 605 605 uses_erlang_externals: false, 606 606 uses_javascript_externals: false, 607 - uses_cranelift_externals: false, 607 + uses_wasm_externals: false, 608 608 can_run_on_erlang: true, 609 609 can_run_on_javascript: true, 610 - can_run_on_cranelift: true, 610 + can_run_on_wasm: true, 611 611 }, 612 612 purity: Purity::Pure, 613 613 }, ··· 656 656 }, 657 657 external_erlang: None, 658 658 external_javascript: None, 659 - external_cranelift: None, 659 + external_wasm: None, 660 660 implementations: Implementations { 661 661 gleam: true, 662 662 uses_erlang_externals: false, 663 663 uses_javascript_externals: false, 664 - uses_cranelift_externals: false, 664 + uses_wasm_externals: false, 665 665 can_run_on_erlang: true, 666 666 can_run_on_javascript: true, 667 - can_run_on_cranelift: true, 667 + can_run_on_wasm: true, 668 668 }, 669 669 purity: Purity::Pure, 670 670 }, ··· 715 715 }, 716 716 external_erlang: None, 717 717 external_javascript: None, 718 - external_cranelift: None, 718 + external_wasm: None, 719 719 implementations: Implementations { 720 720 gleam: true, 721 721 uses_erlang_externals: false, 722 722 uses_javascript_externals: false, 723 - uses_cranelift_externals: false, 723 + uses_wasm_externals: false, 724 724 can_run_on_erlang: true, 725 725 can_run_on_javascript: true, 726 - can_run_on_cranelift: true, 726 + can_run_on_wasm: true, 727 727 }, 728 728 purity: Purity::TrustedPure, 729 729 }, ··· 770 770 }), 771 771 external_erlang: None, 772 772 external_javascript: None, 773 - external_cranelift: None, 773 + external_wasm: None, 774 774 module: "a".into(), 775 775 arity: 5, 776 776 location: SrcSpan { start: 2, end: 11 }, ··· 778 778 gleam: true, 779 779 uses_erlang_externals: false, 780 780 uses_javascript_externals: false, 781 - uses_cranelift_externals: false, 781 + uses_wasm_externals: false, 782 782 can_run_on_erlang: true, 783 783 can_run_on_javascript: true, 784 - can_run_on_cranelift: true, 784 + can_run_on_wasm: true, 785 785 }, 786 786 purity: Purity::Pure, 787 787 }, ··· 1245 1245 gleam: true, 1246 1246 uses_erlang_externals: false, 1247 1247 uses_javascript_externals: false, 1248 - uses_cranelift_externals: false, 1248 + uses_wasm_externals: false, 1249 1249 can_run_on_erlang: true, 1250 1250 can_run_on_javascript: true, 1251 - can_run_on_cranelift: true, 1251 + can_run_on_wasm: true, 1252 1252 }, 1253 1253 name: "one_original".into(), 1254 1254 }, ··· 1280 1280 gleam: true, 1281 1281 uses_erlang_externals: false, 1282 1282 uses_javascript_externals: false, 1283 - uses_cranelift_externals: false, 1283 + uses_wasm_externals: false, 1284 1284 can_run_on_erlang: true, 1285 1285 can_run_on_javascript: true, 1286 - can_run_on_cranelift: true, 1286 + can_run_on_wasm: true, 1287 1287 }, 1288 1288 name: "one".into(), 1289 1289 }, ··· 1304 1304 gleam: true, 1305 1305 uses_erlang_externals: false, 1306 1306 uses_javascript_externals: false, 1307 - uses_cranelift_externals: false, 1307 + uses_wasm_externals: false, 1308 1308 can_run_on_erlang: true, 1309 1309 can_run_on_javascript: true, 1310 - can_run_on_cranelift: true, 1310 + can_run_on_wasm: true, 1311 1311 }, 1312 1312 name: "one_original".into(), 1313 1313 }, ··· 1555 1555 }, 1556 1556 external_erlang: Some(("wibble".into(), "wobble".into())), 1557 1557 external_javascript: Some(("wobble".into(), "wibble".into())), 1558 - external_cranelift: None, 1558 + external_wasm: None, 1559 1559 implementations: Implementations { 1560 1560 gleam: false, 1561 1561 uses_erlang_externals: true, 1562 1562 uses_javascript_externals: true, 1563 - uses_cranelift_externals: false, 1563 + uses_wasm_externals: false, 1564 1564 can_run_on_erlang: false, 1565 1565 can_run_on_javascript: true, 1566 - can_run_on_cranelift: false, 1566 + can_run_on_wasm: false, 1567 1567 }, 1568 1568 purity: Purity::Impure, 1569 1569 }, ··· 1639 1639 }, 1640 1640 external_erlang: Some(("wibble".into(), "wobble".into())), 1641 1641 external_javascript: Some(("wobble".into(), "wibble".into())), 1642 - external_cranelift: None, 1642 + external_wasm: None, 1643 1643 implementations: Implementations { 1644 1644 gleam: false, 1645 1645 uses_erlang_externals: true, 1646 1646 uses_javascript_externals: true, 1647 - uses_cranelift_externals: false, 1647 + uses_wasm_externals: false, 1648 1648 can_run_on_erlang: true, 1649 1649 can_run_on_javascript: true, 1650 - can_run_on_cranelift: false, 1650 + can_run_on_wasm: false, 1651 1651 }, 1652 1652 purity: Purity::Unknown, 1653 1653 }, ··· 1702 1702 }, 1703 1703 external_erlang: Some(("wibble".into(), "wobble".into())), 1704 1704 external_javascript: Some(("wobble".into(), "wibble".into())), 1705 - external_cranelift: None, 1705 + external_wasm: None, 1706 1706 implementations: Implementations { 1707 1707 gleam: false, 1708 1708 uses_erlang_externals: true, 1709 1709 uses_javascript_externals: true, 1710 - uses_cranelift_externals: false, 1710 + uses_wasm_externals: false, 1711 1711 can_run_on_erlang: true, 1712 1712 can_run_on_javascript: true, 1713 - can_run_on_cranelift: false, 1713 + can_run_on_wasm: false, 1714 1714 }, 1715 1715 purity: Purity::Impure, 1716 1716 },
+11 -11
compiler-core/src/package_interface.rs
··· 237 237 /// - `uses_javascript_externals: true` the function is using JavaScript 238 238 /// external code. 239 239 uses_javascript_externals: bool, 240 - /// Set to `true` if the const/function is defined using Cranelift external 241 - /// code. That means that the function will use Cranelift code through FFI when 242 - /// compiled for the Cranelift target. 243 - uses_cranelift_externals: bool, 240 + /// Set to `true` if the const/function is defined using Wasm external 241 + /// code. That means that the function will use Wasm code through FFI when 242 + /// compiled for the Wasm target. 243 + uses_wasm_externals: bool, 244 244 /// Whether the function can be called on the Erlang target, either due to a 245 245 /// pure Gleam implementation or an implementation that uses some Erlang 246 246 /// externals. ··· 249 249 /// to a pure Gleam implementation or an implementation that uses some 250 250 /// JavaScript externals. 251 251 can_run_on_javascript: bool, 252 - /// Whether the function can be called on the Cranelift target, either due to a 253 - /// pure Gleam implementation or an implementation that uses some Cranelift 252 + /// Whether the function can be called on the Wasm target, either due to a 253 + /// pure Gleam implementation or an implementation that uses some Wasm 254 254 /// externals. 255 - can_run_on_cranelift: bool, 255 + can_run_on_wasm: bool, 256 256 } 257 257 258 258 impl ImplementationsInterface { ··· 270 270 gleam, 271 271 uses_erlang_externals, 272 272 uses_javascript_externals, 273 - uses_cranelift_externals, 273 + uses_wasm_externals, 274 274 can_run_on_erlang, 275 275 can_run_on_javascript, 276 - can_run_on_cranelift, 276 + can_run_on_wasm, 277 277 } = implementations; 278 278 279 279 ImplementationsInterface { 280 280 gleam: *gleam, 281 281 uses_erlang_externals: *uses_erlang_externals, 282 282 uses_javascript_externals: *uses_javascript_externals, 283 - uses_cranelift_externals: *uses_cranelift_externals, 283 + uses_wasm_externals: *uses_wasm_externals, 284 284 can_run_on_erlang: *can_run_on_erlang, 285 285 can_run_on_javascript: *can_run_on_javascript, 286 - can_run_on_cranelift: *can_run_on_cranelift, 286 + can_run_on_wasm: *can_run_on_wasm, 287 287 } 288 288 } 289 289 }
+9 -9
compiler-core/src/parse.rs
··· 131 131 deprecated: Deprecation, 132 132 external_erlang: Option<(EcoString, EcoString, SrcSpan)>, 133 133 external_javascript: Option<(EcoString, EcoString, SrcSpan)>, 134 - external_cranelift: Option<(EcoString, EcoString, SrcSpan)>, 134 + external_wasm: Option<(EcoString, EcoString, SrcSpan)>, 135 135 internal: InternalAttribute, 136 136 } 137 137 ··· 139 139 fn has_function_only(&self) -> bool { 140 140 self.external_erlang.is_some() 141 141 || self.external_javascript.is_some() 142 - || self.external_cranelift.is_some() 142 + || self.external_wasm.is_some() 143 143 } 144 144 145 145 fn has_external_for(&self, target: Target) -> bool { 146 146 match target { 147 147 Target::Erlang => self.external_erlang.is_some(), 148 148 Target::JavaScript => self.external_javascript.is_some(), 149 - Target::Cranelift => self.external_cranelift.is_some(), 149 + Target::Wasm => self.external_wasm.is_some(), 150 150 } 151 151 } 152 152 ··· 154 154 match target { 155 155 Target::Erlang => self.external_erlang = ext, 156 156 Target::JavaScript => self.external_javascript = ext, 157 - Target::Cranelift => self.external_cranelift = ext, 157 + Target::Wasm => self.external_wasm = ext, 158 158 } 159 159 } 160 160 } ··· 2273 2273 deprecation: std::mem::take(&mut attributes.deprecated), 2274 2274 external_erlang: attributes.external_erlang.take(), 2275 2275 external_javascript: attributes.external_javascript.take(), 2276 - external_cranelift: attributes.external_cranelift.take(), 2276 + external_wasm: attributes.external_wasm.take(), 2277 2277 implementations: Implementations { 2278 2278 gleam: true, 2279 2279 can_run_on_erlang: true, 2280 2280 can_run_on_javascript: true, 2281 - can_run_on_cranelift: true, 2281 + can_run_on_wasm: true, 2282 2282 uses_erlang_externals: false, 2283 2283 uses_javascript_externals: false, 2284 - uses_cranelift_externals: false, 2284 + uses_wasm_externals: false, 2285 2285 }, 2286 2286 purity: Purity::Pure, 2287 2287 }))) ··· 3308 3308 gleam: true, 3309 3309 can_run_on_erlang: true, 3310 3310 can_run_on_javascript: true, 3311 - can_run_on_cranelift: true, 3311 + can_run_on_wasm: true, 3312 3312 uses_erlang_externals: false, 3313 3313 uses_javascript_externals: false, 3314 - uses_cranelift_externals: false, 3314 + uses_wasm_externals: false, 3315 3315 }, 3316 3316 }))) 3317 3317 }
+3 -3
compiler-core/src/type_.rs
··· 745 745 implementations: Implementations, 746 746 external_erlang: Option<(EcoString, EcoString)>, 747 747 external_javascript: Option<(EcoString, EcoString)>, 748 - external_cranelift: Option<(EcoString, EcoString)>, 748 + external_wasm: Option<(EcoString, EcoString)>, 749 749 purity: Purity, 750 750 }, 751 751 ··· 880 880 gleam: true, 881 881 can_run_on_erlang: true, 882 882 can_run_on_javascript: true, 883 - can_run_on_cranelift: true, 883 + can_run_on_wasm: true, 884 884 uses_javascript_externals: false, 885 885 uses_erlang_externals: false, 886 - uses_cranelift_externals: false, 886 + uses_wasm_externals: false, 887 887 }, 888 888 889 889 ValueConstructorVariant::ModuleFn {
+18 -19
compiler-core/src/type_/expression.rs
··· 51 51 pub gleam: bool, 52 52 pub can_run_on_erlang: bool, 53 53 pub can_run_on_javascript: bool, 54 - pub can_run_on_cranelift: bool, 54 + pub can_run_on_wasm: bool, 55 55 /// Whether the function has an implementation that uses external erlang 56 56 /// code. 57 57 pub uses_erlang_externals: bool, 58 58 /// Whether the function has an implementation that uses external javascript 59 59 /// code. 60 60 pub uses_javascript_externals: bool, 61 - /// Whether the function has an implementation that uses external cranelift 61 + /// Whether the function has an implementation that uses external wasm 62 62 /// code. 63 - pub uses_cranelift_externals: bool, 63 + pub uses_wasm_externals: bool, 64 64 } 65 65 66 66 impl Implementations { ··· 69 69 gleam: true, 70 70 can_run_on_erlang: true, 71 71 can_run_on_javascript: true, 72 - can_run_on_cranelift: true, 72 + can_run_on_wasm: true, 73 73 uses_javascript_externals: false, 74 74 uses_erlang_externals: false, 75 - uses_cranelift_externals: false, 75 + uses_wasm_externals: false, 76 76 } 77 77 } 78 78 } ··· 169 169 pub has_erlang_external: bool, 170 170 /// The function has @external(JavaScript, "...", "...") 171 171 pub has_javascript_external: bool, 172 - /// The function has @external(cranelift, "...", "...") 173 - pub has_cranelift_external: bool, 172 + /// The function has @external(wasm, "...", "...") 173 + pub has_wasm_external: bool, 174 174 } 175 175 176 176 impl FunctionDefinition { ··· 178 178 match target { 179 179 Target::Erlang => self.has_erlang_external, 180 180 Target::JavaScript => self.has_javascript_external, 181 - Target::Cranelift => self.has_cranelift_external, 181 + Target::Wasm => self.has_wasm_external, 182 182 } 183 183 } 184 184 } ··· 198 198 gleam, 199 199 uses_erlang_externals: other_uses_erlang_externals, 200 200 uses_javascript_externals: other_uses_javascript_externals, 201 - uses_cranelift_externals: other_uses_cranelift_externals, 201 + uses_wasm_externals: other_uses_wasm_externals, 202 202 can_run_on_erlang: other_can_run_on_erlang, 203 203 can_run_on_javascript: other_can_run_on_javascript, 204 - can_run_on_cranelift: othere_can_run_on_cranelift, 204 + can_run_on_wasm: other_can_run_on_wasm, 205 205 } = implementations; 206 206 let FunctionDefinition { 207 207 has_body: _, 208 208 has_erlang_external, 209 209 has_javascript_external, 210 - has_cranelift_external, 210 + has_wasm_external, 211 211 } = current_function_definition; 212 212 213 213 // If a pure-Gleam function uses a function that doesn't have a pure ··· 220 220 || (self.can_run_on_erlang && (*gleam || *other_can_run_on_erlang)); 221 221 self.can_run_on_javascript = *has_javascript_external 222 222 || (self.can_run_on_javascript && (*gleam || *other_can_run_on_javascript)); 223 - self.can_run_on_cranelift = *has_cranelift_external 224 - || (self.can_run_on_cranelift && (*gleam || *othere_can_run_on_cranelift)); 223 + self.can_run_on_wasm = 224 + *has_wasm_external || (self.can_run_on_wasm && (*gleam || *other_can_run_on_wasm)); 225 225 226 226 // If a function uses a function that relies on external code (be it 227 227 // javascript or erlang) then it's considered as using external code as ··· 244 244 self.uses_erlang_externals = self.uses_erlang_externals || *other_uses_erlang_externals; 245 245 self.uses_javascript_externals = 246 246 self.uses_javascript_externals || *other_uses_javascript_externals; 247 - self.uses_cranelift_externals = 248 - self.uses_cranelift_externals || *other_uses_cranelift_externals; 247 + self.uses_wasm_externals = self.uses_wasm_externals || *other_uses_wasm_externals; 249 248 } 250 249 251 250 /// Returns true if the current target is supported by the given ··· 257 256 || match target { 258 257 Target::Erlang => self.can_run_on_erlang, 259 258 Target::JavaScript => self.can_run_on_javascript, 260 - Target::Cranelift => self.can_run_on_cranelift, 259 + Target::Wasm => self.can_run_on_wasm, 261 260 } 262 261 } 263 262 } ··· 336 335 gleam: definition.has_body, 337 336 can_run_on_erlang: definition.has_body || definition.has_erlang_external, 338 337 can_run_on_javascript: definition.has_body || definition.has_javascript_external, 339 - can_run_on_cranelift: definition.has_body || definition.has_cranelift_external, 338 + can_run_on_wasm: definition.has_body || definition.has_wasm_external, 340 339 uses_erlang_externals: definition.has_erlang_external, 341 340 uses_javascript_externals: definition.has_javascript_external, 342 - uses_cranelift_externals: definition.has_cranelift_external, 341 + uses_wasm_externals: definition.has_wasm_external, 343 342 }; 344 343 345 344 let uses_externals = match environment.target { 346 345 Target::Erlang => implementations.uses_erlang_externals, 347 346 Target::JavaScript => implementations.uses_javascript_externals, 348 - Target::Cranelift => implementations.uses_cranelift_externals, 347 + Target::Wasm => implementations.uses_wasm_externals, 349 348 }; 350 349 351 350 let purity = if is_trusted_pure_module(environment) {
+15 -15
compiler-core/src/type_/tests.rs
··· 425 425 has_body: true, 426 426 has_erlang_external: false, 427 427 has_javascript_external: false, 428 - has_cranelift_external: false, 428 + has_wasm_external: false, 429 429 }, 430 430 &mut problems, 431 431 ) ··· 2984 2984 gleam: true, 2985 2985 uses_erlang_externals: false, 2986 2986 uses_javascript_externals: false, 2987 - uses_cranelift_externals: false, 2987 + uses_wasm_externals: false, 2988 2988 can_run_on_erlang: true, 2989 2989 can_run_on_javascript: true, 2990 - can_run_on_cranelift: true, 2990 + can_run_on_wasm: true, 2991 2991 }, 2992 2992 name: "main".into(), 2993 2993 }, ··· 3013 3013 module: "module".into(), 3014 3014 external_erlang: None, 3015 3015 external_javascript: None, 3016 - external_cranelift: None, 3016 + external_wasm: None, 3017 3017 implementations: Implementations { 3018 3018 gleam: true, 3019 3019 uses_erlang_externals: false, 3020 3020 uses_javascript_externals: false, 3021 - uses_cranelift_externals: false, 3021 + uses_wasm_externals: false, 3022 3022 can_run_on_erlang: true, 3023 3023 can_run_on_javascript: true, 3024 - can_run_on_cranelift: true, 3024 + can_run_on_wasm: true, 3025 3025 }, 3026 3026 purity: Purity::Pure, 3027 3027 }, ··· 3047 3047 module: "module".into(), 3048 3048 external_erlang: None, 3049 3049 external_javascript: None, 3050 - external_cranelift: None, 3050 + external_wasm: None, 3051 3051 implementations: Implementations { 3052 3052 gleam: true, 3053 3053 uses_erlang_externals: false, 3054 3054 uses_javascript_externals: false, 3055 - uses_cranelift_externals: false, 3055 + uses_wasm_externals: false, 3056 3056 can_run_on_erlang: true, 3057 3057 can_run_on_javascript: true, 3058 - can_run_on_cranelift: true, 3058 + can_run_on_wasm: true, 3059 3059 }, 3060 3060 purity: Purity::Pure, 3061 3061 }, ··· 3081 3081 module: "module".into(), 3082 3082 external_erlang: Some(("wibble".into(), "wobble".into())), 3083 3083 external_javascript: Some(("wobble".into(), "wibble".into())), 3084 - external_cranelift: None, 3084 + external_wasm: None, 3085 3085 implementations: Implementations { 3086 3086 gleam: false, 3087 3087 uses_erlang_externals: true, 3088 3088 uses_javascript_externals: true, 3089 - uses_cranelift_externals: false, 3089 + uses_wasm_externals: false, 3090 3090 can_run_on_erlang: false, 3091 3091 can_run_on_javascript: true, 3092 - can_run_on_cranelift: false, 3092 + can_run_on_wasm: false, 3093 3093 }, 3094 3094 purity: Purity::Impure, 3095 3095 }, ··· 3115 3115 module: "module".into(), 3116 3116 external_erlang: Some(("wibble".into(), "wobble".into())), 3117 3117 external_javascript: Some(("wobble".into(), "wibble".into())), 3118 - external_cranelift: None, 3118 + external_wasm: None, 3119 3119 implementations: Implementations { 3120 3120 gleam: false, 3121 3121 uses_erlang_externals: true, 3122 3122 uses_javascript_externals: true, 3123 - uses_cranelift_externals: false, 3123 + uses_wasm_externals: false, 3124 3124 can_run_on_erlang: true, 3125 3125 can_run_on_javascript: false, 3126 - can_run_on_cranelift: false, 3126 + can_run_on_wasm: false, 3127 3127 }, 3128 3128 purity: Purity::Impure, 3129 3129 },
+30 -30
compiler-core/src/type_/tests/target_implementations.rs
··· 54 54 gleam: true, 55 55 uses_erlang_externals: false, 56 56 uses_javascript_externals: false, 57 - uses_cranelift_externals: false, 57 + uses_wasm_externals: false, 58 58 can_run_on_erlang: true, 59 59 can_run_on_javascript: true, 60 - can_run_on_cranelift: true, 60 + can_run_on_wasm: true, 61 61 } 62 62 ), 63 63 ( ··· 66 66 gleam: true, 67 67 uses_erlang_externals: false, 68 68 uses_javascript_externals: false, 69 - uses_cranelift_externals: false, 69 + uses_wasm_externals: false, 70 70 can_run_on_erlang: true, 71 71 can_run_on_javascript: true, 72 - can_run_on_cranelift: true, 72 + can_run_on_wasm: true, 73 73 } 74 74 ) 75 75 ], ··· 92 92 gleam: false, 93 93 uses_erlang_externals: true, 94 94 uses_javascript_externals: false, 95 - uses_cranelift_externals: false, 95 + uses_wasm_externals: false, 96 96 can_run_on_erlang: true, 97 97 can_run_on_javascript: false, 98 - can_run_on_cranelift: false, 98 + can_run_on_wasm: false, 99 99 } 100 100 ), 101 101 ( ··· 104 104 gleam: false, 105 105 uses_erlang_externals: true, 106 106 uses_javascript_externals: false, 107 - uses_cranelift_externals: false, 107 + uses_wasm_externals: false, 108 108 can_run_on_erlang: true, 109 109 can_run_on_javascript: false, 110 - can_run_on_cranelift: false, 110 + can_run_on_wasm: false, 111 111 } 112 112 ) 113 113 ], ··· 131 131 gleam: false, 132 132 uses_erlang_externals: true, 133 133 uses_javascript_externals: true, 134 - uses_cranelift_externals: false, 134 + uses_wasm_externals: false, 135 135 can_run_on_erlang: true, 136 136 can_run_on_javascript: true, 137 - can_run_on_cranelift: false, 137 + can_run_on_wasm: false, 138 138 } 139 139 ), 140 140 ( ··· 143 143 gleam: false, 144 144 uses_erlang_externals: true, 145 145 uses_javascript_externals: true, 146 - uses_cranelift_externals: false, 146 + uses_wasm_externals: false, 147 147 can_run_on_erlang: true, 148 148 can_run_on_javascript: true, 149 - can_run_on_cranelift: false, 149 + can_run_on_wasm: false, 150 150 } 151 151 ) 152 152 ], ··· 174 174 gleam: true, 175 175 uses_erlang_externals: true, 176 176 uses_javascript_externals: false, 177 - uses_cranelift_externals: false, 177 + uses_wasm_externals: false, 178 178 can_run_on_erlang: true, 179 179 can_run_on_javascript: true, 180 - can_run_on_cranelift: true, 180 + can_run_on_wasm: true, 181 181 } 182 182 ), 183 183 ( ··· 186 186 gleam: true, 187 187 uses_erlang_externals: false, 188 188 uses_javascript_externals: true, 189 - uses_cranelift_externals: false, 189 + uses_wasm_externals: false, 190 190 can_run_on_erlang: true, 191 191 can_run_on_javascript: true, 192 - can_run_on_cranelift: true, 192 + can_run_on_wasm: true, 193 193 } 194 194 ), 195 195 ( ··· 198 198 gleam: true, 199 199 uses_erlang_externals: true, 200 200 uses_javascript_externals: true, 201 - uses_cranelift_externals: false, 201 + uses_wasm_externals: false, 202 202 can_run_on_erlang: true, 203 203 can_run_on_javascript: true, 204 - can_run_on_cranelift: true, 204 + can_run_on_wasm: true, 205 205 } 206 206 ) 207 207 ], ··· 227 227 gleam: false, 228 228 uses_erlang_externals: true, 229 229 uses_javascript_externals: true, 230 - uses_cranelift_externals: false, 230 + uses_wasm_externals: false, 231 231 can_run_on_erlang: true, 232 232 can_run_on_javascript: true, 233 - can_run_on_cranelift: false, 233 + can_run_on_wasm: false, 234 234 } 235 235 ), 236 236 ( ··· 239 239 gleam: false, 240 240 uses_erlang_externals: true, 241 241 uses_javascript_externals: true, 242 - uses_cranelift_externals: false, 242 + uses_wasm_externals: false, 243 243 can_run_on_erlang: true, 244 244 can_run_on_javascript: true, 245 - can_run_on_cranelift: false, 245 + can_run_on_wasm: false, 246 246 } 247 247 ), 248 248 ( ··· 251 251 gleam: false, 252 252 uses_erlang_externals: false, 253 253 uses_javascript_externals: true, 254 - uses_cranelift_externals: false, 254 + uses_wasm_externals: false, 255 255 can_run_on_erlang: false, 256 256 can_run_on_javascript: true, 257 - can_run_on_cranelift: false, 257 + can_run_on_wasm: false, 258 258 } 259 259 ) 260 260 ], ··· 280 280 gleam: false, 281 281 uses_erlang_externals: true, 282 282 uses_javascript_externals: true, 283 - uses_cranelift_externals: false, 283 + uses_wasm_externals: false, 284 284 can_run_on_erlang: true, 285 285 can_run_on_javascript: true, 286 - can_run_on_cranelift: false, 286 + can_run_on_wasm: false, 287 287 } 288 288 ), 289 289 ( ··· 292 292 gleam: false, 293 293 uses_erlang_externals: true, 294 294 uses_javascript_externals: false, 295 - uses_cranelift_externals: false, 295 + uses_wasm_externals: false, 296 296 can_run_on_erlang: true, 297 297 can_run_on_javascript: false, 298 - can_run_on_cranelift: false, 298 + can_run_on_wasm: false, 299 299 } 300 300 ), 301 301 ( ··· 304 304 gleam: false, 305 305 uses_erlang_externals: true, 306 306 uses_javascript_externals: true, 307 - uses_cranelift_externals: false, 307 + uses_wasm_externals: false, 308 308 can_run_on_erlang: true, 309 309 can_run_on_javascript: true, 310 - can_run_on_cranelift: false, 310 + can_run_on_wasm: false, 311 311 } 312 312 ) 313 313 ],
+1 -1
compiler-core/src/warning.rs
··· 388 388 let full_name = match target { 389 389 Target::Erlang => "erlang", 390 390 Target::JavaScript => "javascript", 391 - Target::Cranelift => "cranelift", 391 + Target::Wasm => "wasm", 392 392 }; 393 393 394 394 Diagnostic {
+7
compiler-core/src/wasm.rs
··· 1 + use crate::wasm::mir::ast; 2 + 3 + pub mod mir; 4 + 5 + pub fn compile(_module: ast::Module<ast::CompleteType>) -> Vec<u8> { 6 + todo!() 7 + }
+1 -1
compiler-wasm/src/lib.rs
··· 187 187 emit_source_maps: false, 188 188 prelude_location: Utf8PathBuf::from("./gleam_prelude.mjs"), 189 189 }, 190 - Target::Cranelift => TargetCodegenConfiguration::Cranelift {}, 190 + Target::Wasm => TargetCodegenConfiguration::Wasm {}, 191 191 }; 192 192 193 193 tracing::info!("Compiling package");
+27
flake.nix
··· 1 + { 2 + inputs = { 3 + nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable"; 4 + fenix.url = "github:nix-community/fenix"; 5 + fenix.inputs.nixpkgs.follows = "nixpkgs"; 6 + }; 7 + 8 + outputs = 9 + { nixpkgs, fenix, ... }: 10 + let 11 + forAllSystems = 12 + function: 13 + nixpkgs.lib.genAttrs [ 14 + "aarch64-darwin" 15 + ] (system: function nixpkgs.legacyPackages.${system}); 16 + in 17 + { 18 + devShells = forAllSystems (pkgs: { 19 + default = pkgs.mkShell { 20 + packages = [ 21 + fenix.packages.${pkgs.system}.stable.toolchain 22 + pkgs.capnproto 23 + ]; 24 + }; 25 + }); 26 + }; 27 + }
+1 -1
test-output/src/tests/echo.rs
··· 115 115 Target::Erlang => { 116 116 assert_echo!(&snapshot_name, Some($target), None, $project_name); 117 117 } 118 - Target::Cranelift => { 118 + Target::Wasm => { 119 119 assert_echo!(&snapshot_name, Some($target), None, $project_name); 120 120 } 121 121 }
+1 -1
test-package-compiler/src/lib.rs
··· 37 37 emit_source_maps: config.javascript.source_maps, 38 38 prelude_location: Utf8PathBuf::from("../prelude.mjs"), 39 39 }, 40 - Target::Cranelift => TargetCodegenConfiguration::Cranelift {}, 40 + Target::Wasm => TargetCodegenConfiguration::Wasm {}, 41 41 }; 42 42 43 43 let ids = gleam_core::uid::UniqueIdGenerator::new();
test/project_cranelift/.gitignore test/project_wasm/.gitignore
test/project_cranelift/a.out

This is a binary file and will not be displayed.

test/project_cranelift/fib

This is a binary file and will not be displayed.

-11
test/project_cranelift/fib.c
··· 1 - #include <stdio.h> 2 - 3 - unsigned long long fib(unsigned long long n) { 4 - if (n==0)return 0; 5 - if (n==1)return 1; 6 - return fib(n-1)+fib(n-2); 7 - } 8 - 9 - int main(void) { 10 - printf("%lld\n", fib(40)); 11 - }
-3
test/project_cranelift/gleam.toml
··· 1 - name = "project_cranelift" 2 - version = "1.0.0" 3 - target = "cranelift"
-8
test/project_cranelift/main.c
··· 1 - #include <stdio.h> 2 - 3 - unsigned long long M17project_cranelift_4main_A0a_RI(); 4 - 5 - int main() { 6 - unsigned long long outcome = M17project_cranelift_4main_A0a_RI(); 7 - printf("%lld\n", outcome); 8 - }
test/project_cranelift/manifest.toml test/project_wasm/manifest.toml
-20
test/project_cranelift/src/project_cranelift.gleam
··· 1 - type Wibble { 2 - Wibble(x: Int, y: Int) 3 - Wobble(x: Int) 4 - } 5 - 6 - fn sum(w: Wibble) -> Int { 7 - case w { 8 - Wibble(x:, y:) -> x + y 9 - Wobble(x:) -> x 10 - } 11 - } 12 - 13 - pub fn main() { 14 - let wibble = Wibble(x: 30, y: 35) 15 - let wobble = Wobble(x: 40) 16 - let sample = #(1, 2, 3) 17 - let sample = sample.0 + sample.1 + sample.2 18 - 19 - sum(wibble) + sum(wobble) + sample 20 - }
+3
test/project_wasm/gleam.toml
··· 1 + name = "project_wasm" 2 + version = "1.0.0" 3 + target = "wasm"
+3
test/project_wasm/src/project_wasm.gleam
··· 1 + pub fn main() { 2 + 0 3 + }