9 "github.com/vapor/protocol/vm"
11 "github.com/vapor/equity/compiler"
15 firstClauseShift string = "00000000"
16 endingClauseName string = "ending"
19 // Shift statistics contract clause's offset
20 func Shift(contract *compiler.Contract) (map[string]string, error) {
21 clauseMap := make(map[string]string)
22 if len(contract.Clauses) == 1 {
23 clauseMap[contract.Clauses[0].Name] = firstClauseShift
27 instructions, err := vm.ParseProgram(contract.Body)
32 var jumpifData [][]byte
33 for i, inst := range instructions {
34 if inst.Op.String() == "JUMPIF" {
35 if i > 0 && instructions[i-1].Op.String() == "NOP" {
38 jumpifData = append([][]byte{inst.Data}, jumpifData...)
42 // Check the number of contract's clause
43 if len(contract.Clauses) != len(jumpifData)+1 {
44 return nil, errors.New("the number of contract's clause is not equal to the number of jumpif instruction")
47 for i, clause := range contract.Clauses {
49 clauseMap[clause.Name] = firstClauseShift
52 clauseMap[clause.Name] = hex.EncodeToString(jumpifData[i-1])
55 var buffer bytes.Buffer
56 if err := binary.Write(&buffer, binary.LittleEndian, uint32(len(contract.Body))); err != nil {
59 clauseMap[endingClauseName] = hex.EncodeToString(buffer.Bytes())