Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support 32-bit memories with 65536 pages #2677

Merged
merged 2 commits into from
Nov 10, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
3 changes: 3 additions & 0 deletions tests/ignores.txt
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,9 @@ cranelift spec::simd::simd_i64x2_extmul_i32x4
cranelift spec::simd::simd_i8x16_arith2
cranelift spec::simd::simd_int_to_int_extend

# Windows doesn't overcommit and fails to allocate 4GB of memory
windows wast::wasmer::max_size_of_memory

# Frontends

## WASI
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))