Skip to content

Commit b539694

Browse files
committed
[vm] Removing IntegerValue and Value wrapper
The `values_impl::IntegerValue` type introduced a rather unnecessary wrapper for integer values, creating to conversions back and force to `Value`. Moreover, the newtype wrapper `Value` for `ValueImpl` was unnecessary as well and created overhead because it cannot be eliminated by the compiler when applied in iterators (as in `values.into_iter().map(Value).collect()`). Both have been removed.
1 parent 1dc20f4 commit b539694

File tree

6 files changed

+531
-798
lines changed

6 files changed

+531
-798
lines changed

third_party/move/move-vm/runtime/src/interpreter.rs

Lines changed: 57 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,8 @@ use move_vm_types::{
5252
natives::function::NativeResult,
5353
resolver::ResourceResolver,
5454
values::{
55-
self, AbstractFunction, Closure, GlobalValue, IntegerValue, Locals, Reference, SignerRef,
56-
Struct, StructRef, VMValueCast, Value, Vector, VectorRef,
55+
self, AbstractFunction, Closure, GlobalValue, Locals, Reference, SignerRef, Struct,
56+
StructRef, VMValueCast, Value, Vector, VectorRef,
5757
},
5858
views::TypeView,
5959
};
@@ -1176,68 +1176,48 @@ where
11761176
}
11771177

11781178
/// Perform a binary operation to two values at the top of the stack.
1179-
fn binop<F, T>(&mut self, f: F) -> PartialVMResult<()>
1179+
#[inline(always)]
1180+
fn binop<F>(&mut self, f: F) -> PartialVMResult<()>
11801181
where
1181-
Value: VMValueCast<T>,
1182-
F: FnOnce(T, T) -> PartialVMResult<Value>,
1182+
F: FnOnce(Value, Value) -> PartialVMResult<Value>,
11831183
{
1184-
let rhs = self.operand_stack.pop_as::<T>()?;
1185-
let lhs = self.operand_stack.pop_as::<T>()?;
1184+
let rhs = self.operand_stack.pop()?;
1185+
let lhs = self.operand_stack.pop()?;
11861186
let result = f(lhs, rhs)?;
11871187
self.operand_stack.push(result)
11881188
}
11891189

1190-
/// Perform a unary operation to one value at the top of the stack.
1191-
fn unop<F, T>(&mut self, f: F) -> PartialVMResult<()>
1192-
where
1193-
Value: VMValueCast<T>,
1194-
F: FnOnce(T) -> PartialVMResult<Value>,
1195-
{
1196-
let arg = self.operand_stack.pop_as::<T>()?;
1197-
let result = f(arg)?;
1198-
self.operand_stack.push(result)
1199-
}
1200-
1201-
/// Perform a binary operation for integer values.
1202-
fn binop_int<F>(&mut self, f: F) -> PartialVMResult<()>
1190+
#[inline(always)]
1191+
fn binop_bool<F>(&mut self, f: F) -> PartialVMResult<()>
12031192
where
1204-
F: FnOnce(IntegerValue, IntegerValue) -> PartialVMResult<IntegerValue>,
1193+
F: FnOnce(bool, bool) -> PartialVMResult<bool>,
12051194
{
1206-
self.binop(|lhs, rhs| Ok(Self::integer_value_to_value(f(lhs, rhs)?)))
1195+
let rhs = self.operand_stack.pop_as::<bool>()?;
1196+
let lhs = self.operand_stack.pop_as::<bool>()?;
1197+
let result = f(lhs, rhs)?;
1198+
self.operand_stack.push(Value::bool(result))
12071199
}
12081200

