github.com/linapex/ethereum-go-chinese@v0.0.0-20190316121929-f8b7a73c3fa1/core/vm/analysis.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:35</date>
    10  //</624450081814220800>
    11  
    12  
    13  package vm
    14  
    15  //bitvec是一个位向量,它映射程序中的字节。
    16  //未设置位表示字节为操作码,设置位表示
    17  //这是数据(即pushxx的参数)。
    18  type bitvec []byte
    19  
    20  func (bits *bitvec) set(pos uint64) {
    21  	(*bits)[pos/8] |= 0x80 >> (pos % 8)
    22  }
    23  func (bits *bitvec) set8(pos uint64) {
    24  	(*bits)[pos/8] |= 0xFF >> (pos % 8)
    25  	(*bits)[pos/8+1] |= ^(0xFF >> (pos % 8))
    26  }
    27  
    28  //代码段检查位置是否在代码段中。
    29  func (bits *bitvec) codeSegment(pos uint64) bool {
    30  	return ((*bits)[pos/8] & (0x80 >> (pos % 8))) == 0
    31  }
    32  
    33  //codeBitmap以代码的形式收集数据位置。
    34  func codeBitmap(code []byte) bitvec {
    35  //如果代码
    36  //以push32结束,算法将把0推到
    37  //位向量超出了实际代码的边界。
    38  	bits := make(bitvec, len(code)/8+1+4)
    39  	for pc := uint64(0); pc < uint64(len(code)); {
    40  		op := OpCode(code[pc])
    41  
    42  		if op >= PUSH1 && op <= PUSH32 {
    43  			numbits := op - PUSH1 + 1
    44  			pc++
    45  			for ; numbits >= 8; numbits -= 8 {
    46  bits.set8(pc) //八
    47  				pc += 8
    48  			}
    49  			for ; numbits > 0; numbits-- {
    50  				bits.set(pc)
    51  				pc++
    52  			}
    53  		} else {
    54  			pc++
    55  		}
    56  	}
    57  	return bits
    58  }
    59