Skip to content

Commit b34c701

Browse files
committed
Support Box
1 parent 324f5d0 commit b34c701

File tree

2 files changed

+149
-22
lines changed

2 files changed

+149
-22
lines changed

example/mini_core.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -701,6 +701,7 @@ pub mod libc {
701701
#[cfg(not(target_os = "wasi"))]
702702
pub fn puts(s: *const i8) -> i32;
703703
pub fn malloc(size: usize) -> *mut u8;
704+
#[cfg(not(target_os = "wasi"))]
704705
pub fn free(ptr: *mut u8);
705706
pub fn memcpy(dst: *mut u8, src: *const u8, size: usize);
706707
pub fn memmove(dst: *mut u8, src: *const u8, size: usize);
@@ -724,14 +725,19 @@ pub mod libc {
724725
#[cfg(target_os = "wasi")]
725726
pub extern "C" fn puts(mut s: *const i8) -> i32 {
726727
while unsafe { *s != 0 } {
727-
let ciovec = Ciovec { buf: s as *const u8, buf_len: 1 };
728728
unsafe {
729-
fd_write(1, &ciovec, 1, &mut 0);
729+
fd_write(1, &Ciovec { buf: s as *const u8, buf_len: 1 }, 1, &mut 0);
730730
}
731731
s = (s as usize + 1) as *const i8;
732732
}
733+
unsafe {
734+
fd_write(1, &Ciovec { buf: "\n" as *const str as *const u8, buf_len: 1 }, 1, &mut 0);
735+
}
733736
0
734737
}
738+
739+
#[cfg(target_os = "wasi")]
740+
pub fn free(_ptr: *mut u8) {}
735741
}
736742

737743
#[lang = "index"]

src/driver/wasm.rs

Lines changed: 141 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use std::fs::File;
55
use std::mem;
66

77
use cranelift_codegen::binemit::Reloc;
8-
use cranelift_codegen::ir::{BlockCall, ExternalName, InstructionData, Opcode};
8+
use cranelift_codegen::ir::{BlockCall, ExternalName, InstructionData, LibCall, Opcode};
99
use cranelift_codegen::isa::{self, CallConv, TargetFrontendConfig};
1010
use cranelift_module::{DataId, ModuleDeclarations, ModuleReloc, ModuleRelocTarget};
1111
use rustc_codegen_ssa::{CodegenResults, CompiledModule, CrateInfo, ModuleKind};
@@ -186,6 +186,66 @@ impl WasmModule {
186186
mut self,
187187
mut writer: W,
188188
) -> Result<(), Box<dyn std::error::Error>> {
189+
{
190+
let signature = &Signature {
191+
params: vec![AbiParam::new(types::I32)],
192+
returns: vec![AbiParam::new(types::I32)],
193+
call_conv: CallConv::SystemV,
194+
};
195+
let (malloc_id, _linkage) =
196+
self.declarations.declare_function("malloc", Linkage::Local, signature)?;
197+
198+
self.func_ids
199+
.entry(malloc_id)
200+
.or_insert_with(|| self.waffle_module.funcs.push(waffle::FuncDecl::None));
201+
202+
let waffle_sig =
203+
FunctionBuilder::translate_signature(&mut self.waffle_module, &signature);
204+
205+
let mut waffle_func = waffle::FunctionBody::new(&mut self.waffle_module, waffle_sig);
206+
207+
let alloc_size = waffle_func.blocks[waffle_func.entry].params[0].1;
208+
209+
let page_size = waffle::ValueDef::Operator(
210+
waffle::Operator::I32Const { value: 65536 },
211+
waffle_func.arg_pool.from_iter([].into_iter()),
212+
waffle_func.single_type_list(waffle::Type::I32),
213+
);
214+
let page_size = waffle_func.add_value(page_size);
215+
waffle_func.append_to_block(waffle_func.entry, page_size);
216+
217+
let alloc_size = waffle::ValueDef::Operator(
218+
waffle::Operator::I32Add,
219+
waffle_func.arg_pool.from_iter([alloc_size, page_size].into_iter()),
220+
waffle_func.single_type_list(waffle::Type::I32),
221+
);
222+
let alloc_size = waffle_func.add_value(alloc_size);
223+
waffle_func.append_to_block(waffle_func.entry, alloc_size);
224+
225+
let page_count = waffle::ValueDef::Operator(
226+
waffle::Operator::I32DivU,
227+
waffle_func.arg_pool.from_iter([alloc_size, page_size].into_iter()),
228+
waffle_func.single_type_list(waffle::Type::I32),
229+
);
230+
let page_count = waffle_func.add_value(page_count);
231+
waffle_func.append_to_block(waffle_func.entry, page_count);
232+
233+
let allocated = waffle::ValueDef::Operator(
234+
waffle::Operator::MemoryGrow { mem: self.main_memory },
235+
waffle_func.arg_pool.from_iter([page_count].into_iter()),
236+
waffle_func.single_type_list(waffle::Type::I32),
237+
);
238+
let allocated = waffle_func.add_value(allocated);
239+
waffle_func.append_to_block(waffle_func.entry, allocated);
240+
241+
waffle_func.set_terminator(waffle_func.entry, waffle::Terminator::Return {
242+
values: vec![allocated],
243+
});
244+
245+
self.waffle_module.funcs[self.func_ids[&malloc_id]] =
246+
waffle::FuncDecl::Body(waffle_sig, "malloc".to_owned(), waffle_func);
247+
}
248+
189249
for (func_id, func_decl) in self.declarations.get_functions() {
190250
if func_decl.linkage == Linkage::Import {
191251
let func = self.func_ids[&func_id];
@@ -470,6 +530,14 @@ impl Module for WasmModule {
470530
_ => unreachable!(),
471531
});
472532
}
533+
Opcode::Urem => {
534+
b.emit(inst, match b.clif_func.dfg.ctrl_typevar(inst) {
535+
types::I8 | types::I16 => todo!(),
536+
types::I32 => waffle::Operator::I32RemU,
537+
types::I64 => waffle::Operator::I64RemU,
538+
_ => unreachable!(),
539+
});
540+
}
473541
Opcode::Uextend => {
474542
let arg = b.get_value(b.clif_func.dfg.inst_args(inst)[0]);
475543
let ret = b.get_value(b.clif_func.dfg.inst_results(inst)[0]);
@@ -768,27 +836,77 @@ impl Module for WasmModule {
768836
_ => unreachable!(),
769837
}
770838
}
771-
Opcode::Call => {
772-
let func_id = match ctx.func.dfg.insts[inst] {
773-
InstructionData::Call { opcode: _, args: _, func_ref } => {
774-
match ctx.func.dfg.ext_funcs[func_ref].name {
775-
ExternalName::User(user) => {
776-
let name = &ctx.func.params.user_named_funcs()[user];
777-
assert_eq!(name.namespace, 0);
778-
FuncId::from_u32(name.index)
779-
}
780-
ExternalName::TestCase(_) => todo!(),
781-
ExternalName::LibCall(_libcall) => todo!(),
782-
ExternalName::KnownSymbol(_ks) => todo!(),
839+
Opcode::Call => match ctx.func.dfg.insts[inst] {
840+
InstructionData::Call { opcode: _, args: _, func_ref } => {
841+
match ctx.func.dfg.ext_funcs[func_ref].name {
842+
ExternalName::User(user) => {
843+
let name = &ctx.func.params.user_named_funcs()[user];
844+
assert_eq!(name.namespace, 0);
845+
let func_id = FuncId::from_u32(name.index);
846+
b.emit(inst, waffle::Operator::Call {
847+
function_index: self.func_ids[&func_id],
848+
});
849+
}
850+
ExternalName::TestCase(_) => todo!(),
851+
ExternalName::LibCall(LibCall::Memcpy | LibCall::Memmove) => {
852+
let block = b.clif_func.layout.inst_block(inst).unwrap();
853+
854+
let args = b
855+
.clif_func
856+
.dfg
857+
.inst_args(inst)
858+
.into_iter()
859+
.map(|&arg| b.get_value(arg))
860+
.collect::<Vec<_>>();
861+
862+
let ret_val =
863+
b.get_value(b.clif_func.dfg.inst_results(inst)[0]);
864+
865+
let copy = waffle::ValueDef::Operator(
866+
waffle::Operator::MemoryCopy {
867+
dst_mem: self.main_memory,
868+
src_mem: self.main_memory,
869+
},
870+
b.waffle_func.arg_pool.from_iter(args.iter().copied()),
871+
b.waffle_func.type_pool.from_iter([].into_iter()),
872+
);
873+
let copy = b.waffle_func.add_value(copy);
874+
b.waffle_func.append_to_block(b.block_map[&block], copy);
875+
876+
b.waffle_func.values[ret_val] =
877+
waffle::ValueDef::Alias(args[0]);
783878
}
879+
ExternalName::LibCall(LibCall::Memset) => {
880+
let block = b.clif_func.layout.inst_block(inst).unwrap();
881+
882+
let args = b
883+
.clif_func
884+
.dfg
885+
.inst_args(inst)
886+
.into_iter()
887+
.map(|&arg| b.get_value(arg))
888+
.collect::<Vec<_>>();
889+
890+
let ret_val =
891+
b.get_value(b.clif_func.dfg.inst_results(inst)[0]);
892+
893+
let copy = waffle::ValueDef::Operator(
894+
waffle::Operator::MemoryFill { mem: self.main_memory },
895+
b.waffle_func.arg_pool.from_iter(args.iter().copied()),
896+
b.waffle_func.type_pool.from_iter([].into_iter()),
897+
);
898+
let copy = b.waffle_func.add_value(copy);
899+
b.waffle_func.append_to_block(b.block_map[&block], copy);
900+
901+
b.waffle_func.values[ret_val] =
902+
waffle::ValueDef::Alias(args[0]);
903+
}
904+
ExternalName::LibCall(_libcall) => todo!(),
905+
ExternalName::KnownSymbol(_ks) => todo!(),
784906
}
785-
_ => unreachable!(),
786-
};
787-
788-
b.emit(inst, waffle::Operator::Call {
789-
function_index: self.func_ids[&func_id],
790-
});
791-
}
907+
}
908+
_ => unreachable!(),
909+
},
792910
Opcode::Jump => {
793911
let target_block = ctx.func.dfg.insts[inst]
794912
.branch_destination(&ctx.func.dfg.jump_tables)[0];
@@ -862,6 +980,9 @@ impl Module for WasmModule {
862980
) -> cranelift_module::ModuleResult<()> {
863981
let global = self.data_ids[&data_id];
864982

983+
let align = data.align.unwrap_or(1);
984+
self.next_data_offset = (self.next_data_offset + align - 1) & !(align - 1);
985+
865986
match &data.init {
866987
cranelift_module::Init::Uninitialized => unreachable!(),
867988
cranelift_module::Init::Zeros { size: _ } => {}

0 commit comments

Comments
 (0)