1209-
/// Perform a unary operation for integer values.
1210-
fn unop_int<F>(&mut self, f: F) -> PartialVMResult<()>
1201+
#[inline(always)]
1202+
fn binop_rel<F>(&mut self, f: F) -> PartialVMResult<()>
12111203
where
1212-
F: FnOnce(IntegerValue) -> PartialVMResult<IntegerValue>,
1204+
F: FnOnce(Value, Value) -> PartialVMResult<bool>,
12131205
{
1214-
self.unop(|arg| Ok(Self::integer_value_to_value(f(arg)?)))
1215-
}
1216-
1217-
fn integer_value_to_value(val: IntegerValue) -> Value {
1218-
match val {
1219-
IntegerValue::U8(x) => Value::u8(x),
1220-
IntegerValue::U16(x) => Value::u16(x),
1221-
IntegerValue::U32(x) => Value::u32(x),
1222-
IntegerValue::U64(x) => Value::u64(x),
1223-
IntegerValue::U128(x) => Value::u128(x),
1224-
IntegerValue::U256(x) => Value::u256(x),
1225-
IntegerValue::I8(x) => Value::i8(x),
1226-
IntegerValue::I16(x) => Value::i16(x),
1227-
IntegerValue::I32(x) => Value::i32(x),
1228-
IntegerValue::I64(x) => Value::i64(x),
1229-
IntegerValue::I128(x) => Value::i128(x),
1230-
IntegerValue::I256(x) => Value::i256(x),
1231-
}
1206+
let rhs = self.operand_stack.pop()?;
1207+
let lhs = self.operand_stack.pop()?;
1208+
let result = f(lhs, rhs)?;
1209+
self.operand_stack.push(Value::bool(result))
12321210
}
12331211

1234-
/// Perform a binary operation for boolean values.
1235-
fn binop_bool<F, T>(&mut self, f: F) -> PartialVMResult<()>
1212+
/// Perform a unary operation to one value at the top of the stack.
1213+
#[inline(always)]
1214+
fn unop<F>(&mut self, f: F) -> PartialVMResult<()>
12361215
where
1237-
Value: VMValueCast<T>,
1238-
F: FnOnce(T, T) -> PartialVMResult<bool>,
1216+
F: FnOnce(Value) -> PartialVMResult<Value>,
12391217
{
1240-
self.binop(|lhs, rhs| Ok(Value::bool(f(lhs, rhs)?)))
1218+
let arg = self.operand_stack.pop()?;
1219+
let result = f(arg)?;
1220+
self.operand_stack.push(result)
12411221
}
12421222

