github.com/linapex/ethereum-go-chinese@v0.0.0-20190316121929-f8b7a73c3fa1/core/vm/memory.go (about)

     1  
     2  //<developer>
     3  //    <name>linapex 曹一峰</name>
     4  //    <email>linapex@163.com</email>
     5  //    <wx>superexc</wx>
     6  //    <qqgroup>128148617</qqgroup>
     7  //    <url>https://jsq.ink</url>
     8  //    <role>pku engineer</role>
     9  //    <date>2019-03-16 19:16:36</date>
    10  //</624450083005403136>
    11  
    12  
    13  package vm
    14  
    15  import (
    16  	"fmt"
    17  	"math/big"
    18  
    19  	"github.com/ethereum/go-ethereum/common/math"
    20  )
    21  
    22  //内存为以太坊虚拟机实现了一个简单的内存模型。
    23  type Memory struct {
    24  	store       []byte
    25  	lastGasCost uint64
    26  }
    27  
    28  //new memory返回新的内存模型。
    29  func NewMemory() *Memory {
    30  	return &Memory{}
    31  }
    32  
    33  //将“设置偏移量+大小”设置为“值”
    34  func (m *Memory) Set(offset, size uint64, value []byte) {
    35  //偏移量可能大于0,大小等于0。这是因为
    36  //当大小为零(no-op)时,CalcMemsize(common.go)可能返回0。
    37  	if size > 0 {
    38  //存储长度不能小于偏移量+大小。
    39  //在设置内存之前,应调整存储的大小
    40  		if offset+size > uint64(len(m.store)) {
    41  			panic("invalid memory: store empty")
    42  		}
    43  		copy(m.store[offset:offset+size], value)
    44  	}
    45  }
    46  
    47  //set32将从偏移量开始的32个字节设置为val值,用零左填充到
    48  //32字节。
    49  func (m *Memory) Set32(offset uint64, val *big.Int) {
    50  //存储长度不能小于偏移量+大小。
    51  //在设置内存之前,应调整存储的大小
    52  	if offset+32 > uint64(len(m.store)) {
    53  		panic("invalid memory: store empty")
    54  	}
    55  //把记忆区归零
    56  	copy(m.store[offset:offset+32], []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0})
    57  //填写相关位
    58  	math.ReadBits(val, m.store[offset:offset+32])
    59  }
    60  
    61  //调整大小将内存大小调整为
    62  func (m *Memory) Resize(size uint64) {
    63  	if uint64(m.Len()) < size {
    64  		m.store = append(m.store, make([]byte, size-uint64(m.Len()))...)
    65  	}
    66  }
    67  
    68  //get返回偏移量+作为新切片的大小
    69  func (m *Memory) Get(offset, size int64) (cpy []byte) {
    70  	if size == 0 {
    71  		return nil
    72  	}
    73  
    74  	if len(m.store) > int(offset) {
    75  		cpy = make([]byte, size)
    76  		copy(cpy, m.store[offset:offset+size])
    77  
    78  		return
    79  	}
    80  
    81  	return
    82  }
    83  
    84  //getptr返回偏移量+大小
    85  func (m *Memory) GetPtr(offset, size int64) []byte {
    86  	if size == 0 {
    87  		return nil
    88  	}
    89  
    90  	if len(m.store) > int(offset) {
    91  		return m.store[offset : offset+size]
    92  	}
    93  
    94  	return nil
    95  }
    96  
    97  //len返回背衬片的长度
    98  func (m *Memory) Len() int {
    99  	return len(m.store)
   100  }
   101  
   102  //数据返回备份切片
   103  func (m *Memory) Data() []byte {
   104  	return m.store
   105  }
   106  
   107  //打印转储内存的内容。
   108  func (m *Memory) Print() {
   109  	fmt.Printf("### mem %d bytes ###\n", len(m.store))
   110  	if len(m.store) > 0 {
   111  		addr := 0
   112  		for i := 0; i+32 <= len(m.store); i += 32 {
   113  			fmt.Printf("%03d: % x\n", addr, m.store[i:i+32])
   114  			addr++
   115  		}
   116  	} else {
   117  		fmt.Println("-- empty --")
   118  	}
   119  	fmt.Println("####################")
   120  }
   121