github.com/yinchengtsinghua/golang-Eos-dpos-Ethereum@v0.0.0-20190121132951-92cc4225ed8e/core/vm/memory.go (about)

     1  
     2  //此源码被清华学神尹成大魔王专业翻译分析并修改
     3  //尹成QQ77025077
     4  //尹成微信18510341407
     5  //尹成所在QQ群721929980
     6  //尹成邮箱 yinc13@mails.tsinghua.edu.cn
     7  //尹成毕业于清华大学,微软区块链领域全球最有价值专家
     8  //https://mvp.microsoft.com/zh-cn/PublicProfile/4033620
     9  //版权所有2015 Go Ethereum作者
    10  //此文件是Go以太坊库的一部分。
    11  //
    12  //Go-Ethereum库是免费软件:您可以重新分发它和/或修改
    13  //根据GNU发布的较低通用公共许可证的条款
    14  //自由软件基金会,或者许可证的第3版,或者
    15  //(由您选择)任何更高版本。
    16  //
    17  //Go以太坊图书馆的发行目的是希望它会有用,
    18  //但没有任何保证;甚至没有
    19  //适销性或特定用途的适用性。见
    20  //GNU较低的通用公共许可证,了解更多详细信息。
    21  //
    22  //你应该收到一份GNU较低级别的公共许可证副本
    23  //以及Go以太坊图书馆。如果没有,请参见<http://www.gnu.org/licenses/>。
    24  
    25  package vm
    26  
    27  import (
    28  	"fmt"
    29  	"math/big"
    30  
    31  	"github.com/ethereum/go-ethereum/common/math"
    32  )
    33  
    34  //内存为以太坊虚拟机实现了一个简单的内存模型。
    35  type Memory struct {
    36  	store       []byte
    37  	lastGasCost uint64
    38  }
    39  
    40  //new memory返回新的内存模型。
    41  func NewMemory() *Memory {
    42  	return &Memory{}
    43  }
    44  
    45  //将“设置偏移量+大小”设置为“值”
    46  func (m *Memory) Set(offset, size uint64, value []byte) {
    47  //偏移量可能大于0,大小等于0。这是因为
    48  //当大小为零(no-op)时,CalcMemsize(common.go)可能返回0。
    49  	if size > 0 {
    50  //存储长度不能小于偏移量+大小。
    51  //在设置内存之前,应调整存储的大小
    52  		if offset+size > uint64(len(m.store)) {
    53  			panic("invalid memory: store empty")
    54  		}
    55  		copy(m.store[offset:offset+size], value)
    56  	}
    57  }
    58  
    59  //set32将从偏移量开始的32个字节设置为val值,用零左填充到
    60  //32字节。
    61  func (m *Memory) Set32(offset uint64, val *big.Int) {
    62  //存储长度不能小于偏移量+大小。
    63  //在设置内存之前,应调整存储的大小
    64  	if offset+32 > uint64(len(m.store)) {
    65  		panic("invalid memory: store empty")
    66  	}
    67  //把记忆区归零
    68  	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})
    69  //填写相关位
    70  	math.ReadBits(val, m.store[offset:offset+32])
    71  }
    72  
    73  //调整大小将内存大小调整为
    74  func (m *Memory) Resize(size uint64) {
    75  	if uint64(m.Len()) < size {
    76  		m.store = append(m.store, make([]byte, size-uint64(m.Len()))...)
    77  	}
    78  }
    79  
    80  //get返回偏移量+作为新切片的大小
    81  func (m *Memory) Get(offset, size int64) (cpy []byte) {
    82  	if size == 0 {
    83  		return nil
    84  	}
    85  
    86  	if len(m.store) > int(offset) {
    87  		cpy = make([]byte, size)
    88  		copy(cpy, m.store[offset:offset+size])
    89  
    90  		return
    91  	}
    92  
    93  	return
    94  }
    95  
    96  //getptr返回偏移量+大小
    97  func (m *Memory) GetPtr(offset, size int64) []byte {
    98  	if size == 0 {
    99  		return nil
   100  	}
   101  
   102  	if len(m.store) > int(offset) {
   103  		return m.store[offset : offset+size]
   104  	}
   105  
   106  	return nil
   107  }
   108  
   109  //len返回背衬片的长度
   110  func (m *Memory) Len() int {
   111  	return len(m.store)
   112  }
   113  
   114  //数据返回备份切片
   115  func (m *Memory) Data() []byte {
   116  	return m.store
   117  }
   118  
   119  //打印转储内存的内容。
   120  func (m *Memory) Print() {
   121  	fmt.Printf("### mem %d bytes ###\n", len(m.store))
   122  	if len(m.store) > 0 {
   123  		addr := 0
   124  		for i := 0; i+32 <= len(m.store); i += 32 {
   125  			fmt.Printf("%03d: % x\n", addr, m.store[i:i+32])
   126  			addr++
   127  		}
   128  	} else {
   129  		fmt.Println("-- empty --")
   130  	}
   131  	fmt.Println("####################")
   132  }