Push a stack entry. Returns the stack-shape descriptor and the offset at which to write the pushed value.
(
&mut self,
parent: Option<FrameStackShape>,
ty: FrameValType,
)
| 102 | /// Push a stack entry. Returns the stack-shape descriptor and the |
| 103 | /// offset at which to write the pushed value. |
| 104 | pub fn push_stack( |
| 105 | &mut self, |
| 106 | parent: Option<FrameStackShape>, |
| 107 | ty: FrameValType, |
| 108 | ) -> (FrameStackShape, FrameStateSlotOffset) { |
| 109 | let offset = parent |
| 110 | .map(|parent| { |
| 111 | let (_, ty, offset) = self.stacks[parent.index()]; |
| 112 | offset.add(ty.storage_size(self.pointer_size)) |
| 113 | }) |
| 114 | // N.B.: the stack starts at vmctx_size + locals_size, |
| 115 | // because the layout puts vmctx first, then locals, then |
| 116 | // stack. |
| 117 | .unwrap_or(FrameStateSlotOffset(self.vmctx_size + self.locals_size)); |
| 118 | |
| 119 | self.slot_size = core::cmp::max( |
| 120 | self.slot_size, |
| 121 | offset.0 + ty.storage_size(self.pointer_size), |
| 122 | ); |
| 123 | |
| 124 | let shape = match self.stacks_dedup.entry((parent, ty, offset)) { |
| 125 | Entry::Occupied(o) => *o.get(), |
| 126 | Entry::Vacant(v) => { |
| 127 | let shape = FrameStackShape(u32::try_from(self.stacks.len()).unwrap()); |
| 128 | self.stacks.push((parent, ty, offset)); |
| 129 | *v.insert(shape) |
| 130 | } |
| 131 | }; |
| 132 | |
| 133 | (shape, offset) |
| 134 | } |
| 135 | |
| 136 | /// Get the offset for the top slot in a given stack shape. |
| 137 | pub fn stack_last_offset(&self, shape: FrameStackShape) -> FrameStateSlotOffset { |
no test coverage detected