合约:
public fun test_reference(){
let a = 1;
let ref_a = &a;
let b = *ref_a +1;
let mut_ref_b = &mut b;
*mut_ref_b = 3;
let owner = false;
let _ref_owner = &owner;
let _mut_ref_owner = &mut owner;
}
这个合约演示了针对整数、布尔值的引用操作。引用分为两种:
& : 表示不可修改的引用
&mut :表示可以进行修改的引用
* :解引用
我们通过下面的命令执行反编译:
move disassemble --name test_move
我们可以得到如下指令:
// Move bytecode v5
module f2.test_move {
public test_reference() {
L0: _mut_ref_owner: &mut bool
L1: _mut_ref_v: &mut vector<u8>
L2: _ref_owner: &bool
L3: _ref_v: &vector<u8>
L4: a: u64
L5: b: u64
L6: mut_ref_b: &mut u64
L7: owner: bool
L8: ref_a: &u64
L9: v: vector<u8>
B0:
0: LdU64(1)
1: StLoc[4](a: u64)
2: ImmBorrowLoc[4](a: u64)
3: StLoc[8](ref_a: &u64)
4: MoveLoc[8](ref_a: &u64)
5: ReadRef
6: LdU64(1)
7: Add
8: StLoc[5](b: u64)
9: MutBorrowLoc[5](b: u64)
10: StLoc[6](mut_ref_b: &mut u64)
11: LdU64(3)
12: MoveLoc[6](mut_ref_b: &mut u64)
13: WriteRef
14: LdFalse
15: StLoc[7](owner: bool)
16: ImmBorrowLoc[7](owner: bool)
17: Pop
18: MutBorrowLoc[7](owner: bool)
19: Pop
20: Ret
}
}
LdU64(1):加载整数1到栈上
StLoc[4](a: u64):将整数1从栈上取出,存入寄存器4
ImmBorrowLoc[4](a: u64)
这个指令用来对整数进行引用,具体代码如下:
Bytecode::MutBorrowLoc(idx) | Bytecode::ImmBorrowLoc(idx) => {
let instr = match instruction {
Bytecode::MutBorrowLoc(_) => S::MutBorrowLoc,
_ => S::ImmBorrowLoc,
};
gas_meter.charge_simple_instr(instr)?;
interpreter.operand_stack
.push(self.locals.borrow_loc(*idx as usize)?)?;
}
可以看到两种引用都会走locals.borrow_loc:
impl Locals {
pub fn borrow_loc(&self, idx: usize) -> PartialVMResult<Value> {
// TODO: this is very similar to SharedContainer::borrow_elem. Find a way to
// reuse that code?