286 lines
4.6 KiB
Go
286 lines
4.6 KiB
Go
|
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
|
||
|
}
|
||
|
}
|