Skip to content
This repository was archived by the owner on May 11, 2020. It is now read-only.

Commit 8dd99d5

Browse files
zxh0sbinet
authored andcommitted
exec: fix order of stack value extraction for copysign arguments
Values extracted from the stack for the copysign function were extracted (and thus used) in the wrong order. This CL fixes this bug and adds tests for `float{32,64}`
1 parent 13360f2 commit 8dd99d5

File tree

2 files changed

+74
-2
lines changed

2 files changed

+74
-2
lines changed

exec/num.go

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -377,7 +377,9 @@ func (vm *VM) f32Max() {
377377
}
378378

379379
func (vm *VM) f32Copysign() {
380-
vm.pushFloat32(float32(math.Copysign(float64(vm.popFloat32()), float64(vm.popFloat32()))))
380+
v2 := vm.popFloat32()
381+
v1 := vm.popFloat32()
382+
vm.pushFloat32(float32(math.Copysign(float64(v1), float64(v2))))
381383
}
382384

383385
func (vm *VM) f32Eq() {
@@ -472,7 +474,9 @@ func (vm *VM) f64Max() {
472474
}
473475

474476
func (vm *VM) f64Copysign() {
475-
vm.pushFloat64(math.Copysign(vm.popFloat64(), vm.popFloat64()))
477+
v2 := vm.popFloat64()
478+
v1 := vm.popFloat64()
479+
vm.pushFloat64(math.Copysign(v1, v2))
476480
}
477481

478482
func (vm *VM) f64Eq() {

exec/num_test.go

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
// Copyright 2020 The go-interpreter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style
3+
// license that can be found in the LICENSE file.
4+
5+
package exec
6+
7+
import (
8+
"fmt"
9+
"testing"
10+
11+
"github.com/go-interpreter/wagon/wasm/operators"
12+
)
13+
14+
func TestF32BinOps(t *testing.T) {
15+
for _, tc := range []struct {
16+
opcode byte
17+
z1 float32
18+
z2 float32
19+
want float32
20+
}{
21+
{operators.F32Sub, 3.0, 2.0, 1.0},
22+
{operators.F32Copysign, 3.0, 2.0, 3.0},
23+
{operators.F32Copysign, 3.0, -2.0, -3.0},
24+
} {
25+
name, err := operators.New(tc.opcode)
26+
if err != nil {
27+
t.Fatalf("could not lookup operator 0x%x: %+v", tc.opcode, name)
28+
}
29+
t.Run(fmt.Sprintf("%v(%v,%v)", name, tc.z1, tc.z2), func(t *testing.T) {
30+
vm := new(VM)
31+
vm.newFuncTable()
32+
vm.pushFloat32(tc.z1)
33+
vm.pushFloat32(tc.z2)
34+
vm.funcTable[tc.opcode]()
35+
if got, want := vm.popFloat32(), tc.want; got != want {
36+
t.Fatalf("got=%v, want=%v", got, want)
37+
}
38+
})
39+
}
40+
}
41+
42+
func TestF64BinOps(t *testing.T) {
43+
for _, tc := range []struct {
44+
opcode byte
45+
z1 float64
46+
z2 float64
47+
want float64
48+
}{
49+
{operators.F64Sub, 3.0, 2.0, 1.0},
50+
{operators.F64Copysign, 3.0, 2.0, 3.0},
51+
{operators.F64Copysign, 3.0, -2.0, -3.0},
52+
} {
53+
name, err := operators.New(tc.opcode)
54+
if err != nil {
55+
t.Fatalf("could not lookup operator 0x%x: %+v", tc.opcode, name)
56+
}
57+
t.Run(fmt.Sprintf("%v(%v,%v)", name, tc.z1, tc.z2), func(t *testing.T) {
58+
vm := new(VM)
59+
vm.newFuncTable()
60+
vm.pushFloat64(tc.z1)
61+
vm.pushFloat64(tc.z2)
62+
vm.funcTable[tc.opcode]()
63+
if got, want := vm.popFloat64(), tc.want; got != want {
64+
t.Fatalf("got=%v, want=%v", got, want)
65+
}
66+
})
67+
}
68+
}

0 commit comments

Comments
 (0)