core/asm: assembly parser label fixes (#20210)
* core/asm: Fix encoding of pushed labels EVM uses big-endian byte-order, so to pad a label value to 4 bytes, zeros must be added to the front, not the end. * core/asm: Fix PC calculations when a label is pushed Incrementing PC by 5 is only correct if the label appears after a jump, in which case there is an implicit push. When it appears after an explicit push, PC should only be incremented by 4. * core/asm: Allow JUMP with no argument This way, a label can be pushed explicitly, or loaded from memory to implement a jump table.
This commit is contained in:
committed by
Felix Lange
parent
ecdbb402ee
commit
b0b277525c
@ -57,6 +57,7 @@ func NewCompiler(debug bool) *Compiler {
|
||||
// second stage to push labels and determine the right
|
||||
// position.
|
||||
func (c *Compiler) Feed(ch <-chan token) {
|
||||
var prev token
|
||||
for i := range ch {
|
||||
switch i.typ {
|
||||
case number:
|
||||
@ -73,10 +74,14 @@ func (c *Compiler) Feed(ch <-chan token) {
|
||||
c.labels[i.text] = c.pc
|
||||
c.pc++
|
||||
case label:
|
||||
c.pc += 5
|
||||
c.pc += 4
|
||||
if prev.typ == element && isJump(prev.text) {
|
||||
c.pc++
|
||||
}
|
||||
}
|
||||
|
||||
c.tokens = append(c.tokens, i)
|
||||
prev = i
|
||||
}
|
||||
if c.debug {
|
||||
fmt.Fprintln(os.Stderr, "found", len(c.labels), "labels")
|
||||
@ -181,6 +186,8 @@ func (c *Compiler) compileElement(element token) error {
|
||||
pos := big.NewInt(int64(c.labels[rvalue.text])).Bytes()
|
||||
pos = append(make([]byte, 4-len(pos)), pos...)
|
||||
c.pushBin(pos)
|
||||
case lineEnd:
|
||||
c.pos--
|
||||
default:
|
||||
return compileErr(rvalue, rvalue.text, "number, string or label")
|
||||
}
|
||||
@ -201,8 +208,8 @@ func (c *Compiler) compileElement(element token) error {
|
||||
case stringValue:
|
||||
value = []byte(rvalue.text[1 : len(rvalue.text)-1])
|
||||
case label:
|
||||
value = make([]byte, 4)
|
||||
copy(value, big.NewInt(int64(c.labels[rvalue.text])).Bytes())
|
||||
value = big.NewInt(int64(c.labels[rvalue.text])).Bytes()
|
||||
value = append(make([]byte, 4-len(value)), value...)
|
||||
default:
|
||||
return compileErr(rvalue, rvalue.text, "number, string or label")
|
||||
}
|
||||
|
Reference in New Issue
Block a user