12431223
/// Creates a data cache entry for the specified address-type pair. Charges gas for the number
@@ -2571,84 +2551,84 @@ impl Frame {
25712551
},
25722552
Bytecode::CastU8 => {
25732553
gas_meter.charge_simple_instr(S::CastU8)?;
2574-
let integer_value = interpreter.operand_stack.pop_as::<IntegerValue>()?;
2554+
let integer_value = interpreter.operand_stack.pop()?;
25752555
interpreter
25762556
.operand_stack
25772557
.push(Value::u8(integer_value.cast_u8()?))?;
25782558
},
25792559
Bytecode::CastU16 => {
25802560
gas_meter.charge_simple_instr(S::CastU16)?;
2581-
let integer_value = interpreter.operand_stack.pop_as::<IntegerValue>()?;
2561+
let integer_value = interpreter.operand_stack.pop()?;
25822562
interpreter
25832563
.operand_stack
25842564
.push(Value::u16(integer_value.cast_u16()?))?;
25852565
},
25862566
Bytecode::CastU32 => {
25872567
gas_meter.charge_simple_instr(S::CastU32)?;
2588-
let integer_value = interpreter.operand_stack.pop_as::<IntegerValue>()?;
2568+
let integer_value = interpreter.operand_stack.pop()?;
25892569
interpreter
25902570
.operand_stack
25912571
.push(Value::u32(integer_value.cast_u32()?))?;
25922572
},
25932573
Bytecode::CastU64 => {
25942574
gas_meter.charge_simple_instr(S::CastU64)?;
2595-
let integer_value = interpreter.operand_stack.pop_as::<IntegerValue>()?;
2575+
let integer_value = interpreter.operand_stack.pop()?;
25962576
interpreter
25972577
.operand_stack
25982578
.push(Value::u64(integer_value.cast_u64()?))?;
25992579
},
26002580
Bytecode::CastU128 => {
26012581
gas_meter.charge_simple_instr(S::CastU128)?;
2602-
let integer_value = interpreter.operand_stack.pop_as::<IntegerValue>()?;
2582+
let integer_value = interpreter.operand_stack.pop()?;
26032583
interpreter
26042584
.operand_stack
26052585
.push(Value::u128(integer_value.cast_u128()?))?;
26062586
},
26072587
Bytecode::CastU256 => {
26082588
gas_meter.charge_simple_instr(S::CastU256)?;
2609-
let integer_value = interpreter.operand_stack.pop_as::<IntegerValue>()?;
2589+
let integer_value = interpreter.operand_stack.pop()?;
26102590
interpreter
26112591
.operand_stack
26122592
.push(Value::u256(integer_value.cast_u256()?))?;
26132593
},
26142594
Bytecode::CastI8 => {
26152595
gas_meter.charge_simple_instr(S::CastI8)?;
2616-
let integer_value = interpreter.operand_stack.pop_as::<IntegerValue>()?;
2596+
let integer_value = interpreter.operand_stack.pop()?;
26172597
interpreter
26182598
.operand_stack
26192599
.push(Value::i8(integer_value.cast_i8()?))?;
26202600
},
26212601
Bytecode::CastI16 => {
26222602
gas_meter.charge_simple_instr(S::CastI16)?;
2623-
let integer_value = interpreter.operand_stack.pop_as::<IntegerValue>()?;
2603+
let integer_value = interpreter.operand_stack.pop()?;
26242604
interpreter
26252605
.operand_stack
26262606
.push(Value::i16(integer_value.cast_i16()?))?;
26272607
},
26282608
Bytecode::CastI32 => {
26292609
gas_meter.charge_simple_instr(S::CastI32)?;
2630-
let integer_value = interpreter.operand_stack.pop_as::<IntegerValue>()?;
2610+
let integer_value = interpreter.operand_stack.pop()?;
26312611
interpreter
26322612
.operand_stack
26332613
.push(Value::i32(integer_value.cast_i32()?))?;
26342614
},
26352615
Bytecode::CastI64 => {
26362616
gas_meter.charge_simple_instr(S::CastI64)?;
2637-
let integer_value = interpreter.operand_stack.pop_as::<IntegerValue>()?;
2617+
let integer_value = interpreter.operand_stack.pop()?;
26382618
interpreter
26392619
.operand_stack
26402620
.push(Value::i64(integer_value.cast_i64()?))?;
26412621
},
26422622
Bytecode::CastI128 => {
26432623
gas_meter.charge_simple_instr(S::CastI128)?;
2644-
let integer_value = interpreter.operand_stack.pop_as::<IntegerValue>()?;
2624+
let integer_value = interpreter.operand_stack.pop()?;
26452625
interpreter
26462626
.operand_stack
26472627
.push(Value::i128(integer_value.cast_i128()?))?;
26482628
},
26492629
Bytecode::CastI256 => {
26502630
gas_meter.charge_simple_instr(S::CastI256)?;
2651-
let integer_value = interpreter.operand_stack.pop_as::<IntegerValue>()?;
2631+
let integer_value = interpreter.operand_stack.pop()?;
26522632
interpreter
26532633
.operand_stack
26542634
.push(Value::i256(integer_value.cast_i256()?))?;
@@ -2657,55 +2637,51 @@ impl Frame {
26572637
// Arithmetic Operations
26582638
Bytecode::Add => {
26592639
gas_meter.charge_simple_instr(S::Add)?;
2660-
interpreter.binop_int(IntegerValue::add_checked)?
2640+
interpreter.binop(Value::add_checked)?
26612641
},
26622642
Bytecode::Sub => {
26632643
gas_meter.charge_simple_instr(S::Sub)?;
2664-
interpreter.binop_int(IntegerValue::sub_checked)?
2644+
interpreter.binop(Value::sub_checked)?
26652645
},
26662646
Bytecode::Mul => {
26672647
gas_meter.charge_simple_instr(S::Mul)?;
2668-
interpreter.binop_int(IntegerValue::mul_checked)?
2648+
interpreter.binop(Value::mul_checked)?
26692649
},
26702650
Bytecode::Mod => {
26712651
gas_meter.charge_simple_instr(S::Mod)?;
2672-
interpreter.binop_int(IntegerValue::rem_checked)?
2652+
interpreter.binop(Value::rem_checked)?
26732653
},
26742654
Bytecode::Div => {
26752655
gas_meter.charge_simple_instr(S::Div)?;
2676-
interpreter.binop_int(IntegerValue::div_checked)?
2656+
interpreter.binop(Value::div_checked)?
26772657
},
26782658
Bytecode::Negate => {
26792659
gas_meter.charge_simple_instr(S::Negate)?;
2680-
interpreter.unop_int(IntegerValue::negate_checked)?
2660+
interpreter.unop(Value::negate_checked)?
26812661
},
26822662
Bytecode::BitOr => {
26832663
gas_meter.charge_simple_instr(S::BitOr)?;
2684-
interpreter.binop_int(IntegerValue::bit_or)?
2664+
interpreter.binop(Value::bit_or)?
26852665
},
26862666
Bytecode::BitAnd => {
26872667
gas_meter.charge_simple_instr(S::BitAnd)?;
2688-
interpreter.binop_int(IntegerValue::bit_and)?
2668+
interpreter.binop(Value::bit_and)?
26892669
},
26902670
Bytecode::Xor => {
26912671
gas_meter.charge_simple_instr(S::Xor)?;
2692-
interpreter.binop_int(IntegerValue::bit_xor)?
2672+
interpreter.binop(Value::bit_xor)?
26932673
},
26942674
Bytecode::Shl => {
26952675
gas_meter.charge_simple_instr(S::Shl)?;
26962676
let rhs = interpreter.operand_stack.pop_as::<u8>()?;
2697-
let lhs = interpreter.operand_stack.pop_as::<IntegerValue>()?;
2698-
interpreter
2699-
.operand_stack
2700-
.push(lhs.shl_checked(rhs)?.into_value())?;
2677+
let lhs = interpreter.operand_stack.pop()?;
2678+
interpreter.operand_stack.push(lhs.shl_checked(rhs)?)?;
27012679
},
27022680
Bytecode::Shr => {
27032681
gas_meter.charge_simple_instr(S::Shr)?;
27042682
let rhs = interpreter.operand_stack.pop_as::<u8>()?;
2705-
let lhs = interpreter.operand_stack.pop_as::<IntegerValue>()?;
2706-
interpreter
2707-
.operand_stack
2708-
.push(lhs.shr_checked(rhs)?.into_value())?;
2683+
let lhs = interpreter.operand_stack.pop()?;
2684+
interpreter.operand_stack.push(lhs.shr_checked(rhs)?)?;
27092685
},
27102686
Bytecode::Or => {
27112687
gas_meter.charge_simple_instr(S::Or)?;
@@ -2717,19 +2693,19 @@ impl Frame {
27172693
},
27182694
Bytecode::Lt => {
27192695
gas_meter.charge_simple_instr(S::Lt)?;
2720-
interpreter.binop_bool(IntegerValue::lt)?
2696+
interpreter.binop_rel(Value::lt)?
27212697
},
27222698
Bytecode::Gt => {
27232699
gas_meter.charge_simple_instr(S::Gt)?;
2724-
interpreter.binop_bool(IntegerValue::gt)?
2700+
interpreter.binop_rel(Value::gt)?
27252701
},
27262702
Bytecode::Le => {
27272703
gas_meter.charge_simple_instr(S::Le)?;
2728-
interpreter.binop_bool(IntegerValue::le)?
2704+
interpreter.binop_rel(Value::le)?
27292705
},
27302706
Bytecode::Ge => {
27312707
gas_meter.charge_simple_instr(S::Ge)?;
2732-
interpreter.binop_bool(IntegerValue::ge)?
2708+
interpreter.binop_rel(Value::ge)?
27332709
},
27342710
Bytecode::Abort => {
27352711
gas_meter.charge_simple_instr(S::Abort)?;

third_party/move/move-vm/types/src/value_serde.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,7 @@ impl<'a> ValueSerDeContext<'a> {
193193
let value = SerializationReadyValue {
194194
ctx: &self,
195195
layout,
196-
value: &value.0,
196+
value,
197197
depth: 1,
198198
};
199199

@@ -223,7 +223,7 @@ impl<'a> ValueSerDeContext<'a> {
223223
let value = SerializationReadyValue {
224224
ctx: &self,
225225
layout,
226-
value: &value.0,
226+
value,
227227
depth: 1,
228228
};
229229
bcs::serialized_size(&value).map_err(|e| {

third_party/move/move-vm/types/src/value_traversal.rs

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
use crate::{
55
delayed_values::error::code_invariant_error,
6-
values::{Closure, Container, Value, ValueImpl},
6+
values::{Closure, Container, Value},
77
};
88
use move_binary_format::errors::{PartialVMError, PartialVMResult};
99
use move_core_types::vm_status::StatusCode;
@@ -16,30 +16,30 @@ pub fn find_identifiers_in_value(
1616
value: &Value,
1717
identifiers: &mut HashSet<u64>,
1818
) -> PartialVMResult<()> {
19-
find_identifiers_in_value_impl(&value.0, identifiers)
19+
find_identifiers_in_value_impl(value, identifiers)
2020
}
2121

2222
fn find_identifiers_in_value_impl(
23-
value: &ValueImpl,
23+
value: &Value,
2424
identifiers: &mut HashSet<u64>,
2525
) -> PartialVMResult<()> {
2626
match value {
27-
ValueImpl::U8(_)
28-
| ValueImpl::U16(_)
29-
| ValueImpl::U32(_)
30-
| ValueImpl::U64(_)
31-
| ValueImpl::U128(_)
32-
| ValueImpl::U256(_)
33-
| ValueImpl::I8(_)
34-
| ValueImpl::I16(_)
35-
| ValueImpl::I32(_)
36-
| ValueImpl::I64(_)
37-
| ValueImpl::I128(_)
38-
| ValueImpl::I256(_)
39-
| ValueImpl::Bool(_)
40-
| ValueImpl::Address(_) => {},
41-
42-
ValueImpl::Container(c) => match c {
27+
Value::U8(_)
28+
| Value::U16(_)
29+
| Value::U32(_)
30+
| Value::U64(_)
31+
| Value::U128(_)
32+
| Value::U256(_)
33+
| Value::I8(_)
34+
| Value::I16(_)
35+
| Value::I32(_)
36+
| Value::I64(_)
37+
| Value::I128(_)
38+
| Value::I256(_)
39+
| Value::Bool(_)
40+
| Value::Address(_) => {},
41+
42+
Value::Container(c) => match c {
4343
Container::Locals(_) => {
4444
return Err(PartialVMError::new(
4545
StatusCode::UNKNOWN_INVARIANT_VIOLATION_ERROR,
@@ -68,19 +68,19 @@ fn find_identifiers_in_value_impl(
6868
},
6969
},
7070

71-
ValueImpl::ClosureValue(Closure(_, captured)) => {
71+
Value::ClosureValue(Closure(_, captured)) => {
7272
for val in captured.iter() {
7373
find_identifiers_in_value_impl(val, identifiers)?;
7474
}
7575
},
7676

77-
ValueImpl::Invalid | ValueImpl::ContainerRef(_) | ValueImpl::IndexedRef(_) => {
77+
Value::Invalid | Value::ContainerRef(_) | Value::IndexedRef(_) => {
7878
return Err(PartialVMError::new(
7979
StatusCode::UNKNOWN_INVARIANT_VIOLATION_ERROR,
8080
))
8181
},
8282

83-
ValueImpl::DelayedFieldID { id } => {
83+
Value::DelayedFieldID { id } => {
8484
if !identifiers.insert(id.as_u64()) {
8585
return Err(code_invariant_error(
8686
"Duplicated identifiers for Move value".to_string(),

0 commit comments

Comments
 (0)