@@ -6,13 +6,14 @@ use crate::imms::*;
66use crate :: profile:: { ExecutingPc , ExecutingPcRef } ;
77use crate :: regs:: * ;
88use alloc:: string:: ToString ;
9- use alloc:: vec:: Vec ;
109use core:: fmt;
1110use core:: mem;
1211use core:: ops:: ControlFlow ;
1312use core:: ops:: { Index , IndexMut } ;
1413use core:: ptr:: NonNull ;
1514use pulley_macros:: interp_disable_if_cfg;
15+ use wasmtime_core:: alloc:: TryVec ;
16+ use wasmtime_core:: error:: OutOfMemory ;
1617use wasmtime_core:: math:: { WasmFloat , f32_cvt_to_int_bounds, f64_cvt_to_int_bounds} ;
1718
1819mod debug;
@@ -29,24 +30,18 @@ pub struct Vm {
2930 executing_pc : ExecutingPc ,
3031}
3132
32- impl Default for Vm {
33- fn default ( ) -> Self {
34- Vm :: new ( )
35- }
36- }
37-
3833impl Vm {
3934 /// Create a new virtual machine with the default stack size.
40- pub fn new ( ) -> Self {
35+ pub fn new ( ) -> Result < Self , OutOfMemory > {
4136 Self :: with_stack ( DEFAULT_STACK_SIZE )
4237 }
4338
4439 /// Create a new virtual machine with the given stack.
45- pub fn with_stack ( stack_size : usize ) -> Self {
46- Self {
47- state : MachineState :: with_stack ( stack_size) ,
40+ pub fn with_stack ( stack_size : usize ) -> Result < Self , OutOfMemory > {
41+ Ok ( Self {
42+ state : MachineState :: with_stack ( stack_size) ? ,
4843 executing_pc : ExecutingPc :: default ( ) ,
49- }
44+ } )
5045 }
5146
5247 /// Get a shared reference to this VM's machine state.
@@ -762,7 +757,7 @@ unsafe impl Sync for MachineState {}
762757/// done with a custom `Vec<T>` internally where `T` has size and align of 16.
763758/// This is manually done with a helper `Align16` type below.
764759struct Stack {
765- storage : Vec < Align16 > ,
760+ storage : TryVec < Align16 > ,
766761}
767762
768763/// Helper type used with `Stack` above.
@@ -778,14 +773,14 @@ impl Stack {
778773 /// Creates a new stack which will have a byte size of at least `size`.
779774 ///
780775 /// The allocated stack might be slightly larger due to rounding necessary.
781- fn new ( size : usize ) -> Stack {
782- Stack {
783- // Round up `size` to the nearest multiple of 16. Note that the
784- // stack is also allocated here but not initialized, and that's
785- // intentional as pulley bytecode should always initialize the stack
786- // before use.
787- storage : Vec :: with_capacity ( ( size + 15 ) / 16 ) ,
788- }
776+ fn new ( size : usize ) -> Result < Stack , OutOfMemory > {
777+ let mut storage = TryVec :: new ( ) ;
778+ // Round up `size` to the nearest multiple of 16. Note that the
779+ // stack is also allocated here but not initialized, and that's
780+ // intentional as pulley bytecode should always initialize the stack
781+ // before use.
782+ storage. reserve_exact ( size. checked_next_multiple_of ( 16 ) . unwrap_or ( usize :: MAX ) / 16 ) ? ;
783+ Ok ( Stack { storage } )
789784 }
790785
791786 /// Returns a pointer to the top of the stack (the highest address).
@@ -896,13 +891,13 @@ index_reg!(VReg, VRegVal, v_regs);
896891const HOST_RETURN_ADDR : * mut u8 = usize:: MAX as * mut u8 ;
897892
898893impl MachineState {
899- fn with_stack ( stack_size : usize ) -> Self {
894+ fn with_stack ( stack_size : usize ) -> Result < Self , OutOfMemory > {
900895 let mut state = Self {
901896 x_regs : [ Default :: default ( ) ; XReg :: RANGE . end as usize ] ,
902897 f_regs : Default :: default ( ) ,
903898 #[ cfg( not( pulley_disable_interp_simd) ) ]
904899 v_regs : Default :: default ( ) ,
905- stack : Stack :: new ( stack_size) ,
900+ stack : Stack :: new ( stack_size) ? ,
906901 done_reason : None ,
907902 fp : HOST_RETURN_ADDR ,
908903 lr : HOST_RETURN_ADDR ,
@@ -911,7 +906,7 @@ impl MachineState {
911906 let sp = state. stack . top ( ) ;
912907 state[ XReg :: sp] = XRegVal :: new_ptr ( sp) ;
913908
914- state
909+ Ok ( state)
915910 }
916911}
917912
@@ -1294,7 +1289,7 @@ impl AddressingMode for AddrG32Bne {
12941289
12951290#[ test]
12961291fn simple_push_pop ( ) {
1297- let mut state = MachineState :: with_stack ( 16 ) ;
1292+ let mut state = MachineState :: with_stack ( 16 ) . unwrap ( ) ;
12981293 let pc = ExecutingPc :: default ( ) ;
12991294 unsafe {
13001295 let mut bytecode = [ 0 ; 10 ] ;
0 commit comments