ai_old/goja/vm_test.go

286 lines
4.6 KiB
Go
Raw Normal View History

2024-09-20 16:50:35 +08:00
package goja
import (
"github.com/dop251/goja/file"
"github.com/dop251/goja/parser"
"github.com/dop251/goja/unistring"
"testing"
)
func TestTaggedTemplateArgExport(t *testing.T) {
vm := New()
vm.Set("f", func(v Value) {
v.Export()
})
vm.RunString("f`test`")
}
func TestVM1(t *testing.T) {
r := &Runtime{}
r.init()
vm := r.vm
vm.prg = &Program{
src: file.NewFile("dummy", "", 1),
code: []instruction{
&bindGlobal{vars: []unistring.String{"v"}},
newObject,
setGlobal("v"),
loadVal{asciiString("test")},
loadVal{valueInt(3)},
loadVal{valueInt(2)},
add,
setElem,
pop,
loadDynamic("v"),
},
}
vm.run()
rv := vm.pop()
if obj, ok := rv.(*Object); ok {
if v := obj.self.getStr("test", nil).ToInteger(); v != 5 {
t.Fatalf("Unexpected property value: %v", v)
}
} else {
t.Fatalf("Unexpected result: %v", rv)
}
}
func TestEvalVar(t *testing.T) {
const SCRIPT = `
function test() {
var a;
return eval("var a = 'yes'; var z = 'no'; a;") === "yes" && a === "yes";
}
test();
`
testScript(SCRIPT, valueTrue, t)
}
func TestResolveMixedStack1(t *testing.T) {
const SCRIPT = `
function test(arg) {
var a = 1;
var scope = {};
(function() {return arg})(); // move arguments to stash
with (scope) {
a++; // resolveMixedStack1 here
return a + arg;
}
}
test(40);
`
testScript(SCRIPT, valueInt(42), t)
}
func TestNewArrayFromIterClosed(t *testing.T) {
const SCRIPT = `
const [a, ...other] = [];
assert.sameValue(a, undefined);
assert(Array.isArray(other));
assert.sameValue(other.length, 0);
`
testScriptWithTestLib(SCRIPT, _undefined, t)
}
func BenchmarkVmNOP2(b *testing.B) {
prg := []func(*vm){
//loadVal(0).exec,
//loadVal(1).exec,
//add.exec,
jump(1).exec,
}
r := &Runtime{}
r.init()
vm := r.vm
vm.prg = &Program{}
for i := 0; i < b.N; i++ {
vm.pc = 0
for !vm.halted() {
prg[vm.pc](vm)
}
//vm.sp--
/*r := vm.pop()
if r.ToInteger() != 5 {
b.Fatalf("Unexpected result: %+v", r)
}
if vm.sp != 0 {
b.Fatalf("Unexpected sp: %d", vm.sp)
}*/
}
}
func BenchmarkVmNOP(b *testing.B) {
r := &Runtime{}
r.init()
vm := r.vm
vm.prg = &Program{
code: []instruction{
jump(1),
//jump(1),
},
}
for i := 0; i < b.N; i++ {
vm.pc = 0
vm.run()
}
}
func BenchmarkVm1(b *testing.B) {
r := &Runtime{}
r.init()
vm := r.vm
//ins1 := loadVal1(0)
//ins2 := loadVal1(1)
vm.prg = &Program{
code: []instruction{
loadVal{valueInt(2)},
loadVal{valueInt(3)},
add,
},
}
for i := 0; i < b.N; i++ {
vm.pc = 0
vm.run()
r := vm.pop()
if r.ToInteger() != 5 {
b.Fatalf("Unexpected result: %+v", r)
}
if vm.sp != 0 {
b.Fatalf("Unexpected sp: %d", vm.sp)
}
}
}
func BenchmarkFib(b *testing.B) {
const TEST_FIB = `
function fib(n) {
if (n < 2) return n;
return fib(n - 2) + fib(n - 1);
}
fib(35);
`
b.StopTimer()
prg, err := parser.ParseFile(nil, "test.js", TEST_FIB, 0)
if err != nil {
b.Fatal(err)
}
c := newCompiler()
c.compile(prg, false, true, nil)
c.p.dumpCode(b.Logf)
r := &Runtime{}
r.init()
vm := r.vm
var expectedResult Value = valueInt(9227465)
b.StartTimer()
vm.prg = c.p
vm.run()
v := vm.result
b.Logf("stack size: %d", len(vm.stack))
b.Logf("stashAllocs: %d", vm.stashAllocs)
if !v.SameAs(expectedResult) {
b.Fatalf("Result: %+v, expected: %+v", v, expectedResult)
}
}
func BenchmarkEmptyLoop(b *testing.B) {
const SCRIPT = `
function f() {
for (var i = 0; i < 100; i++) {
}
}
f()
`
b.StopTimer()
vm := New()
prg := MustCompile("test.js", SCRIPT, false)
// prg.dumpCode(log.Printf)
b.StartTimer()
for i := 0; i < b.N; i++ {
vm.RunProgram(prg)
}
}
func BenchmarkVMAdd(b *testing.B) {
vm := &vm{}
vm.stack = append(vm.stack, nil, nil)
vm.sp = len(vm.stack)
var v1 Value = valueInt(3)
var v2 Value = valueInt(5)
for i := 0; i < b.N; i++ {
vm.stack[0] = v1
vm.stack[1] = v2
add.exec(vm)
vm.sp++
}
}
func BenchmarkFuncCall(b *testing.B) {
const SCRIPT = `
function f(a, b, c, d) {
}
`
b.StopTimer()
vm := New()
prg := MustCompile("test.js", SCRIPT, false)
vm.RunProgram(prg)
if f, ok := AssertFunction(vm.Get("f")); ok {
b.StartTimer()
for i := 0; i < b.N; i++ {
f(nil, nil, intToValue(1), intToValue(2), intToValue(3), intToValue(4), intToValue(5), intToValue(6))
}
} else {
b.Fatal("f is not a function")
}
}
func BenchmarkAssertInt(b *testing.B) {
v := intToValue(42)
for i := 0; i < b.N; i++ {
if i, ok := v.(valueInt); !ok || int64(i) != 42 {
b.Fatal()
}
}
}
func BenchmarkLoadVal(b *testing.B) {
var ins instruction
b.ReportAllocs()
for i := 0; i < b.N; i++ {
ins = loadVal{valueInt(1)}
_ = ins
}
}