Skip to content
Open
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
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use crate::{
},
};
use move_binary_format::{
errors::PartialVMResult,
errors::{PartialVMError, PartialVMResult},
file_format::{
Bytecode, ConstantPoolIndex, FieldHandleIndex, FieldInstantiationIndex,
FunctionHandleIndex, FunctionInstantiationIndex, SignatureIndex,
Expand Down Expand Up @@ -332,28 +332,28 @@ impl GasMeter for GasStatus<'_> {
fn charge_copy_loc(&mut self, val: impl ValueView) -> PartialVMResult<()> {
self.charge_instr_with_size(
Opcodes::COPY_LOC,
val.abstract_memory_size(&MOVE_TEST_SIZE_CONFIG),
val.abstract_memory_size(&MOVE_TEST_SIZE_CONFIG)?,
)
}

fn charge_move_loc(&mut self, val: impl ValueView) -> PartialVMResult<()> {
self.charge_instr_with_size(
Opcodes::MOVE_LOC,
val.abstract_memory_size(&MOVE_TEST_SIZE_CONFIG),
val.abstract_memory_size(&MOVE_TEST_SIZE_CONFIG)?,
)
}

fn charge_store_loc(&mut self, val: impl ValueView) -> PartialVMResult<()> {
self.charge_instr_with_size(
Opcodes::ST_LOC,
val.abstract_memory_size(&MOVE_TEST_SIZE_CONFIG),
val.abstract_memory_size(&MOVE_TEST_SIZE_CONFIG)?,
)
}

fn charge_pack(
&mut self,
is_generic: bool,
args: impl ExactSizeIterator<Item = impl ValueView>,
mut args: impl ExactSizeIterator<Item = impl ValueView>,
) -> PartialVMResult<()> {
let field_count = AbstractMemorySize::new(args.len() as u64);
self.charge_instr_with_size(
Expand All @@ -362,16 +362,16 @@ impl GasMeter for GasStatus<'_> {
} else {
Opcodes::PACK
},
args.fold(field_count, |acc, val| {
acc + val.abstract_memory_size(&MOVE_TEST_SIZE_CONFIG)
}),
args.try_fold(field_count, |acc, val| {
Ok::<_, PartialVMError>(acc + val.abstract_memory_size(&MOVE_TEST_SIZE_CONFIG)?)
})?,
)
}

fn charge_unpack(
&mut self,
is_generic: bool,
args: impl ExactSizeIterator<Item = impl ValueView>,
mut args: impl ExactSizeIterator<Item = impl ValueView>,
) -> PartialVMResult<()> {
let field_count = AbstractMemorySize::new(args.len() as u64);
self.charge_instr_with_size(
Expand All @@ -380,23 +380,23 @@ impl GasMeter for GasStatus<'_> {
} else {
Opcodes::UNPACK
},
args.fold(field_count, |acc, val| {
acc + val.abstract_memory_size(&MOVE_TEST_SIZE_CONFIG)
}),
args.try_fold(field_count, |acc, val| {
Ok::<_, PartialVMError>(acc + val.abstract_memory_size(&MOVE_TEST_SIZE_CONFIG)?)
})?,
)
}

fn charge_variant_switch(&mut self, val: impl ValueView) -> PartialVMResult<()> {
self.charge_instr_with_size(
Opcodes::VARIANT_SWITCH,
val.abstract_memory_size(&MOVE_TEST_SIZE_CONFIG),
val.abstract_memory_size(&MOVE_TEST_SIZE_CONFIG)?,
)
}

fn charge_read_ref(&mut self, ref_val: impl ValueView) -> PartialVMResult<()> {
self.charge_instr_with_size(
Opcodes::READ_REF,
ref_val.abstract_memory_size(&MOVE_TEST_SIZE_CONFIG),
ref_val.abstract_memory_size(&MOVE_TEST_SIZE_CONFIG)?,
)
}

Expand All @@ -407,23 +407,23 @@ impl GasMeter for GasStatus<'_> {
) -> PartialVMResult<()> {
self.charge_instr_with_size(
Opcodes::WRITE_REF,
new_val.abstract_memory_size(&MOVE_TEST_SIZE_CONFIG),
new_val.abstract_memory_size(&MOVE_TEST_SIZE_CONFIG)?,
)
}

fn charge_eq(&mut self, lhs: impl ValueView, rhs: impl ValueView) -> PartialVMResult<()> {
self.charge_instr_with_size(
Opcodes::EQ,
lhs.abstract_memory_size(&MOVE_TEST_SIZE_CONFIG)
+ rhs.abstract_memory_size(&MOVE_TEST_SIZE_CONFIG),
lhs.abstract_memory_size(&MOVE_TEST_SIZE_CONFIG)?
+ rhs.abstract_memory_size(&MOVE_TEST_SIZE_CONFIG)?,
)
}

