Skip to content

Commit

Permalink
Support 32-bit memories with 65536 pages
Browse files Browse the repository at this point in the history
  • Loading branch information
Amanieu committed Nov 10, 2021
1 parent 04a4758 commit 6a0b381
Show file tree
Hide file tree
Showing 8 changed files with 36 additions and 25 deletions.
2 changes: 1 addition & 1 deletion lib/api/src/sys/externals/memory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ impl Memory {
pub fn data_size(&self) -> u64 {
let definition = self.vm_memory.from.vmmemory();
let def = unsafe { definition.as_ref() };
def.current_length.into()
def.current_length.try_into().unwrap()
}

/// Returns the size (in [`Pages`]) of the `Memory`.
Expand Down
10 changes: 6 additions & 4 deletions lib/compiler-llvm/src/trampoline/wasm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,10 @@ impl FuncTrampoline {
let module = self.ctx.create_module("");
let target_machine = &self.target_machine;
let target_triple = target_machine.get_triple();
let target_data = target_machine.get_target_data();
module.set_triple(&target_triple);
module.set_data_layout(&target_machine.get_target_data().get_data_layout());
let intrinsics = Intrinsics::declare(&module, &self.ctx);
module.set_data_layout(&target_data.get_data_layout());
let intrinsics = Intrinsics::declare(&module, &self.ctx, &target_data);

let (callee_ty, callee_attrs) =
self.abi
Expand Down Expand Up @@ -177,10 +178,11 @@ impl FuncTrampoline {
let function = CompiledKind::DynamicFunctionTrampoline(ty.clone());
let module = self.ctx.create_module("");
let target_machine = &self.target_machine;
let target_data = target_machine.get_target_data();
let target_triple = target_machine.get_triple();
module.set_triple(&target_triple);
module.set_data_layout(&target_machine.get_target_data().get_data_layout());
let intrinsics = Intrinsics::declare(&module, &self.ctx);
module.set_data_layout(&target_data.get_data_layout());
let intrinsics = Intrinsics::declare(&module, &self.ctx, &target_data);

let (trampoline_ty, trampoline_attrs) =
self.abi
Expand Down
5 changes: 3 additions & 2 deletions lib/compiler-llvm/src/translator/code.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,16 +83,17 @@ impl FuncTranslator {

let target_machine = &self.target_machine;
let target_triple = target_machine.get_triple();
let target_data = target_machine.get_target_data();
module.set_triple(&target_triple);
module.set_data_layout(&target_machine.get_target_data().get_data_layout());
module.set_data_layout(&target_data.get_data_layout());
let wasm_fn_type = wasm_module
.signatures
.get(wasm_module.functions[func_index])
.unwrap();

// TODO: pointer width
let offsets = VMOffsets::new(8, &wasm_module);
let intrinsics = Intrinsics::declare(&module, &self.ctx);
let intrinsics = Intrinsics::declare(&module, &self.ctx, &target_data);
let (func_type, func_attrs) =
self.abi
.func_type_to_llvm(&self.ctx, &intrinsics, Some(&offsets), wasm_fn_type)?;
Expand Down
19 changes: 16 additions & 3 deletions lib/compiler-llvm/src/translator/intrinsics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ use inkwell::{
builder::Builder,
context::Context,
module::{Linkage, Module},
targets::TargetData,
types::{
BasicMetadataTypeEnum, BasicType, BasicTypeEnum, FloatType, IntType, PointerType,
StructType, VectorType, VoidType,
Expand Down Expand Up @@ -168,6 +169,7 @@ pub struct Intrinsics<'ctx> {
pub i32_ty: IntType<'ctx>,
pub i64_ty: IntType<'ctx>,
pub i128_ty: IntType<'ctx>,
pub isize_ty: IntType<'ctx>,
pub f32_ty: FloatType<'ctx>,
pub f64_ty: FloatType<'ctx>,

Expand All @@ -185,6 +187,7 @@ pub struct Intrinsics<'ctx> {
pub i32_ptr_ty: PointerType<'ctx>,
pub i64_ptr_ty: PointerType<'ctx>,
pub i128_ptr_ty: PointerType<'ctx>,
pub isize_ptr_ty: PointerType<'ctx>,
pub f32_ptr_ty: PointerType<'ctx>,
pub f64_ptr_ty: PointerType<'ctx>,

Expand All @@ -199,6 +202,7 @@ pub struct Intrinsics<'ctx> {
pub i32_zero: IntValue<'ctx>,
pub i64_zero: IntValue<'ctx>,
pub i128_zero: IntValue<'ctx>,
pub isize_zero: IntValue<'ctx>,
pub f32_zero: FloatValue<'ctx>,
pub f64_zero: FloatValue<'ctx>,
pub f32x4_zero: VectorValue<'ctx>,
Expand Down Expand Up @@ -260,7 +264,11 @@ pub struct Intrinsics<'ctx> {

impl<'ctx> Intrinsics<'ctx> {
/// Create an [`Intrinsics`] for the given [`Context`].
pub fn declare(module: &Module<'ctx>, context: &'ctx Context) -> Self {
pub fn declare(
module: &Module<'ctx>,
context: &'ctx Context,
target_data: &TargetData,
) -> Self {
let void_ty = context.void_type();
let i1_ty = context.bool_type();
let i2_ty = context.custom_width_int_type(2);
Expand All @@ -270,6 +278,7 @@ impl<'ctx> Intrinsics<'ctx> {
let i32_ty = context.i32_type();
let i64_ty = context.i64_type();
let i128_ty = context.i128_type();
let isize_ty = context.ptr_sized_int_type(target_data, None);
let f32_ty = context.f32_type();
let f64_ty = context.f64_type();

Expand All @@ -289,6 +298,7 @@ impl<'ctx> Intrinsics<'ctx> {
let i32_ptr_ty = i32_ty.ptr_type(AddressSpace::Generic);
let i64_ptr_ty = i64_ty.ptr_type(AddressSpace::Generic);
let i128_ptr_ty = i128_ty.ptr_type(AddressSpace::Generic);
let isize_ptr_ty = isize_ty.ptr_type(AddressSpace::Generic);
let f32_ptr_ty = f32_ty.ptr_type(AddressSpace::Generic);
let f64_ptr_ty = f64_ty.ptr_type(AddressSpace::Generic);

Expand All @@ -297,6 +307,7 @@ impl<'ctx> Intrinsics<'ctx> {
let i32_zero = i32_ty.const_int(0, false);
let i64_zero = i64_ty.const_int(0, false);
let i128_zero = i128_ty.const_int(0, false);
let isize_zero = isize_ty.const_int(0, false);
let f32_zero = f32_ty.const_float(0.0);
let f64_zero = f64_ty.const_float(0.0);
let f32x4_zero = f32x4_ty.const_zero();
Expand Down Expand Up @@ -703,6 +714,7 @@ impl<'ctx> Intrinsics<'ctx> {
i32_ty,
i64_ty,
i128_ty,
isize_ty,
f32_ty,
f64_ty,

Expand All @@ -720,6 +732,7 @@ impl<'ctx> Intrinsics<'ctx> {
i32_ptr_ty,
i64_ptr_ty,
i128_ptr_ty,
isize_ptr_ty,
f32_ptr_ty,
f64_ptr_ty,

Expand All @@ -734,6 +747,7 @@ impl<'ctx> Intrinsics<'ctx> {
i32_zero,
i64_zero,
i128_zero,
isize_zero,
f32_zero,
f64_zero,
f32x4_zero,
Expand Down Expand Up @@ -1001,9 +1015,8 @@ impl<'ctx> Intrinsics<'ctx> {
vmfunction_import_body_element: 0,
vmfunction_import_vmctx_element: 1,

// TODO: this i64 is actually a rust usize
vmmemory_definition_ptr_ty: context
.struct_type(&[i8_ptr_ty_basic, i32_ty.into()], false)
.struct_type(&[i8_ptr_ty_basic, isize_ty.into()], false)
.ptr_type(AddressSpace::Generic),
vmmemory_definition_base_element: 0,
vmmemory_definition_current_length_element: 1,
Expand Down
2 changes: 1 addition & 1 deletion lib/compiler-singlepass/src/codegen_x64.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1290,7 +1290,7 @@ impl<'a> FuncGen<'a> {
// Load bound into temporary register, if needed.
if need_check {
self.assembler
.emit_mov(Size::S32, bound_loc, Location::GPR(tmp_bound));
.emit_mov(Size::S64, bound_loc, Location::GPR(tmp_bound));

// Wasm -> Effective.
// Assuming we never underflow - should always be true on Linux/macOS and Windows >=8,
Expand Down
6 changes: 3 additions & 3 deletions lib/vm/src/instance/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -813,9 +813,9 @@ impl Instance {
if src
.checked_add(len)
.map_or(true, |n| n as usize > data.len())
|| dst
.checked_add(len)
.map_or(true, |m| m > memory.current_length)
|| dst.checked_add(len).map_or(true, |m| {
usize::try_from(m).unwrap() > memory.current_length
})
{
return Err(Trap::lib(TrapCode::HeapAccessOutOfBounds));
}
Expand Down
16 changes: 5 additions & 11 deletions lib/vm/src/vmcontext.rs
Original file line number Diff line number Diff line change
Expand Up @@ -345,7 +345,7 @@ pub struct VMMemoryDefinition {
pub base: *mut u8,

/// The current logical size of this linear memory in bytes.
pub current_length: u32,
pub current_length: usize,
}

/// # Safety
Expand All @@ -362,7 +362,7 @@ unsafe impl Sync for VMMemoryDefinition {}
impl MemoryUsage for VMMemoryDefinition {
fn size_of_val(&self, tracker: &mut dyn MemoryUsageTracker) -> usize {
if tracker.track(self.base as *const _ as *const ()) {
POINTER_BYTE_SIZE * (self.current_length as usize)
POINTER_BYTE_SIZE * self.current_length
} else {
0
}
Expand All @@ -384,10 +384,10 @@ impl VMMemoryDefinition {
// https://webassembly.github.io/reference-types/core/exec/instructions.html#exec-memory-copy
if src
.checked_add(len)
.map_or(true, |n| n > self.current_length)
.map_or(true, |n| usize::try_from(n).unwrap() > self.current_length)
|| dst
.checked_add(len)
.map_or(true, |m| m > self.current_length)
.map_or(true, |m| usize::try_from(m).unwrap() > self.current_length)
{
return Err(Trap::lib(TrapCode::HeapAccessOutOfBounds));
}
Expand Down Expand Up @@ -417,7 +417,7 @@ impl VMMemoryDefinition {
pub(crate) unsafe fn memory_fill(&self, dst: u32, val: u32, len: u32) -> Result<(), Trap> {
if dst
.checked_add(len)
.map_or(true, |m| m > self.current_length)
.map_or(true, |m| usize::try_from(m).unwrap() > self.current_length)
{
return Err(Trap::lib(TrapCode::HeapAccessOutOfBounds));
}
Expand Down Expand Up @@ -458,12 +458,6 @@ mod test_vmmemory_definition {
offset_of!(VMMemoryDefinition, current_length),
usize::from(offsets.vmmemory_definition_current_length())
);
/* TODO: Assert that the size of `current_length` matches.
assert_eq!(
size_of::<VMMemoryDefinition::current_length>(),
usize::from(offsets.size_of_vmmemory_definition_current_length())
);
*/
}
}

Expand Down
1 change: 1 addition & 0 deletions tests/wast/wasmer/max_size_of_memory.wast
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
(module (memory 65536))

0 comments on commit 6a0b381

Please sign in to comment.