|
|
|
@ -92,25 +92,28 @@ func (c *Contract) validJumpdest(dest *big.Int) bool { |
|
|
|
|
if OpCode(c.Code[udest]) != JUMPDEST { |
|
|
|
|
return false |
|
|
|
|
} |
|
|
|
|
// Do we have a contract hash already?
|
|
|
|
|
// Do we have it locally already?
|
|
|
|
|
if c.analysis != nil { |
|
|
|
|
return c.analysis.codeSegment(udest) |
|
|
|
|
} |
|
|
|
|
// If we have the code hash (but no analysis), we should look into the
|
|
|
|
|
// parent analysis map and see if the analysis has been made previously
|
|
|
|
|
if c.CodeHash != (common.Hash{}) { |
|
|
|
|
// Does parent context have the analysis?
|
|
|
|
|
analysis, exist := c.jumpdests[c.CodeHash] |
|
|
|
|
if !exist { |
|
|
|
|
// Do the analysis and save in parent context
|
|
|
|
|
// We do not need to store it in c.analysis
|
|
|
|
|
analysis = codeBitmap(c.Code) |
|
|
|
|
c.jumpdests[c.CodeHash] = analysis |
|
|
|
|
} |
|
|
|
|
// Also stash it in current contract for faster access
|
|
|
|
|
c.analysis = analysis |
|
|
|
|
return analysis.codeSegment(udest) |
|
|
|
|
} |
|
|
|
|
// We don't have the code hash, most likely a piece of initcode not already
|
|
|
|
|
// in state trie. In that case, we do an analysis, and save it locally, so
|
|
|
|
|
// we don't have to recalculate it for every JUMP instruction in the execution
|
|
|
|
|
// However, we don't save it within the parent context
|
|
|
|
|
if c.analysis == nil { |
|
|
|
|
c.analysis = codeBitmap(c.Code) |
|
|
|
|
} |
|
|
|
|
c.analysis = codeBitmap(c.Code) |
|
|
|
|
return c.analysis.codeSegment(udest) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|