fn charge_neq(&mut self, lhs: impl ValueView, rhs: impl ValueView) -> PartialVMResult<()> {
self.charge_instr_with_size(
Opcodes::NEQ,
lhs.abstract_memory_size(&MOVE_TEST_SIZE_CONFIG)
+ rhs.abstract_memory_size(&MOVE_TEST_SIZE_CONFIG),
lhs.abstract_memory_size(&MOVE_TEST_SIZE_CONFIG)?
+ rhs.abstract_memory_size(&MOVE_TEST_SIZE_CONFIG)?,
)
}

Expand Down Expand Up @@ -461,7 +461,7 @@ impl GasMeter for GasStatus<'_> {
) -> PartialVMResult<()> {
self.charge_instr_with_size(
Opcodes::VEC_PUSH_BACK,
val.abstract_memory_size(&MOVE_TEST_SIZE_CONFIG),
val.abstract_memory_size(&MOVE_TEST_SIZE_CONFIG)?,
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,13 @@
//! It is important to note that the cost schedule defined in this file does not track hashing
//! operations or other native operations; the cost of each native operation will be returned by the
//! native function itself.
use move_binary_format::errors::PartialVMResult;
use move_binary_format::errors::{PartialVMError, PartialVMResult};
use move_core_types::{
gas_algebra::{
AbstractMemorySize, GasQuantity, InternalGas, InternalGasUnit, NumArgs, NumBytes, ToUnit,
ToUnitFractional,
},
language_storage::ModuleId,
vm_status::StatusCode,
};

use crate::{
Expand Down Expand Up @@ -445,7 +444,7 @@ impl<'b> GasMeter for GasStatus<'b> {
}

fn charge_pop(&mut self, popped_val: impl ValueView) -> PartialVMResult<()> {
self.charge(1, 0, 1, 0, abstract_memory_size(popped_val).into())
self.charge(1, 0, 1, 0, abstract_memory_size(popped_val)?.into())
}

fn charge_native_function(
Expand All @@ -461,11 +460,12 @@ impl<'b> GasMeter for GasStatus<'b> {
.unwrap_or(0) as u64;
// Calculate the number of bytes that are getting pushed onto the stack.
let size_increase = ret_vals
.map(|ret_vals| {
ret_vals.fold(AbstractMemorySize::zero(), |acc, elem| {
acc + abstract_memory_size(elem)
.map(|mut ret_vals| {
ret_vals.try_fold(AbstractMemorySize::zero(), |acc, elem| {
Ok::<_, PartialVMError>(acc + abstract_memory_size(elem)?)
})
})
.transpose()?
.unwrap_or_else(AbstractMemorySize::zero);
// Charge for the stack operations. We don't count this as an "instruction" since we
// already accounted for the `Call` instruction in the
Expand All @@ -485,15 +485,15 @@ impl<'b> GasMeter for GasStatus<'b> {
fn charge_native_function_before_execution(
&mut self,
_ty_args: impl ExactSizeIterator<Item = impl TypeView>,
args: impl ExactSizeIterator<Item = impl ValueView>,
mut args: impl ExactSizeIterator<Item = impl ValueView>,
) -> PartialVMResult<()> {
// Determine the number of pops that are going to be needed for this function call, and
// charge for them.
let pops = args.len() as u64;
// Calculate the size decrease of the stack from the above pops.
let stack_reduction_size = args.fold(AbstractMemorySize::new(pops), |acc, elem| {
acc + abstract_memory_size(elem)
});
let stack_reduction_size = args.try_fold(AbstractMemorySize::new(pops), |acc, elem| {
Ok::<_, PartialVMError>(acc + abstract_memory_size(elem)?)
})?;
// Track that this is going to be popping from the operand stack. We also increment the
// instruction count as we need to account for the `Call` bytecode that initiated this
// native call.
Expand All @@ -504,16 +504,16 @@ impl<'b> GasMeter for GasStatus<'b> {
&mut self,
_module_id: &ModuleId,
_func_name: &str,
args: impl ExactSizeIterator<Item = impl ValueView>,
mut args: impl ExactSizeIterator<Item = impl ValueView>,
_num_locals: NumArgs,
) -> PartialVMResult<()> {
// We will have to perform this many pops for the call.
let pops = args.len() as u64;
// Size stays the same -- we're just moving it from the operand stack to the locals. But
// the size on the operand stack is reduced by sum_{args} arg.size().
let stack_reduction_size = args.fold(AbstractMemorySize::new(0), |acc, elem| {
acc + abstract_memory_size(elem)
});
let stack_reduction_size = args.try_fold(AbstractMemorySize::new(0), |acc, elem| {
Ok::<_, PartialVMError>(acc + abstract_memory_size(elem)?)
})?;
self.charge(1, 0, pops, 0, stack_reduction_size.into())
}

Expand All @@ -522,15 +522,15 @@ impl<'b> GasMeter for GasStatus<'b> {
_module_id: &ModuleId,
_func_name: &str,
_ty_args: impl ExactSizeIterator<Item = impl TypeView>,
args: impl ExactSizeIterator<Item = impl ValueView>,
mut args: impl ExactSizeIterator<Item = impl ValueView>,
_num_locals: NumArgs,
) -> PartialVMResult<()> {
// We have to perform this many pops from the operand stack for this function call.
let pops = args.len() as u64;
// Calculate the size reduction on the operand stack.
let stack_reduction_size = args.fold(AbstractMemorySize::new(0), |acc, elem| {
acc + abstract_memory_size(elem)
});
let stack_reduction_size = args.try_fold(AbstractMemorySize::new(0), |acc, elem| {
Ok::<_, PartialVMError>(acc + abstract_memory_size(elem)?)
})?;
// Charge for the pops, no pushes, and account for the stack size decrease. Also track the
// `CallGeneric` instruction we must have encountered for this.
self.charge(1, 0, pops, 0, stack_reduction_size.into())
Expand All @@ -551,21 +551,21 @@ impl<'b> GasMeter for GasStatus<'b> {

fn charge_copy_loc(&mut self, val: impl ValueView) -> PartialVMResult<()> {
// Charge for the copy of the local onto the stack.
self.charge(1, 1, 0, abstract_memory_size(val).into(), 0)
self.charge(1, 1, 0, abstract_memory_size(val)?.into(), 0)
}

fn charge_move_loc(&mut self, val: impl ValueView) -> PartialVMResult<()> {
// Charge for the move of the local on to the stack. Note that we charge here since we
// aren't tracking the local size (at least not yet). If we were, this should be a net-zero
// operation in terms of memory usage.
self.charge(1, 1, 0, abstract_memory_size(val).into(), 0)
self.charge(1, 1, 0, abstract_memory_size(val)?.into(), 0)
}

fn charge_store_loc(&mut self, val: impl ValueView) -> PartialVMResult<()> {
// Charge for the storing of the value on the stack into a local. Note here that if we were
// also accounting for the size of the locals that this would be a net-zero operation in
// terms of memory.
self.charge(1, 0, 1, 0, abstract_memory_size(val).into())
self.charge(1, 0, 1, 0, abstract_memory_size(val)?.into())
}

fn charge_pack(
Expand All @@ -591,7 +591,7 @@ impl<'b> GasMeter for GasStatus<'b> {
}

fn charge_variant_switch(&mut self, val: impl ValueView) -> PartialVMResult<()> {
self.charge(1, 0, 1, 0, abstract_memory_size(val).into())
self.charge(1, 0, 1, 0, abstract_memory_size(val)?.into())
}

fn charge_read_ref(&mut self, ref_val: impl ValueView) -> PartialVMResult<()> {
Expand All @@ -602,7 +602,7 @@ impl<'b> GasMeter for GasStatus<'b> {
1,
1,
1,
abstract_memory_size(ref_val).into(),
abstract_memory_size(ref_val)?.into(),
REFERENCE_SIZE.into(),
)
}
Expand All @@ -619,14 +619,14 @@ impl<'b> GasMeter for GasStatus<'b> {
1,
1,
2,
abstract_memory_size(new_val).into(),
abstract_memory_size(old_val).into(),
abstract_memory_size(new_val)?.into(),
abstract_memory_size(old_val)?.into(),
)
}

fn charge_eq(&mut self, lhs: impl ValueView, rhs: impl ValueView) -> PartialVMResult<()> {
let size_reduction =
abstract_memory_size_with_traversal(lhs) + abstract_memory_size_with_traversal(rhs);
abstract_memory_size_with_traversal(lhs)? + abstract_memory_size_with_traversal(rhs)?;
self.charge(
1,
1,
Expand All @@ -638,7 +638,7 @@ impl<'b> GasMeter for GasStatus<'b> {

fn charge_neq(&mut self, lhs: impl ValueView, rhs: impl ValueView) -> PartialVMResult<()> {
let size_reduction =
abstract_memory_size_with_traversal(lhs) + abstract_memory_size_with_traversal(rhs);
abstract_memory_size_with_traversal(lhs)? + abstract_memory_size_with_traversal(rhs)?;
self.charge(
1,
1,
Expand Down Expand Up @@ -783,14 +783,14 @@ pub fn initial_cost_schedule() -> CostTable {
}
}

fn abstract_memory_size(v: impl ValueView) -> AbstractMemorySize {
fn abstract_memory_size(v: impl ValueView) -> PartialVMResult<AbstractMemorySize> {
v.abstract_memory_size(&SizeConfig {
include_vector_size: true,
traverse_references: false,
})
}

fn abstract_memory_size_with_traversal(v: impl ValueView) -> AbstractMemorySize {
fn abstract_memory_size_with_traversal(v: impl ValueView) -> PartialVMResult<AbstractMemorySize> {
v.abstract_memory_size(&SizeConfig {
include_vector_size: true,
traverse_references: true,
Expand Down
Loading
Loading