compiler: copy locals slice during inline

Consider function call `f(1, g(2, 3))` when
both `f` and `g` are inlined. If `f` contains some locals,
inlining `g` will replace them with it's another locals map,
because slices in Go reuse storage on `append`.
Thus scope needs to be copied.
This commit is contained in:
Evgeniy Stratonikov 2021-02-26 18:02:54 +03:00
parent b66b853285
commit 7577bbef22
3 changed files with 31 additions and 1 deletions

View file

@ -3,6 +3,8 @@ package compiler_test
import (
"errors"
"fmt"
"math/big"
"strconv"
"strings"
"testing"
@ -107,6 +109,7 @@ func newStoragePlugin() *storagePlugin {
s.interops[interopnames.ToID([]byte(interopnames.SystemStoragePut))] = s.Put
s.interops[interopnames.ToID([]byte(interopnames.SystemStorageGetContext))] = s.GetContext
s.interops[interopnames.ToID([]byte(interopnames.SystemRuntimeNotify))] = s.Notify
s.interops[interopnames.ToID([]byte(interopnames.SystemBinaryAtoi))] = s.Atoi
s.interops[interopnames.ToID([]byte(interopnames.SystemBinaryItoa))] = s.Itoa
return s
@ -123,6 +126,17 @@ func (s *storagePlugin) syscallHandler(v *vm.VM, id uint32) error {
return errors.New("syscall not found")
}
func (s *storagePlugin) Atoi(v *vm.VM) error {
str := v.Estack().Pop().String()
base := v.Estack().Pop().BigInt().Int64()
n, err := strconv.ParseInt(str, int(base), 64)
if err != nil {
return err
}
v.Estack().PushVal(big.NewInt(n))
return nil
}
func (s *storagePlugin) Itoa(v *vm.VM) error {
n := v.Estack().Pop().BigInt()
base := v.Estack().Pop().BigInt()