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