1 package goja
2
3 import (
4 "github.com/dop251/goja/file"
5 "github.com/dop251/goja/parser"
6 "github.com/dop251/goja/unistring"
7 "testing"
8 )
9
10 func TestTaggedTemplateArgExport(t *testing.T) {
11 vm := New()
12 vm.Set("f", func(v Value) {
13 v.Export()
14 })
15 vm.RunString("f`test`")
16 }
17
18 func TestVM1(t *testing.T) {
19 r := &Runtime{}
20 r.init()
21
22 vm := r.vm
23
24 vm.prg = &Program{
25 src: file.NewFile("dummy", "", 1),
26 values: []Value{valueInt(2), valueInt(3), asciiString("test")},
27 code: []instruction{
28 &bindGlobal{vars: []unistring.String{"v"}},
29 newObject,
30 setGlobal("v"),
31 loadVal(2),
32 loadVal(1),
33 loadVal(0),
34 add,
35 setElem,
36 pop,
37 loadDynamic("v"),
38 },
39 }
40
41 vm.run()
42
43 rv := vm.pop()
44
45 if obj, ok := rv.(*Object); ok {
46 if v := obj.self.getStr("test", nil).ToInteger(); v != 5 {
47 t.Fatalf("Unexpected property value: %v", v)
48 }
49 } else {
50 t.Fatalf("Unexpected result: %v", rv)
51 }
52
53 }
54
55 func TestEvalVar(t *testing.T) {
56 const SCRIPT = `
57 function test() {
58 var a;
59 return eval("var a = 'yes'; var z = 'no'; a;") === "yes" && a === "yes";
60 }
61 test();
62 `
63
64 testScript(SCRIPT, valueTrue, t)
65 }
66
67 func TestResolveMixedStack1(t *testing.T) {
68 const SCRIPT = `
69 function test(arg) {
70 var a = 1;
71 var scope = {};
72 (function() {return arg})(); // move arguments to stash
73 with (scope) {
74 a++; // resolveMixedStack1 here
75 return a + arg;
76 }
77 }
78 test(40);
79 `
80
81 testScript(SCRIPT, valueInt(42), t)
82 }
83
84 func TestNewArrayFromIterClosed(t *testing.T) {
85 const SCRIPT = `
86 const [a, ...other] = [];
87 assert.sameValue(a, undefined);
88 assert(Array.isArray(other));
89 assert.sameValue(other.length, 0);
90 `
91 testScriptWithTestLib(SCRIPT, _undefined, t)
92 }
93
94 func BenchmarkVmNOP2(b *testing.B) {
95 prg := []func(*vm){
96
97
98
99 jump(1).exec,
100 }
101
102 r := &Runtime{}
103 r.init()
104
105 vm := r.vm
106 vm.prg = &Program{
107 values: []Value{intToValue(2), intToValue(3)},
108 }
109
110 for i := 0; i < b.N; i++ {
111 vm.pc = 0
112 for !vm.halted() {
113 prg[vm.pc](vm)
114 }
115
116
123 }
124 }
125
126 func BenchmarkVmNOP(b *testing.B) {
127 r := &Runtime{}
128 r.init()
129
130 vm := r.vm
131 vm.prg = &Program{
132 code: []instruction{
133 jump(1),
134
135 },
136 }
137
138 for i := 0; i < b.N; i++ {
139 vm.pc = 0
140 vm.run()
141 }
142
143 }
144
145 func BenchmarkVm1(b *testing.B) {
146 r := &Runtime{}
147 r.init()
148
149 vm := r.vm
150
151
152
153
154 vm.prg = &Program{
155 values: []Value{valueInt(2), valueInt(3)},
156 code: []instruction{
157 loadVal(0),
158 loadVal(1),
159 add,
160 },
161 }
162
163 for i := 0; i < b.N; i++ {
164 vm.pc = 0
165 vm.run()
166 r := vm.pop()
167 if r.ToInteger() != 5 {
168 b.Fatalf("Unexpected result: %+v", r)
169 }
170 if vm.sp != 0 {
171 b.Fatalf("Unexpected sp: %d", vm.sp)
172 }
173 }
174 }
175
176 func BenchmarkFib(b *testing.B) {
177 const TEST_FIB = `
178 function fib(n) {
179 if (n < 2) return n;
180 return fib(n - 2) + fib(n - 1);
181 }
182
183 fib(35);
184 `
185 b.StopTimer()
186 prg, err := parser.ParseFile(nil, "test.js", TEST_FIB, 0)
187 if err != nil {
188 b.Fatal(err)
189 }
190
191 c := newCompiler()
192 c.compile(prg, false, true, nil)
193 c.p.dumpCode(b.Logf)
194
195 r := &Runtime{}
196 r.init()
197
198 vm := r.vm
199
200 var expectedResult Value = valueInt(9227465)
201
202 b.StartTimer()
203
204 vm.prg = c.p
205 vm.run()
206 v := vm.result
207
208 b.Logf("stack size: %d", len(vm.stack))
209 b.Logf("stashAllocs: %d", vm.stashAllocs)
210
211 if !v.SameAs(expectedResult) {
212 b.Fatalf("Result: %+v, expected: %+v", v, expectedResult)
213 }
214
215 }
216
217 func BenchmarkEmptyLoop(b *testing.B) {
218 const SCRIPT = `
219 function f() {
220 for (var i = 0; i < 100; i++) {
221 }
222 }
223 f()
224 `
225 b.StopTimer()
226 vm := New()
227 prg := MustCompile("test.js", SCRIPT, false)
228
229 b.StartTimer()
230 for i := 0; i < b.N; i++ {
231 vm.RunProgram(prg)
232 }
233 }
234
235 func BenchmarkVMAdd(b *testing.B) {
236 vm := &vm{}
237 vm.stack = append(vm.stack, nil, nil)
238 vm.sp = len(vm.stack)
239
240 var v1 Value = valueInt(3)
241 var v2 Value = valueInt(5)
242
243 for i := 0; i < b.N; i++ {
244 vm.stack[0] = v1
245 vm.stack[1] = v2
246 add.exec(vm)
247 vm.sp++
248 }
249 }
250
251 func BenchmarkFuncCall(b *testing.B) {
252 const SCRIPT = `
253 function f(a, b, c, d) {
254 }
255 `
256
257 b.StopTimer()
258
259 vm := New()
260 prg := MustCompile("test.js", SCRIPT, false)
261
262 vm.RunProgram(prg)
263 if f, ok := AssertFunction(vm.Get("f")); ok {
264 b.StartTimer()
265 for i := 0; i < b.N; i++ {
266 f(nil, nil, intToValue(1), intToValue(2), intToValue(3), intToValue(4), intToValue(5), intToValue(6))
267 }
268 } else {
269 b.Fatal("f is not a function")
270 }
271 }
272
273 func BenchmarkAssertInt(b *testing.B) {
274 v := intToValue(42)
275 for i := 0; i < b.N; i++ {
276 if i, ok := v.(valueInt); !ok || int64(i) != 42 {
277 b.Fatal()
278 }
279 }
280 }
281
View as plain text