fix a bug in bytecode optimization code (#292)
* fix a bug in bytecode optimization code * add a test
This commit is contained in:
parent
d08a636e7c
commit
d1dd01499f
2 changed files with 28 additions and 3 deletions
12
bytecode.go
12
bytecode.go
|
@ -97,6 +97,7 @@ func (b *Bytecode) RemoveDuplicates() {
|
||||||
var deduped []Object
|
var deduped []Object
|
||||||
|
|
||||||
indexMap := make(map[int]int) // mapping from old constant index to new index
|
indexMap := make(map[int]int) // mapping from old constant index to new index
|
||||||
|
fns := make(map[*CompiledFunction]int)
|
||||||
ints := make(map[int64]int)
|
ints := make(map[int64]int)
|
||||||
strings := make(map[string]int)
|
strings := make(map[string]int)
|
||||||
floats := make(map[float64]int)
|
floats := make(map[float64]int)
|
||||||
|
@ -106,9 +107,14 @@ func (b *Bytecode) RemoveDuplicates() {
|
||||||
for curIdx, c := range b.Constants {
|
for curIdx, c := range b.Constants {
|
||||||
switch c := c.(type) {
|
switch c := c.(type) {
|
||||||
case *CompiledFunction:
|
case *CompiledFunction:
|
||||||
// add to deduped list
|
if newIdx, ok := fns[c]; ok {
|
||||||
indexMap[curIdx] = len(deduped)
|
indexMap[curIdx] = newIdx
|
||||||
deduped = append(deduped, c)
|
} else {
|
||||||
|
newIdx = len(deduped)
|
||||||
|
fns[c] = newIdx
|
||||||
|
indexMap[curIdx] = newIdx
|
||||||
|
deduped = append(deduped, c)
|
||||||
|
}
|
||||||
case *ImmutableMap:
|
case *ImmutableMap:
|
||||||
modName := inferModuleName(c)
|
modName := inferModuleName(c)
|
||||||
newIdx, ok := immutableMaps[modName]
|
newIdx, ok := immutableMaps[modName]
|
||||||
|
|
19
vm_test.go
19
vm_test.go
|
@ -2654,6 +2654,25 @@ export func(a) {
|
||||||
expectRun(t, `out = import("mod0")`,
|
expectRun(t, `out = import("mod0")`,
|
||||||
Opts().Module("mod0", `for v:=0;;v++ { if v == 3 { break } } }`),
|
Opts().Module("mod0", `for v:=0;;v++ { if v == 3 { break } } }`),
|
||||||
tengo.UndefinedValue)
|
tengo.UndefinedValue)
|
||||||
|
|
||||||
|
// duplicate compiled functions
|
||||||
|
// NOTE: module "mod" has a function with some local variable, and it's
|
||||||
|
// imported twice by the main script. That causes the same CompiledFunction
|
||||||
|
// put in constants twice and the Bytecode optimization (removing duplicate
|
||||||
|
// constants) should still work correctly.
|
||||||
|
expectRun(t, `
|
||||||
|
m1 := import("mod")
|
||||||
|
m2 := import("mod")
|
||||||
|
out = m1.x
|
||||||
|
`,
|
||||||
|
Opts().Module("mod", `
|
||||||
|
f1 := func(a, b) {
|
||||||
|
c := a + b + 1
|
||||||
|
return a + b + 1
|
||||||
|
}
|
||||||
|
export { x: 1 }
|
||||||
|
`),
|
||||||
|
1)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestModuleBlockScopes(t *testing.T) {
|
func TestModuleBlockScopes(t *testing.T) {
|
||||||
|
|
Loading…
Reference in a new issue